SYNOPSIS

 use base qw(CGI::Application);
 use CGI::Application::Plugin::Authorization;

 # Simple task based authentication
 _\|_PACKAGE_\|_->authz->config(
     DRIVER => [ 'DBI',
         TABLES      => ['account', 'task'],
         JOIN_ON     => 'account.id = task.accountid',
         USERNAME    => 'account.name',
         CONSTRAINTS => {
             'task.name' => '_\|_PARAM_1_\|_',
         }
     ],
 );
 if ($self->authz->authorize('editfoo') {
    # User is allowed access if it can 'editfoo'
 }

DESCRIPTION

This Authorization driver uses the \s-1DBI\s0 module to allow you to gather authorization information from any database for which there is a \s-1DBD\s0 module. You can either provide an active database handle, or provide the parameters necessary to connect to the database.

\s-1DBH\s0

The \s-1DBI\s0 database handle to use. Defaults to \*(C`$self->dbh()\*(C', which is provided and configured through CGI::Application::Plugin::DBH

When describing the database structure you have two options:

\s-1TABLE\s0(S), \s-1JOIN_ON\s0, \s-1USERNAME\s0 and \s-1CONSTRAINTS:\s0

Use these values to describe the table structure, and an sql statement will be automatically generated to query the database

\s-1SQL:\s0

just provide one \s-1SQL\s0 parameters that gives a complete sql statement that will be used to query the database

Following is a description of all the available parameters:

\s-1TABLE\s0(S)

Provide either a single table name, or an array of table names. You can give the table names aliases which can be referenced in later columns.

TABLE => 'group',

- or -

TABLES => ['user U', 'group G'],

\s-1JOIN_ON\s0

If you have specified multiple tables, then you need to provide an \s-1SQL\s0 expression that can be used to join those tables.

JOIN_ON => 'user.id = group.userid',

- or -

JOIN_ON => 'U.id = G.userid',

\s-1USERNAME\s0

This should be set to the column name that contains the username. This column will be compared against the currently logged in user.

USERNAME => 'name'

- or -

USERNAME => 'U.name'

\s-1CONSTRAINTS\s0

Constraints are used to restrict the database query against the options that are passed to the \*(C`authorize\*(C' method. In the common case, you will check these parameters against a group permission table, although there is no limit to the number of parameters that can be used. Each constraint can be set to a static value, or it can be set to '_\|_PARAM_n_\|_' where 'n' is the position of the parameter that is passed in to the \*(C`authorize\*(C' method.

CONSTRAINTS => { 'user.active' => 't', 'group.type' => '_\|_PARAM_1_\|_', 'group.name' => '_\|_PARAM_2_\|_', }

\s-1SQL\s0

If you need to perform a complex query that can not be defined by the above syntax, then you can provide your own \s-1SQL\s0 statment where the first placeholder is used to fill in the username, and the rest of the placeholders are filled in using the parameters passed to the authorize method.

SQL => 'SELECT count(*) FROM account LEFT JOIN ip ON (account.id = ip.accountid) LEFT JOIN task ON (account.id = task.accountid) WHERE account.name = ? AND (ip.address >> inet ? OR task.name = ?) ',

EXAMPLE

# # Example table structure (for PostgreSQL): # CREATE TABLE account ( id SERIAL NOT NULL PRIMARY KEY, name VARCHAR(50) NOT NULL ); CREATE TABLE task ( id SERIAL NOT NULL PRIMARY KEY, accountid INTEGER NOT NULL REFERENCES account(id), name VARCHAR(50) NOT NULL ); CREATE TABLE ip ( id SERIAL NOT NULL PRIMARY KEY, accountid INTEGER NOT NULL REFERENCES account(id), address INET NOT NULL ); INSERT INTO account (name) VALUES ('testuser'); INSERT INTO task (accountid, name) VALUES (1, 'editfoo'); INSERT INTO ip (accountid, address) VALUES (1, '192.168.1.0/24');

# Simple task based authentication _\|_PACKAGE_\|_->authz->config( DRIVER => [ 'DBI', # the handle comes from $self->dbh, via the "DBH" plugin. TABLES => ['account', 'task'], JOIN_ON => 'account.id = task.accountid', USERNAME => 'account.name', CONSTRAINTS => { 'task.name' => '_\|_PARAM_1_\|_', 'task.active' => 't' } ], ); if ($self->authz->authorize('editfoo') { # User is allowed access if they can 'editfoo' }

# IP address configuration _\|_PACKAGE_\|_->authz('byIP')->config( DRIVER => [ 'DBI', SQL => 'SELECT count(*) FROM account JOIN ip ON (account.id = ip.accountid) WHERE account.name = ? AND ip.address >> inet ? ', ], ); if ($self->authz('byIP')->authorize($ENV{REMOTE_ADDR}) { # User is allowed to connect from this address }

# both together in one test # IP address configuration _\|_PACKAGE_\|_->authz->config( DRIVER => [ 'DBI', SQL => 'SELECT count(*) FROM account JOIN ip ON (account.id = ip.accountid) JOIN task ON (account.id = task.accountid) WHERE account.name = ? AND task.name = ? AND ip.address >> inet ? ', ], ); if ($self->authz->authorize('editfoo', $ENV{REMOTE_ADDR}) { # User is allowed to connect from this address if they can # also 'editfoo' }

METHODS

authorize_user

This method accepts a username followed by a list of parameters and will return true if the configured query returns at least one row based on the given parameters.

RELATED TO CGI::Application::Plugin::Authorization::Driver::DBI…

CGI::Application::Plugin::Authorization::Driver, CGI::Application::Plugin::Authorization, perl\|(1)

LICENCE AND COPYRIGHT

Copyright (c) 2005, SiteSuite. All rights reserved.

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

DISCLAIMER OF WARRANTY

\s-1BECAUSE\s0 \s-1THIS\s0 \s-1SOFTWARE\s0 \s-1IS\s0 \s-1LICENSED\s0 \s-1FREE\s0 \s-1OF\s0 \s-1CHARGE\s0, \s-1THERE\s0 \s-1IS\s0 \s-1NO\s0 \s-1WARRANTY\s0 \s-1FOR\s0 \s-1THE\s0 \s-1SOFTWARE\s0, \s-1TO\s0 \s-1THE\s0 \s-1EXTENT\s0 \s-1PERMITTED\s0 \s-1BY\s0 \s-1APPLICABLE\s0 \s-1LAW\s0. \s-1EXCEPT\s0 \s-1WHEN\s0 \s-1OTHERWISE\s0 \s-1STATED\s0 \s-1IN\s0 \s-1WRITING\s0 \s-1THE\s0 \s-1COPYRIGHT\s0 \s-1HOLDERS\s0 \s-1AND/OR\s0 \s-1OTHER\s0 \s-1PARTIES\s0 \s-1PROVIDE\s0 \s-1THE\s0 \s-1SOFTWARE\s0 \*(L"\s-1AS\s0 \s-1IS\s0\*(R" \s-1WITHOUT\s0 \s-1WARRANTY\s0 \s-1OF\s0 \s-1ANY\s0 \s-1KIND\s0, \s-1EITHER\s0 \s-1EXPRESSED\s0 \s-1OR\s0 \s-1IMPLIED\s0, \s-1INCLUDING\s0, \s-1BUT\s0 \s-1NOT\s0 \s-1LIMITED\s0 \s-1TO\s0, \s-1THE\s0 \s-1IMPLIED\s0 \s-1WARRANTIES\s0 \s-1OF\s0 \s-1MERCHANTABILITY\s0 \s-1AND\s0 \s-1FITNESS\s0 \s-1FOR\s0 A \s-1PARTICULAR\s0 \s-1PURPOSE\s0. \s-1THE\s0 \s-1ENTIRE\s0 \s-1RISK\s0 \s-1AS\s0 \s-1TO\s0 \s-1THE\s0 \s-1QUALITY\s0 \s-1AND\s0 \s-1PERFORMANCE\s0 \s-1OF\s0 \s-1THE\s0 \s-1SOFTWARE\s0 \s-1IS\s0 \s-1WITH\s0 \s-1YOU\s0. \s-1SHOULD\s0 \s-1THE\s0 \s-1SOFTWARE\s0 \s-1PROVE\s0 \s-1DEFECTIVE\s0, \s-1YOU\s0 \s-1ASSUME\s0 \s-1THE\s0 \s-1COST\s0 \s-1OF\s0 \s-1ALL\s0 \s-1NECESSARY\s0 \s-1SERVICING\s0, \s-1REPAIR\s0, \s-1OR\s0 \s-1CORRECTION\s0.

\s-1IN\s0 \s-1NO\s0 \s-1EVENT\s0 \s-1UNLESS\s0 \s-1REQUIRED\s0 \s-1BY\s0 \s-1APPLICABLE\s0 \s-1LAW\s0 \s-1OR\s0 \s-1AGREED\s0 \s-1TO\s0 \s-1IN\s0 \s-1WRITING\s0 \s-1WILL\s0 \s-1ANY\s0 \s-1COPYRIGHT\s0 \s-1HOLDER\s0, \s-1OR\s0 \s-1ANY\s0 \s-1OTHER\s0 \s-1PARTY\s0 \s-1WHO\s0 \s-1MAY\s0 \s-1MODIFY\s0 \s-1AND/OR\s0 \s-1REDISTRIBUTE\s0 \s-1THE\s0 \s-1SOFTWARE\s0 \s-1AS\s0 \s-1PERMITTED\s0 \s-1BY\s0 \s-1THE\s0 \s-1ABOVE\s0 \s-1LICENCE\s0, \s-1BE\s0 \s-1LIABLE\s0 \s-1TO\s0 \s-1YOU\s0 \s-1FOR\s0 \s-1DAMAGES\s0, \s-1INCLUDING\s0 \s-1ANY\s0 \s-1GENERAL\s0, \s-1SPECIAL\s0, \s-1INCIDENTAL\s0, \s-1OR\s0 \s-1CONSEQUENTIAL\s0 \s-1DAMAGES\s0 \s-1ARISING\s0 \s-1OUT\s0 \s-1OF\s0 \s-1THE\s0 \s-1USE\s0 \s-1OR\s0 \s-1INABILITY\s0 \s-1TO\s0 \s-1USE\s0 \s-1THE\s0 \s-1SOFTWARE\s0 (\s-1INCLUDING\s0 \s-1BUT\s0 \s-1NOT\s0 \s-1LIMITED\s0 \s-1TO\s0 \s-1LOSS\s0 \s-1OF\s0 \s-1DATA\s0 \s-1OR\s0 \s-1DATA\s0 \s-1BEING\s0 \s-1RENDERED\s0 \s-1INACCURATE\s0 \s-1OR\s0 \s-1LOSSES\s0 \s-1SUSTAINED\s0 \s-1BY\s0 \s-1YOU\s0 \s-1OR\s0 \s-1THIRD\s0 \s-1PARTIES\s0 \s-1OR\s0 A \s-1FAILURE\s0 \s-1OF\s0 \s-1THE\s0 \s-1SOFTWARE\s0 \s-1TO\s0 \s-1OPERATE\s0 \s-1WITH\s0 \s-1ANY\s0 \s-1OTHER\s0 \s-1SOFTWARE\s0), \s-1EVEN\s0 \s-1IF\s0 \s-1SUCH\s0 \s-1HOLDER\s0 \s-1OR\s0 \s-1OTHER\s0 \s-1PARTY\s0 \s-1HAS\s0 \s-1BEEN\s0 \s-1ADVISED\s0 \s-1OF\s0 \s-1THE\s0 \s-1POSSIBILITY\s0 \s-1OF\s0 \s-1SUCH\s0 \s-1DAMAGES\s0.