Commit | Line | Data |
5c5af345 |
1 | package Catalyst::Authentication::Store::Minimal; |
2 | |
3 | use strict; |
4 | use warnings; |
5 | |
6 | use Catalyst::Authentication::User::Hash; |
7 | use Scalar::Util qw( blessed ); |
8 | use base qw/Class::Accessor::Fast/; |
9 | |
10 | BEGIN { |
11 | __PACKAGE__->mk_accessors(qw/userhash/); |
12 | } |
13 | |
14 | sub new { |
15 | my ( $class, $config, $app, $realm) = @_; |
16 | |
17 | bless { userhash => $config->{'users'} }, $class; |
18 | } |
19 | |
20 | sub from_session { |
21 | my ( $self, $c, $id ) = @_; |
22 | |
23 | return $id if ref $id; |
24 | |
25 | $self->find_user( { id => $id } ); |
26 | } |
27 | |
28 | ## this is not necessarily a good example of what find_user can do, since all we do is |
29 | ## look up with the id anyway. find_user can be used to locate a user based on other |
30 | ## combinations of data. See C::P::Authentication::Store::DBIx::Class for a better example |
31 | sub find_user { |
32 | my ( $self, $userinfo, $c ) = @_; |
33 | |
34 | my $id = $userinfo->{'id'}; |
35 | |
36 | $id ||= $userinfo->{'username'}; |
37 | |
38 | return unless exists $self->userhash->{$id}; |
39 | |
40 | my $user = $self->userhash->{$id}; |
41 | |
5c5af345 |
42 | if ( ref($user) eq "HASH") { |
43 | $user->{id} ||= $id; |
44 | return bless $user, "Catalyst::Authentication::User::Hash"; |
45 | } elsif ( ref($user) && blessed($user) && $user->isa('Catalyst::Authentication::User::Hash')) { |
46 | return $user; |
47 | } else { |
48 | Catalyst::Exception->throw( "The user '$id' must be a hash reference or an " . |
49 | "object of class Catalyst::Authentication::User::Hash"); |
50 | } |
51 | return $user; |
52 | } |
53 | |
54 | sub user_supports { |
55 | my $self = shift; |
56 | |
57 | # choose a random user |
58 | scalar keys %{ $self->userhash }; |
59 | ( undef, my $user ) = each %{ $self->userhash }; |
60 | |
61 | $user->supports(@_); |
62 | } |
63 | |
64 | ## Backwards compatibility |
65 | # |
66 | # This is a backwards compatible routine. get_user is specifically for loading a user by it's unique id |
67 | # find_user is capable of doing the same by simply passing { id => $id } |
68 | # no new code should be written using get_user as it is deprecated. |
69 | sub get_user { |
70 | my ( $self, $id ) = @_; |
71 | $self->find_user({id => $id}); |
72 | } |
73 | |
74 | ## backwards compatibility |
75 | sub setup { |
76 | my $c = shift; |
77 | |
692dcea4 |
78 | ### If a user does 'use Catalyst qw/Authentication::Store::Minimal/' |
79 | ### he will be proxied on to this setup routine (and only then -- |
80 | ### non plugins should NOT have their setup routine invoked!) |
81 | ### Beware what we pass to the 'new' routine; it wants |
82 | ### a config has with a top level key 'users'. New style |
83 | ### configs do not have this, and split by realms. If we |
84 | ### blindly pass this to new, we will 1) overwrite what we |
85 | ### already passed and 2) make ->userhash undefined, which |
86 | ### leads to: |
87 | ### Can't use an undefined value as a HASH reference at |
88 | ### lib/Catalyst/Authentication/Store/Minimal.pm line 38. |
89 | ### |
90 | ### So only do this compatibility call if: |
91 | ### 1) we have a {users} config directive |
92 | ### |
93 | ### Ideally we could also check for: |
94 | ### 2) we don't already have a ->userhash |
95 | ### however, that's an attribute of an object we can't |
96 | ### access =/ --kane |
97 | |
98 | my $cfg = $c->config->{'Plugin::Authentication'}->{users} |
99 | ? $c->config->{'Plugin::Authentication'} |
100 | : undef; |
5c5af345 |
101 | |
692dcea4 |
102 | $c->default_auth_store( __PACKAGE__->new( $cfg, $c ) ) if $cfg; |
103 | |
5c5af345 |
104 | $c->NEXT::setup(@_); |
105 | } |
106 | |
107 | __PACKAGE__; |
108 | |
109 | __END__ |
110 | |
111 | =pod |
112 | |
113 | =head1 NAME |
114 | |
115 | Catalyst::Authentication::Store::Minimal - Minimal authentication store |
116 | |
117 | =head1 SYNOPSIS |
118 | |
119 | # you probably just want Store::Minimal under most cases, |
120 | # but if you insist you can instantiate your own store: |
121 | |
122 | use Catalyst::Authentication::Store::Minimal; |
123 | |
124 | use Catalyst qw/ |
125 | Authentication |
126 | /; |
127 | |
7c4d44af |
128 | __PACKAGE__->config->{'Plugin::Authentication'} = |
5c5af345 |
129 | { |
130 | default_realm => 'members', |
131 | realms => { |
132 | members => { |
133 | credential => { |
134 | class => 'Password', |
135 | password_field => 'password', |
136 | password_type => 'clear' |
137 | }, |
138 | store => { |
139 | class => 'Minimal', |
140 | users = { |
141 | bob => { |
142 | password => "s00p3r", |
143 | editor => 'yes', |
144 | roles => [qw/edit delete/], |
145 | }, |
146 | william => { |
147 | password => "s3cr3t", |
148 | roles => [qw/comment/], |
149 | } |
150 | } |
151 | } |
152 | } |
153 | } |
154 | }; |
155 | |
156 | |
157 | =head1 DESCRIPTION |
158 | |
159 | This authentication store lets you create a very quick and dirty user |
160 | database in your application's config hash. |
161 | |
162 | You will need to include the Authentication plugin, and at least one Credential |
163 | plugin to use this Store. Credential::Password is reccommended. |
164 | |
165 | It's purpose is mainly for testing, and it should probably be replaced by a |
166 | more "serious" store for production. |
167 | |
168 | The hash in the config, as well as the user objects/hashes are freely mutable |
169 | at runtime. |
170 | |
171 | =head1 CONFIGURATION |
172 | |
173 | =over 4 |
174 | |
175 | =item class |
176 | |
177 | The classname used for the store. This is part of |
178 | L<Catalyst::Plugin::Authentication> and is the method by which |
179 | Catalyst::Authentication::Store::Minimal is loaded as the |
180 | user store. For this module to be used, this must be set to |
181 | 'Minimal'. |
182 | |
183 | =item users |
184 | |
185 | This is a simple hash of users, the keys are the usenames, and the values are |
186 | hashrefs containing a password key/value pair, and optionally, a roles/list |
187 | of role-names pair. If using roles, you will also need to add the |
188 | Authorization::Roles plugin. |
189 | |
190 | See the SYNOPSIS for an example. |
191 | |
192 | =back |
193 | |
194 | =head1 METHODS |
195 | |
196 | There are no publicly exported routines in the Minimal store (or indeed in |
197 | most authentication stores) However, below is a description of the routines |
198 | required by L<Catalyst::Plugin::Authentication> for all authentication stores. |
199 | |
200 | =head2 new( $config, $app, $realm ) |
201 | |
202 | Constructs a new store object, which uses the user element of the supplied config |
203 | hash ref as it's backing structure. |
204 | |
205 | =head2 find_user( $authinfo, $c ) |
206 | |
207 | Keys the hash by the 'id' or 'username' element in the authinfo hash and returns the user. |
208 | |
209 | ... documentation fairy stopped here. ... |
210 | |
211 | If the return value is unblessed it will be blessed as |
212 | L<Catalyst::Authentication::User::Hash>. |
213 | |
214 | =head2 from_session( $id ) |
215 | |
216 | Delegates to C<get_user>. |
217 | |
218 | =head2 user_supports( ) |
219 | |
220 | Chooses a random user from the hash and delegates to it. |
221 | |
222 | =head2 get_user( ) |
223 | |
224 | =head2 setup( ) |
225 | |
226 | =cut |
227 | |
228 | |