NAME

Schema::RDBMS::AUS::User - Manipulate users and groups in the AUS schema.

SYNOPSIS

use Schema::RDBMS::AUS::User;
use DBIx::Transaction;

my $dbh = DBIx::Transaction->connect('DBI:Pg:');

if(my $user = Schema::RDBMS::AUS::User->login('user', 'pass', _dbh => $dbh)) {
    print "user id is $user->{id}\n";
    $user->clear_flag("never_logged_in");
}

$user->change_password($old, $new);

my $group = Schema::RDBMS::AUS::User->create(name => "Resellers", is_group => 1);
$user->add_to_group($group);
$user->save;

$group->set_flag("back_room", 1, 1);
$group->save;

$user->refresh;

if($user->permission('back_room')) {
    print "User $user->{name} is allowed in the back room.\n";
}

etc...

DESCRIPTION

A Schema::RDBMS::AUS::User object represents a User or a Group in the Authentication, Users and Sessions (AUS) schema. Most of the rest of the schema is managed via a user.

DATA ELEMENTS

The information stored about a user or group has been organized with maximum flexibility in mind. Each of the underlying SQL tables is as represents as small a piece of information as possible so that applications can easily cross-reference whatever they need with foreign keys.

Users, Groups, Flags, and Sessions are concrete, editable information.

Permissions and Membership are automatically generated based on the users, groups, and flags.

Sessions are covered in CGI::Session::AUS. The other data elements are described below:

Users

A user can log in using their username and password.

Groups

A "Group" is just a user with it's "is_group" flag set. It behaves slightly differently than a user:

A group can not log in. A group can have users (or groups) assigned to it. There is no limit to how "deep" group members can get (a group can be a member of a group that is a member 2 other groups, one of which is a member of...), but "circular" group memberships (group 1 is a member of group 2, who is a member of group 3, who is a member of group 1) are not allowed.

Flags

Flags may be assigned to users or groups. A flag may be set true, set false, or unset (1, 0, or undef).

Membership

A user or group may be a member of one or more groups. In turn, those groups can be members of other groups, etc. A membership tree is available on a User or Group, showing each of it's ancestors and how many hops away each one is. (A user or group is also considered to be a member of itself, zero hops away.)

Permissions

Flags set on groups are visible as "permissions" on their (user or group) children. If more than one parent to a user or group has the same flag set, the "nearest" parent's value for that flag is used. If two parents are just as close, but have conflicting values for a flag, false, the least permissive setting, is used.

This allows you to set default permissions as flags on a group, and then make small adjustments on a user-by-user basis.

DATABASE HANDLES

Any database handles passed to Schema::RDBMS::AUS::User must be from the DBIx::Transaction class. DBIx::Transaction is a DBI subclass that provides enhanced control over database transactions.

METHODS

All interaction with the User object is done through this object-oriented interface:

Constructors

login($user, $password, %args)

Attempt to log a user in. If successful, a user object will be returned. If unsuccessful, login() will die with an error message explaining why the login failed.

The following attributes are useful for the login() method:

_dbh

Database handle to use. If not specified, one will be created from the envrionment. (See Schema::RDBMS::AUS.)

_ip

IP address the login attempt came from.

Other attributes may be specified, but should start with an underscore (_) to distinguish them from user attributes. Any attributes specified will be written to the user's log entry for this login attempt.

load(%args)

Load a user. Returns the user object if successful, die()s with a useful error message if not. At least one of the following arguments must be provided:

name

The user's login name

id

The user's id

_dbh is also a useful argument to specify here.

create(%args)

Create a new user. At a minimum, "name" must be specified. Any of the other user attributes (except id) can be specified as well. If successful, a user object is returned, if not, create() will die with a useful error message.

Object Methods

password

Validate a password (using the _validate_password attribute described below). If the password is valid, it is returned. If not, Schema::RDBMS::AUS::User will die with the error message "Invalid password.".

reset_password($new_pass)

Reset the user's password to $new_pass.

change_password($old_pass, $new_pass, %args)

Change a user's password. $old_pass must match the user's old password. %args are saved to the authentication log by the log method; specifying things like "_ip" (ip address of the client that asked for the password change) can be useful here.

save

Save the user's data and flags. If successful, the user object is returned. If not, save will die() with a useful error message.

used

Specify that this account has been used. Updates 'time_used' to the current time and saves this update to the database immediately.

