$ sqlite3 myapp.db < myapp02.sql
+
=head2 Add User and Role Information to DBIC Schema
Although we could manually edit the DBIC schema information to include
# 1) Name of relationship, DBIC will create accessor with this name
# 2) Name of the model class referenced by this relationship
# 3) Column name in *foreign* table (aka, foreign key in peer table)
- __PACKAGE__->has_many(map_user_role => 'MyApp::Schema::Result::UserRole', 'user_id');
+ __PACKAGE__->has_many(map_user_roles => 'MyApp::Schema::Result::UserRole', 'user_id');
# many_to_many():
# args:
# 2) Name of has_many() relationship this many_to_many() is shortcut for
# 3) Name of belongs_to() relationship in model class of has_many() above
# You must already have the has_many() defined to use a many_to_many().
- __PACKAGE__->many_to_many(roles => 'map_user_role', 'role');
+ __PACKAGE__->many_to_many(roles => 'map_user_roles', 'role');
C<lib/MyApp/Schema/Result/Role.pm>:
# 1) Name of relationship, DBIC will create accessor with this name
# 2) Name of the model class referenced by this relationship
# 3) Column name in *foreign* table (aka, foreign key in peer table)
- __PACKAGE__->has_many(map_user_role => 'MyApp::Schema::Result::UserRole', 'role_id');
+ __PACKAGE__->has_many(map_user_roles => 'MyApp::Schema::Result::UserRole', 'role_id');
C<lib/MyApp/Schema/Result/UserRole.pm>:
C<StackTrace> is new):
# Load plugins
- use Catalyst qw/-Debug
+ use Catalyst qw/
+ -Debug
ConfigLoader
Static::Simple
/;
B<Note:> As discussed in MoreCatalystBasics, different versions of
-C<Catalyst::Devel> have used a variety of methods to load the plugins.
-You can put the plugins in the C<use Catalyst> statement if you prefer.
+C<Catalyst::Devel> have used a variety of methods to load the plugins,
+but we are going to use the current Catalyst 5.8X practice of putting
+them on the C<use Catalyst> line.
The C<Authentication> plugin supports Authentication while the
C<Session> plugins are required to maintain state across multiple HTTP
<Plugin::Authentication>
use_session 1
<default>
- password_type self_check
+ password_type clear
user_model DB::User
class SimpleDB
</default>
my $password = $c->request->params->{password} || "";
# If the username and password values were found in form
- if ($username && $password) {
+ if (defined($username) && defined($password)) {
# Attempt to log the user in
if ($c->authenticate({ username => $username,
password => $password } )) {
We need something that provides enforcement for the authentication
mechanism -- a I<global> mechanism that prevents users who have not
passed authentication from reaching any pages except the login page.
-This is generally done via an C<auto> action/method (prior to Catalyst
-v5.66, this sort of thing would go in C<MyApp.pm>, but starting in
-v5.66, the preferred location is C<lib/MyApp/Controller/Root.pm>).
+This is generally done via an C<auto> action/method in
+C<lib/MyApp/Controller/Root.pm>.
Edit the existing C<lib/MyApp/Controller/Root.pm> class file and insert
the following method:
easy with the Catalyst plugin Catalyst::Plugin:RequireSSL.
-=head2 Install DBIx::Class::EncodedColumn
-
-L<DBIx::Class::EncodedColumn|DBIx::Class::EncodedColumn> provides features
-that can greatly simplify the maintenance of passwords. It's currently
-not available as a .deb package in the normal Debian repositories, so let's
-install it directly from CPAN:
-
- $ sudo cpan DBIx::Class::EncodedColumn
-
-
=head2 Re-Run the DBIC::Schema Model Helper to Include DBIx::Class::EncodedColumn
Next, we can re-run the model helper to have it include
Then run the following command:
- $ perl -Ilib set_hashed_passwords.pl
+ $ DBIC_TRACE=1 perl -Ilib set_hashed_passwords.pl
We had to use the C<-Ilib> arguement to tell perl to look under the
C<lib> directory for our C<MyApp::Schema> model.
-Then dump the users table to verify that it worked:
+The DBIC_TRACE output should show that the update worked:
+
+ $ DBIC_TRACE=1 perl -Ilib set_hashed_passwords.pl
+ SELECT me.id, me.username, me.password, me.email_address,
+ me.first_name, me.last_name, me.active FROM user me:
+ UPDATE user SET password = ? WHERE ( id = ? ):
+ 'oXiyAcGOjowz7ISUhpIm1IrS8AxSZ9r4jNjpX9VnVeQmN6GRtRKTz', '1'
+ UPDATE user SET password = ? WHERE ( id = ? ):
+ 'PmyEPrkB8EGwvaF/DvJm7LIfxoZARjv8ygFIR7pc1gEA1OfwHGNzs', '2'
+ UPDATE user SET password = ? WHERE ( id = ? ):
+ 'h7CS1Fm9UCs4hjcbu2im0HumaHCJUq4Uriac+SQgdUMUfFSoOrz3c', '3'
+
+But we can further confirm our actions by dumping the users table:
$ sqlite3 myapp.db "select * from user"
1|test01|38d3974fa9e9263099f7bc2574284b2f55473a9bM=fwpX2NR8|t01@na.com|Joe|Blow|1
3|test03|af929a151340c6aed4d54d7e2651795d1ad2e2f7UW8dHoGv9z|t03@na.com|No|Go|0
As you can see, the passwords are much harder to steal from the
-database. Also note that this demonstrates how to use a DBIx::Class
+database (not only are the hashes stored, but every hash is different
+even though the passwords are the same because of the added "salt"
+value). Also note that this demonstrates how to use a DBIx::Class
model outside of your web application -- a very useful feature in many
situations.
=head2 Enable Hashed and Salted Passwords
-Edit C<lib/MyApp.pm> and update it to match the following text (the only change
-is to the C<password_type> field):
+Edit C<lib/MyApp.pm> and update it to match the following text (the
+only change is to the C<password_type> field):
# Configure SimpleDB Authentication
__PACKAGE__->config->{'Plugin::Authentication'} = {
...
Although the sample above only shows the C<content> div, leave the
-rest of the file intact -- the only change we made to the C<wrapper.tt2>
-was to add "C<|| c.request.params.status_msg>" to the
-C<E<lt>span class="message"E<gt>> line.
+rest of the file intact -- the only change we made to replace
+"|| c.request.params.status_msg" with "c.flash.status_msg" in the
+C<< <span class="message"> >> line.
=head2 Try Out Flash
__PACKAGE__->config(
name => 'MyApp',
- session => {flash_to_stash => 1}
+ session => {flash_to_stash => 1},
);
B<or> add the following to C<myapp.conf>:
Please report any errors, issues or suggestions to the author. The
most recent version of the Catalyst Tutorial can be found at
-L<http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Manual/5.70/trunk/lib/Catalyst/Manual/Tutorial/>.
+L<http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Manual/5.80/trunk/lib/Catalyst/Manual/Tutorial/>.
Copyright 2006-2008, Kennedy Clark, under Creative Commons License
(L<http://creativecommons.org/licenses/by-sa/3.0/us/>).