Changes to allow for dropping of the 'realms' config hash and instead
Jay Kuri [Sun, 26 Oct 2008 23:29:14 +0000 (23:29 +0000)]
including each realm within the main Plugin::Authentication hash

Changes
lib/Catalyst/Authentication/Realm.pm
lib/Catalyst/Authentication/Store/Minimal.pm
lib/Catalyst/Plugin/Authentication.pm
lib/Catalyst/Plugin/Authentication/Internals.pod
t/lib/AuthRealmTestAppCompat.pm
t/lib/AuthSessionTestApp.pm
t/lib/AuthTestApp.pm
t/live_app.t
t/live_app_realms.t
t/live_app_realms_compat.t

diff --git a/Changes b/Changes
index ccad9d3..ab6bb59 100644 (file)
--- 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<kane@cpan.org>)
-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
index a0c3474..019189e 100644 (file)
@@ -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
index 6fa764f..df3d93a 100644 (file)
@@ -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";
index ae61fc6..0774362 100644 (file)
@@ -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<Catalyst::Authentication::Realm> class using the 'class' element within the
index 5106094..9c2b0f6 100644 (file)
@@ -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<Sessions> - 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
index 4a8b50c..8ff5389 100644 (file)
@@ -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;
index e3f3680..49ec14b 100644 (file)
@@ -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",
index 1c43cd1..529e32f 100644 (file)
@@ -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");
index d3da817..70ca676 100644 (file)
@@ -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';
index 0e1fbc6..0e79b8b 100644 (file)
@@ -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/;
index a4bbbbb..5deccf1 100644 (file)
@@ -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/;