log($event, %args)

Write an entry to the user's event log. Typical values for $event are 'reset_password', 'login', 'login_fail', etc. %args is a hash of extra information that is saved to the log as a query string (eg; _ip=1.2.3.4&foo=bar).

crypt($string)

Encrypt $string using our current password_crypt class. Returns the encrypted string.

flag($name)

Returns the current value of the flag $name on the user:

1

The flag is set to "true" on this user.

0

The flag is set to "false" on this user.

undef

The flag is not set on this user.

permission($name)

Returns the current value of the flag $name on this user, or one of it's parent groups:

1

The flag is set to "true" on this user, or one of it's parents.

0

The flag is set to "false" on this user, or one of it's parents.

undef

The flag is not set on this user or any of it's parents.

set_flag($name, $value, $create)

Set a flag on the current user. $name is the name of the flag to set. $value and $create are optional. If $value is not defined, the flag is set to "true" (if you want to un-set a flag, see clear_flag below).

If $create is a true value, the flag will be created in the database if it doesn't already exist. If $create is not specified and the flag does not exist, set_flag will die() with a useful error message.

The user's flag settings are not saved until you call the save method above. However, if you specified $create to set_flag, the new flag will exist in the database right away.

clear_flag($name)

Remove a flag from the current user.

add_to_group($group)

Add a this user to group $group. $group may be specified as the group's name, or as a user object containing the group itself. This change takes effect in the database immediately, it does not wait for the save method to be called! (This may change in a future release.)

remove_from_group($group)

Remove this user from group $group. As with add_to_group(), the effect on the database is currently immediate.

refresh

Reload the user's data, flags, and membership from the database. If you're keeping a user object around for awhile, you should call this method every so often to ensure that the user's settings on the object still reflect what's in the database.

dbh

Returns the DBIx::Transaction database handle that Schema::RDBMS::AUS::User is using for it's transactions.

USER ATTRIBUTES

The following attributes are valid for a User's database record:

id

The user's unique ID#. This value should never be changed once a user is created.

name

The user's login name.

password

The user's password, encrypted with password_crypt (see below.) When setting this, it is usually best to use either the change_password or reset_password method.

password_crypt

What type of encryption to apply to the password. Currently, this can be one of None, MD5, or SHA1.

is_group

If true, this is a Group. If false, this is a regular user. This value should only be set when the user/group is first created and should never be changed after that.

time_used

Last time the user "used" their account (logged in, etc). This stamp doesn't usually get updated for groups.

In addition, the following meta-attributes are stored on the User object:

_validate_password

A subroutine reference, which, when passed a password, is expected to return a true value if the password is valid, or a false value if not. The default handler will return true for any string that is more than zero bytes. Here is an example validator that will only allow passwords that contain a mix of numbers and letters, at least 6 characters long:

my $validator = sub { $_[0] =~ m{(?=.*\d)(?=.*[A-Za-z])^.+{6,}$}; };
my $user = Schema::RDBMS::AUS::User->load(name => "Bob", _validate_password => $validator);
_crypt_class

The perl package that supplies our crypt() method for encrypting passwords. This is automatically set, based on the user's password_crypt attribute.

_dbh

The database handle we are currently using. This must be a DBIx::Transaction database handle.

_dbh_driver

The name of the database driver our handle uses (eg; "mysql", "Pg", etc). This is automatically set when the object is initialized, and can be used to compensate for quirks in certain SQL implementations.

_flags

A hash of all flags set on the current user. The keys are the flag names, and the values are "1" if the flag is set to true, "0" for false.

_membership

A hash describing all of the groups that the current user or group is a part of. The keys are user ID's, the values represent how many hops along the organizational chart each group is from the user. The current user's ID will always have a value of "0" in this hash, it's immediate parent groups will have a value of "1", their parents will have a value of "2", etc.

_permissions

A hash describing all permissions the user has. This is the culmination of all of the flags on the user and it's ancestors, as described in "Permissions" above.

AUTHOR

Tyler "Crackerjack" MacDonald <japh@crackerjack.net>

LICENSE

Copyright 2006 Tyler "Crackerjack" MacDonald <japh@crackerjack.net>

This is free software; You may distribute it under the same terms as perl itself.

SEE ALSO

Schema::RDBMS::AUS, CGI::Session::AUS.