3 package Catalyst::Plugin::Authentication;
5 use base qw/Class::Accessor::Fast Class::Data::Inheritable/;
8 __PACKAGE__->mk_accessors(qw/_user/);
9 __PACKAGE__->mk_classdata($_) for qw/_auth_stores _auth_store_names/;
20 # constant->import(have_want => eval { require Want });
23 our $VERSION = "0.02";
25 sub set_authenticated {
26 my ( $c, $user ) = @_;
29 $c->request->{user} = $user; # compatibility kludge
31 if ( $c->isa("Catalyst::Plugin::Session")
32 and $c->config->{authentication}{use_session}
33 and $user->supports("session") )
35 $c->save_user_in_session($user);
38 $c->NEXT::set_authenticated($user);
50 if ( $user and !Scalar::Util::blessed($user) ) {
51 # return 1 if have_want() && Want::want("BOOL");
52 return $c->auth_restore_user($user);
60 return defined($c->_user);
63 sub save_user_in_session {
64 my ( $c, $user ) = @_;
66 my $store = $user->store || ref $user;
67 $c->session->{__user_store} = $c->get_auth_store_name($store) || $store;
68 $c->session->{__user} = $user->for_session;
76 if ( $c->isa("Catalyst::Plugin::Session")
77 and $c->config->{authentication}{use_session} )
79 delete @{ $c->session }{qw/__user __user_store/};
88 if ( my $store = $c->default_auth_store ) {
89 return $store->get_user($uid);
92 Catalyst::Exception->throw(
93 "The user id $uid was passed to an authentication "
94 . "plugin, but no default store was specified" );
99 my $c = shift->NEXT::prepare(@_);
101 if ( $c->isa("Catalyst::Plugin::Session")
104 if ( $c->sessionid and my $frozen_user = $c->session->{__user} ) {
105 $c->_user($frozen_user);
112 sub auth_restore_user {
113 my ( $c, $frozen_user, $store_name ) = @_;
116 unless $c->isa("Catalyst::Plugin::Session")
117 and $c->config->{authentication}{use_session}
120 $store_name ||= $c->session->{__user_store};
121 $frozen_user ||= $c->session->{__user};
123 my $store = $c->get_auth_store($store_name);
124 $c->_user( my $user = $store->from_session( $c, $frozen_user ) );
133 my $cfg = $c->config->{authentication} || {};
140 $c->register_auth_stores(
141 default => $cfg->{store},
142 %{ $cfg->{stores} || {} },
149 my ( $self, $name ) = @_;
150 $self->auth_stores->{$name} || ( Class::Inspector->loaded($name) && $name );
153 sub get_auth_store_name {
154 my ( $self, $store ) = @_;
155 $self->auth_store_names->{$store};
158 sub register_auth_stores {
159 my ( $self, %new ) = @_;
161 foreach my $name ( keys %new ) {
162 my $store = $new{$name} or next;
163 $self->auth_stores->{$name} = $store;
164 $self->auth_store_names->{$store} = $name;
170 $self->_auth_stores(@_) || $self->_auth_stores( {} );
173 sub auth_store_names {
176 $self->_auth_store_names || do {
177 tie my %hash, 'Tie::RefHash';
178 $self->_auth_store_names( \%hash );
182 sub default_auth_store {
185 if ( my $new = shift ) {
186 $self->register_auth_stores( default => $new );
189 $self->get_auth_store("default");
200 Catalyst::Plugin::Authentication - Infrastructure plugin for the Catalyst
201 authentication framework.
207 Authentication::Store::Foo
208 Authentication::Credential::Password
212 # ->login is provided by the Credential::Password module
213 $c->login('myusername', 'mypassword');
214 my $age = $c->user->age;
219 The authentication plugin provides generic user support. It is the basis
220 for both authentication (checking the user is who they claim to be), and
221 authorization (allowing the user to do what the system authorises them to do).
223 Using authentication is split into two parts. A Store is used to actually
224 store the user information, and can store any amount of data related to
225 the user. Multiple stores can be accessed from within one application.
226 Credentials are used to verify users, using the store, given data from
229 To implement authentication in a catalyst application you need to add this
230 module, plus at least one store and one credential module.
232 Authentication data can also be stored in a session, if the application
233 is using the L<Catalyst::Plugin::Session> module.
241 Returns the currently logged in user or undef if there is none.
245 Whether or not a user is logged in right now.
247 The reason this method exists is that C<<$c->user>> may needlessly load the
248 user from the auth store.
250 If you're just going to say
252 if ( $c->user_user ) {
255 $c->forward("login");
258 it should be more efficient than C<<$c->user>> when a user is marked in the session
259 but C<< $c->user >> hasn't been called yet.
263 Delete the currently logged in user from C<user> and the session.
267 Fetch a particular users details, defined by the given ID, via the default store.
277 Whether or not to store the user's logged in state in the session, if the
278 application is also using the L<Catalyst::Plugin::Session> plugin. This
279 value is set to true per default.
283 If multiple stores are being used, set the module you want as default here.
289 If multiple stores are being used, you need to provide a name for each store
290 here, as a hash, the keys are the names you wish to use, and the values are
291 the the names of the plugins.
294 __PACKAGE__->config( authentication => {
295 store => 'Catalyst::Plugin::Authentication::Store::HtPasswd',
297 'dbic' => 'Catalyst::Plugin::Authentication::Store::DBIC'
302 =head1 METHODS FOR STORE MANAGEMENT
306 =item default_auth_store
308 Return the store whose name is 'default'.
310 This is set to C<< $c->config->{authentication}{store} >> if that value exists,
311 or by using a Store plugin:
313 use Catalyst qw/Authentication Authentication::Store::Minimal/;
315 Sets the default store to
316 L<Catalyst::Plugin::Authentication::Store::Minimal::Backend>.
319 =item get_auth_store $name
321 Return the store whose name is $name.
323 =item get_auth_store_name $store
325 Return the name of the store $store.
329 A hash keyed by name, with the stores registered in the app.
331 =item auth_store_names
333 A ref-hash keyed by store, which contains the names of the stores.
335 =item register_auth_stores %stores_by_name
337 Register stores into the application.
341 =head1 INTERNAL METHODS
345 =item set_authenticated $user
347 Marks a user as authenticated. Should be called from a
348 C<Catalyst::Plugin::Authentication::Credential> plugin after successful
351 This involves setting C<user> and the internal data in C<session> if
352 L<Catalyst::Plugin::Session> is loaded.
354 =item auth_restore_user $user
356 Used to restore a user from the session, by C<user> only when it's actually
359 =item save_user_in_session $user
361 Used to save the user in a session.
365 Revives a user from the session object if there is one.
369 Sets the default configuration parameters.
377 L<Catalyst::Plugin::Authentication::Credential::Password>,
378 L<Catalyst::Plugin::Authentication::Store::Minimal>,
379 L<Catalyst::Plugin::Authorization::ACL>,
380 L<Catalyst::Plugin::Authorization::Roles>.
384 Yuval Kogman, C<nothingmuch@woobling.org>
388 =head1 COPYRIGHT & LICNESE
390 Copyright (c) 2005 the aforementioned authors. All rights
391 reserved. This program is free software; you can redistribute
392 it and/or modify it under the same terms as Perl itself.