Adding SimpleDB Realm to make basic configuration of DBIx::Class / Password
[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
f55cb81e 7our $VERSION= "0.108";
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',
f55cb81e 115 user_model => '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
f55cb81e 149config's B<class> element to DBIx::Class as shown above. See the
150L<Catalyst::Plugin::Authentication> documentation for more details on
151configuring the store. You can also use
152L<Catalyst::Authentication::Realm::SimpleDB> for a simplified setup.
93102ff5 153
154The DBIx::Class storage module has several configuration options
155
93102ff5 156
157 __PACKAGE__->config->{authentication} =
158 {
159 default_realm => 'members',
160 realms => {
161 members => {
162 credential => {
163 # ...
164 },
165 store => {
166 class => 'DBIx::Class',
f55cb81e 167 user_model => 'MyApp::User',
93102ff5 168 role_relation => 'roles',
169 role_field => 'rolename',
f26005a7 170 ignore_fields_in_find => [ 'remote_name' ],
171 use_userdata_from_session => 1,
93102ff5 172 }
173 }
174 }
175 };
176
b81ead77 177=over 4
178
93102ff5 179=item class
180
fff51ece 181Class is part of the core Catalyst::Plugin::Authentication module; it
93102ff5 182contains the class name of the store to be used.
183
f55cb81e 184=item user_model
5000f545 185
f55cb81e 186Contains the model name (as passed to $c->model()) of the DBIx::Class schema
187to use as the source for user information. This config item is B<REQUIRED>.
188(Note that this option used to be called user_class. user_class is still
189functional, but should be used only for compatibility with previous configs.)
5000f545 190
93102ff5 191=item role_column
5000f545 192
93102ff5 193If your role information is stored in the same table as the rest of your user
194information, this item tells the module which field contains your role
195information. The DBIx::Class authentication store expects the data in this
196field to be a series of role names separated by some combination of spaces,
fff51ece 197commas, or pipe characters.
5000f545 198
93102ff5 199=item role_relation
5000f545 200
93102ff5 201If your role information is stored in a separate table, this is the name of
202the relation that will lead to the roles the user is in. If this is
fff51ece 203specified, then a role_field is also required. Also when using this method
93102ff5 204it is expected that your role table will return one row for each role
205the user is in.
5000f545 206
93102ff5 207=item role_field
5000f545 208
93102ff5 209This is the name of the field in the role table that contains the string
210identifying the role.
5000f545 211
93102ff5 212=item ignore_fields_in_find
5000f545 213
c1d29ab7 214This item is an array containing fields that may be passed to the
215$c->authenticate() routine (and therefore find_user in the storage class), but
216which should be ignored when creating the DBIx::Class search to retrieve a
217user. This makes it possible to avoid problems when a credential requires an
218authinfo element whose name overlaps with a column name in your users table.
219If this doesn't make sense to you, you probably don't need it.
5000f545 220
f26005a7 221=item use_userdata_from_session
222
223Under normal circumstances, on each request the user's data is re-retrieved
224from the database using the primary key for the user table. When this flag
225is set in the configuration, it causes the DBIx::Class store to avoid this
226database hit on session restore. Instead, the user object's column data
227is retrieved from the session and used as-is.
228
229B<NOTE>: Since the user object's column
230data is only stored in the session during the initial authentication of
231the user, turning this on can potentially lead to a situation where the data
232in $c->user is different from what is stored the database. You can force
233a reload of the data from the database at any time by calling $c->user->get_object(1);
234Note that this will update $c->user for the remainder of this request.
235It will NOT update the session. If you need to update the session
236you should call $c->update_user_in_session() as well.
237
93102ff5 238=item store_user_class
5000f545 239
93102ff5 240This allows you to override the authentication user class that the
28aa2168 241DBIx::Class store module uses to perform its work. Most of the
93102ff5 242work done in this module is actually done by the user class,
6727afe2 243L<Catalyst::Authentication::Store::DBIx::Class::User>, so
93102ff5 244overriding this doesn't make much sense unless you are using your
245own class to extend the functionality of the existing class.
246Chances are you do not want to set this.
5000f545 247
f7e6d29f 248=item id_field
249
250In most cases, this config variable does not need to be set, as
251Catalyst::Authentication::Store::DBIx::Class will determine the primary
fff51ece 252key of the user table on its own. If you need to override the default,
f7e6d29f 253or your user table has multiple primary keys, then id_field
254should contain the column name that should be used to restore the user.
255A given value in this column should correspond to a single user in the database.
256Note that this is used B<ONLY> when restoring a user from the session and
257has no bearing whatsoever in the initial authentication process. Note also
258that if use_userdata_from_session is enabled, this config parameter
259is not used at all.
260
93102ff5 261=back
5000f545 262
93102ff5 263=head1 USAGE
5000f545 264
6727afe2 265The L<Catalyst::Authentication::Store::DBIx::Class> storage module
93102ff5 266is not called directly from application code. You interface with it
267through the $c->authenticate() call.
5000f545 268
c1d29ab7 269There are three methods you can use to retrieve information from the DBIx::Class
270storage module. They are Simple retrieval, and the advanced retrieval methods
271Searchargs and Resultset.
272
273=head2 Simple Retrieval
274
28aa2168 275The first, and most common, method is simple retrieval. As its name implies
c1d29ab7 276simple retrieval allows you to simply to provide the column => value pairs
277that should be used to locate the user in question. An example of this usage
278is below:
279
280 if ($c->authenticate({
f7e6d29f 281 screen_name => $c->req->params->{'username'},
c1d29ab7 282 password => $c->req->params->{'password'},
283 status => [ 'registered', 'active', 'loggedin']
284 })) {
285
286 # ... authenticated user code here
287 }
288
f7e6d29f 289The above example would attempt to retrieve a user whose username column (here,
290screen_name) matched the username provided, and whose status column matched one of the
c1d29ab7 291values provided. These name => value pairs are used more or less directly in
fff51ece 292the DBIx::Class search() routine, so in most cases, you can use DBIx::Class
c1d29ab7 293syntax to retrieve the user according to whatever rules you have.
294
295NOTE: Because the password in most cases is encrypted - it is not used
28aa2168 296directly but its encryption and comparison with the value provided is usually
c1d29ab7 297handled by the Password Credential. Part of the Password Credential's behavior
298is to remove the password argument from the authinfo that is passed to the
6727afe2 299storage module. See L<Catalyst::Authentication::Credential::Password>.
c1d29ab7 300
301One thing you need to know about this retrieval method is that the name
fff51ece 302portion of the pair is checked against the user class's column list. Pairs are
c1d29ab7 303only used if a matching column is found. Other pairs will be ignored. This
304means that you can only provide simple name-value pairs, and that some more
305advanced DBIx::Class constructs, such as '-or', '-and', etc. are in most cases
306not possible using this method. For queries that require this level of
307functionality, see the 'searchargs' method below.
308
309=head2 Advanced Retrieval
310
311The Searchargs and Resultset retrieval methods are used when more advanced
312features of the underlying L<DBIx::Class> schema are required. These methods
313provide a direct interface with the DBIx::Class schema and therefore
314require a better understanding of the DBIx::Class module.
315
316=head3 The dbix_class key
317
318Since the format of these arguments are often complex, they are not keys in
319the base authinfo hash. Instead, both of these arguments are placed within
320a hash attached to the store-specific 'dbix_class' key in the base $authinfo
321hash. When the DBIx::Class authentication store sees the 'dbix_class' key
322in the passed authinfo hash, all the other information in the authinfo hash
323is ignored and only the values within the 'dbix_class' hash are used as
324though they were passed directly within the authinfo hash. In other words, if
325'dbix_class' is present, it replaces the authinfo hash for processing purposes.
326
327The 'dbix_class' hash can be used to directly pass arguments to the
328DBIx::Class authentication store. Reasons to do this are to avoid credential
329modification of the authinfo hash, or to avoid overlap between credential and
330store key names. It's a good idea to avoid using it in this way unless you are
331sure you have an overlap/modification issue. However, the two advanced
28aa2168 332retrieval methods, B<searchargs> and B<resultset>, require its use, as they
333are only processed as part of the 'dbix_class' hash.
c1d29ab7 334
335=over 4
336
337=item Searchargs
338
339The B<searchargs> method of retrieval allows you to specify an arrayref containing
ad93b3e9 340the two arguments to the search() method from L<DBIx::Class::ResultSet>. If provided,
c1d29ab7 341all other args are ignored, and the search args provided are used directly to locate
342the user. An example will probably make more sense:
343
344 if ($c->authenticate(
345 {
346 password => $password,
347 'dbix_class' =>
348 {
f26005a7 349 searchargs => [ { -or => [ username => $username,
c1d29ab7 350 email => $email,
351 clientid => $clientid ]
352 },
353 { prefetch => qw/ preferences / }
354 ]
355 }
356 } ) )
357 {
358 # do successful authentication actions here.
359 }
360
361The above would allow authentication based on any of the three items -
fff51ece 362username, email, or clientid - and would prefetch the data related to that user
c1d29ab7 363from the preferences table. The searchargs array is passed directly to the
f55cb81e 364search() method associated with the user_model.
c1d29ab7 365
366=item Resultset
367
368The B<resultset> method of retrieval allows you to directly specify a
369resultset to be used for user retrieval. This allows you to create a resultset
370within your login action and use it for retrieving the user. A simple example:
371
372 my $rs = $c->model('MyApp::User')->search({ email => $c->request->params->{'email'} });
373 ... # further $rs adjustments
374
375 if ($c->authenticate({
376 password => $password,
fff51ece 377 'dbix_class' => { resultset => $rs }
c1d29ab7 378 })) {
379 # do successful authentication actions here.
380 }
381
382Be aware that the resultset method will not verify that you are passing a
f55cb81e 383resultset that is attached to the same user_model as specified in the config.
c1d29ab7 384
385NOTE: All of these methods of user retrieval, including the resultset method,
386consider the first row returned to be the matching user. In most cases there
387will be only one matching row, but it is easy to produce multiple rows,
388especially when using the advanced retrieval methods. Remember, what you get
389when you use this module is what you would get when calling
390search(...)->first;
391
392NOTE ALSO: The user info used to save the user to the session and to retrieve
393it is the same regardless of what method of retrieval was used. In short,
394the value in the id field (see 'id_field' config item) is used to retrieve the
395user from the database upon restoring from the session. When the DBIx::Class storage
396module does this, it does so by doing a simple search using the id field. In other
397words, it will not use the same arguments you used to request the user initially.
398This is especially important to those using the advanced methods of user retrieval.
399If you need more complicated logic when reviving the user from the session, you will
6727afe2 400most likely want to subclass the L<Catalyst::Authentication::Store::DBIx::Class::User> class
c1d29ab7 401and provide your own for_session and from_session routines.
402
403=back
5000f545 404
6727afe2 405
93102ff5 406=head1 METHODS
5000f545 407
93102ff5 408There are no publicly exported routines in the DBIx::Class authentication
fff51ece 409store (or indeed in most authentication stores). However, below is a
93102ff5 410description of the routines required by L<Catalyst::Plugin::Authentication>
411for all authentication stores. Please see the documentation for
412L<Catalyst::Plugin::Authentication::Internals> for more information.
413
6727afe2 414
415=head2 new ( $config, $app )
93102ff5 416
c1d29ab7 417Constructs a new store object.
93102ff5 418
6727afe2 419=head2 find_user ( $authinfo, $c )
93102ff5 420
c1d29ab7 421Finds a user using the information provided in the $authinfo hashref and
fff51ece 422returns the user, or undef on failure. This is usually called from the
c1d29ab7 423Credential. This translates directly to a call to
6727afe2 424L<Catalyst::Authentication::Store::DBIx::Class::User>'s load() method.
93102ff5 425
6727afe2 426=head2 for_session ( $c, $user )
93102ff5 427
c1d29ab7 428Prepares a user to be stored in the session. Currently returns the value of
fff51ece 429the user's id field (as indicated by the 'id_field' config element)
93102ff5 430
6727afe2 431=head2 from_session ( $c, $frozenuser)
93102ff5 432
c1d29ab7 433Revives a user from the session based on the info provided in $frozenuser.
93102ff5 434Currently treats $frozenuser as an id and retrieves a user with a matching id.
435
6727afe2 436=head2 user_supports
93102ff5 437
438Provides information about what the user object supports.
439
76e7a763 440=head2 auto_update_user( $authinfo, $c, $res )
441
442This method is called if the realm's auto_update_user setting is true. It
443will delegate to the user object's C<auto_update> method.
67f6319b 444
76e7a763 445=head2 auto_create_user( $authinfo, $c )
67f6319b 446
76e7a763 447This method is called if the realm's auto_create_user setting is true. It
fff51ece 448will delegate to the user class's (resultset) C<auto_create> method.
5000f545 449
450=head1 NOTES
451
93102ff5 452As of the current release, session storage consists of simply storing the user's
fff51ece 453id in the session, and then using that same id to re-retrieve the user's information
93102ff5 454from the database upon restoration from the session. More dynamic storage of
455user information in the session is intended for a future release.
5000f545 456
457=head1 BUGS AND LIMITATIONS
458
fff51ece 459None known currently; please email the author if you find any.
5000f545 460
461=head1 SEE ALSO
462
93102ff5 463L<Catalyst::Plugin::Authentication>, L<Catalyst::Plugin::Authentication::Internals>,
464and L<Catalyst::Plugin::Authorization::Roles>
5000f545 465
466=head1 AUTHOR
467
b33ee900 468Jason Kuri (jayk@cpan.org)
5000f545 469
c1d29ab7 470=head1 LICENSE
5000f545 471
c1d29ab7 472Copyright (c) 2007 the aforementioned authors. All rights
93102ff5 473reserved. This program is free software; you can redistribute
474it and/or modify it under the same terms as Perl itself.
5000f545 475
476=cut