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