Documentation. Finally.
[catagits/Catalyst-Authentication-Store-DBIx-Class.git] / lib / Catalyst / Plugin / Authentication / Store / DBIx / Class.pm
index 1ecbe68..6593fca 100644 (file)
@@ -80,69 +80,333 @@ Catalyst::Plugin::Authentication::Store::DBIx::Class - A storage class for Catal
 
 =head1 VERSION
 
-This documentation refers to version 0.01.
+This documentation refers to version 0.02.
 
 =head1 SYNOPSIS
 
-use Catalyst::Plugin::Authentication::Store::DBIx::Class;
-
+    use Catalyst qw/
+                    Authentication
+                    Authorization::Roles/;
+
+    __PACKAGE__->config->{authentication} = 
+                    {  
+                        default_realm => 'members',
+                        realms => {
+                            members => {
+                                credential => {
+                                    class => 'Password',
+                                    password_field => 'password',
+                                    password_type => 'clear'
+                                },
+                                store => {
+                                    class => 'DBIx::Class',
+                                   user_class => 'MyApp::Users',
+                                   id_field => 'user_id',
+                                   role_relation => 'roles',
+                                   role_field => 'rolename',                   
+                               }
+                            }
+                       }
+                    };
+
+    # Log a user in:
+    
+    sub login : Global {
+        my ( $self, $c ) = @_;
+        
+        $c->authenticate({  
+                          username => $c->req->params->username,
+                          password => $c->req->params->password,
+                          status => [ 'registered', 'loggedin', 'active']
+                          }))
+    }
+    
+    # verify a role 
+    
+    if ( $c->check_user_roles( 'editor' ) ) {
+        # do editor stuff
+    }
+    
 =head1 DESCRIPTION
 
-The Catalyst::Plugin::Authentication::Store::DBIx::Class class implements ...
+The Catalyst::Plugin::Authentication::Store::DBIx::Class class provides 
+access to authentication information stored in a database via DBIx::Class.
 
-=head1 SUBROUTINES / METHODS
+=head1 CONFIGURATION
 
-=head2 new (constructor)
+The DBIx::Class authentication store is activated by setting the store
+config's B<class> element to DBIx::Class as shown above.  See the 
+L<Catalyst::Plugin::Authentication> documentation for more details on 
+configuring the store.
 
-Parameters:
-    class
-    config
-    app
+The DBIx::Class storage module has several configuration options
 
-Insert description of constructor here...
+=over 4
 
-=head2 from_session (method)
+    __PACKAGE__->config->{authentication} = 
+                    {  
+                        default_realm => 'members',
+                        realms => {
+                            members => {
+                                credential => {
+                                    # ...
+                                },
+                                store => {
+                                    class => 'DBIx::Class',
+                                   user_class => 'MyApp::Users',
+                                   id_field => 'user_id',
+                                   role_relation => 'roles',
+                                   role_field => 'rolename',
+                                   ignore_fields_in_find => [ 'remote_name' ]          
+                               }
+                               }
+                       }
+                    };
 
-Parameters:
-    c
-    frozenuser
+=item class
+
+Class is part of the core Catalyst::Authentication::Plugin module, it
+contains the class name of the store to be used.
+
+=item user_class
 
-Insert description of method here...
+Contains the class name (as passed to $c->model()) of the DBIx::Class schema
+to use as the source for user information.  This config item is B<REQUIRED>.
+
+=item id_field
 
-=head2 for_session (method)
+Contains the field name containing the unique identifier for a user.  This is 
+used when storing and retrieving a user from the session.  The value in this
+field should correspond to a single user in the database.  Defaults to 'id'.
 
