authorization section, Chapter 6). Create a new SQL script file by opening
C<myapp02.sql> in your editor and insert:
+ PRAGMA foreign_keys = ON;
--
-- Add user and role tables, along with a many-to-many join table
--
role TEXT
);
CREATE TABLE user_role (
- user_id INTEGER,
- role_id INTEGER,
+ user_id INTEGER REFERENCES user(id) ON DELETE CASCADE ON UPDATE CASCADE,
+ role_id INTEGER REFERENCES role(id) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (user_id, role_id)
);
--
option on the DBIC model helper to do most of the work for us:
$ script/myapp_create.pl model DB DBIC::Schema MyApp::Schema \
- create=static components=TimeStamp dbi:SQLite:myapp.db
+ create=static components=TimeStamp dbi:SQLite:myapp.db \
+ on_connect_do="PRAGMA foreign_keys = ON"
exists "/root/dev/MyApp/script/../lib/MyApp/Model"
exists "/root/dev/MyApp/script/../t"
Dumping manual schema for MyApp::Schema to directory /root/dev/MyApp/script/../lib ...
C<lib/MyApp/Schema/Result/User.pm>:
- #
- # Set relationships:
- #
-
- # has_many():
- # args:
- # 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_roles => 'MyApp::Schema::Result::UserRole', 'user_id');
-
+
# many_to_many():
# args:
# 1) Name of relationship, DBIC will create accessor with this name
# 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_roles', 'role');
-
-
-C<lib/MyApp/Schema/Result/Role.pm>:
-
- #
- # Set relationships:
- #
-
- # has_many():
- # args:
- # 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_roles => 'MyApp::Schema::Result::UserRole', 'role_id');
+ __PACKAGE__->many_to_many(roles => 'user_roles', 'role');
-C<lib/MyApp/Schema/Result/UserRole.pm>:
-
- #
- # Set relationships:
- #
-
- # belongs_to():
- # args:
- # 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 *this* table
- __PACKAGE__->belongs_to(user => 'MyApp::Schema::Result::User', 'user_id');
-
- # belongs_to():
- # args:
- # 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 *this* table
- __PACKAGE__->belongs_to(role => 'MyApp::Schema::Result::Role', 'role_id');
-
-The code for these three sets of updates is obviously very similar to
-the edits we made to the C<Book>, C<Author>, and C<BookAuthor>
-classes created in Chapter 3.
+The code for this update is obviously very similar to the edits we made to the
+C<Book> and C<Author> classes created in Chapter 3.
Note that we do not need to make any change to the
C<lib/MyApp/Schema.pm> schema file. It simply tells DBIC to load all
Make sure you include the additional plugins as new dependencies in
the Makefile.PL file something like this:
- requires (
- 'Catalyst::Plugin::Authentication' => '0',
- 'Catalyst::Plugin::Session' => '0',
- 'Catalyst::Plugin::Session::Store::FastMmap' => '0',
- 'Catalyst::Plugin::Session::State::Cookie' => '0',
- );
+ requires 'Catalyst::Plugin::Authentication';
+ requires 'Catalyst::Plugin::Session';
+ requires 'Catalyst::Plugin::Session::Store::FastMmap';
+ requires 'Catalyst::Plugin::Session::State::Cookie';
Note that there are several options for
L<Session::Store|Catalyst::Plugin::Session::Store>
-(L<Session::Store::FastMmap|Catalyst::Plugin::Session::Store::FastMmap>
-is generally a good choice if you are on Unix; try
+
+(L<Session::Store::Memcached|Catalyst::Plugin::Session::Store::Memcached> or
+L<Session::Store::FastMmap|Catalyst::Plugin::Session::Store::FastMmap> is
+generally a good choice if you are on Unix; try
L<Session::Store::File|Catalyst::Plugin::Session::Store::File> if you
are on Win32) -- consult
L<Session::Store|Catalyst::Plugin::Session::Store> and its subclasses
my ($self, $c) = @_;
# Get the username and password from form
- my $username = $c->request->params->{username} || "";
- my $password = $c->request->params->{password} || "";
+ my $username = $c->request->params->{username};
+ my $password = $c->request->params->{password};
# If the username and password values were found in form
- if (defined($username) && defined($password)) {
+ if ($username && $password) {
# Attempt to log the user in
if ($c->authenticate({ username => $username,
password => $password } )) {
# Set an error message
$c->stash->{error_msg} = "Bad username or password.";
}
+ } else {
+ # Set an error message
+ $c->stash->{error_msg} = "Empty username or password.";
}
# If either of above don't work out, send to the login page
argument:
$ script/myapp_create.pl model DB DBIC::Schema MyApp::Schema \
- create=static components=TimeStamp,EncodedColumn dbi:SQLite:myapp.db
+ create=static components=TimeStamp,EncodedColumn dbi:SQLite:myapp.db \
+ on_connect_do="PRAGMA foreign_keys = ON"
If you then open one of the Result Classes, you will see that it
includes EncodedColumn in the C<load_components> line. Take a look at
C<lib/MyApp/Schema/Result/User.pm> since that's the main class where we
want to use hashed and salted passwords:
- __PACKAGE__->load_components("InflateColumn::DateTime", "TimeStamp", "EncodedColumn", "Core");
+ __PACKAGE__->load_components("InflateColumn::DateTime", "TimeStamp", "EncodedColumn");
=head2 Modify the "password" Column to Use EncodedColumn
$ DBIC_TRACE=1 perl -Ilib set_hashed_passwords.pl
-We had to use the C<-Ilib> arguement to tell perl to look under the
+We had to use the C<-Ilib> argument to tell perl to look under the
C<lib> directory for our C<MyApp::Schema> model.
The DBIC_TRACE output should show that the update worked:
__PACKAGE__->config(
name => 'MyApp',
- session => {flash_to_stash => 1},
+ session => { flash_to_stash => 1 },
);
B<or> add the following to C<myapp.conf>: