Major modifications
[catagits/Catalyst-Plugin-Authentication.git] / lib / Catalyst / Plugin / Authentication.pm
index 596ac7b..b2e7cbd 100644 (file)
@@ -40,7 +40,7 @@ sub set_authenticated {
     {
         $c->save_user_in_session($user, $realmname);
     }
-    $user->_set_auth_realm($realmname);
+    $user->auth_realm($realmname);
     
     $c->NEXT::set_authenticated($user, $realmname);
 }
@@ -73,8 +73,8 @@ sub user {
         return $c->_user(@_);
     }
 
-    if ( defined(my $user = $c->_user) ) {
-        return $user;
+    if ( defined($c->_user) ) {
+        return $c->_user;
     } else {
         return $c->auth_restore_user;
     }
@@ -87,15 +87,28 @@ sub user_exists {
        return defined($c->_user) || defined($c->_user_in_session);
 }
 
+# works like user_exists - except only returns true if user 
+# exists AND is in the realm requested.
+sub user_in_realm {
+    my ($c, $realmname) = @_;
+
+    if (defined($c->_user)) {
+        return ($c->_user->auth_realm eq $realmname);
+    } elsif (defined($c->_user_in_session)) {
+        return ($c->session->{__user_realm} eq $realmname);  
+    } else {
+        return undef;
+    }
+}
 
 sub save_user_in_session {
     my ( $c, $user, $realmname ) = @_;
 
     $c->session->{__user_realm} = $realmname;
     
-    # we want to ask the backend for a user prepared for the session.
+    # we want to ask the store for a user prepared for the session.
     # but older modules split this functionality between the user and the
-    # backend.  We try the store first.  If not, we use the old method.
+    # store.  We try the store first.  If not, we use the old method.
     my $realm = $c->get_auth_realm($realmname);
     if ($realm->{'store'}->can('for_session')) {
         $c->session->{__user} = $realm->{'store'}->for_session($c, $user);
@@ -141,14 +154,6 @@ sub _user_in_session {
     return $c->session->{__user};
 }
 
-sub _store_in_session {
-    my $c = shift;
-    
-    # we don't need verification, it's only called if _user_in_session returned something useful
-
-    return $c->session->{__user_store};
-}
-
 sub auth_restore_user {
     my ( $c, $frozen_user, $realmname ) = @_;
 
@@ -162,7 +167,7 @@ sub auth_restore_user {
     $c->_user( my $user = $realm->{'store'}->from_session( $c, $frozen_user ) );
     
     # this sets the realm the user originated in.
-    $user->_set_auth_realm($realmname);
+    $user->auth_realm($realmname);
     return $user;
 
 }
@@ -216,7 +221,6 @@ sub _authentication_initialize {
     
 }
 
-
 # set up realmname.
 sub setup_auth_realm {
     my ($app, $realmname, $config) = @_;
@@ -230,9 +234,9 @@ sub setup_auth_realm {
     my $storeclass = $config->{'store'}{'class'};
     
     ## follow catalyst class naming - a + prefix means a fully qualified class, otherwise it's
-    ## taken to mean C::P::A::Store::(specifiedclass)::Backend
+    ## taken to mean C::P::A::Store::(specifiedclass)
     if ($storeclass !~ /^\+(.*)$/ ) {
-        $storeclass = "Catalyst::Plugin::Authentication::Store::${storeclass}::Backend";
+        $storeclass = "Catalyst::Plugin::Authentication::Store::${storeclass}";
     } else {
         $storeclass = $1;
     }
@@ -269,15 +273,8 @@ sub setup_auth_realm {
     }
     
     $app->auth_realms->{$realmname}{'store'} = $storeclass->new($config->{'store'}, $app);
-    if ($credentialclass->can('new')) {
-        $app->auth_realms->{$realmname}{'credential'} = $credentialclass->new($config->{'credential'}, $app);
-    } else {
-        # if the credential class is not actually a class - has no 'new' operator, we wrap it, 
-        # once again - to allow our code to be simple at runtime and allow non-OO packages to function.
-        my $wrapperclass = 'Catalyst::Plugin::Authentication::Credential::Wrapper';
-        Catalyst::Utils::ensure_class_loaded( $wrapperclass );
-        $app->auth_realms->{$realmname}{'credential'} = $wrapperclass->new($config->{'credential'}, $app);
-    }
+    $app->auth_realms->{$realmname}{'credential'} = $credentialclass->new($config->{'credential'}, $app);
+   
 }
 
 sub auth_realms {
@@ -314,9 +311,11 @@ sub authenticate {
         
     my $realm = $app->get_auth_realm($realmname);
     
+    ## note to self - make authenticate throw an exception if realm is invalid.
+    
     if ($realm && exists($realm->{'credential'})) {
         my $user = $realm->{'credential'}->authenticate($app, $realm->{store}, $userinfo);
-        if ($user) {
+        if (ref($user)) {
             $app->set_authenticated($user, $realmname);
             return $user;
         }
@@ -447,8 +446,8 @@ module, and specify at least one realm in the configuration.
 Authentication data can also be stored in a session, if the application 
 is using the L<Catalyst::Plugin::Session> module.
 
-B<NOTE> in version 0.10 of this module, the api changed.  Please see 
-L</COMPATIBILITY ROUTINES> for more information.
+B<NOTE> in version 0.10 of this module, the interface to this module changed.
+Please see L</COMPATIBILITY ROUTINES> for more information.
 
 =head1 INTRODUCTION
 
@@ -509,7 +508,7 @@ they claim to be.
 
 =head3 Storage Backends
 
-The authentication data also identifies a user, and the Storage Backend modules
+The authentication data also identifies a user, and the Storage backend modules
 use this data to locate and return a standardized object-oriented
 representation of a user.
 
@@ -741,7 +740,7 @@ class name. Otherwise it is considered to be a portion of the class name. For
 credentials, the classname 'B<Password>', for example, is expanded to
 Catalyst::Plugin::Authentication::Credential::B<Password>. For stores, the
 classname 'B<storename>' is expanded to:
-Catalyst::Plugin::Authentication::Store::B<storename>::Backend.
+Catalyst::Plugin::Authentication::Store::B<storename>.
 
 
 =back
@@ -765,10 +764,15 @@ Returns the currently logged in user or undef if there is none.
 
 Returns true if a user is logged in right now. The difference between
 user_exists and user is that user_exists will return true if a user is logged
-in, even if it has not been retrieved from the storage backend. If you only
+in, even if it has not been yet retrieved from the storage backend. If you only
 need to know if the user is logged in, depending on the storage mechanism this
 can be much more efficient.
 
+=item user_in_realm ( $realm )
+
+Works like user_exists, except that it only returns true if a user is both 
+logged in right now and is from the realm provided.  
+
 =item logout
 
 Logs the user out, Deletes the currently logged in user from $c->user and the session.
@@ -822,19 +826,17 @@ Retrieves the realm instance for the realmname provided.
 
 =head1 SEE ALSO
 
-This list might not be up to date.
+This list might not be up to date.  Below are modules known to work with the updated
+API of 0.10 and are therefore compatible with realms.  
 
 =head2 User Storage Backends
 
 L<Catalyst::Plugin::Authentication::Store::Minimal>,
-L<Catalyst::Plugin::Authentication::Store::Htpasswd>,
-L<Catalyst::Plugin::Authentication::Store::DBIC> (also works with Class::DBI).
+L<Catalyst::Plugin::Authentication::Store::DBIx::Class>,
 
 =head2 Credential verification
 
 L<Catalyst::Plugin::Authentication::Credential::Password>,
-L<Catalyst::Plugin::Authentication::Credential::HTTP>,
-L<Catalyst::Plugin::Authentication::Credential::TypeKey>
 
 =head2 Authorization
 
@@ -843,7 +845,7 @@ L<Catalyst::Plugin::Authorization::Roles>
 
 =head2 Internals Documentation
 
-L<Catalyst::Plugin::Authentication::Store>
+L<Catalyst::Plugin::Authentication::Internals>
 
 =head2 Misc
 
@@ -862,23 +864,33 @@ L<Catalyst::Plugin::Authentication::LDAP>,
 L<Catalyst::Plugin::Authentication::CDBI::Basic>,
 L<Catalyst::Plugin::Authentication::Basic::Remote>.
 
+=head1 INCOMPATABILITIES
 
-=head1 COMPATIBILITY ROUTINES
+The realms based configuration and functionality of the 0.10 update 
+of L<Catalyst::Plugin::Authentication> required a change in the API used by
+credentials and stores.  It has a compatibility mode which allows use of
+modules that have not yet been updated. This, however, completely mimics the
+older api and disables the new realm-based features. In other words you can
+not mix the older credential and store modules with realms, or realm-based
+configs. The changes required to update modules are relatively minor and are
+covered in L<Catalyst::Plugin::Authentication::Internals>.  We hope that most
+modules will move to the compatible list above very quickly.
 
-=over 4
+=head1 COMPATIBILITY ROUTINES
 
 In version 0.10 of L<Catalyst::Plugin::Authentication>, the API
 changed. For app developers, this change is fairly minor, but for
 Credential and Store authors, the changes are significant. 
 
 Please see the documentation in version 0.09 of
-Catalyst::Plugin::Authentication for a better understanding of how the old api
+Catalyst::Plugin::Authentication for a better understanding of how the old API
 functioned.
 
 The items below are still present in the plugin, though using them is
 deprecated. They remain only as a transition tool, for those sites which can
-not be upgraded to use the new system due to local customizations, or use of
-Credential / store modules that have not yet been updated.
+not yet be upgraded to use the new system due to local customizations or use
+of Credential / Store modules that have not yet been updated to work with the 
+new API.
 
 These routines should not be used in any application using realms
 functionality or any of the methods described above. These are for reference
@@ -889,8 +901,9 @@ purposes only.
 =item login
 
 This method is used to initiate authentication and user retrieval. Technically
-this is part of the old Password credential module, included here for
-completeness.
+this is part of the old Password credential module and it still resides in the
+L<Password|Catalyst::Plugin::Authentication::Credential::Password> class. It is
+included here for reference only.
 
 =item default_auth_store
 
@@ -899,10 +912,11 @@ Return the store whose name is 'default'.
 This is set to C<< $c->config->{authentication}{store} >> if that value exists,
 or by using a Store plugin:
 
+    # load the Minimal authentication store.
        use Catalyst qw/Authentication Authentication::Store::Minimal/;
 
 Sets the default store to
-L<Catalyst::Plugin::Authentication::Store::Minimal::Backend>.
+L<Catalyst::Plugin::Authentication::Store::Minimal>.
 
 =item get_auth_store $name
 
@@ -928,11 +942,12 @@ Register stores into the application.
 
 Yuval Kogman, C<nothingmuch@woobling.org>
 
+Jay Kuri, C<jayk@cpan.org>
+
 Jess Robinson
 
 David Kamholz
 
-Jay Kuri C<jayk@cpan.org>
 
 =head1 COPYRIGHT & LICENSE