POD doc pokingses
[catagits/Catalyst-Plugin-Authentication.git] / lib / Catalyst / Authentication / Realm.pm
CommitLineData
5c5af345 1package Catalyst::Authentication::Realm;
646ea5b1 2
3use strict;
4use warnings;
1489b476 5
646ea5b1 6use base qw/Class::Accessor::Fast/;
7
8BEGIN {
9 __PACKAGE__->mk_accessors(qw/store credential name config/);
10};
11
12sub new {
13 my ($class, $realmname, $config, $app) = @_;
14
15 my $self = { config => $config };
16 bless $self, $class;
17
18 $self->name($realmname);
19
20 $app->log->debug("Setting up auth realm $realmname") if $app->debug;
5ef7a3dc 21
22 # use the Null store as a default
23 if( ! exists $config->{store}{class} ) {
39ce54e8 24 $config->{store}{class} = '+Catalyst::Authentication::Store::Null';
5ef7a3dc 25 $app->log->debug( qq(No Store specified for realm "$realmname", using the Null store.) );
646ea5b1 26 }
646ea5b1 27 my $storeclass = $config->{'store'}{'class'};
28
29 ## follow catalyst class naming - a + prefix means a fully qualified class, otherwise it's
30 ## taken to mean C::P::A::Store::(specifiedclass)
31 if ($storeclass !~ /^\+(.*)$/ ) {
39ce54e8 32 $storeclass = "Catalyst::Authentication::Store::${storeclass}";
646ea5b1 33 } else {
34 $storeclass = $1;
35 }
646ea5b1 36
37 # a little niceness - since most systems seem to use the password credential class,
38 # if no credential class is specified we use password.
39ce54e8 39 $config->{credential}{class} ||= '+Catalyst::Authentication::Credential::Password';
646ea5b1 40
41 my $credentialclass = $config->{'credential'}{'class'};
42
43 ## follow catalyst class naming - a + prefix means a fully qualified class, otherwise it's
39ce54e8 44 ## taken to mean C::A::Credential::(specifiedclass)
646ea5b1 45 if ($credentialclass !~ /^\+(.*)$/ ) {
39ce54e8 46 $credentialclass = "Catalyst::Authentication::Credential::${credentialclass}";
646ea5b1 47 } else {
48 $credentialclass = $1;
49 }
50
39ce54e8 51 # if we made it here - we have what we need to load the classes
52
53 ### BACKWARDS COMPATIBILITY - DEPRECATION WARNING:
54 ### we must eval the ensure_class_loaded - because we might need to try the old-style
55 ### ::Plugin:: module naming if the standard method fails.
56
57 eval {
58 Catalyst::Utils::ensure_class_loaded( $credentialclass );
59 };
60
61 if ($@) {
62 $app->log->warn( qq(Credential class "$credentialclass" not found, trying deprecated ::Plugin:: style naming. ) );
63 $credentialclass =~ s/Catalyst::Authentication/Catalyst::Plugin::Authentication/;
64 Catalyst::Utils::ensure_class_loaded( $credentialclass );
65 }
66
67 eval {
68 Catalyst::Utils::ensure_class_loaded( $storeclass );
69 };
70
71 if ($@) {
72 $app->log->warn( qq(Store class "$storeclass" not found, trying deprecated ::Plugin:: style naming. ) );
73 $storeclass =~ s/Catalyst::Authentication/Catalyst::Plugin::Authentication/;
74 Catalyst::Utils::ensure_class_loaded( $storeclass );
75 }
646ea5b1 76
77 # BACKWARDS COMPATIBILITY - if the store class does not define find_user, we define it in terms
78 # of get_user and add it to the class. this is because the auth routines use find_user,
79 # and rely on it being present. (this avoids per-call checks)
80 if (!$storeclass->can('find_user')) {
81 no strict 'refs';
82 *{"${storeclass}::find_user"} = sub {
83 my ($self, $info) = @_;
84 my @rest = @{$info->{rest}} if exists($info->{rest});
85 $self->get_user($info->{id}, @rest);
86 };
87 }
88
89 ## a little cruft to stay compatible with some poorly written stores / credentials
90 ## we'll remove this soon.
91 if ($storeclass->can('new')) {
92 $self->store($storeclass->new($config->{'store'}, $app, $self));
93 } else {
94 $app->log->error("THIS IS DEPRECATED: $storeclass has no new() method - Attempting to use uninstantiated");
95 $self->store($storeclass);
96 }
97 if ($credentialclass->can('new')) {
98 $self->credential($credentialclass->new($config->{'credential'}, $app, $self));
99 } else {
100 $app->log->error("THIS IS DEPRECATED: $credentialclass has no new() method - Attempting to use uninstantiated");
101 $self->credential($credentialclass);
102 }
103
104 return $self;
105}
106
107sub find_user {
108 my ( $self, $authinfo, $c ) = @_;
109
110 my $res = $self->store->find_user($authinfo, $c);
111
4bd1f581 112 if (!$res) {
68c40c8b 113 if ($self->config->{'auto_create_user'} && $self->store->can('auto_create_user') ) {
114 $res = $self->store->auto_create_user($authinfo, $c);
4bd1f581 115 }
68c40c8b 116 } elsif ($self->config->{'auto_update_user'} && $self->store->can('auto_update_user')) {
117 $res = $self->store->auto_update_user($authinfo, $c, $res);
4bd1f581 118 }
646ea5b1 119
120 return $res;
121}
122
123sub authenticate {
124 my ($self, $c, $authinfo) = @_;
125
126 my $user = $self->credential->authenticate($c, $self, $authinfo);
127 if (ref($user)) {
128 $c->set_authenticated($user, $self->name);
129 return $user;
130 } else {
131 return undef;
132 }
133}
134
135sub save_user_in_session {
136 my ( $self, $c, $user ) = @_;
137
138 $c->session->{__user_realm} = $self->name;
139
140 # we want to ask the store for a user prepared for the session.
141 # but older modules split this functionality between the user and the
142 # store. We try the store first. If not, we use the old method.
143 if ($self->store->can('for_session')) {
144 $c->session->{__user} = $self->store->for_session($c, $user);
145 } else {
146 $c->session->{__user} = $user->for_session;
147 }
148}
149
150sub from_session {
151 my ($self, $c, $frozen_user) = @_;
152
153 return $self->store->from_session($c, $frozen_user);
154}
155
156
157__PACKAGE__;
158
52a3537a 159__END__
1489b476 160
161=pod
162
163=head1 NAME
164
5c5af345 165Catalyst::Authentication::Realm - Base class for realm objects.
1489b476 166
167=head1 DESCRIPTION
168
5afc0dde 169=head1 CONFIGURATION
1489b476 170
171=over 4
172
5afc0dde 173=item class
174
85593aa9 175By default this class is the default realm class. You can specify a custom
176realm class with this config parameter.
177
5afc0dde 178=item auto_create_user
1489b476 179
85593aa9 180Set this to true if you wish this realm to auto-create user accounts when the
181user doesn't exist (most useful for remote authentication schemes).
182
5afc0dde 183=item auto_update_user
1489b476 184
85593aa9 185Set this to true if you wish this realm to auto-update user accounts after
186authentication (most useful for remote authentication schemes).
187
5afc0dde 188=back
189
190=head1 METHODS
1489b476 191
5afc0dde 192=head2 new( )
1489b476 193
85593aa9 194Instantiantes this realm, plus the specified store and credential classes.
195
196=head2 store( )
197
198Holds an instance of the store object for this realm.
199
200=head2 credential( )
201
202Holds an instance of the credential object for this realm.
203
5afc0dde 204=head2 find_user( )
205
85593aa9 206Delegates to the store object. Will also re-delegate auto_create_user and
207auto_update_user at this time, if necessary.
208
5afc0dde 209=head2 authenticate( )
210
85593aa9 211Delegates to the credential objects and sets the authenticated user on success.
212
5afc0dde 213=head2 save_user_in_session( )
214
85593aa9 215Delegates to the store object.
216
5afc0dde 217=head2 from_session( )
1489b476 218
85593aa9 219Delegates to the store object.
220
1489b476 221=cut
222