Commit | Line | Data |
646ea5b1 |
1 | package Catalyst::Plugin::Authentication::Realm; |
2 | |
3 | use strict; |
4 | use warnings; |
1489b476 |
5 | |
646ea5b1 |
6 | use base qw/Class::Accessor::Fast/; |
7 | |
8 | BEGIN { |
9 | __PACKAGE__->mk_accessors(qw/store credential name config/); |
10 | }; |
11 | |
12 | sub 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; |
21 | if (!exists($config->{'store'}{'class'})) { |
22 | Carp::croak "Couldn't setup the authentication realm named '$realmname', no class defined"; |
23 | } |
24 | |
25 | $config->{store}{class} ||= '+Catalyst::Plugin::Authentication::Store::Null'; |
26 | |
27 | # use the |
28 | my $storeclass = $config->{'store'}{'class'}; |
29 | |
30 | ## follow catalyst class naming - a + prefix means a fully qualified class, otherwise it's |
31 | ## taken to mean C::P::A::Store::(specifiedclass) |
32 | if ($storeclass !~ /^\+(.*)$/ ) { |
33 | $storeclass = "Catalyst::Plugin::Authentication::Store::${storeclass}"; |
34 | } else { |
35 | $storeclass = $1; |
36 | } |
37 | |
38 | |
39 | # a little niceness - since most systems seem to use the password credential class, |
40 | # if no credential class is specified we use password. |
41 | $config->{credential}{class} ||= '+Catalyst::Plugin::Authentication::Credential::Password'; |
42 | |
43 | my $credentialclass = $config->{'credential'}{'class'}; |
44 | |
45 | ## follow catalyst class naming - a + prefix means a fully qualified class, otherwise it's |
46 | ## taken to mean C::P::A::Credential::(specifiedclass) |
47 | if ($credentialclass !~ /^\+(.*)$/ ) { |
48 | $credentialclass = "Catalyst::Plugin::Authentication::Credential::${credentialclass}"; |
49 | } else { |
50 | $credentialclass = $1; |
51 | } |
52 | |
53 | # if we made it here - we have what we need to load the classes; |
54 | Catalyst::Utils::ensure_class_loaded( $credentialclass ); |
55 | Catalyst::Utils::ensure_class_loaded( $storeclass ); |
56 | |
57 | # BACKWARDS COMPATIBILITY - if the store class does not define find_user, we define it in terms |
58 | # of get_user and add it to the class. this is because the auth routines use find_user, |
59 | # and rely on it being present. (this avoids per-call checks) |
60 | if (!$storeclass->can('find_user')) { |
61 | no strict 'refs'; |
62 | *{"${storeclass}::find_user"} = sub { |
63 | my ($self, $info) = @_; |
64 | my @rest = @{$info->{rest}} if exists($info->{rest}); |
65 | $self->get_user($info->{id}, @rest); |
66 | }; |
67 | } |
68 | |
69 | ## a little cruft to stay compatible with some poorly written stores / credentials |
70 | ## we'll remove this soon. |
71 | if ($storeclass->can('new')) { |
72 | $self->store($storeclass->new($config->{'store'}, $app, $self)); |
73 | } else { |
74 | $app->log->error("THIS IS DEPRECATED: $storeclass has no new() method - Attempting to use uninstantiated"); |
75 | $self->store($storeclass); |
76 | } |
77 | if ($credentialclass->can('new')) { |
78 | $self->credential($credentialclass->new($config->{'credential'}, $app, $self)); |
79 | } else { |
80 | $app->log->error("THIS IS DEPRECATED: $credentialclass has no new() method - Attempting to use uninstantiated"); |
81 | $self->credential($credentialclass); |
82 | } |
83 | |
84 | return $self; |
85 | } |
86 | |
87 | sub find_user { |
88 | my ( $self, $authinfo, $c ) = @_; |
89 | |
90 | my $res = $self->store->find_user($authinfo, $c); |
91 | |
4bd1f581 |
92 | if (!$res) { |
93 | if ($self->config->{'auto_create'} && $self->store->can('auto_create') ) { |
94 | $res = $self->store->auto_create($authinfo, $c); |
95 | } |
96 | } elsif ($self->config->{'auto_update'} && $self->store->can('auto_update')) { |
52a3537a |
97 | $res = $self->store->auto_update($authinfo, $c, $res); |
4bd1f581 |
98 | } |
646ea5b1 |
99 | |
100 | return $res; |
101 | } |
102 | |
103 | sub authenticate { |
104 | my ($self, $c, $authinfo) = @_; |
105 | |
106 | my $user = $self->credential->authenticate($c, $self, $authinfo); |
107 | if (ref($user)) { |
108 | $c->set_authenticated($user, $self->name); |
109 | return $user; |
110 | } else { |
111 | return undef; |
112 | } |
113 | } |
114 | |
115 | sub save_user_in_session { |
116 | my ( $self, $c, $user ) = @_; |
117 | |
118 | $c->session->{__user_realm} = $self->name; |
119 | |
120 | # we want to ask the store for a user prepared for the session. |
121 | # but older modules split this functionality between the user and the |
122 | # store. We try the store first. If not, we use the old method. |
123 | if ($self->store->can('for_session')) { |
124 | $c->session->{__user} = $self->store->for_session($c, $user); |
125 | } else { |
126 | $c->session->{__user} = $user->for_session; |
127 | } |
128 | } |
129 | |
130 | sub from_session { |
131 | my ($self, $c, $frozen_user) = @_; |
132 | |
133 | return $self->store->from_session($c, $frozen_user); |
134 | } |
135 | |
136 | |
137 | __PACKAGE__; |
138 | |
52a3537a |
139 | __END__ |
1489b476 |
140 | |
141 | =pod |
142 | |
143 | =head1 NAME |
144 | |
145 | Catalyst::Plugin::Authentication::Realm - Base class for realm objects. |
146 | |
147 | =head1 DESCRIPTION |
148 | |
149 | =head1 METHODS |
150 | |
151 | =over 4 |
152 | |
153 | =item new |
154 | |
155 | =item find_user |
156 | |
157 | =item authenticate |
158 | |
159 | =item save_user_in_session |
160 | |
161 | =item from_session |
162 | |
163 | =back |
164 | |
165 | =cut |
166 | |
167 | |