-Parameters:
-    c
-    user
+=item role_column
+
+If your role information is stored in the same table as the rest of your user
+information, this item tells the module which field contains your role
+information.  The DBIx::Class authentication store expects the data in this
+field to be a series of role names separated by some combination of spaces, 
+commas or pipe characters.  
+
+=item role_relation
+
+If your role information is stored in a separate table, this is the name of
+the relation that will lead to the roles the user is in.  If this is 
+specified then a role_field is also required.  Also when using this method
+it is expected that your role table will return one row for each role 
+the user is in.
+
+=item role_field
+
+This is the name of the field in the role table that contains the string 
+identifying the role.  
+
+=item ignore_fields_in_find
+
+This item is an array containing fields that may be passed to the
+$c->authenticate() routine (and therefore find_user in the storage class), but
+which should be ignored when creating the DBIx::Class search to retrieve a
+user. This makes it possible to avoid problems when a credential requires an
+authinfo element whose name overlaps with a column name in your users table.
+If this doesn't make sense to you, you probably don't need it.
+
+=item store_user_class
+
+This allows you to override the authentication user class that the 
+DBIx::Class store module uses to perform it's work.  Most of the
+work done in this module is actually done by the user class, 
+L<Catalyst::Plugin::Authentication::Store::DBIx::Class::User>, so
+overriding this doesn't make much sense unless you are using your
+own class to extend the functionality of the existing class.  
+Chances are you do not want to set this.
+
+=back
+
+=head1 USAGE 
+
+The L<Catalyst::Plugin::Authentication::Store::DBIx::Class> storage module
+is not called directly from application code.  You interface with it 
+through the $c->authenticate() call.  
+
+There are three methods you can use to retrieve information from the DBIx::Class
+storage module.  They are Simple retrieval, and the advanced retrieval methods
+Searchargs and Resultset.
+
+=head2 Simple Retrieval 
+
+The first, and most common, method is simple retrieval. As it's name implies
+simple retrieval allows you to simply to provide the column => value pairs
+that should be used to locate the user in question. An example of this usage
+is below:
+
+    if ($c->authenticate({  
+                          username => $c->req->params->{'username'},
+                          password => $c->req->params->{'password'},
+                          status => [ 'registered', 'active', 'loggedin']
+                         })) {
+
+        # ... authenticated user code here
+    }
+
+The above example would attempt to retrieve a user whose username column
+matched the username provided, and whose status column matched one of the
+values provided. These name => value pairs are used more or less directly in
+the DBIx::Class' search() routine, so in most cases, you can use DBIx::Class
+syntax to retrieve the user according to whatever rules you have.
+
+NOTE: Because the password in most cases is encrypted - it is not used
+directly but it's encryption and comparison with the value provided is usually
+handled by the Password Credential. Part of the Password Credential's behavior
+is to remove the password argument from the authinfo that is passed to the
+storage module. See L<Catalyst::Plugin::Authentication::Credential::Password>.
+
+One thing you need to know about this retrieval method is that the name
+portion of the pair is checked against the user class' column list. Pairs are
+only used if a matching column is found. Other pairs will be ignored. This
+means that you can only provide simple name-value pairs, and that some more
+advanced DBIx::Class constructs, such as '-or', '-and', etc. are in most cases
+not possible using this method. For queries that require this level of
+functionality, see the 'searchargs' method below.
+
+=head2 Advanced Retrieval
+
+The Searchargs and Resultset retrieval methods are used when more advanced
+features of the underlying L<DBIx::Class> schema are required. These methods
+provide a direct interface with the DBIx::Class schema and therefore
+require a better understanding of the DBIx::Class module.  
+
+=head3 The dbix_class key
+
+Since the format of these arguments are often complex, they are not keys in
+the base authinfo hash.  Instead, both of these arguments are placed within 
+a hash attached to the store-specific 'dbix_class' key in the base $authinfo 
+hash.  When the DBIx::Class authentication store sees the 'dbix_class' key
+in the passed authinfo hash, all the other information in the authinfo hash
+is ignored and only the values within the 'dbix_class' hash are used as 
+though they were passed directly within the authinfo hash.  In other words, if
+'dbix_class' is present, it replaces the authinfo hash for processing purposes.
+
+The 'dbix_class' hash can be used to directly pass arguments to the
+DBIx::Class authentication store. Reasons to do this are to avoid credential
+modification of the authinfo hash, or to avoid overlap between credential and
+store key names. It's a good idea to avoid using it in this way unless you are
+sure you have an overlap/modification issue. However, the two advanced
+retrieval methods, B<searchargs> and B<resultset>, require it's use, as they 
+are only processed as part of the 'dbix_class' hash
+
+=over 4
+
+=item Searchargs
+
+The B<searchargs> method of retrieval allows you to specify an arrayref containing
+the two arguments to the search() method from L<DBIx::Class::Resultset>.  If provided,
+all other args are ignored, and the search args provided are used directly to locate
+the user.  An example will probably make more sense:
+
+    if ($c->authenticate(
+        { 
+            password => $password,
+            'dbix_class' => 
+                {
+                    searchargs = [ { -or => [ username => $username,
+                                              email => $email,
+                                              clientid => $clientid ] 
+                                   },
+                                   { prefetch => qw/ preferences / } 
+                                 ]
+                }
+        } ) ) 
+    {
+        # do successful authentication actions here.
+    }
+
+The above would allow authentication based on any of the three items -
+username, email or clientid and would prefetch the data related to that user
+from the preferences table. The searchargs array is passed directly to the
+search() method associated with the user_class.
+
+=item Resultset
+
+The B<resultset> method of retrieval allows you to directly specify a
+resultset to be used for user retrieval. This allows you to create a resultset
+within your login action and use it for retrieving the user. A simple example:
+
+    my $rs = $c->model('MyApp::User')->search({ email => $c->request->params->{'email'} });
+       ... # further $rs adjustments
+       
+    if ($c->authenticate({ 
+                           password => $password,
+                           'dbix_class' => {  resultset = $rs }
+                         })) {
+       # do successful authentication actions here.
+    } 
+
+Be aware that the resultset method will not verify that you are passing a
+resultset that is attached to the same user_class as specified in the config.
+
+NOTE: All of these methods of user retrieval, including the resultset method,
+consider the first row returned to be the matching user. In most cases there
+will be only one matching row, but it is easy to produce multiple rows,
+especially when using the advanced retrieval methods. Remember, what you get
+when you use this module is what you would get when calling
+search(...)->first;
+
+NOTE ALSO:  The user info used to save the user to the session and to retrieve
+it is the same regardless of what method of retrieval was used.  In short,
+the value in the id field (see 'id_field' config item) is used to retrieve the 
+user from the database upon restoring from the session.  When the DBIx::Class storage
+module does this, it does so by doing a simple search using the id field.  In other
+words, it will not use the same arguments you used to request the user initially. 
+This is especially important to those using the advanced methods of user retrieval. 
+If you need more complicated logic when reviving the user from the session, you will
+most likely want to subclass the L<Catalyst::Plugin::Authentication::Store::DBIx::Class::User> class 
+and provide your own for_session and from_session routines.
+
+=back
+
+
+=head1 METHODS
+
+There are no publicly exported routines in the DBIx::Class authentication 
+store (or indeed in most authentication stores)  However, below is a 
+description of the routines required by L<Catalyst::Plugin::Authentication> 
+for all authentication stores.  Please see the documentation for 
+L<Catalyst::Plugin::Authentication::Internals> for more information.
+
+=over 4
+
+=item new ( $config, $app )
+
+Constructs a new store object.
+
+=item find_user ( $authinfo, $c ) 
+
+Finds a user using the information provided in the $authinfo hashref and
+returns the user, or undef on failure; This is usually called from the
+Credential. This translates directly to a call to
+L<Catalyst::Plugin::Authentication::Store::DBIx::Class::User>'s load() method.
 
