X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FPlugin%2FAuthentication.pm;h=32b23daa7c8f42ca0ad2ad12c0a155c85afb4bb1;hb=1ca3887743d363fd1a8c544ef45a0d9680c98740;hp=211f609557c6553c091ecccc350a9e69750a8360;hpb=b003080b492fdac6ff876744b4666117ed85bd7b;p=catagits%2FCatalyst-Plugin-Authentication.git diff --git a/lib/Catalyst/Plugin/Authentication.pm b/lib/Catalyst/Plugin/Authentication.pm index 211f609..32b23da 100644 --- a/lib/Catalyst/Plugin/Authentication.pm +++ b/lib/Catalyst/Plugin/Authentication.pm @@ -5,25 +5,62 @@ package Catalyst::Plugin::Authentication; use base qw/Class::Accessor::Fast Class::Data::Inheritable/; BEGIN { - __PACKAGE__->mk_accessors(qw/user/); - __PACKAGE__->mk_classdata(qw/default_auth_store/); + __PACKAGE__->mk_accessors(qw/_user/); + __PACKAGE__->mk_classdata($_) for qw/_auth_stores _auth_store_names/; } use strict; use warnings; +use Tie::RefHash; +use Class::Inspector; + +BEGIN { + require constant; + constant->import(have_want => eval { require Want }); +} + +our $VERSION = "0.01"; + sub set_authenticated { my ( $c, $user ) = @_; $c->user($user); + $c->request->{user} = $user; # compatibility kludge if ( $c->isa("Catalyst::Plugin::Session") - and $c->config->{authentication}{use_session} ) + and $c->config->{authentication}{use_session} + and $user->supports("session") ) { - $c->session->{__user} = $user->for_session - if $user->supperts("session"); - $c->session->{__user_class} = ref $user; + $c->save_user_in_session($user); + } + + $c->NEXT::set_authenticated($user); +} + +sub user { + my $c = shift; + + if (@_) { + return $c->_user(@_); + } + + my $user = $c->_user; + + if ( $user and !Scalar::Util::blessed($user) ) { + return 1 if have_want() && Want::want("BOOL"); + return $c->auth_restore_user($user); } + + return $user; +} + +sub save_user_in_session { + my ( $c, $user ) = @_; + + my $store = $user->store || ref $user; + $c->session->{__user_store} = $c->get_auth_store_name($store) || $store; + $c->session->{__user} = $user->for_session; } sub logout { @@ -34,7 +71,7 @@ sub logout { if ( $c->isa("Catalyst::Plugin::Session") and $c->config->{authentication}{use_session} ) { - delete @{ $c->session }{qw/__user __user_class/}; + delete @{ $c->session }{qw/__user __user_store/}; } } @@ -54,31 +91,97 @@ sub get_user { sub prepare { my $c = shift->NEXT::prepare(@_); - if ( $c->isa("Catalyst::Plugin::Session") - and $c->config->{authentication}{use_session} + if ( $c->isa("Catalyst::Plugin::Session") and !$c->user ) { - if ( $c->sessionid and my $user = $c->session->{__user} ) { - $c->user( $c->session->{__user_class}->from_session( $c, $user ) ); + if ( $c->sessionid and my $frozen_user = $c->session->{__user} ) { + $c->_user($frozen_user); } } return $c; } +sub auth_restore_user { + my ( $c, $frozen_user, $store_name ) = @_; + + return + unless $c->isa("Catalyst::PLugin::Session") + and $c->config->{authentication}{use_session} + and $c->sessionid; + + $store_name ||= $c->session->{__user_store}; + $frozen_user ||= $c->session->{__user}; + + my $store = $c->get_auth_store($store_name); + $c->_user( my $user = $store->from_session( $c, $frozen_user ) ); + + return $user; + +} + sub setup { my $c = shift; - my $cfg = $c->config->{authentication}; + my $cfg = $c->config->{authentication} || {}; %$cfg = ( use_session => 1, %$cfg, ); + $c->register_auth_stores( + default => $cfg->{store}, + %{ $cfg->{stores} || {} }, + ); + $c->NEXT::setup(@_); } +sub get_auth_store { + my ( $self, $name ) = @_; + $self->auth_stores->{$name} || ( Class::Inspector->loaded($name) && $name ); +} + +sub get_auth_store_name { + my ( $self, $store ) = @_; + $self->auth_store_names->{$store}; +} + +sub register_auth_stores { + my ( $self, %new ) = @_; + + foreach my $name ( keys %new ) { + my $store = $new{$name} or next; + $self->auth_stores->{$name} = $store; + $self->auth_store_names->{$store} = $name; + } +} + +sub auth_stores { + my $self = shift; + $self->_auth_stores(@_) || $self->_auth_stores( {} ); +} + +sub auth_store_names { + my $self = shift; + + $self->_auth_store_names || do { + tie my %hash, 'Tie::RefHash'; + $self->_auth_store_names( \%hash ); + } +} + +sub default_auth_store { + my $self = shift; + + if ( my $new = shift ) { + $self->register_auth_stores( default => $new ); + } + + $self->get_auth_store("default"); +} + __PACKAGE__; __END__ @@ -87,7 +190,8 @@ __END__ =head1 NAME -Catalyst::Plugin::Authentication - +Catalyst::Plugin::Authentication - Infrastructure plugin for the Catalyst +authentication framework. =head1 SYNOPSIS @@ -102,29 +206,61 @@ Catalyst::Plugin::Authentication - The authentication plugin is used by the various authentication and authorization plugins in catalyst. -It defines the notion of a logged in user, and provides integration with the +It defines the notion of a logged in user, and provides integration with the +L plugin, =head1 METHODS =over 4 -=item logout - -Delete the currently logged in user from C and the session. - =item user Returns the currently logged user or undef if there is none. +=item logout + +Delete the currently logged in user from C and the session. + =item get_user $uid Delegate C to the default store. +=back + +=head1 METHODS FOR STORE MANAGEMENT + =item default_auth_store -Returns C<< $c->config->{authentication}{store} >>. +Return the store whose name is 'default'. -=back +This is set to C<<$c->config->{authentication}{store}>> if that value exists, +or by using a Store plugin: + + use Catalyst qw/Authentication Authentication::Store::Minimal/; + +Sets the default store to +L. + + +=item get_auth_store $name + +Return the store whose name is $name. + +=item get_auth_store_name $store + +Return the name of the store $store. + +=item auth_stores + +A hash keyed by name, with the stores registered in the app. + +=item auth_store_names + +A ref-hash keyed by store, which contains the names of the stores. + +=item register_auth_stores %stores_by_name + +Register stores into the application. =head1 INTERNAL METHODS @@ -139,6 +275,15 @@ authentication. This involves setting C and the internal data in C if L is loaded. +=item auth_restore_user $user + +Used to restore a user from the session, by C only when it's actually +needed. + +=item save_user_in_session $user + +Used to save the user in a session. + =item prepare Revives a user from the session object if there is one.