Woot. Forgot the svk add. I rule
[catagits/Catalyst-Authentication-Store-DBIx-Class.git] / lib / Catalyst / Authentication / Realm / SimpleDB.pm
1 package Catalyst::Authentication::Realm::SimpleDB;
2
3 use strict;
4 use warnings;
5 use Catalyst::Exception;
6 use base qw/Catalyst::Authentication::Realm/;
7
8 sub new {
9     my ($class, $realmname, $config, $app) = @_;
10     
11     my $newconfig = {
12         credential => {
13             class => 'Password',
14             password_type => 'clear'
15         },
16         store => {
17             class => 'DBIx::Class',
18             role_relation => 'roles',
19             role_field => 'role',
20             use_userdata_from_session => '1'
21         }
22     };
23     
24     if (!defined($config->{'user_model'})) {
25             Catalyst::Exception->throw("Unable to initialize authentication, no user_model specified in SimpleDB config.");
26         }
27
28     
29     ## load any overrides for the credential 
30     foreach my $key (qw/ password_type password_field password_hash_type/) {
31         if (exists($config->{$key})) {
32             $newconfig->{credential}{$key} = $config->{$key};
33         }
34     } 
35     
36     ## load any overrides for the store
37     foreach my $key (qw/ user_model role_relation role_field role_column use_userdata_from_session/) {
38         if (exists($config->{$key})) {
39             $newconfig->{store}{$key} = $config->{$key};
40         }
41     }
42     if (exists($newconfig->{'store'}{'role_column'})) {
43         delete $newconfig->{'store'}{'role_relation'};
44         delete $newconfig->{'store'}{'role_field'};
45     }
46     
47     return $class->SUPER::new($realmname, $newconfig, $app);
48 }
49
50 1;
51 __END__
52
53 =head1 NAME
54
55 Catalyst::Authentication::Realm::SimpleDB - A simplified Catalyst authentication configurator.
56
57 =head1 SYNOPSIS
58
59     use Catalyst qw/
60         Authentication
61     /;
62
63     __PACKAGE__->config->{'Plugin::Authentication'} = 
64         {  
65             default => {
66                 class => 'SimpleDB',
67                 user_class => 'MyApp::User'
68             }
69         }
70
71     # later on ...
72     $c->authenticate({ username => 'myusername', 
73                        password => 'mypassword' });
74
75     my $age = $c->user->get('age');
76
77     $c->logout;            
78
79
80 =head1 DESCRIPTION
81
82 The Catalyst::Authentication::Realm::SimpleDB provides a simple way to configure Catalyst Authentication 
83 when using the most common configuration of a password protected user retrieved from an SQL database.
84
85 =head1 CONFIGURATION
86
87 The SimpleDB Realm class configures the Catalyst authentication system based on the following:
88
89 =over
90
91 =item *
92 Your user data is stored in a table that is accessible via $c->model('User');
93
94 =item *
95 Your passwords are stored in the 'password' field in your users table and are not encrypted.
96
97 =item *
98 Your roles for users are stored in a separate table and are directly
99 accessible via a DBIx::Class relationship called 'roles' and the text of the
100 role is stored in a field called 'role' within the role table.
101
102 =item *
103 Your user information is stored in the session once the user is authenticated.
104
105 =back
106
107 For the above usage, only one configuration option is necessary, 'user_class'.
108 B<user_class> should contain the class name of your user class. See the
109 L</PREPARATION> section for info on how to set up your database for use with
110 this module.
111
112 If your system differs from the above, some minor configuration may be
113 necessary. The options available are detailed below. These options match the
114 configuration options used by the underlying credential and store modules.
115 More information on these options can be found in
116 L<Catalyst::Authentication::Credential::Password> and
117 L<Catalyst::Authentication::Store::DBIx::Class>.
118
119 =over 
120
121 =item user_class
122
123 Contains the class name (as passed to $c->model() ) of the DBIx::Class schema
124 to use as the source for user information.  This config item is B<REQUIRED>.
125
126 =item password_field 
127
128 If your password field is not 'password' set this option to the name of your password field.  Note that if you change this
129 to, say 'users_password' you will need to use that in the authenticate call:  
130
131     $c->authenticate({ username => 'bob', users_password => 'foo' });
132
133 =item password_type
134
135 If the password is not stored in plaintext you will need to define what format the password is in.  The common options are
136 B<crypted> and B<hashed>.  Crypted uses the standard unix crypt to encrypt the password.  Hashed uses the L<Digest> modules to
137 perform password hashing.  
138
139 =item password_hash_type
140
141 If you use a hashed password type - this defines the type of hashing. See L<Catalyst::Authentication::Credential::Password> 
142 for more details on this setting.  
143
144 =item role_column
145
146 If your users roles are stored directly in your user table, set this to the column name that contains your roles.  For 
147 example, if your user table contains a field called 'permissions', the value of role_column would be 'permissions'. 
148 B<NOTE>: If multiple values are stored in the role column, they should be space or pipe delimited. 
149
150 =item role_relation and role_field
151
152 These define an alternate role relationship name and the column that holds the role's name in plain text.  See 
153 L<Catalyst::Authentication::Store::DBIx::Class/CONFIGURATION> for more details on these settings.
154
155 =item use_userdata_from_session
156
157 This is a simple 1 / 0 setting which determines how a user's data is saved / restored from the session.  If 
158 it is set to 1, the user's complete information (at the time of authentication) is cached between requests.
159 If it is set to 0, the users information is loaded from the database on each request.
160
161 =back
162
163
164 =head1 PREPARATION
165
166 This module makes several assumptions about the structure of your database.
167 Below is an example of a table structure which will function with this module
168 in it's default configuration. You can use this table structure as-is or add
169 additional fields as necessary. B<NOTE> that this is the default SimpleDB
170 configuration only. Your table structure can differ significantly from this
171 when using the L<DBIx::Class
172 Store|Catalyst::Authentication::Store::DBIx::Class/> directly.
173
174
175     --
176     -- note that you can add any additional columns you require to the users table.
177     --
178     CREATE TABLE users (
179             id            INTEGER PRIMARY KEY,
180             username      TEXT,
181             password      TEXT,
182     );
183
184     CREATE TABLE roles (
185             id   INTEGER PRIMARY KEY,
186             role TEXT
187     );
188     CREATE TABLE user_roles (
189             user_id INTEGER,
190             role_id INTEGER,
191             PRIMARY KEY (user_id, role_id)
192     );
193
194 Also, after you have loaded this table structure into your DBIx::Class schema,
195 please be sure that you have a many_to_many DBIx::Class relationship defined
196 for the users to roles relation. Your schema files should contain something
197 along these lines:
198
199 C<lib/MyApp/Schema/Users.pm>:
200
201     __PACKAGE__->has_many(map_user_role => 'MyApp::Schema::UserRoles', 'user_id');
202     __PACKAGE__->many_to_many(roles => 'map_user_role', 'role');
203
204 C<lib/MyApp/Schema/UserRoles.pm>:
205
206     __PACKAGE__->belongs_to(role => 'MyApp::Schema::Roles', 'role_id');
207
208 =head1 MIGRATION 
209
210 If and when your application becomes complex enough that you need more features
211 than SimpleDB gives you access to, you can migrate to a standard Catalyst
212 Authentication configuration fairly easily.  SimpleDB simply creates a standard
213 Auth config based on the inputs you give it.  The config SimpleDB creates by default
214 looks like this:  
215
216     MyApp->config('Plugin::Authentication') = { 
217         default => {
218             credential => {
219                 class => 'Password',
220                 password_type => 'clear'
221             },
222             store => {
223                 class => 'DBIx::Class',
224                 role_relation => 'roles',
225                 role_field => 'role',
226                 use_userdata_from_session => '1',
227                 user_model => $user_model_from_simpledb_config
228                 }
229             }
230     }; 
231
232
233 =head1 SEE ALSO
234
235 This module relies on a number of other modules to do it's job.  For more information
236 you can refer to the following:
237
238 =over 
239
240 =item * 
241 L<Catalyst::Manual::Tutorial::Authentication>
242
243 =item *
244 L<Catalyst::Plugin::Authentication>
245
246 =item *
247 L<Catalyst::Authentication::Credential::Password>
248
249 =item *
250 L<Catalyst::Authentication::Store::DBIx::Class>
251
252 =item *
253 L<Catalyst::Plugin::Authorization::Roles>
254
255 =back
256
257 =head1 WARNINGS
258
259 ...
260
261 =head1 NOTES
262
263 ...
264
265 =head1 BUGS
266
267 What?
268
269 =cut
270