-Insert description of method here...
+=item for_session ( $c, $user )
 
-=head2 find_user (method)
+Prepares a user to be stored in the session. Currently returns the value of
+the user's id field - (as indicated by the 'id_field' config element)
 
-Parameters:
-    authinfo
-    c
+=item from_session ( $c, $frozenuser)
 
-Insert description of method here...
+Revives a user from the session based on the info provided in $frozenuser.
+Currently treats $frozenuser as an id and retrieves a user with a matching id.
 
-=head2 user_supports
+=item user_supports
 
-Parameters:
-    none
+Provides information about what the user object supports.  
 
-Insert description of subroutine here...
-
-=head1 DEPENDENCIES
-
-Modules used, version dependencies, core yes/no
-
-strict
-
-warnings
+=back 
 
 =head1 NOTES
 
-...
+As of the current release, session storage consists of simply storing the user's
+id in the session, and then using that same id to re-retrieve the users information
+from the database upon restoration from the session.  More dynamic storage of
+user information in the session is intended for a future release.
 
 =head1 BUGS AND LIMITATIONS
 
@@ -150,16 +414,17 @@ None known currently, please email the author if you find any.
 
 =head1 SEE ALSO
 
-L<Catalyst::Plugin::Authentication>, L<Catalyst::Plugin::Authorization::Roles>
+L<Catalyst::Plugin::Authentication>, L<Catalyst::Plugin::Authentication::Internals>,
+and L<Catalyst::Plugin::Authorization::Roles>
 
 =head1 AUTHOR
 
 Jason Kuri (jayk@cpan.org)
 
-=head1 LICENCE
-
-Copyright 2006 by Jason Kuri.
+=head1 LICENSE
 
-This software is free.  It is licensed under the same terms as Perl itself.
+Copyright (c) 2007 the aforementioned authors. All rights
+reserved. This program is free software; you can redistribute
+it and/or modify it under the same terms as Perl itself.
 
 =cut