
Catalyst::Plugin::Authentication::Store::DBIC - Authentication and authorization against a DBIx::Class or Class::DBI model.

use Catalyst qw/
Authentication
Authentication::Store::DBIC
Authentication::Credential::Password
Authorization::Roles # if using roles
/;
# Authentication
__PACKAGE__->config->{authentication}->{dbic} = {
user_class => 'MyApp::Model::User',
user_field => 'username',
password_field => 'password',
password_type => 'hashed',
password_hash_type => 'SHA-1',
};
# Authorization using a many-to-many role relationship
# For more detailed instructions on setting up role-based auth, please
# see the section below titled L<"Roles">.
__PACKAGE__->config->{authorization}->{dbic} = {
role_class => 'MyApp::Model::Role',
role_field => 'role',
role_rel => 'map_user_role', # DBIx::Class only
user_role_user_field => 'user',
user_role_class => 'MyApp::Model::UserRole', # Class::DBI only
user_role_role_field => 'role', # Class::DBI only
};
# log a user in
sub login : Global {
my ( $self, $c ) = @_;
$c->login( $c->req->param("email"), $c->req->param("password"), );
}
# verify a role
if ( $c->check_user_roles( 'admin' ) ) {
$model->delete_everything;
}

This plugin uses a DBIx::Class (or Class::DBI) object to authenticate a user.

Authentication is configured by setting an authentication->{dbic} hash reference in your application's config method. The following configuration options are supported.
The name of the class that represents a user object.
The name of the column holding the user identifier (defaults to "user")
The name of the column holding the user's password (defaults to "password")
The type of password your user object stores. One of: clear, crypted, or hashed. Defaults to clear.
If using a password_type of hashed, this option specifies the hashing method being used. Any hashing method supported by the Digest module may be used.
Use this option if your passwords are hashed with a prefix salt value.
Use this option if your passwords are hashed with a postfix salt value.

Role-based authorization is configured by setting an authorization->{dbic} hash reference in your application's config method. The following options are supported. For more detailed instructions on setting up roles, please see the section below titled "Roles".
The name of the class that contains the list of roles.
The name of the field in "role_class" that contains the role name.
DBIx::Class models only. This field specifies the name of the relationship in "role_class" that refers to the mapping table between users and roles. Using this relationship, DBIx::Class models can retrieve the list of roles for a user in a single SQL statement using a join.
Class::DBI models only. The name of the class that contains the many-to-many linking data between users and roles.
The name of the field in "user_role_class" that contains the user ID. This is required for both DBIx::Class and Class::DBI.
Class::DBI models only. The name of the field in "user_role_class" that contains the role ID.

Returns the DBIx::Class or Class::DBI object representing the user in the database.


This section will attempt to provide detailed instructions for configuring role-based authorization in your application.
The basic database structure for roles consists of the following 3 tables. This syntax is for SQLite, but can be easily adapted to other databases.
CREATE TABLE user (
id INTEGER PRIMARY KEY,
username TEXT,
password TEXT
);
CREATE TABLE role (
id INTEGER PRIMARY KEY,
role TEXT
);
# DBIx::Class can handle multiple primary keys
CREATE TABLE user_role (
user INTEGER,
role INTEGER,
PRIMARY KEY (user, role)
);
# Class::DBI may need the following user_role table
CREATE TABLE user_role (
id INTEGER PRIMARY KEY,
user INTEGER,
role INTEGER,
UNIQUE (user, role)
);
For best performance when using roles, DBIx::Class models are recommended. By using DBIx::Class you will benefit from optimized SQL using joins that can retrieve roles for a user with a single SQL statement.
The steps for setting up roles with DBIx::Class are:
# Example User Model
package MyApp::Model::User;
use strict;
use warnings;
use base 'MyApp::Model::DBIC';
__PACKAGE__->table( 'user' );
__PACKAGE__->add_columns( qw/id username password/ );
__PACKAGE__->set_primary_key( 'id' );
__PACKAGE__->has_many(
map_user_role => 'MyApp::Model::UserRole' => 'user' );
1;
# Example Role Model
package MyApp::Model::Role;
use strict;
use warnings;
use base 'MyApp::Model::DBIC';
__PACKAGE__->table( 'role' );
__PACKAGE__->add_columns( qw/id role/ );
__PACKAGE__->set_primary_key( 'id' );
__PACKAGE__->has_many(
map_user_role => 'MyApp::Model::UserRole' => 'role' );
1;
# Example UserRole Model
package MyApp::Model::UserRole;
use strict;
use warnings;
use base 'MyApp::Model::DBIC';
__PACKAGE__->table( 'user_role' );
__PACKAGE__->add_columns( qw/user role/ );
__PACKAGE__->set_primary_key( qw/user role/ );
1;
For the above DBIx::Class model classes, the configuration would look like this:
__PACKAGE__->config->{authorization}->{dbic} = {
role_class => 'MyApp::Model::Role',
role_field => 'role',
role_rel => 'map_user_role',
user_role_user_field => 'user',
};
Class::DBI models are also supported but require slightly more configuration. Performance will also suffer as more SQL statements must be run to retrieve all roles for a user.
The steps for setting up roles with Class::DBI are:
# Example User Model
package MyApp::Model::User;
use strict;
use warnings;
use base 'MyApp::Model::CDBI';
__PACKAGE__->table ( 'user' );
__PACKAGE__->columns( Primary => qw/id/ );
__PACKAGE__->columns( Essential => qw/username password/ );
1;
# Example Role Model
package MyApp::Model::Role;
use strict;
use warnings;
use base 'MyApp::Model::CDBI';
__PACKAGE__->table ( 'role' );
__PACKAGE__->columns( Primary => qw/id/ );
__PACKAGE__->columns( Essential => qw/role/ );
1;
# Example UserRole Model
package MyApp::Model::UserRole;
use strict;
use warnings;
use base 'MyApp::Model::CDBI';
__PACKAGE__->table ( 'user_role' );
__PACKAGE__->columns( Primary => qw/id/ );
__PACKAGE__->columns( Essential => qw/user role/ );
1;
For the above Class::DBI model classes, the configuration would look like this:
__PACKAGE__->config->{authorization}->{dbic} = {
role_class => 'MyApp::Model::Role',
role_field => 'role',
user_role_class => 'MyApp::Model::UserRole',
user_role_user_field => 'user',
user_role_role_field => 'role',
};

Catalyst::Plugin::Authentication, Catalyst::Plugin::Authorization::Roles

Andy Grundman, <andy@hybridized.org>

This program is free software, you can redistribute it and/or modify it under the same terms as Perl itself.