NAME

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

SYNOPSIS

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;
}

DESCRIPTION

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

AUTHENTICATION CONFIGURATION

Authentication is configured by setting an authentication->{dbic} hash reference in your application's config method. The following configuration options are supported.

user_class

The name of the class that represents a user object.

user_field

The name of the column holding the user identifier (defaults to "user")

password_field

The name of the column holding the user's password (defaults to "password")

password_type

The type of password your user object stores. One of: clear, crypted, or hashed. Defaults to clear.

password_hash_type

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.

password_pre_salt

Use this option if your passwords are hashed with a prefix salt value.

password_post_salt

Use this option if your passwords are hashed with a postfix salt value.

AUTHORIZATION CONFIGURATION

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".

role_class

The name of the class that contains the list of roles.

role_field

The name of the field in "role_class" that contains the role name.

role_rel

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.

user_role_class

Class::DBI models only. The name of the class that contains the many-to-many linking data between users and roles.

user_role_user_field

The name of the field in "user_role_class" that contains the user ID. This is required for both DBIx::Class and Class::DBI.

user_role_role_field

Class::DBI models only. The name of the field in "user_role_class" that contains the role ID.

METHODS

user_object

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

INTERNAL METHODS

setup

ROLES

This section will attempt to provide detailed instructions for configuring role-based authorization in your application.

Database Schema

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)
);

DBIx::Class

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:

1. Create Model classes and define relationships

# 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;

2. Specify authorization configuration settings

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

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:

1. Create Model classes

# 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;

2. Specify authorization configuration settings

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',
};

SEE ALSO

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

AUTHOR

Andy Grundman, <andy@hybridized.org>

COPYRIGHT

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