$self->config->{'use_session'} = 1;
}
}
- print STDERR "use session is " . $self->config->{'use_session'} . "\n";
+
$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'};
};
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;
}
};
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;
}
my ($self, $c) = @_;
return unless
- $c->isa("Catalyst::Plugin::Session")
+ $c->can('session')
and $self->config->{'use_session'}
and $c->session_is_valid;
$frozen_user ||= $self->user_is_restorable($c);
return unless defined($frozen_user);
- $c->_user( my $user = $self->from_session( $c, $frozen_user ) );
+ my $user = $self->from_session( $c, $frozen_user );
- # this sets the realm the user originated in.
- $user->auth_realm($self->name);
+ if ($user) {
+ $c->_user( $user );
+ # this sets the realm the user originated in.
+ $user->auth_realm($self->name);
+ }
+ 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")
) {
my ($self, $c) = @_;
if (
- $c->isa("Catalyst::Plugin::Session")
+ $c->can('session')
and $self->config->{'use_session'}
and $c->session_is_valid
) {
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
realm class simply delegates this to the credential and sets
the authenticated user on success. Returns the authenticated user object;
-=head2 save_user_in_session($c, $user)
+=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
+session system to accomplish this. By overriding the methods below
+in a custom Realm class, however, you can handle user persistance in
+any way you see fit.
+
+=head2 persist_user($c, $user)
+
+persist_user is the entry point for saving user information between requests
+in most cases this will utilize the session. By default this uses the
+catalyst session system to store the user by calling for_session on the
+active store. The user object must be a subclass of
+Catalyst::Authentication::User. If you have updated the user object, you
+must call persist_user again to ensure that the persisted user object reflects
+your updates.
-Used to save the user in a session. Saves $user in the current session,
-marked as originating in the current realm. Calls $store->for_session() by
-default. If for_session is not available in the store class, will attempt
-to call $user->for_session().
+=head2 remove_persisted_user($c)
+
+Removes any persisted user data. By default, removes the user from the session.
+
+=head2 user_is_restorable( $c )
+
+Returns whether there is a persisted user that may be restored. Returns
+a token used to restore the user. With the default session persistance
+it returns the raw frozen user information.
+
+=head2 restore_user($c, [$frozen_user])
+
+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 )
-Triggers restoring of the user from data in the session. The default realm
-class simply delegates the call to $store->from_session($c, $frozenuser);
+Decodes the frozenuser information provided and returns an instantiated
+user object. By default, this call is delegated to $store->from_session().
-=cut
+=head2 save_user_in_session($c, $user)
+DEPRECATED. Use persist_user instead. (this simply calls persist_user)
+
+=cut