Making id_field dynamic - so that session storage works
[catagits/Catalyst-Authentication-Store-DBIx-Class.git] / lib / Catalyst / Plugin / Authentication / Store / DBIx / Class / User.pm
CommitLineData
5000f545 1package Catalyst::Plugin::Authentication::Store::DBIx::Class::User;
2
3use strict;
4use warnings;
5use base qw/Catalyst::Plugin::Authentication::User/;
ff7203cb 6use base qw/Class::Accessor::Fast/;
7
8BEGIN {
9 __PACKAGE__->mk_accessors(qw/config resultset _user _roles/);
10}
5000f545 11
12sub new {
ff7203cb 13 my ( $class, $config, $c) = @_;
5000f545 14
ff7203cb 15 my $self = {
16 resultset => $c->model($config->{'user_class'}),
17 config => $config,
078727e0 18 _roles => undef,
ff7203cb 19 _user => undef
20 };
5000f545 21
22 bless $self, $class;
23
ff7203cb 24
93102ff5 25 if (!exists($self->config->{'id_field'})) {
26 $self->config->{'id_field'} = 'id';
27 }
ff7203cb 28
5000f545 29 ## if we have lazyloading turned on - we should not query the DB unless something gets read.
30 ## that's the idea anyway - still have to work out how to manage that - so for now we always force
31 ## lazyload to off.
ff7203cb 32 $self->config->{lazyload} = 0;
5000f545 33
ff7203cb 34# if (!$self->config->{lazyload}) {
35# return $self->load_user($authinfo, $c);
36# } else {
37# ## what do we do with a lazyload?
38# ## presumably this is coming out of session storage.
39# ## use $authinfo to fill in the user in that case?
40# }
41
5000f545 42 return $self;
43}
44
45
ff7203cb 46sub load {
5000f545 47 my ($self, $authinfo, $c) = @_;
48
ff7203cb 49 my $dbix_class_config = 0;
50
51 if (exists($authinfo->{'dbix_class'})) {
52 $authinfo = $authinfo->{'dbix_class'};
53 $dbix_class_config = 1;
54 }
55
5000f545 56 ## User can provide an arrayref containing the arguments to search on the user class.
ff7203cb 57 ## or even provide a prepared resultset, allowing maximum flexibility for user retreival.
58 ## these options are only available when using the dbix_class authinfo hash.
59 if ($dbix_class_config && exists($authinfo->{'resultset'})) {
60 $self->_user($authinfo->{'resultset'}->first);
61 } elsif ($dbix_class_config && exists($authinfo->{'searchargs'})) {
62 $self->_user($self->resultset->search(@{$authinfo->{'searchargs'}})->first);
5000f545 63 } else {
64 ## merge the ignore fields array into a hash - so we can do an easy check while building the query
ff7203cb 65 my %ignorefields = map { $_ => 1} @{$self->config->{'ignore_fields_in_find'}};
5000f545 66 my $searchargs = {};
67
68 # now we walk all the fields passed in, and build up a search hash.
69 foreach my $key (grep {!$ignorefields{$_}} keys %{$authinfo}) {
ff7203cb 70 if ($self->resultset->result_source->has_column($key)) {
5000f545 71 $searchargs->{$key} = $authinfo->{$key};
72 }
ff7203cb 73 }
74 $self->_user($self->resultset->search($searchargs)->first);
75 }
76
77 if ($self->get_object) {
93102ff5 78 return $self;
ff7203cb 79 } else {
80 return undef;
5000f545 81 }
ff7203cb 82 #$c->log->debug(dumper($self->{'user'}));
5000f545 83
84}
85
86sub supported_features {
87 my $self = shift;
5000f545 88
89 return {
5000f545 90 session => 1,
91 roles => 1,
92 };
93}
94
95
96sub roles {
b5c13b47 97 my ( $self ) = shift;
98 ## this used to load @wantedroles - but that doesn't seem to be used by the roles plugin, so I dropped it.
5000f545 99
100 ## shortcut if we have already retrieved them
ff7203cb 101 if (ref $self->_roles eq 'ARRAY') {
102 return(@{$self->_roles});
5000f545 103 }
104
105 my @roles = ();
ff7203cb 106 if (exists($self->config->{'role_column'})) {
93102ff5 107 @roles = split /[ ,\|]+/, $self->get($self->config->{'role_column'});
078727e0 108 $self->_roles(\@roles);
ff7203cb 109 } elsif (exists($self->config->{'role_relation'})) {
110 my $relation = $self->config->{'role_relation'};
111 if ($self->_user->$relation->result_source->has_column($self->config->{'role_field'})) {
078727e0 112 @roles = map { $_->get_column($self->config->{'role_field'}) } $self->_user->$relation->search(undef, { columns => [ $self->config->{'role_field'}]})->all();
113 $self->_roles(\@roles);
5000f545 114 } else {
ff7203cb 115 Catalyst::Exception->throw("role table does not have a column called " . $self->config->{'role_field'});
5000f545 116 }
5000f545 117 } else {
118 Catalyst::Exception->throw("user->roles accessed, but no role configuration found");
119 }
120
ff7203cb 121 return @{$self->_roles};
5000f545 122}
123
124sub for_session {
ff7203cb 125 my $self = shift;
126
93102ff5 127 return $self->get($self->config->{'id_field'});
ff7203cb 128}
129
130sub from_session {
131 my ($self, $frozenuser, $c) = @_;
132
133 # this could be a lot better. But for now it just assumes $frozenuser is an id and uses find_user
134 # XXX: hits the database on every request? Not good...
93102ff5 135 return $self->load( { $self->config->{'id_field'} => $frozenuser }, $c);
5000f545 136}
137
138sub get {
139 my ($self, $field) = @_;
140
ff7203cb 141 if ($self->_user->can($field)) {
142 return $self->_user->$field;
5000f545 143 } else {
144 return undef;
145 }
146}
147
148sub obj {
149 my $self = shift;
ff7203cb 150
5000f545 151 return $self->get_object;
152}
153
154sub get_object {
155 my $self = shift;
156
ff7203cb 157 return $self->_user;
5000f545 158}
159
160sub AUTOLOAD {
161 my $self = shift;
162 (my $method) = (our $AUTOLOAD =~ /([^:]+)$/);
163 return if $method eq "DESTROY";
164
ff7203cb 165 $self->_user->$method(@_);
5000f545 166}
167
1681;
169__END__
170
171=head1 NAME
172
173Catalyst::Plugin::Authentication::Store::DBIx::Class::User - A class to ...
174
175=head1 VERSION
176
177This documentation refers to version 0.01.
178
179=head1 SYNOPSIS
180
93102ff5 181Internal - not used directly. use Catalyst::Plugin::Authentication::Store::DBIx::Class::User;
182
183
184
5000f545 185
186=head1 DESCRIPTION
187
188The Catalyst::Plugin::Authentication::Store::DBIx::Class::User class implements ...
189
190=head1 SUBROUTINES / METHODS
191
192=head2 new (constructor)
193
194Parameters:
195 class
196 authinfo
197 config
198 c
199 lazyload
200
201Insert description of constructor here...
202
203=head2 load_user (method)
204
205Parameters:
206 authinfo
207 c
208
209Insert description of method here...
210
211=head2 supported_features (method)
212
213Parameters:
214 none
215
216Insert description of method here...
217
218=head2 roles
219
220Parameters:
221 none
222
223Insert description of subroutine here...
224
225=head2 for_session
226
227Parameters:
228 none
229
230Insert description of subroutine here...
231
232=head2 get (method)
233
234Parameters:
235 field
236
237Insert description of method here...
238
239=head2 obj (method)
240
241Parameters:
242 none
243
244Insert description of method here...
245
246=head2 get_object (method)
247
248Parameters:
249 none
250
251Insert description of method here...
252
253=head2 AUTOLOAD (method)
254
255Parameters:
256 none
257
258Insert description of method here...
259
260=head1 DEPENDENCIES
261
262Modules used, version dependencies, core yes/no
263
264strict
265
266warnings
267
268=head1 NOTES
269
270...
271
272=head1 BUGS AND LIMITATIONS
273
274None known currently, please email the author if you find any.
275
276=head1 AUTHOR
277
278Jason Kuri (jk@domain.tld)
279
280=head1 LICENCE
281
282Copyright 2006 by Jason Kuri.
283
284This software is free. It is licensed under the same terms as Perl itself.
285
286=cut