changes and version update in prep for release
[catagits/Catalyst-Authentication-Store-DBIx-Class.git] / lib / Catalyst / Authentication / Store / DBIx / Class.pm
CommitLineData
6727afe2 1package Catalyst::Authentication::Store::DBIx::Class;
5000f545 2
3use strict;
4use warnings;
5use base qw/Class::Accessor::Fast/;
6
bf76ff13 7our $VERSION= "0.107";
6727afe2 8
b33ee900 9
10BEGIN {
11 __PACKAGE__->mk_accessors(qw/config/);
12}
13
6727afe2 14
5000f545 15sub new {
16 my ( $class, $config, $app ) = @_;
17
b33ee900 18 ## figure out if we are overriding the default store user class
19 $config->{'store_user_class'} = (exists($config->{'store_user_class'})) ? $config->{'store_user_class'} :
6727afe2 20 "Catalyst::Authentication::Store::DBIx::Class::User";
b33ee900 21
5000f545 22 ## make sure the store class is loaded.
b33ee900 23 Catalyst::Utils::ensure_class_loaded( $config->{'store_user_class'} );
5000f545 24
b33ee900 25 ## fields can be specified to be ignored during user location. This allows
ff7203cb 26 ## the store to ignore certain fields in the authinfo hash.
5000f545 27
b33ee900 28 $config->{'ignore_fields_in_find'} ||= [ ];
29
30 my $self = {
31 config => $config
32 };
5000f545 33
34 bless $self, $class;
b33ee900 35
5000f545 36}
37
ba48c9c3 38## --jk note to self:
fff51ece 39## let's use DBIC's get_columns method to return a hash and save / restore that
ba48c9c3 40## from the session. Then we can respond to get() calls, etc. in most cases without
41## resorting to a DB call. If user_object is called, THEN we can hit the DB and
42## return a real object.
5000f545 43sub from_session {
44 my ( $self, $c, $frozenuser ) = @_;
45
f26005a7 46# return $frozenuser if ref $frozenuser;
47
b33ee900 48 my $user = $self->config->{'store_user_class'}->new($self->{'config'}, $c);
b33ee900 49 return $user->from_session($frozenuser, $c);
5000f545 50}
51
52sub for_session {
53 my ($self, $c, $user) = @_;
54
55 return $user->for_session($c);
56}
57
58sub find_user {
59 my ( $self, $authinfo, $c ) = @_;
60
b33ee900 61 my $user = $self->config->{'store_user_class'}->new($self->{'config'}, $c);
5000f545 62
b33ee900 63 return $user->load($authinfo, $c);
64
65}
5000f545 66
67sub user_supports {
b33ee900 68 my $self = shift;
69 # this can work as a class method on the user class
70 $self->config->{'store_user_class'}->supports( @_ );
5000f545 71}
72
67f6319b 73sub auto_create_user {
fb689852 74 my( $self, $authinfo, $c ) = @_;
75 my $res = $self->config->{'store_user_class'}->new($self->{'config'}, $c);
76 return $res->auto_create( $authinfo, $c );
77}
78
67f6319b 79sub auto_update_user {
fb689852 80 my( $self, $authinfo, $c, $res ) = @_;
81 $res->auto_update( $authinfo, $c );
82 return $res;
83}
84
5000f545 85__PACKAGE__;
86
87__END__
88
89=head1 NAME
90
6727afe2 91Catalyst::Authentication::Store::DBIx::Class - A storage class for Catalyst Authentication using DBIx::Class
5000f545 92
93=head1 VERSION
94
bf76ff13 95This documentation refers to version 0.107.
5000f545 96
97=head1 SYNOPSIS
98
93102ff5 99 use Catalyst qw/
100 Authentication
101 Authorization::Roles/;
102
103 __PACKAGE__->config->{authentication} =
104 {
105 default_realm => 'members',
106 realms => {
107 members => {
108 credential => {
109 class => 'Password',
110 password_field => 'password',
111 password_type => 'clear'
112 },
113 store => {
114 class => 'DBIx::Class',
f26005a7 115 user_class => 'MyApp::User',
93102ff5 116 role_relation => 'roles',
117 role_field => 'rolename',
118 }
c1d29ab7 119 }
93102ff5 120 }
121 };
122
123 # Log a user in:
124
125 sub login : Global {
126 my ( $self, $c ) = @_;
127
128 $c->authenticate({
f7e6d29f 129 screen_name => $c->req->params->username,
c1d29ab7 130 password => $c->req->params->password,
131 status => [ 'registered', 'loggedin', 'active']
132 }))
93102ff5 133 }
134
135 # verify a role
136
137 if ( $c->check_user_roles( 'editor' ) ) {
138 # do editor stuff
139 }
140
5000f545 141=head1 DESCRIPTION
142
6727afe2 143The Catalyst::Authentication::Store::DBIx::Class class provides
93102ff5 144access to authentication information stored in a database via DBIx::Class.
145
146=head1 CONFIGURATION
147
148The DBIx::Class authentication store is activated by setting the store
c1d29ab7 149config's B<class> element to DBIx::Class as shown above. See the
93102ff5 150L<Catalyst::Plugin::Authentication> documentation for more details on
151configuring the store.
152
153The DBIx::Class storage module has several configuration options
154
93102ff5 155
156 __PACKAGE__->config->{authentication} =
157 {
158 default_realm => 'members',
159 realms => {
160 members => {
161 credential => {
162 # ...
163 },
164 store => {
165 class => 'DBIx::Class',
f26005a7 166 user_class => 'MyApp::User',
93102ff5 167 role_relation => 'roles',
168 role_field => 'rolename',
f26005a7 169 ignore_fields_in_find => [ 'remote_name' ],
170 use_userdata_from_session => 1,
93102ff5 171 }
172 }
173 }
174 };
175
b81ead77 176=over 4
177
93102ff5 178=item class
179
fff51ece 180Class is part of the core Catalyst::Plugin::Authentication module; it
93102ff5 181contains the class name of the store to be used.
182
183=item user_class
5000f545 184
93102ff5 185Contains the class name (as passed to $c->model()) of the DBIx::Class schema
186to use as the source for user information. This config item is B<REQUIRED>.
5000f545 187
93102ff5 188=item role_column
5000f545 189
93102ff5 190If your role information is stored in the same table as the rest of your user
191information, this item tells the module which field contains your role
192information. The DBIx::Class authentication store expects the data in this
193field to be a series of role names separated by some combination of spaces,
fff51ece 194commas, or pipe characters.
5000f545 195
93102ff5 196=item role_relation
5000f545 197
93102ff5 198If your role information is stored in a separate table, this is the name of
199the relation that will lead to the roles the user is in. If this is
fff51ece 200specified, then a role_field is also required. Also when using this method
93102ff5 201it is expected that your role table will return one row for each role
202the user is in.
5000f545 203
93102ff5 204=item role_field
5000f545 205
93102ff5 206This is the name of the field in the role table that contains the string
207identifying the role.
5000f545 208
93102ff5 209=item ignore_fields_in_find
5000f545 210
c1d29ab7 211This item is an array containing fields that may be passed to the
212$c->authenticate() routine (and therefore find_user in the storage class), but
213which should be ignored when creating the DBIx::Class search to retrieve a
214user. This makes it possible to avoid problems when a credential requires an
215authinfo element whose name overlaps with a column name in your users table.
216If this doesn't make sense to you, you probably don't need it.
5000f545 217
f26005a7 218=item use_userdata_from_session
219
220Under normal circumstances, on each request the user's data is re-retrieved
221from the database using the primary key for the user table. When this flag
222is set in the configuration, it causes the DBIx::Class store to avoid this
223database hit on session restore. Instead, the user object's column data
224is retrieved from the session and used as-is.
225
226B<NOTE>: Since the user object's column
227data is only stored in the session during the initial authentication of
228the user, turning this on can potentially lead to a situation where the data
229in $c->user is different from what is stored the database. You can force
230a reload of the data from the database at any time by calling $c->user->get_object(1);
231Note that this will update $c->user for the remainder of this request.
232It will NOT update the session. If you need to update the session
233you should call $c->update_user_in_session() as well.
234
93102ff5 235=item store_user_class
5000f545 236
93102ff5 237This allows you to override the authentication user class that the
28aa2168 238DBIx::Class store module uses to perform its work. Most of the
93102ff5 239work done in this module is actually done by the user class,
6727afe2 240L<Catalyst::Authentication::Store::DBIx::Class::User>, so
93102ff5 241overriding this doesn't make much sense unless you are using your
242own class to extend the functionality of the existing class.
243Chances are you do not want to set this.
5000f545 244
f7e6d29f 245=item id_field
246
247In most cases, this config variable does not need to be set, as
248Catalyst::Authentication::Store::DBIx::Class will determine the primary
fff51ece 249key of the user table on its own. If you need to override the default,
f7e6d29f 250or your user table has multiple primary keys, then id_field
251should contain the column name that should be used to restore the user.
252A given value in this column should correspond to a single user in the database.
253Note that this is used B<ONLY> when restoring a user from the session and
254has no bearing whatsoever in the initial authentication process. Note also
255that if use_userdata_from_session is enabled, this config parameter
256is not used at all.
257
93102ff5 258=back
5000f545 259
93102ff5 260=head1 USAGE
5000f545 261
6727afe2 262The L<Catalyst::Authentication::Store::DBIx::Class> storage module
93102ff5 263is not called directly from application code. You interface with it
264through the $c->authenticate() call.
5000f545 265
c1d29ab7 266There are three methods you can use to retrieve information from the DBIx::Class
267storage module. They are Simple retrieval, and the advanced retrieval methods
268Searchargs and Resultset.
269
270=head2 Simple Retrieval
271
28aa2168 272The first, and most common, method is simple retrieval. As its name implies
c1d29ab7 273simple retrieval allows you to simply to provide the column => value pairs
274that should be used to locate the user in question. An example of this usage
275is below:
276
277 if ($c->authenticate({
f7e6d29f 278 screen_name => $c->req->params->{'username'},
c1d29ab7 279 password => $c->req->params->{'password'},
280 status => [ 'registered', 'active', 'loggedin']
281 })) {
282
283 # ... authenticated user code here
284 }
285
f7e6d29f 286The above example would attempt to retrieve a user whose username column (here,
287screen_name) matched the username provided, and whose status column matched one of the
c1d29ab7 288values provided. These name => value pairs are used more or less directly in
fff51ece 289the DBIx::Class search() routine, so in most cases, you can use DBIx::Class
c1d29ab7 290syntax to retrieve the user according to whatever rules you have.
291
292NOTE: Because the password in most cases is encrypted - it is not used
28aa2168 293directly but its encryption and comparison with the value provided is usually
c1d29ab7 294handled by the Password Credential. Part of the Password Credential's behavior
295is to remove the password argument from the authinfo that is passed to the
6727afe2 296storage module. See L<Catalyst::Authentication::Credential::Password>.
c1d29ab7 297
298One thing you need to know about this retrieval method is that the name
fff51ece 299portion of the pair is checked against the user class's column list. Pairs are
c1d29ab7 300only used if a matching column is found. Other pairs will be ignored. This
301means that you can only provide simple name-value pairs, and that some more
302advanced DBIx::Class constructs, such as '-or', '-and', etc. are in most cases
303not possible using this method. For queries that require this level of
304functionality, see the 'searchargs' method below.
305
306=head2 Advanced Retrieval
307
308The Searchargs and Resultset retrieval methods are used when more advanced
309features of the underlying L<DBIx::Class> schema are required. These methods
310provide a direct interface with the DBIx::Class schema and therefore
311require a better understanding of the DBIx::Class module.
312
313=head3 The dbix_class key
314
315Since the format of these arguments are often complex, they are not keys in
316the base authinfo hash. Instead, both of these arguments are placed within
317a hash attached to the store-specific 'dbix_class' key in the base $authinfo
318hash. When the DBIx::Class authentication store sees the 'dbix_class' key
319in the passed authinfo hash, all the other information in the authinfo hash
320is ignored and only the values within the 'dbix_class' hash are used as
321though they were passed directly within the authinfo hash. In other words, if
322'dbix_class' is present, it replaces the authinfo hash for processing purposes.
323
324The 'dbix_class' hash can be used to directly pass arguments to the
325DBIx::Class authentication store. Reasons to do this are to avoid credential
326modification of the authinfo hash, or to avoid overlap between credential and
327store key names. It's a good idea to avoid using it in this way unless you are
328sure you have an overlap/modification issue. However, the two advanced
28aa2168 329retrieval methods, B<searchargs> and B<resultset>, require its use, as they
330are only processed as part of the 'dbix_class' hash.
c1d29ab7 331
332=over 4
333
334=item Searchargs
335
336The B<searchargs> method of retrieval allows you to specify an arrayref containing
ad93b3e9 337the two arguments to the search() method from L<DBIx::Class::ResultSet>. If provided,
c1d29ab7 338all other args are ignored, and the search args provided are used directly to locate
339the user. An example will probably make more sense:
340
341 if ($c->authenticate(
342 {
343 password => $password,
344 'dbix_class' =>
345 {
f26005a7 346 searchargs => [ { -or => [ username => $username,
c1d29ab7 347 email => $email,
348 clientid => $clientid ]
349 },
350 { prefetch => qw/ preferences / }
351 ]
352 }
353 } ) )
354 {
355 # do successful authentication actions here.
356 }
357
358The above would allow authentication based on any of the three items -
fff51ece 359username, email, or clientid - and would prefetch the data related to that user
c1d29ab7 360from the preferences table. The searchargs array is passed directly to the
361search() method associated with the user_class.
362
363=item Resultset
364
365The B<resultset> method of retrieval allows you to directly specify a
366resultset to be used for user retrieval. This allows you to create a resultset
367within your login action and use it for retrieving the user. A simple example:
368
369 my $rs = $c->model('MyApp::User')->search({ email => $c->request->params->{'email'} });
370 ... # further $rs adjustments
371
372 if ($c->authenticate({
373 password => $password,
fff51ece 374 'dbix_class' => { resultset => $rs }
c1d29ab7 375 })) {
376 # do successful authentication actions here.
377 }
378
379Be aware that the resultset method will not verify that you are passing a
380resultset that is attached to the same user_class as specified in the config.
381
382NOTE: All of these methods of user retrieval, including the resultset method,
383consider the first row returned to be the matching user. In most cases there
384will be only one matching row, but it is easy to produce multiple rows,
385especially when using the advanced retrieval methods. Remember, what you get
386when you use this module is what you would get when calling
387search(...)->first;
388
389NOTE ALSO: The user info used to save the user to the session and to retrieve
390it is the same regardless of what method of retrieval was used. In short,
391the value in the id field (see 'id_field' config item) is used to retrieve the
392user from the database upon restoring from the session. When the DBIx::Class storage
393module does this, it does so by doing a simple search using the id field. In other
394words, it will not use the same arguments you used to request the user initially.
395This is especially important to those using the advanced methods of user retrieval.
396If you need more complicated logic when reviving the user from the session, you will
6727afe2 397most likely want to subclass the L<Catalyst::Authentication::Store::DBIx::Class::User> class
c1d29ab7 398and provide your own for_session and from_session routines.
399
400=back
5000f545 401
6727afe2 402
93102ff5 403=head1 METHODS
5000f545 404
93102ff5 405There are no publicly exported routines in the DBIx::Class authentication
fff51ece 406store (or indeed in most authentication stores). However, below is a
93102ff5 407description of the routines required by L<Catalyst::Plugin::Authentication>
408for all authentication stores. Please see the documentation for
409L<Catalyst::Plugin::Authentication::Internals> for more information.
410
6727afe2 411
412=head2 new ( $config, $app )
93102ff5 413
c1d29ab7 414Constructs a new store object.
93102ff5 415
6727afe2 416=head2 find_user ( $authinfo, $c )
93102ff5 417
c1d29ab7 418Finds a user using the information provided in the $authinfo hashref and
fff51ece 419returns the user, or undef on failure. This is usually called from the
c1d29ab7 420Credential. This translates directly to a call to
6727afe2 421L<Catalyst::Authentication::Store::DBIx::Class::User>'s load() method.
93102ff5 422
6727afe2 423=head2 for_session ( $c, $user )
93102ff5 424
c1d29ab7 425Prepares a user to be stored in the session. Currently returns the value of
fff51ece 426the user's id field (as indicated by the 'id_field' config element)
93102ff5 427
6727afe2 428=head2 from_session ( $c, $frozenuser)
93102ff5 429
c1d29ab7 430Revives a user from the session based on the info provided in $frozenuser.
93102ff5 431Currently treats $frozenuser as an id and retrieves a user with a matching id.
432
6727afe2 433=head2 user_supports
93102ff5 434
435Provides information about what the user object supports.
436
76e7a763 437=head2 auto_update_user( $authinfo, $c, $res )
438
439This method is called if the realm's auto_update_user setting is true. It
440will delegate to the user object's C<auto_update> method.
67f6319b 441
76e7a763 442=head2 auto_create_user( $authinfo, $c )
67f6319b 443
76e7a763 444This method is called if the realm's auto_create_user setting is true. It
fff51ece 445will delegate to the user class's (resultset) C<auto_create> method.
5000f545 446
447=head1 NOTES
448
93102ff5 449As of the current release, session storage consists of simply storing the user's
fff51ece 450id in the session, and then using that same id to re-retrieve the user's information
93102ff5 451from the database upon restoration from the session. More dynamic storage of
452user information in the session is intended for a future release.
5000f545 453
454=head1 BUGS AND LIMITATIONS
455
fff51ece 456None known currently; please email the author if you find any.
5000f545 457
458=head1 SEE ALSO
459
93102ff5 460L<Catalyst::Plugin::Authentication>, L<Catalyst::Plugin::Authentication::Internals>,
461and L<Catalyst::Plugin::Authorization::Roles>
5000f545 462
463=head1 AUTHOR
464
b33ee900 465Jason Kuri (jayk@cpan.org)
5000f545 466
c1d29ab7 467=head1 LICENSE
5000f545 468
c1d29ab7 469Copyright (c) 2007 the aforementioned authors. All rights
93102ff5 470reserved. This program is free software; you can redistribute
471it and/or modify it under the same terms as Perl itself.
5000f545 472
473=cut