From: Jay Kuri Date: Sun, 26 Oct 2008 23:29:14 +0000 (+0000) Subject: Changes to allow for dropping of the 'realms' config hash and instead X-Git-Tag: v0.10009_01~9 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=bf4d93a4eb7914bd8dda9e0c98895353e6653476;p=catagits%2FCatalyst-Plugin-Authentication.git Changes to allow for dropping of the 'realms' config hash and instead including each realm within the main Plugin::Authentication hash --- diff --git a/Changes b/Changes index ccad9d3..ab6bb59 100644 --- a/Changes +++ b/Changes @@ -1,17 +1,15 @@ Revision history for Perl extension Catalyst::Plugin::Authentication -0.1XXX XXXX - - Update tests prereqs to include Test::Exception (RT #36339) - - Update live tests to have plans, so that smoke tests against - 5.80 don't give false positives (t0m) +0.10007 2008-10-23 + - Updating config to allow for inclusion of realm ref's in the main + config hash rather than in a subref called 'realms' -0.10007_01 2008-06-05 +0.10007 2008-08-17 + - Update tests prereqs to include Test::Exception (RT #36339) - Some documentation fixes (including RT #36062) - Compatibility fix where the use of new style config and old style Authentication::Store::Minimal would cause a crash (Reported & fixed by Jos Boumans C) - -0.10007 2008-03-17 - Documentation update on Password - to indicate proper field naming - Decouple Authentication system from session. The realm class now allows complete control over how a user is persisted across diff --git a/lib/Catalyst/Authentication/Realm.pm b/lib/Catalyst/Authentication/Realm.pm index a0c3474..019189e 100644 --- a/lib/Catalyst/Authentication/Realm.pm +++ b/lib/Catalyst/Authentication/Realm.pm @@ -269,6 +269,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 +303,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 diff --git a/lib/Catalyst/Authentication/Store/Minimal.pm b/lib/Catalyst/Authentication/Store/Minimal.pm index 6fa764f..df3d93a 100644 --- a/lib/Catalyst/Authentication/Store/Minimal.pm +++ b/lib/Catalyst/Authentication/Store/Minimal.pm @@ -39,8 +39,6 @@ sub find_user { my $user = $self->userhash->{$id}; - #print STDERR "FOO1! " . ref($user) . " - ". Scalar::Util::blessed($user) . "\n"; - if ( ref($user) eq "HASH") { $user->{id} ||= $id; return bless $user, "Catalyst::Authentication::User::Hash"; diff --git a/lib/Catalyst/Plugin/Authentication.pm b/lib/Catalyst/Plugin/Authentication.pm index ae61fc6..0774362 100644 --- a/lib/Catalyst/Plugin/Authentication.pm +++ b/lib/Catalyst/Plugin/Authentication.pm @@ -13,8 +13,7 @@ use Tie::RefHash; use Class::Inspector; use Catalyst::Authentication::Realm; - -our $VERSION = "0.10007_01"; +our $VERSION = "0.10008"; sub set_authenticated { my ( $c, $user, $realmname ) = @_; @@ -56,7 +55,7 @@ sub user { # in addition to verifying that they exist. sub user_exists { my $c = shift; - return defined($c->_user) || defined($c->_find_realm_for_persisted_user); + return defined($c->_user) || defined($c->find_realm_for_persisted_user); } # works like user_exists - except only returns true if user @@ -67,7 +66,7 @@ sub user_in_realm { if (defined($c->_user)) { return ($c->_user->auth_realm eq $realmname); } else { - my $realm = $c->_find_realm_for_persisted_user; + my $realm = $c->find_realm_for_persisted_user; if ($realm) { return ($realm->name eq $realmname); } else { @@ -128,7 +127,7 @@ sub logout { $c->user(undef); - my $realm = $c->_find_realm_for_persisted_user; + my $realm = $c->find_realm_for_persisted_user; if ($realm) { $realm->remove_persisted_user($c); } @@ -149,8 +148,9 @@ sub find_user { return $realm->find_user($userinfo, $c); } - -sub _find_realm_for_persisted_user { +## Consider making this a public method. - would make certain things easier when +## dealing with things pre-auth restore. +sub find_realm_for_persisted_user { my $c = shift; my $realm; @@ -182,10 +182,10 @@ sub auth_restore_user { if (defined($realmname)) { $realm = $c->get_auth_realm($realmname); } else { - $realm = $c->_find_realm_for_persisted_user; + $realm = $c->find_realm_for_persisted_user; } - return unless $realm; # FIXME die unless? This is an internal inconsistency - + return undef unless $realm; # FIXME die unless? This is an internal inconsistency + $c->_user( my $user = $realm->restore_user( $c, $frozen_user ) ); # this sets the realm the user originated in. @@ -226,8 +226,9 @@ sub _authentication_initialize { ## into play if session is disabled. $app->mk_classdata( '_auth_realm_restore_order' => []); - + my $cfg = $app->config->{'Plugin::Authentication'}; + my $realmshash; if (!defined($cfg)) { if (exists($app->config->{'authentication'})) { $cfg = $app->config->{'authentication'}; @@ -235,7 +236,17 @@ sub _authentication_initialize { } else { $cfg = {}; } - } + } else { + # the realmshash contains the various configured realms. By default this is + # the main $app->config->{'Plugin::Authentication'} hash - but if that is + # not defined, or there is a subkey {'realms'} then we use that. + $realmshash = $cfg; + } + + ## If we have a sub-key of {'realms'} then we use that for realm configuration + if (exists($cfg->{'realms'})) { + $realmshash = $cfg->{'realms'}; + } # old default was to force use_session on. This must remain for that # reason - but if use_session is already in the config, we respect its setting. @@ -243,21 +254,25 @@ sub _authentication_initialize { $cfg->{'use_session'} = 1; } - if (exists($cfg->{'realms'})) { + ## if we have a realms hash + if (ref($realmshash) eq 'HASH') { my %auth_restore_order; my $authcount = 2; my $defaultrealm = 'default'; - - foreach my $realm (sort keys %{$cfg->{'realms'}}) { - - $app->setup_auth_realm($realm, $cfg->{'realms'}{$realm}); + + foreach my $realm (sort keys %{$realmshash}) { + if (ref($realmshash->{$realm}) eq 'HASH' && + (exists($realmshash->{$realm}{credential}) || exists($realmshash->{$realm}{class}))) { + + $app->setup_auth_realm($realm, $realmshash->{$realm}); - if (exists($cfg->{'realms'}{$realm}{'user_restore_priority'})) { - $auth_restore_order{$realm} = $cfg->{'realms'}{$realm}{'user_restore_priority'}; - } else { - $auth_restore_order{$realm} = $authcount++; - } + if (exists($realmshash->{$realm}{'user_restore_priority'})) { + $auth_restore_order{$realm} = $realmshash->{$realm}{'user_restore_priority'}; + } else { + $auth_restore_order{$realm} = $authcount++; + } + } } # if we have a 'default_realm' in the config hash and we don't already @@ -271,7 +286,7 @@ sub _authentication_initialize { } ## if the default realm did not have a defined priority in its config - we put it at the front. - if (!exists($cfg->{'realms'}{$defaultrealm}{'user_restore_priority'})) { + if (!exists($realmshash->{$defaultrealm}{'user_restore_priority'})) { $auth_restore_order{'default'} = 1; } @@ -614,30 +629,27 @@ This means that our application will begin like this: __PACKAGE__->config->{'Plugin::Authentication'} = { - default_realm => 'members', - realms => { - members => { - credential => { - class => 'Password', - password_field => 'password', - password_type => 'clear' - }, - store => { - class => 'Minimal', - users => { - bob => { - password => "s00p3r", - editor => 'yes', - roles => [qw/edit delete/], - }, - william => { - password => "s3cr3t", - roles => [qw/comment/], - } - } - } - } - } + default => { + credential => { + class => 'Password', + password_field => 'password', + password_type => 'clear' + }, + store => { + class => 'Minimal', + users => { + bob => { + password => "s00p3r", + editor => 'yes', + roles => [qw/edit delete/], + }, + william => { + password => "s3cr3t", + roles => [qw/comment/], + } + } + } + } }; @@ -738,33 +750,6 @@ changing your config: __PACKAGE__->config->{'Plugin::Authentication'} = { default_realm => 'members', - realms => { - members => { - credential => { - class => 'Password', - password_field => 'password', - password_type => 'clear' - }, - store => { - class => 'DBIx::Class', - user_class => 'MyApp::Users', - role_column => 'roles' - } - } - } - }; - -The authentication system works behind the scenes to load your data from the -new source. The rest of your application is completely unchanged. - - -=head1 CONFIGURATION - - # example - __PACKAGE__->config->{'Plugin::Authentication'} = - { - default_realm => 'members', - realms => { members => { credential => { class => 'Password', @@ -776,20 +761,43 @@ new source. The rest of your application is completely unchanged. user_class => 'MyApp::Users', role_column => 'roles' } - }, - admins => { - credential => { - class => 'Password', - password_field => 'password', - password_type => 'clear' - }, - store => { - class => '+MyApp::Authentication::Store::NetAuth', - authserver => '192.168.10.17' - } } - - } + }; + +The authentication system works behind the scenes to load your data from the +new source. The rest of your application is completely unchanged. + + +=head1 CONFIGURATION + + # example + __PACKAGE__->config->{'Plugin::Authentication'} = + { + default_realm => 'members', + + members => { + credential => { + class => 'Password', + password_field => 'password', + password_type => 'clear' + }, + store => { + class => 'DBIx::Class', + user_class => 'MyApp::Users', + role_column => 'roles' + } + }, + admins => { + credential => { + class => 'Password', + password_field => 'password', + password_type => 'clear' + }, + store => { + class => '+MyApp::Authentication::Store::NetAuth', + authserver => '192.168.10.17' + } + } }; =over 4 @@ -805,11 +813,15 @@ value is set to true per default. This defines which realm should be used as when no realm is provided to methods that require a realm such as authenticate or find_user. -=item realms +=item realm refs -This contains the series of realm configurations you want to use for your app. -The only rule here is that there must be at least one. A realm consists of a -name, which is used to reference the realm, a credential and a store. +The Plugin::Authentication config hash contains the series of realm +configurations you want to use for your app. The only rule here is +that there must be at least one. A realm consists of a name, which is used +to reference the realm, a credential and a store. You may also put your +realm configurations within a subelement called 'realms' if you desire to +separate them from the remainder of your configuration. Note that if you use +a 'realms' subelement, you must put ALL of your realms within it. You can also specify a realm class to instantiate instead of the default L class using the 'class' element within the diff --git a/lib/Catalyst/Plugin/Authentication/Internals.pod b/lib/Catalyst/Plugin/Authentication/Internals.pod index 5106094..9c2b0f6 100644 --- a/lib/Catalyst/Plugin/Authentication/Internals.pod +++ b/lib/Catalyst/Plugin/Authentication/Internals.pod @@ -88,7 +88,7 @@ the credentials match, the authenticate() method should return a user object. If the user object supports session storage, the successfully authenticated user will be placed in session storage. This is done by calling the realm -object's save_user_in_session() method. The save_user_in_session() routine by +object's persist_user() method. The persist_user() routine by default calls the Store's for_session() method, which should return serialized data (IE a scalar). This serialized data is passed back to the store via the from_session() method, so the data should contain enough information for the @@ -106,7 +106,7 @@ B - Per-Request operations When any user-related activity occurs, and $c->authenticate has not yet been called, the Catalyst::Plugin::Authentication module will -attempt to restore the user from the session (if one is available). +attempt to restore the persisted user (normally from the session if one is available). There is only one step in this process: =over 4 @@ -122,7 +122,7 @@ method should return a valid user object. Note that the for_session() is only called during the original $c->authenticate() call, so if changes are made to the user that need to be reflected in your session data, you will want to call the -$c->save_user_in_session() method - which will perform the session +$c->persist_user() method - which will perform the session storage process again (complete with call to for_session()). =back diff --git a/t/lib/AuthRealmTestAppCompat.pm b/t/lib/AuthRealmTestAppCompat.pm index 4a8b50c..8ff5389 100644 --- a/t/lib/AuthRealmTestAppCompat.pm +++ b/t/lib/AuthRealmTestAppCompat.pm @@ -43,7 +43,6 @@ sub moose : Local { __PACKAGE__->config->{'Plugin::Authentication'} = { default_realm => 'members', - realms => { members => { credential => { class => 'Password', @@ -55,7 +54,7 @@ __PACKAGE__->config->{'Plugin::Authentication'} = { users => $members, } }, - } + }; __PACKAGE__->setup; diff --git a/t/lib/AuthSessionTestApp.pm b/t/lib/AuthSessionTestApp.pm index e3f3680..49ec14b 100644 --- a/t/lib/AuthSessionTestApp.pm +++ b/t/lib/AuthSessionTestApp.pm @@ -68,7 +68,7 @@ sub butterfly : Local { ok( !$c->user, "no user object either" ); } -__PACKAGE__->config->{'Plugin::Authentication'}{users} = $users = { +__PACKAGE__->config->{'authentication'}{users} = $users = { foo => User::SessionRestoring->new( id => 'foo', password => "s3cr3t", diff --git a/t/lib/AuthTestApp.pm b/t/lib/AuthTestApp.pm index 1c43cd1..529e32f 100644 --- a/t/lib/AuthTestApp.pm +++ b/t/lib/AuthTestApp.pm @@ -13,9 +13,13 @@ use Digest::SHA1 qw/sha1_base64/; our $users; +sub number_of_elements { return scalar @_ } + sub moose : Local { my ( $self, $c ) = @_; + is(number_of_elements($c->user), 1, "Array undef"); + is($c->user, undef, "no user, returns undef"); ok(!$c->user, "no user"); ok($c->login( "foo", "s3cr3t" ), "can login with clear"); is( $c->user, $users->{foo}, "user object is in proper place"); diff --git a/t/live_app.t b/t/live_app.t index d3da817..70ca676 100644 --- a/t/live_app.t +++ b/t/live_app.t @@ -1,10 +1,11 @@ use strict; use warnings; -use Test::More tests => 1; +use Test::More; BEGIN { plan skip_all => "Digest::SHA1 is required for this test" unless eval { require Digest::SHA1 }; + plan "no_plan"; } use lib 't/lib'; diff --git a/t/live_app_realms.t b/t/live_app_realms.t index 0e1fbc6..0e79b8b 100644 --- a/t/live_app_realms.t +++ b/t/live_app_realms.t @@ -1,7 +1,12 @@ use strict; use warnings; -use Test::More tests => 1; +use Test::More; + +BEGIN { + plan "no_plan"; +} + use lib 't/lib'; use Catalyst::Test qw/AuthRealmTestApp/; diff --git a/t/live_app_realms_compat.t b/t/live_app_realms_compat.t index a4bbbbb..5deccf1 100644 --- a/t/live_app_realms_compat.t +++ b/t/live_app_realms_compat.t @@ -1,7 +1,11 @@ use strict; use warnings; -use Test::More tests => 1; +use Test::More; + +BEGIN { + plan "no_plan"; +} use lib 't/lib'; use Catalyst::Test qw/AuthRealmTestAppCompat/;