X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FAuthentication%2FRealm.pm;h=db9b4c27a81b3fe66965620872502ca435eb53b0;hb=f0312fca4a199bf694276f180d566ca4e4e28875;hp=a0c3474b53ad7265bd5b67b48329a2191043dabf;hpb=bfbbe6e7a1a14a90657d8f652380736159bc9e7e;p=catagits%2FCatalyst-Plugin-Authentication.git diff --git a/lib/Catalyst/Authentication/Realm.pm b/lib/Catalyst/Authentication/Realm.pm index a0c3474..db9b4c2 100644 --- a/lib/Catalyst/Authentication/Realm.pm +++ b/lib/Catalyst/Authentication/Realm.pm @@ -29,10 +29,13 @@ sub new { $app->log->debug("Setting up auth realm $realmname") if $app->debug; - # use the Null store as a default - if( ! exists $config->{store}{class} ) { + # use the Null store as a default - Don't complain if the realm class is being overridden, + # as the new realm may behave differently. + if( ! exists($config->{store}{class}) ) { $config->{store}{class} = '+Catalyst::Authentication::Store::Null'; - $app->log->debug( qq(No Store specified for realm "$realmname", using the Null store.) ); + if (! exists($config->{class})) { + $app->log->debug( qq(No Store specified for realm "$realmname", using the Null store.) ); + } } my $storeclass = $config->{'store'}{'class'}; @@ -71,12 +74,18 @@ sub new { }; if ($@) { + # If the file is missing, then try the old-style fallback, + # but re-throw anything else for the user to deal with. + die unless $@ =~ /^Can't locate/; $app->log->warn( qq(Credential class "$credentialclass" not found, trying deprecated ::Plugin:: style naming. ) ); my $origcredentialclass = $credentialclass; $credentialclass =~ s/Catalyst::Authentication/Catalyst::Plugin::Authentication/; eval { Catalyst::Utils::ensure_class_loaded( $credentialclass ); }; if ($@) { + # Likewise this croak is useful if the second exception is also "not found", + # but would be confusing if it's anything else. + die unless $@ =~ /^Can't locate/; Carp::croak "Unable to load credential class, " . $origcredentialclass . " OR " . $credentialclass . " in realm " . $self->name; } @@ -87,11 +96,17 @@ sub new { }; if ($@) { + # If the file is missing, then try the old-style fallback, + # but re-throw anything else for the user to deal with. + die unless $@ =~ /^Can't locate/; $app->log->warn( qq(Store class "$storeclass" not found, trying deprecated ::Plugin:: style naming. ) ); my $origstoreclass = $storeclass; $storeclass =~ s/Catalyst::Authentication/Catalyst::Plugin::Authentication/; eval { Catalyst::Utils::ensure_class_loaded( $storeclass ); }; if ($@) { + # Likewise this croak is useful if the second exception is also "not found", + # but would be confusing if it's anything else. + die unless $@ =~ /^Can't locate/; Carp::croak "Unable to load store class, " . $origstoreclass . " OR " . $storeclass . " in realm " . $self->name; } @@ -159,7 +174,7 @@ sub user_is_restorable { my ($self, $c) = @_; return unless - $c->isa("Catalyst::Plugin::Session") + $c->can('session') and $self->config->{'use_session'} and $c->session_is_valid; @@ -179,18 +194,30 @@ sub restore_user { # this sets the realm the user originated in. $user->auth_realm($self->name); - } else { - Catalyst::Exception->throw("Store claimed to have a restorable user, but restoration failed. Did you change the user's id_field?"); + } + else { + $self->failed_user_restore($c) || + $c->error("Store claimed to have a restorable user, but restoration failed. Did you change the user's id_field?"); } return $user; } +## this occurs if there is a session but the thing the session refers to +## can not be found. Do what you must do here. +## Return true if you can fix the situation and find a user, false otherwise +sub failed_user_restore { + my ($self, $c) = @_; + + $self->remove_persisted_user($c); + return; +} + sub persist_user { my ($self, $c, $user) = @_; if ( - $c->isa("Catalyst::Plugin::Session") + $c->can('session') and $self->config->{'use_session'} and $user->supports("session") ) { @@ -212,7 +239,7 @@ sub remove_persisted_user { my ($self, $c) = @_; if ( - $c->isa("Catalyst::Plugin::Session") + $c->can('session') and $self->config->{'use_session'} and $c->session_is_valid ) { @@ -269,6 +296,11 @@ user doesn't exist (most useful for remote authentication schemes). Set this to true if you wish this realm to auto-update user accounts after authentication (most useful for remote authentication schemes). +=item use_session + +Sets session usage for this particular realm - overriding the global use_sesion setting. + + =back =head1 METHODS @@ -298,7 +330,7 @@ Performs the authentication process for the current realm. The default realm class simply delegates this to the credential and sets the authenticated user on success. Returns the authenticated user object; -=head1 USER PERSISTANCE +=head1 USER PERSISTENCE The Realm class allows complete control over the persistance of users between requests. By default the realm attempts to use the Catalyst @@ -332,6 +364,11 @@ Restores the user from the given frozen_user parameter, or if not provided, using the response from $self->user_is_restorable(); Uses $self->from_session() to decode the frozen user. +=head2 failed_user_restore($c) + +If there is a session to restore, but the restore fails for any reason then this method +is called. This method supplied just removes the persisted user, but can be overridden +if required to have more complex logic (e.g. finding a the user by their 'old' username). =head2 from_session($c, $frozenuser )