Also check hex digests in Cred::Password
[catagits/Catalyst-Plugin-Authentication.git] / lib / Catalyst / Plugin / Authentication.pm
CommitLineData
06675d2e 1#!/usr/bin/perl
2
3package Catalyst::Plugin::Authentication;
4
b003080b 5use base qw/Class::Accessor::Fast Class::Data::Inheritable/;
06675d2e 6
b003080b 7BEGIN {
7bb06c91 8 __PACKAGE__->mk_accessors(qw/_user/);
96777f3a 9 __PACKAGE__->mk_classdata($_) for qw/_auth_stores _auth_store_names/;
b003080b 10}
06675d2e 11
12use strict;
13use warnings;
14
96777f3a 15use Tie::RefHash;
12dae309 16use Class::Inspector;
96777f3a 17
c7c003d3 18our $VERSION = "0.01";
19
06675d2e 20sub set_authenticated {
21 my ( $c, $user ) = @_;
22
23 $c->user($user);
e300c5b6 24 $c->request->{user} = $user; # compatibility kludge
06675d2e 25
26 if ( $c->isa("Catalyst::Plugin::Session")
96777f3a 27 and $c->config->{authentication}{use_session}
12dae309 28 and $user->supports("session") )
06675d2e 29 {
12dae309 30 $c->save_user_in_session($user);
06675d2e 31 }
32}
33
7bb06c91 34sub user {
e300c5b6 35 my $c = shift;
7bb06c91 36
e300c5b6 37 if (@_) {
38 return $c->_user(@_);
39 }
7bb06c91 40
e300c5b6 41 my $user = $c->_user;
7bb06c91 42
e300c5b6 43 if ( $user and !Scalar::Util::blessed($user) ) {
44 return $c->auth_restore_user($user);
45 }
7bb06c91 46
e300c5b6 47 return $user;
7bb06c91 48}
49
12dae309 50sub save_user_in_session {
e300c5b6 51 my ( $c, $user ) = @_;
12dae309 52
53 my $store = $user->store || ref $user;
54 $c->session->{__user_store} = $c->get_auth_store_name($store) || $store;
55 $c->session->{__user} = $user->for_session;
56}
57
06675d2e 58sub logout {
59 my $c = shift;
60
61 $c->user(undef);
b003080b 62
63 if ( $c->isa("Catalyst::Plugin::Session")
64 and $c->config->{authentication}{use_session} )
65 {
96777f3a 66 delete @{ $c->session }{qw/__user __user_store/};
b003080b 67 }
06675d2e 68}
69
7d0922d8 70sub get_user {
71 my ( $c, $uid ) = @_;
72
73 if ( my $store = $c->default_auth_store ) {
74 return $store->get_user($uid);
75 }
76 else {
77 Catalyst::Exception->throw(
78 "The user id $uid was passed to an authentication "
79 . "plugin, but no default store was specified" );
80 }
81}
82
06675d2e 83sub prepare {
84 my $c = shift->NEXT::prepare(@_);
85
86 if ( $c->isa("Catalyst::Plugin::Session")
22be989b 87 and $c->default_auth_store
06675d2e 88 and !$c->user )
89 {
7bb06c91 90 if ( $c->sessionid and my $frozen_user = $c->session->{__user} ) {
e300c5b6 91 $c->_user($frozen_user);
06675d2e 92 }
93 }
94
95 return $c;
96}
97
7bb06c91 98sub auth_restore_user {
e300c5b6 99 my ( $c, $frozen_user, $store_name ) = @_;
7bb06c91 100
e300c5b6 101 $store_name ||= $c->session->{__user_store};
102 $frozen_user ||= $c->session->{__user};
7bb06c91 103
e300c5b6 104 my $store = $c->get_auth_store($store_name);
105 $c->_user( my $user = $store->from_session( $c, $frozen_user ) );
7bb06c91 106
e300c5b6 107 return $user;
7bb06c91 108
109}
110
06675d2e 111sub setup {
112 my $c = shift;
113
712a35bf 114 my $cfg = $c->config->{authentication} || {};
06675d2e 115
116 %$cfg = (
117 use_session => 1,
118 %$cfg,
119 );
b003080b 120
12dae309 121 $c->register_auth_stores(
122 default => $cfg->{store},
123 %{ $cfg->{stores} || {} },
124 );
96777f3a 125
b003080b 126 $c->NEXT::setup(@_);
06675d2e 127}
128
96777f3a 129sub get_auth_store {
12dae309 130 my ( $self, $name ) = @_;
131 $self->auth_stores->{$name} || ( Class::Inspector->loaded($name) && $name );
96777f3a 132}
133
134sub get_auth_store_name {
12dae309 135 my ( $self, $store ) = @_;
136 $self->auth_store_names->{$store};
96777f3a 137}
138
139sub register_auth_stores {
12dae309 140 my ( $self, %new ) = @_;
96777f3a 141
12dae309 142 foreach my $name ( keys %new ) {
143 my $store = $new{$name} or next;
144 $self->auth_stores->{$name} = $store;
145 $self->auth_store_names->{$store} = $name;
146 }
96777f3a 147}
148
149sub auth_stores {
12dae309 150 my $self = shift;
151 $self->_auth_stores(@_) || $self->_auth_stores( {} );
96777f3a 152}
153
154sub auth_store_names {
12dae309 155 my $self = shift;
96777f3a 156
12dae309 157 unless ( $self->_auth_store_names ) {
158 tie my %hash, 'Tie::RefHash';
159 $self->_auth_store_names( \%hash );
160 }
96777f3a 161
12dae309 162 $self->_auth_store_names;
96777f3a 163}
164
165sub default_auth_store {
12dae309 166 my $self = shift;
96777f3a 167
12dae309 168 if ( my $new = shift ) {
169 $self->register_auth_stores( default => $new );
170 }
96777f3a 171
12dae309 172 $self->get_auth_store("default");
96777f3a 173}
174
06675d2e 175__PACKAGE__;
176
177__END__
178
179=pod
180
181=head1 NAME
182
183Catalyst::Plugin::Authentication -
184
185=head1 SYNOPSIS
186
187 use Catalyst qw/
188 Authentication
189 Authentication::Store::Foo
190 Authentication::Credential::Password
191 /;
192
193=head1 DESCRIPTION
194
195The authentication plugin is used by the various authentication and
196authorization plugins in catalyst.
197
198It defines the notion of a logged in user, and provides integration with the
199
200=head1 METHODS
201
202=over 4
203
204=item logout
205
206Delete the currently logged in user from C<user> and the session.
207
208=item user
209
210Returns the currently logged user or undef if there is none.
211
7d0922d8 212=item get_user $uid
213
214Delegate C<get_user> to the default store.
215
216=item default_auth_store
217
218Returns C<< $c->config->{authentication}{store} >>.
219
06675d2e 220=back
221
222=head1 INTERNAL METHODS
223
224=over 4
225
226=item set_authenticated $user
227
228Marks a user as authenticated. Should be called from a
229C<Catalyst::Plugin::Authentication::Credential> plugin after successful
230authentication.
231
232This involves setting C<user> and the internal data in C<session> if
233L<Catalyst::Plugin::Session> is loaded.
234
e300c5b6 235=item auth_restore_user $user
236
237Used to restore a user from the session, by C<user> only when it's actually
238needed.
239
240=item save_user_in_session $user
241
242Used to save the user in a session.
243
06675d2e 244=item prepare
245
246Revives a user from the session object if there is one.
247
248=item setup
249
250Sets the default configuration parameters.
251
252=item
253
254=back
255
256=head1 CONFIGURATION
257
258=over 4
259
260=item use_session
261
262Whether or not to store the user's logged in state in the session, if the
263application is also using the L<Catalyst::Plugin::Authentication> plugin.
264
265=back
266
267=cut
268
269