explicitly call auto_create and auto_update properly. jayk -- fix them docs. :)
[catagits/Catalyst-Authentication-Store-DBIx-Class.git] / lib / Catalyst / Authentication / Store / DBIx / Class / User.pm
CommitLineData
6727afe2 1package Catalyst::Authentication::Store::DBIx::Class::User;
5000f545 2
3use strict;
4use warnings;
6727afe2 5use base qw/Catalyst::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'})) {
ad93b3e9 26 my @pks = $self->{'resultset'}->result_source->primary_columns;
27 if ($#pks == 0) {
28 $self->config->{'id_field'} = $pks[0];
29 } else {
30 Catalyst::Exception->throw("user table does not contain a single primary key column - please specify 'id_field' in config!");
31 }
32 }
33 if (!$self->{'resultset'}->result_source->has_column($self->config->{'id_field'})) {
34 Catalyst::Exception->throw("id_field set to " . $self->config->{'id_field'} . " but user table has no column by that name!");
93102ff5 35 }
ff7203cb 36
5000f545 37 ## if we have lazyloading turned on - we should not query the DB unless something gets read.
38 ## that's the idea anyway - still have to work out how to manage that - so for now we always force
39 ## lazyload to off.
ff7203cb 40 $self->config->{lazyload} = 0;
5000f545 41
ff7203cb 42# if (!$self->config->{lazyload}) {
43# return $self->load_user($authinfo, $c);
44# } else {
45# ## what do we do with a lazyload?
46# ## presumably this is coming out of session storage.
47# ## use $authinfo to fill in the user in that case?
48# }
49
5000f545 50 return $self;
51}
52
53
ff7203cb 54sub load {
5000f545 55 my ($self, $authinfo, $c) = @_;
56
ff7203cb 57 my $dbix_class_config = 0;
58
59 if (exists($authinfo->{'dbix_class'})) {
60 $authinfo = $authinfo->{'dbix_class'};
61 $dbix_class_config = 1;
62 }
63
5000f545 64 ## User can provide an arrayref containing the arguments to search on the user class.
ff7203cb 65 ## or even provide a prepared resultset, allowing maximum flexibility for user retreival.
66 ## these options are only available when using the dbix_class authinfo hash.
67 if ($dbix_class_config && exists($authinfo->{'resultset'})) {
68 $self->_user($authinfo->{'resultset'}->first);
69 } elsif ($dbix_class_config && exists($authinfo->{'searchargs'})) {
70 $self->_user($self->resultset->search(@{$authinfo->{'searchargs'}})->first);
5000f545 71 } else {
72 ## merge the ignore fields array into a hash - so we can do an easy check while building the query
ff7203cb 73 my %ignorefields = map { $_ => 1} @{$self->config->{'ignore_fields_in_find'}};
5000f545 74 my $searchargs = {};
75
76 # now we walk all the fields passed in, and build up a search hash.
77 foreach my $key (grep {!$ignorefields{$_}} keys %{$authinfo}) {
ff7203cb 78 if ($self->resultset->result_source->has_column($key)) {
5000f545 79 $searchargs->{$key} = $authinfo->{$key};
80 }
ff7203cb 81 }
82 $self->_user($self->resultset->search($searchargs)->first);
83 }
84
85 if ($self->get_object) {
93102ff5 86 return $self;
ff7203cb 87 } else {
88 return undef;
5000f545 89 }
ff7203cb 90 #$c->log->debug(dumper($self->{'user'}));
5000f545 91
92}
93
94sub supported_features {
95 my $self = shift;
5000f545 96
97 return {
5000f545 98 session => 1,
99 roles => 1,
100 };
101}
102
103
104sub roles {
b5c13b47 105 my ( $self ) = shift;
106 ## this used to load @wantedroles - but that doesn't seem to be used by the roles plugin, so I dropped it.
5000f545 107
108 ## shortcut if we have already retrieved them
ff7203cb 109 if (ref $self->_roles eq 'ARRAY') {
110 return(@{$self->_roles});
5000f545 111 }
112
113 my @roles = ();
ff7203cb 114 if (exists($self->config->{'role_column'})) {
ad93b3e9 115 my $role_data = $self->get($self->config->{'role_column'});
116 if ($role_data) {
117 @roles = split /[ ,\|]+/, $self->get($self->config->{'role_column'});
118 }
078727e0 119 $self->_roles(\@roles);
ff7203cb 120 } elsif (exists($self->config->{'role_relation'})) {
121 my $relation = $self->config->{'role_relation'};
122 if ($self->_user->$relation->result_source->has_column($self->config->{'role_field'})) {
078727e0 123 @roles = map { $_->get_column($self->config->{'role_field'}) } $self->_user->$relation->search(undef, { columns => [ $self->config->{'role_field'}]})->all();
124 $self->_roles(\@roles);
5000f545 125 } else {
ff7203cb 126 Catalyst::Exception->throw("role table does not have a column called " . $self->config->{'role_field'});
5000f545 127 }
5000f545 128 } else {
129 Catalyst::Exception->throw("user->roles accessed, but no role configuration found");
130 }
131
ff7203cb 132 return @{$self->_roles};
5000f545 133}
134
135sub for_session {
ff7203cb 136 my $self = shift;
137
93102ff5 138 return $self->get($self->config->{'id_field'});
ff7203cb 139}
140
141sub from_session {
142 my ($self, $frozenuser, $c) = @_;
143
144 # this could be a lot better. But for now it just assumes $frozenuser is an id and uses find_user
145 # XXX: hits the database on every request? Not good...
93102ff5 146 return $self->load( { $self->config->{'id_field'} => $frozenuser }, $c);
5000f545 147}
148
149sub get {
150 my ($self, $field) = @_;
151
ff7203cb 152 if ($self->_user->can($field)) {
153 return $self->_user->$field;
5000f545 154 } else {
155 return undef;
156 }
157}
158
c1d29ab7 159sub get_object {
5000f545 160 my $self = shift;
ff7203cb 161
c1d29ab7 162 return $self->_user;
5000f545 163}
164
c1d29ab7 165sub obj {
5000f545 166 my $self = shift;
167
c1d29ab7 168 return $self->get_object;
5000f545 169}
170
69100364 171sub auto_create {
172 my $self = shift;
173 $self->_user( $self->resultset->auto_create( @_ ) );
174 return $self;
175}
176
177sub auto_update {
178 my $self = shift;
179 $self->_user->auto_update( @_ );
180}
181
5000f545 182sub AUTOLOAD {
183 my $self = shift;
184 (my $method) = (our $AUTOLOAD =~ /([^:]+)$/);
185 return if $method eq "DESTROY";
186
ff7203cb 187 $self->_user->$method(@_);
5000f545 188}
189
1901;
191__END__
192
193=head1 NAME
194
6727afe2 195Catalyst::Authentication::Store::DBIx::Class::User - The backing user
196class for the Catalyst::Authentication::Store::DBIx::Class storage
c1d29ab7 197module.
5000f545 198
199=head1 VERSION
200
ad93b3e9 201This documentation refers to version 0.10.
5000f545 202
203=head1 SYNOPSIS
204
c1d29ab7 205Internal - not used directly, please see
6727afe2 206L<Catalyst::Authentication::Store::DBIx::Class> for details on how to
c1d29ab7 207use this module. If you need more information than is present there, read the
208source.
93102ff5 209
210
5000f545 211
212=head1 DESCRIPTION
213
6727afe2 214The Catalyst::Authentication::Store::DBIx::Class::User class implements user storage
c1d29ab7 215connected to an underlying DBIx::Class schema object.
5000f545 216
217=head1 SUBROUTINES / METHODS
218
c1d29ab7 219=head2 new
5000f545 220
c1d29ab7 221Constructor.
5000f545 222
fbe76043 223=head2 load ( $authinfo, $c )
5000f545 224
c1d29ab7 225Retrieves a user from storage using the information provided in $authinfo.
5000f545 226
c1d29ab7 227=head2 supported_features
5000f545 228
c1d29ab7 229Indicates the features supported by this class. These are currently Roles and Session.
5000f545 230
231=head2 roles
232
c1d29ab7 233Returns an array of roles associated with this user, if roles are configured for this user class.
5000f545 234
235=head2 for_session
236
c1d29ab7 237Returns a serialized user for storage in the session. Currently, this is the value of the field
238specified by the 'id_field' config variable.
5000f545 239
fbe76043 240=head2 from_session
241
242Revives a serialized user from storage in the session. Currently, this uses the serialized data as the
243value of the 'id_field' config variable.
244
c1d29ab7 245=head2 get ( $fieldname )
5000f545 246
c1d29ab7 247Returns the value of $fieldname for the user in question. Roughly translates to a call to
248the DBIx::Class::Row's get_column( $fieldname ) routine.
5000f545 249
c1d29ab7 250=head2 get_object
5000f545 251
c1d29ab7 252Retrieves the DBIx::Class object that corresponds to this user
5000f545 253
254=head2 obj (method)
255
c1d29ab7 256Synonym for get_object
5000f545 257
69100364 258=head2 auto_create
259
260This will delegate a call to the C<auto_create()> method of the resultset associated
261with this object. It is up to you to implement that method.
262
263=head2 auto_update
264
265This will delegate a call to the C<auto_create()> method of the current instance of the resultset
266associated with this object. It is up to you to implement that method.
267
5000f545 268=head1 BUGS AND LIMITATIONS
269
270None known currently, please email the author if you find any.
271
272=head1 AUTHOR
273
fbe76043 274Jason Kuri (jayk@cpan.org)
5000f545 275
c1d29ab7 276=head1 LICENSE
5000f545 277
c1d29ab7 278Copyright (c) 2007 the aforementioned authors. All rights
279reserved. This program is free software; you can redistribute
280it and/or modify it under the same terms as Perl itself.
5000f545 281
282=cut