1 package Catalyst::Plugin::Authentication::Store::DBIx::Class;
5 use base qw/Class::Accessor::Fast/;
10 __PACKAGE__->mk_accessors(qw/config/);
15 my ( $class, $config, $app ) = @_;
17 ## figure out if we are overriding the default store user class
18 $config->{'store_user_class'} = (exists($config->{'store_user_class'})) ? $config->{'store_user_class'} :
19 "Catalyst::Plugin::Authentication::Store::DBIx::Class::User";
21 ## make sure the store class is loaded.
22 Catalyst::Utils::ensure_class_loaded( $config->{'store_user_class'} );
24 ## fields can be specified to be ignored during user location. This allows
25 ## the store to ignore certain fields in the authinfo hash.
27 $config->{'ignore_fields_in_find'} ||= [ ];
38 ## let's use DBICs get_columns method to return a hash and save / restore that
39 ## from the session. Then we can respond to get() calls, etc. in most cases without
40 ## resorting to a DB call. If user_object is called, THEN we can hit the DB and
41 ## return a real object.
43 my ( $self, $c, $frozenuser ) = @_;
45 return $frozenuser if ref $frozenuser;
47 my $user = $self->config->{'store_user_class'}->new($self->{'config'}, $c);
49 return $user->from_session($frozenuser, $c);
53 my ($self, $c, $user) = @_;
55 return $user->for_session($c);
59 my ( $self, $authinfo, $c ) = @_;
61 my $user = $self->config->{'store_user_class'}->new($self->{'config'}, $c);
63 return $user->load($authinfo, $c);
69 # this can work as a class method on the user class
70 $self->config->{'store_user_class'}->supports( @_ );
79 Catalyst::Plugin::Authentication::Store::DBIx::Class - A storage class for Catalyst Authentication using DBIx::Class
83 This documentation refers to version 0.02.
89 Authorization::Roles/;
91 __PACKAGE__->config->{authentication} =
93 default_realm => 'members',
98 password_field => 'password',
99 password_type => 'clear'
102 class => 'DBIx::Class',
103 user_class => 'MyApp::Users',
104 id_field => 'user_id',
105 role_relation => 'roles',
106 role_field => 'rolename',
115 my ( $self, $c ) = @_;
118 username => $c->req->params->username,
119 password => $c->req->params->password,
120 status => [ 'registered', 'loggedin', 'active']
126 if ( $c->check_user_roles( 'editor' ) ) {
132 The Catalyst::Plugin::Authentication::Store::DBIx::Class class provides
133 access to authentication information stored in a database via DBIx::Class.
137 The DBIx::Class authentication store is activated by setting the store
138 config's B<class> element to DBIx::Class as shown above. See the
139 L<Catalyst::Plugin::Authentication> documentation for more details on
140 configuring the store.
142 The DBIx::Class storage module has several configuration options
146 __PACKAGE__->config->{authentication} =
148 default_realm => 'members',
155 class => 'DBIx::Class',
156 user_class => 'MyApp::Users',
157 id_field => 'user_id',
158 role_relation => 'roles',
159 role_field => 'rolename',
160 ignore_fields_in_find => [ 'remote_name' ]
168 Class is part of the core Catalyst::Authentication::Plugin module, it
169 contains the class name of the store to be used.
173 Contains the class name (as passed to $c->model()) of the DBIx::Class schema
174 to use as the source for user information. This config item is B<REQUIRED>.
178 Contains the field name containing the unique identifier for a user. This is
179 used when storing and retrieving a user from the session. The value in this
180 field should correspond to a single user in the database. Defaults to 'id'.
184 If your role information is stored in the same table as the rest of your user
185 information, this item tells the module which field contains your role
186 information. The DBIx::Class authentication store expects the data in this
187 field to be a series of role names separated by some combination of spaces,
188 commas or pipe characters.
192 If your role information is stored in a separate table, this is the name of
193 the relation that will lead to the roles the user is in. If this is
194 specified then a role_field is also required. Also when using this method
195 it is expected that your role table will return one row for each role
200 This is the name of the field in the role table that contains the string
201 identifying the role.
203 =item ignore_fields_in_find
205 This item is an array containing fields that may be passed to the
206 $c->authenticate() routine (and therefore find_user in the storage class), but
207 which should be ignored when creating the DBIx::Class search to retrieve a
208 user. This makes it possible to avoid problems when a credential requires an
209 authinfo element whose name overlaps with a column name in your users table.
210 If this doesn't make sense to you, you probably don't need it.
212 =item store_user_class
214 This allows you to override the authentication user class that the
215 DBIx::Class store module uses to perform it's work. Most of the
216 work done in this module is actually done by the user class,
217 L<Catalyst::Plugin::Authentication::Store::DBIx::Class::User>, so
218 overriding this doesn't make much sense unless you are using your
219 own class to extend the functionality of the existing class.
220 Chances are you do not want to set this.
226 The L<Catalyst::Plugin::Authentication::Store::DBIx::Class> storage module
227 is not called directly from application code. You interface with it
228 through the $c->authenticate() call.
230 There are three methods you can use to retrieve information from the DBIx::Class
231 storage module. They are Simple retrieval, and the advanced retrieval methods
232 Searchargs and Resultset.
234 =head2 Simple Retrieval
236 The first, and most common, method is simple retrieval. As it's name implies
237 simple retrieval allows you to simply to provide the column => value pairs
238 that should be used to locate the user in question. An example of this usage
241 if ($c->authenticate({
242 username => $c->req->params->{'username'},
243 password => $c->req->params->{'password'},
244 status => [ 'registered', 'active', 'loggedin']
247 # ... authenticated user code here
250 The above example would attempt to retrieve a user whose username column
251 matched the username provided, and whose status column matched one of the
252 values provided. These name => value pairs are used more or less directly in
253 the DBIx::Class' search() routine, so in most cases, you can use DBIx::Class
254 syntax to retrieve the user according to whatever rules you have.
256 NOTE: Because the password in most cases is encrypted - it is not used
257 directly but it's encryption and comparison with the value provided is usually
258 handled by the Password Credential. Part of the Password Credential's behavior
259 is to remove the password argument from the authinfo that is passed to the
260 storage module. See L<Catalyst::Plugin::Authentication::Credential::Password>.
262 One thing you need to know about this retrieval method is that the name
263 portion of the pair is checked against the user class' column list. Pairs are
264 only used if a matching column is found. Other pairs will be ignored. This
265 means that you can only provide simple name-value pairs, and that some more
266 advanced DBIx::Class constructs, such as '-or', '-and', etc. are in most cases
267 not possible using this method. For queries that require this level of
268 functionality, see the 'searchargs' method below.
270 =head2 Advanced Retrieval
272 The Searchargs and Resultset retrieval methods are used when more advanced
273 features of the underlying L<DBIx::Class> schema are required. These methods
274 provide a direct interface with the DBIx::Class schema and therefore
275 require a better understanding of the DBIx::Class module.
277 =head3 The dbix_class key
279 Since the format of these arguments are often complex, they are not keys in
280 the base authinfo hash. Instead, both of these arguments are placed within
281 a hash attached to the store-specific 'dbix_class' key in the base $authinfo
282 hash. When the DBIx::Class authentication store sees the 'dbix_class' key
283 in the passed authinfo hash, all the other information in the authinfo hash
284 is ignored and only the values within the 'dbix_class' hash are used as
285 though they were passed directly within the authinfo hash. In other words, if
286 'dbix_class' is present, it replaces the authinfo hash for processing purposes.
288 The 'dbix_class' hash can be used to directly pass arguments to the
289 DBIx::Class authentication store. Reasons to do this are to avoid credential
290 modification of the authinfo hash, or to avoid overlap between credential and
291 store key names. It's a good idea to avoid using it in this way unless you are
292 sure you have an overlap/modification issue. However, the two advanced
293 retrieval methods, B<searchargs> and B<resultset>, require it's use, as they
294 are only processed as part of the 'dbix_class' hash
300 The B<searchargs> method of retrieval allows you to specify an arrayref containing
301 the two arguments to the search() method from L<DBIx::Class::Resultset>. If provided,
302 all other args are ignored, and the search args provided are used directly to locate
303 the user. An example will probably make more sense:
305 if ($c->authenticate(
307 password => $password,
310 searchargs = [ { -or => [ username => $username,
312 clientid => $clientid ]
314 { prefetch => qw/ preferences / }
319 # do successful authentication actions here.
322 The above would allow authentication based on any of the three items -
323 username, email or clientid and would prefetch the data related to that user
324 from the preferences table. The searchargs array is passed directly to the
325 search() method associated with the user_class.
329 The B<resultset> method of retrieval allows you to directly specify a
330 resultset to be used for user retrieval. This allows you to create a resultset
331 within your login action and use it for retrieving the user. A simple example:
333 my $rs = $c->model('MyApp::User')->search({ email => $c->request->params->{'email'} });
334 ... # further $rs adjustments
336 if ($c->authenticate({
337 password => $password,
338 'dbix_class' => { resultset = $rs }
340 # do successful authentication actions here.
343 Be aware that the resultset method will not verify that you are passing a
344 resultset that is attached to the same user_class as specified in the config.
346 NOTE: All of these methods of user retrieval, including the resultset method,
347 consider the first row returned to be the matching user. In most cases there
348 will be only one matching row, but it is easy to produce multiple rows,
349 especially when using the advanced retrieval methods. Remember, what you get
350 when you use this module is what you would get when calling
353 NOTE ALSO: The user info used to save the user to the session and to retrieve
354 it is the same regardless of what method of retrieval was used. In short,
355 the value in the id field (see 'id_field' config item) is used to retrieve the
356 user from the database upon restoring from the session. When the DBIx::Class storage
357 module does this, it does so by doing a simple search using the id field. In other
358 words, it will not use the same arguments you used to request the user initially.
359 This is especially important to those using the advanced methods of user retrieval.
360 If you need more complicated logic when reviving the user from the session, you will
361 most likely want to subclass the L<Catalyst::Plugin::Authentication::Store::DBIx::Class::User> class
362 and provide your own for_session and from_session routines.
369 There are no publicly exported routines in the DBIx::Class authentication
370 store (or indeed in most authentication stores) However, below is a
371 description of the routines required by L<Catalyst::Plugin::Authentication>
372 for all authentication stores. Please see the documentation for
373 L<Catalyst::Plugin::Authentication::Internals> for more information.
377 =item new ( $config, $app )
379 Constructs a new store object.
381 =item find_user ( $authinfo, $c )
383 Finds a user using the information provided in the $authinfo hashref and
384 returns the user, or undef on failure; This is usually called from the
385 Credential. This translates directly to a call to
386 L<Catalyst::Plugin::Authentication::Store::DBIx::Class::User>'s load() method.
388 =item for_session ( $c, $user )
390 Prepares a user to be stored in the session. Currently returns the value of
391 the user's id field - (as indicated by the 'id_field' config element)
393 =item from_session ( $c, $frozenuser)
395 Revives a user from the session based on the info provided in $frozenuser.
396 Currently treats $frozenuser as an id and retrieves a user with a matching id.
400 Provides information about what the user object supports.
406 As of the current release, session storage consists of simply storing the user's
407 id in the session, and then using that same id to re-retrieve the users information
408 from the database upon restoration from the session. More dynamic storage of
409 user information in the session is intended for a future release.
411 =head1 BUGS AND LIMITATIONS
413 None known currently, please email the author if you find any.
417 L<Catalyst::Plugin::Authentication>, L<Catalyst::Plugin::Authentication::Internals>,
418 and L<Catalyst::Plugin::Authorization::Roles>
422 Jason Kuri (jayk@cpan.org)
426 Copyright (c) 2007 the aforementioned authors. All rights
427 reserved. This program is free software; you can redistribute
428 it and/or modify it under the same terms as Perl itself.