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