=pod =head1 NAME Schema::RDBMS::AUS::User - Manipulate users and groups in the AUS schema. =head1 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... =head1 DESCRIPTION A C 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. =head1 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. I, I, I, and I are concrete, editable information. I and I are automatically generated based on the users, groups, and flags. Sessions are covered in L. The other data elements are described below: =head2 Users A user can log in using their username and password. =head2 Groups A "Group" is just a user with it's "C" 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. =head2 Flags Flags may be assigned to users or groups. A flag may be set C, set C, or unset (C<1>, C<0>, or C). =head2 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.) =head2 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, C, 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. =head1 DATABASE HANDLES Any database handles passed to Schema::RDBMS::AUS::User B be from the L class. DBIx::Transaction is a DBI subclass that provides enhanced control over database transactions. =head1 METHODS All interaction with the User object is done through this object-oriented interface: =head2 Constructors =over =item 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: =over =item _dbh Database handle to use. If not specified, one will be created from the envrionment. (See L.) =item _ip IP address the login attempt came from. =back 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. =item 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: =over =item name The user's login name =item id The user's id =back C<_dbh> is also a useful argument to specify here. =item create(%args) Create a new user. At a minimum, "name" must be specified. Any of the other L (except id) can be specified as well. If successful, a user object is returned, if not, create() will die with a useful error message. =back =head2 Object Methods =over =item 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.". =item reset_password($new_pass) Reset the user's password to $new_pass. =item change_password($old_pass, $new_pass, %args) Change a user's password. C<$old_pass> must match the user's old password. C<%args> are saved to the authentication log by the C method; specifying things like "_ip" (ip address of the client that asked for the password change) can be useful here. =item 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. =item used Specify that this account has been used. Updates 'time_used' to the current time and saves this update to the database immediately. =item log($event, %args) Write an entry to the user's event log. Typical values for C<$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; C<_ip=1.2.3.4&foo=bar>). =item crypt($string) Encrypt C<$string> using our current C class. Returns the encrypted string. =item flag($name) Returns the current value of the flag C<$name> on the user: =over =item C<1> The flag is set to "true" on this user. =item C<0> The flag is set to "false" on this user. =item C The flag is not set on this user. =back =item permission($name) Returns the current value of the flag C<$name> on this user, or one of it's parent groups: =over =item C<1> The flag is set to "true" on this user, or one of it's parents. =item C<0> The flag is set to "false" on this user, or one of it's parents. =item C The flag is not set on this user or any of it's parents. =back =item set_flag($name, $value, $create) Set a flag on the current user. C<$name> is the name of the flag to set. C<$value> and C<$create> are optional. If C<$value> is not defined, the flag is set to "true" (if you want to un-set a flag, see clear_flag below). If C<$create> is a true value, the flag will be created in the database if it doesn't already exist. If C<$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 C method above. I, if you specified C<$create> to set_flag, the new flag will exist in the database right away. =item clear_flag($name) Remove a flag from the current user. =item add_to_group($group) Add a this user to group C<$group>. C<$group> may be specified as the group's C, or as a user object containing the group itself. This change takes effect in the database I, it does B wait for the C method to be called! (This may change in a future release.) =item remove_from_group($group) Remove this user from group C<$group>. As with add_to_group(), the effect on the database is currently immediate. =item 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. =item dbh Returns the L database handle that Schema::RDBMS::AUS::User is using for it's transactions. =back =head1 USER ATTRIBUTES The following attributes are valid for a User's database record: =over =item id The user's unique ID#. This value should never be changed once a user is created. =item name The user's login name. =item password The user's password, encrypted with C (see below.) When setting this, it is usually best to use either the C or C method. =item password_crypt What type of encryption to apply to the password. Currently, this can be one of C, C, or C. =item 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. =item time_used Last time the user "used" their account (logged in, etc). This stamp doesn't usually get updated for groups. =back In addition, the following meta-attributes are stored on the User object: =over =item _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); =item _crypt_class The perl package that supplies our C method for encrypting passwords. This is automatically set, based on the user's C attribute. =item _dbh The database handle we are currently using. This must be a L database handle. =item _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. =item _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. =item _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. =item _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 L above. =back =head1 AUTHOR Tyler "Crackerjack" MacDonald =head1 LICENSE Copyright 2006 Tyler "Crackerjack" MacDonald This is free software; You may distribute it under the same terms as perl itself. =head1 SEE ALSO L, L. =cut