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