Version bump plus changelog 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
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
7d0922d8 232=item default_auth_store
233
4fbe2e14 234Return the store whose name is 'default'.
7d0922d8 235
4fbe2e14 236This is set to C<<$c->config->{authentication}{store}>> if that value exists,
237or by using a Store plugin:
238
239 use Catalyst qw/Authentication Authentication::Store::Minimal/;
240
241Sets the default store to
242L<Catalyst::Plugin::Authentication::Store::Minimal::Backend>.
243
a1e5bd36 244
4fbe2e14 245=item get_auth_store $name
246
247Return the store whose name is $name.
248
249=item get_auth_store_name $store
250
251Return the name of the store $store.
252
253=item auth_stores
254
255A hash keyed by name, with the stores registered in the app.
256
257=item auth_store_names
258
259A ref-hash keyed by store, which contains the names of the stores.
260
261=item register_auth_stores %stores_by_name
262
263Register stores into the application.
06675d2e 264
265=head1 INTERNAL METHODS
266
267=over 4
268
269=item set_authenticated $user
270
271Marks a user as authenticated. Should be called from a
272C<Catalyst::Plugin::Authentication::Credential> plugin after successful
273authentication.
274
275This involves setting C<user> and the internal data in C<session> if
276L<Catalyst::Plugin::Session> is loaded.
277
e300c5b6 278=item auth_restore_user $user
279
280Used to restore a user from the session, by C<user> only when it's actually
281needed.
282
283=item save_user_in_session $user
284
285Used to save the user in a session.
286
06675d2e 287=item prepare
288
289Revives a user from the session object if there is one.
290
291=item setup
292
293Sets the default configuration parameters.
294
295=item
296
297=back
298
299=head1 CONFIGURATION
300
301=over 4
302
303=item use_session
304
305Whether or not to store the user's logged in state in the session, if the
306application is also using the L<Catalyst::Plugin::Authentication> plugin.
307
308=back
309
fbe577ac 310=head1 SEE ALSO
311
312L<Catalyst::Plugin::Authentication::Credential::Password>,
313L<Catalyst::Plugin::Authentication::Store::Minimal>,
314L<Catalyst::Plugin::Authorization::ACL>,
315L<Catalyst::Plugin::Authorization::Roles>.
316
317=head1 AUTHOR
318
319Yuval Kogman, C<nothingmuch@woobling.org>
06675d2e 320
fbe577ac 321=head1 COPYRIGHT & LICNESE
322
323 Copyright (c) 2005 the aforementioned authors. All rights
324 reserved. This program is free software; you can redistribute
325 it and/or modify it under the same terms as Perl itself.
326
327=cut
06675d2e 328