Documentation. Finally.
[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
c1d29ab7 148sub get_object {
5000f545 149 my $self = shift;
ff7203cb 150
c1d29ab7 151 return $self->_user;
5000f545 152}
153
c1d29ab7 154sub obj {
5000f545 155 my $self = shift;
156
c1d29ab7 157 return $self->get_object;
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
c1d29ab7 173Catalyst::Plugin::Authentication::Store::DBIx::Class::User - The backing user
174class for the Catalyst::Plugin::Authentication::Store::DBIx::Class storage
175module.
5000f545 176
177=head1 VERSION
178
c1d29ab7 179This documentation refers to version 0.02.
5000f545 180
181=head1 SYNOPSIS
182
c1d29ab7 183Internal - not used directly, please see
184L<Catalyst::Plugin::Authentication::Store::DBIx::Class> for details on how to
185use this module. If you need more information than is present there, read the
186source.
93102ff5 187
188
5000f545 189
190=head1 DESCRIPTION
191
c1d29ab7 192The Catalyst::Plugin::Authentication::Store::DBIx::Class::User class implements user storage
193connected to an underlying DBIx::Class schema object.
5000f545 194
195=head1 SUBROUTINES / METHODS
196
c1d29ab7 197=head2 new
5000f545 198
c1d29ab7 199Constructor.
5000f545 200
c1d29ab7 201=head2 load_user ( $authinfo, $c )
5000f545 202
c1d29ab7 203Retrieves a user from storage using the information provided in $authinfo.
5000f545 204
c1d29ab7 205=head2 supported_features
5000f545 206
c1d29ab7 207Indicates the features supported by this class. These are currently Roles and Session.
5000f545 208
209=head2 roles
210
c1d29ab7 211Returns an array of roles associated with this user, if roles are configured for this user class.
5000f545 212
213=head2 for_session
214
c1d29ab7 215Returns a serialized user for storage in the session. Currently, this is the value of the field
216specified by the 'id_field' config variable.
5000f545 217
c1d29ab7 218=head2 get ( $fieldname )
5000f545 219
c1d29ab7 220Returns the value of $fieldname for the user in question. Roughly translates to a call to
221the DBIx::Class::Row's get_column( $fieldname ) routine.
5000f545 222
c1d29ab7 223=head2 get_object
5000f545 224
c1d29ab7 225Retrieves the DBIx::Class object that corresponds to this user
5000f545 226
227=head2 obj (method)
228
c1d29ab7 229Synonym for get_object
5000f545 230
231=head1 BUGS AND LIMITATIONS
232
233None known currently, please email the author if you find any.
234
235=head1 AUTHOR
236
237Jason Kuri (jk@domain.tld)
238
c1d29ab7 239=head1 LICENSE
5000f545 240
c1d29ab7 241Copyright (c) 2007 the aforementioned authors. All rights
242reserved. This program is free software; you can redistribute
243it and/or modify it under the same terms as Perl itself.
5000f545 244
245=cut