Lots of doc for C::P::Authentication
[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 }
55395841 32
4fbe2e14 33 $c->NEXT::set_authenticated($user);
06675d2e 34}
35
7bb06c91 36sub user {
e300c5b6 37 my $c = shift;
7bb06c91 38
e300c5b6 39 if (@_) {
40 return $c->_user(@_);
41 }
7bb06c91 42
e300c5b6 43 my $user = $c->_user;
7bb06c91 44
e300c5b6 45 if ( $user and !Scalar::Util::blessed($user) ) {
46 return $c->auth_restore_user($user);
47 }
7bb06c91 48
e300c5b6 49 return $user;
7bb06c91 50}
51
12dae309 52sub save_user_in_session {
e300c5b6 53 my ( $c, $user ) = @_;
12dae309 54
55 my $store = $user->store || ref $user;
56 $c->session->{__user_store} = $c->get_auth_store_name($store) || $store;
57 $c->session->{__user} = $user->for_session;
58}
59
06675d2e 60sub logout {
61 my $c = shift;
62
63 $c->user(undef);
b003080b 64
65 if ( $c->isa("Catalyst::Plugin::Session")
66 and $c->config->{authentication}{use_session} )
67 {
96777f3a 68 delete @{ $c->session }{qw/__user __user_store/};
b003080b 69 }
06675d2e 70}
71
7d0922d8 72sub get_user {
73 my ( $c, $uid ) = @_;
74
75 if ( my $store = $c->default_auth_store ) {
76 return $store->get_user($uid);
77 }
78 else {
79 Catalyst::Exception->throw(
80 "The user id $uid was passed to an authentication "
81 . "plugin, but no default store was specified" );
82 }
83}
84
06675d2e 85sub prepare {
86 my $c = shift->NEXT::prepare(@_);
87
4fbe2e14 88 if ( $c->isa("Catalyst::Plugin::Session")
06675d2e 89 and !$c->user )
90 {
7bb06c91 91 if ( $c->sessionid and my $frozen_user = $c->session->{__user} ) {
e300c5b6 92 $c->_user($frozen_user);
06675d2e 93 }
94 }
95
96 return $c;
97}
98
7bb06c91 99sub auth_restore_user {
e300c5b6 100 my ( $c, $frozen_user, $store_name ) = @_;
7bb06c91 101
4fbe2e14 102 return
103 unless $c->isa("Catalyst::PLugin::Session")
104 and $c->config->{authentication}{use_session}
105 and $c->sessionid;
4402d92d 106
e300c5b6 107 $store_name ||= $c->session->{__user_store};
108 $frozen_user ||= $c->session->{__user};
7bb06c91 109
e300c5b6 110 my $store = $c->get_auth_store($store_name);
111 $c->_user( my $user = $store->from_session( $c, $frozen_user ) );
7bb06c91 112
e300c5b6 113 return $user;
7bb06c91 114
115}
116
06675d2e 117sub setup {
118 my $c = shift;
119
712a35bf 120 my $cfg = $c->config->{authentication} || {};
06675d2e 121
122 %$cfg = (
123 use_session => 1,
124 %$cfg,
125 );
b003080b 126
12dae309 127 $c->register_auth_stores(
128 default => $cfg->{store},
129 %{ $cfg->{stores} || {} },
130 );
96777f3a 131
b003080b 132 $c->NEXT::setup(@_);
06675d2e 133}
134
96777f3a 135sub get_auth_store {
12dae309 136 my ( $self, $name ) = @_;
137 $self->auth_stores->{$name} || ( Class::Inspector->loaded($name) && $name );
96777f3a 138}
139
140sub get_auth_store_name {
12dae309 141 my ( $self, $store ) = @_;
142 $self->auth_store_names->{$store};
96777f3a 143}
144
145sub register_auth_stores {
12dae309 146 my ( $self, %new ) = @_;
96777f3a 147
12dae309 148 foreach my $name ( keys %new ) {
149 my $store = $new{$name} or next;
150 $self->auth_stores->{$name} = $store;
151 $self->auth_store_names->{$store} = $name;
152 }
96777f3a 153}
154
155sub auth_stores {
12dae309 156 my $self = shift;
157 $self->_auth_stores(@_) || $self->_auth_stores( {} );
96777f3a 158}
159
160sub auth_store_names {
12dae309 161 my $self = shift;
96777f3a 162
4402d92d 163 $self->_auth_store_names || do {
12dae309 164 tie my %hash, 'Tie::RefHash';
165 $self->_auth_store_names( \%hash );
4fbe2e14 166 }
96777f3a 167}
168
169sub default_auth_store {
12dae309 170 my $self = shift;
96777f3a 171
12dae309 172 if ( my $new = shift ) {
173 $self->register_auth_stores( default => $new );
174 }
96777f3a 175
12dae309 176 $self->get_auth_store("default");
96777f3a 177}
178
06675d2e 179__PACKAGE__;
180
181__END__
182
183=pod
184
185=head1 NAME
186
55395841 187Catalyst::Plugin::Authentication - Infrastructure plugin for the Catalyst
188authentication framework.
06675d2e 189
190=head1 SYNOPSIS
191
192 use Catalyst qw/
193 Authentication
194 Authentication::Store::Foo
195 Authentication::Credential::Password
196 /;
197
198=head1 DESCRIPTION
199
200The authentication plugin is used by the various authentication and
201authorization plugins in catalyst.
202
55395841 203It defines the notion of a logged in user, and provides integration with the
204L<Catalyst::Plugin::Session> plugin,
06675d2e 205
206=head1 METHODS
207
208=over 4
209
06675d2e 210=item user
211
212Returns the currently logged user or undef if there is none.
213
4402d92d 214=item logout
215
216Delete the currently logged in user from C<user> and the session.
217
7d0922d8 218=item get_user $uid
219
220Delegate C<get_user> to the default store.
221
4fbe2e14 222=back
223
224=head1 METHODS FOR STORE MANAGEMENT
225
7d0922d8 226=item default_auth_store
227
4fbe2e14 228Return the store whose name is 'default'.
7d0922d8 229
4fbe2e14 230This is set to C<<$c->config->{authentication}{store}>> if that value exists,
231or by using a Store plugin:
232
233 use Catalyst qw/Authentication Authentication::Store::Minimal/;
234
235Sets the default store to
236L<Catalyst::Plugin::Authentication::Store::Minimal::Backend>.
237
238=item get_auth_store $name
239
240Return the store whose name is $name.
241
242=item get_auth_store_name $store
243
244Return the name of the store $store.
245
246=item auth_stores
247
248A hash keyed by name, with the stores registered in the app.
249
250=item auth_store_names
251
252A ref-hash keyed by store, which contains the names of the stores.
253
254=item register_auth_stores %stores_by_name
255
256Register stores into the application.
06675d2e 257
258=head1 INTERNAL METHODS
259
260=over 4
261
262=item set_authenticated $user
263
264Marks a user as authenticated. Should be called from a
265C<Catalyst::Plugin::Authentication::Credential> plugin after successful
266authentication.
267
268This involves setting C<user> and the internal data in C<session> if
269L<Catalyst::Plugin::Session> is loaded.
270
e300c5b6 271=item auth_restore_user $user
272
273Used to restore a user from the session, by C<user> only when it's actually
274needed.
275
276=item save_user_in_session $user
277
278Used to save the user in a session.
279
06675d2e 280=item prepare
281
282Revives a user from the session object if there is one.
283
284=item setup
285
286Sets the default configuration parameters.
287
288=item
289
290=back
291
292=head1 CONFIGURATION
293
294=over 4
295
296=item use_session
297
298Whether or not to store the user's logged in state in the session, if the
299application is also using the L<Catalyst::Plugin::Authentication> plugin.
300
301=back
302
303=cut
304
305