Making id_field dynamic - so that session storage works
[catagits/Catalyst-Authentication-Store-DBIx-Class.git] / lib / Catalyst / Plugin / Authentication / Store / DBIx / Class.pm
1 package Catalyst::Plugin::Authentication::Store::DBIx::Class;
2
3 use strict;
4 use warnings;
5 use base qw/Class::Accessor::Fast/;
6
7 our $VERSION= "0.02";
8
9 BEGIN {
10     __PACKAGE__->mk_accessors(qw/config/);
11 }
12
13
14 sub new {
15     my ( $class, $config, $app ) = @_;
16
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";
20
21     ## make sure the store class is loaded.
22     Catalyst::Utils::ensure_class_loaded( $config->{'store_user_class'} );
23     
24     ## fields can be specified to be ignored during user location.  This allows
25     ## the store to ignore certain fields in the authinfo hash.
26     
27     $config->{'ignore_fields_in_find'} ||= [ ];
28
29     my $self = {
30                     config => $config
31                };
32
33     bless $self, $class;
34
35 }
36
37 ## --jk note to self:
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.  
42 sub from_session {
43     my ( $self, $c, $frozenuser ) = @_;
44
45     return $frozenuser if ref $frozenuser;
46     
47     my $user = $self->config->{'store_user_class'}->new($self->{'config'}, $c);
48     
49     return $user->from_session($frozenuser, $c);
50 }
51
52 sub for_session {
53     my ($self, $c, $user) = @_;
54     
55     return $user->for_session($c);
56 }
57
58 sub find_user {
59     my ( $self, $authinfo, $c ) = @_;
60     
61     my $user = $self->config->{'store_user_class'}->new($self->{'config'}, $c);
62
63     return $user->load($authinfo, $c);
64
65 }
66
67 sub user_supports {
68     my $self = shift;
69     # this can work as a class method on the user class
70     $self->config->{'store_user_class'}->supports( @_ );
71 }
72
73 __PACKAGE__;
74
75 __END__
76
77 =head1 NAME
78
79 Catalyst::Plugin::Authentication::Store::DBIx::Class - A storage class for Catalyst Authentication using DBIx::Class
80
81 =head1 VERSION
82
83 This documentation refers to version 0.01.
84
85 =head1 SYNOPSIS
86
87     use Catalyst qw/
88                     Authentication
89                     Authorization::Roles/;
90
91     __PACKAGE__->config->{authentication} = 
92                     {  
93                         default_realm => 'members',
94                         realms => {
95                             members => {
96                                 credential => {
97                                     class => 'Password',
98                                     password_field => 'password',
99                                     password_type => 'clear'
100                                 },
101                                 store => {
102                                     class => 'DBIx::Class',
103                                     user_class => 'MyApp::Users',
104                                     id_field => 'user_id',
105                                     role_relation => 'roles',
106                                     role_field => 'rolename',                   
107                                 }
108                                 }
109                         }
110                     };
111
112     # Log a user in:
113     
114     sub login : Global {
115         my ( $self, $c ) = @_;
116         
117         $c->authenticate({  
118                                     username => $c->req->params->username,
119                                     password => $c->req->params->password,
120                                     status => [ 'registered', 'loggedin', 'active' ]
121                                  }))
122     }
123     
124     # verify a role 
125     
126     if ( $c->check_user_roles( 'editor' ) ) {
127         # do editor stuff
128     }
129     
130 =head1 DESCRIPTION
131
132 The Catalyst::Plugin::Authentication::Store::DBIx::Class class provides 
133 access to authentication information stored in a database via DBIx::Class.
134
135 =head1 CONFIGURATION
136
137 The DBIx::Class authentication store is activated by setting the store
138 config's class element to DBIx::Class as shown above.  See the 
139 L<Catalyst::Plugin::Authentication> documentation for more details on 
140 configuring the store.
141
142 The DBIx::Class storage module has several configuration options
143
144 =over 4
145
146     __PACKAGE__->config->{authentication} = 
147                     {  
148                         default_realm => 'members',
149                         realms => {
150                             members => {
151                                 credential => {
152                                     # ...
153                                 },
154                                 store => {
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' ]          
161                                 }
162                                 }
163                         }
164                     };
165
166 =item class
167
168 Class is part of the core Catalyst::Authentication::Plugin module, it
169 contains the class name of the store to be used.
170
171 =item user_class
172
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>.
175
176 =item id_field
177
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'.
181
182 =item role_column
183
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.  
189
190 =item role_relation
191
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 
196 the user is in.
197
198 =item role_field
199
200 This is the name of the field in the role table that contains the string 
201 identifying the role.  
202
203 =item ignore_fields_in_find
204
205 This item is an array containing fields that may be passed to the 
206 find_user routine, but which should be ignored when creating the 
207 DBIx::Class search to retrieve a user.  This makes it possible to
208 avoid problems when a credential requires an authinfo element whose
209 name overlaps with a column name in your users table.  If this doesn't
210 make sense to you, you probably don't need it.
211
212 =item store_user_class
213
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.
221
222 =back
223
224 =head1 USAGE 
225
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.  
229
230 ... documentation fairy fell asleep here ...
231
232
233 =head1 METHODS
234
235 There are no publicly exported routines in the DBIx::Class authentication 
236 store (or indeed in most authentication stores)  However, below is a 
237 description of the routines required by L<Catalyst::Plugin::Authentication> 
238 for all authentication stores.  Please see the documentation for 
239 L<Catalyst::Plugin::Authentication::Internals> for more information.
240
241 =over 4
242
243 =item new ( $config, $app )
244
245 Constructs a new store object, which uses the user element of the supplied config 
246 hash ref as it's backing structure.
247
248 =item find_user ( $authinfo, $c ) 
249
250 Finds a user using the information provided in the $authinfo hashref and returns
251 the user, or undef on failure;  This translates directly to a call to 
252 L<Catalyst::Plugin::Authentication::Store::DBIx::Class::User>'s load() method.
253
254 =item for_session ( $c, $user )
255
256 Prepares a user to be stored in the session.  Currently returns the value of the
257 user's id field - (as indicated by the 'id_field' config element)
258
259 =item from_session ( $c, $frozenuser)
260
261 Revives a user from the session based on the info provided in $frozenuser.  
262 Currently treats $frozenuser as an id and retrieves a user with a matching id.
263
264 =item user_supports
265
266 Provides information about what the user object supports.  
267
268 =back 
269
270 =head1 NOTES
271
272 As of the current release, session storage consists of simply storing the user's
273 id in the session, and then using that same id to re-retrieve the users information
274 from the database upon restoration from the session.  More dynamic storage of
275 user information in the session is intended for a future release.
276
277 =head1 BUGS AND LIMITATIONS
278
279 None known currently, please email the author if you find any.
280
281 =head1 SEE ALSO
282
283 L<Catalyst::Plugin::Authentication>, L<Catalyst::Plugin::Authentication::Internals>,
284 and L<Catalyst::Plugin::Authorization::Roles>
285
286 =head1 AUTHOR
287
288 Jason Kuri (jayk@cpan.org)
289
290 =head1 LICENCE
291
292 Copyright (c) 2005 the aforementioned authors. All rights
293 reserved. This program is free software; you can redistribute
294 it and/or modify it under the same terms as Perl itself.
295
296 =cut