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