authenticate_hook['config'], which might be an array, or whatever is needed. * * In order to be called: * - This file should be included * - $c->authenticate_hook['call'] should be set to the name of the plugin * - $c->authenticate_hook['config'] should be set up with any configuration data for the plugin * * @package davical * @subpackage authentication * @author Andrew McMillan * @copyright Catalyst IT Ltd, Morphoss Ltd * @license http://gnu.org/copyleft/gpl.html GNU GPL v2 or later */ require_once("AWLUtilities.php"); require_once("DataUpdate.php"); /** * Create a default home calendar for the user. * @param string $username The username of the user we are creating relationships for. */ function CreateHomeCalendar( $username ) { global $session, $c; if ( ! isset($c->home_calendar_name) || strlen($c->home_calendar_name) == 0 ) return true; $usr = getUserByName( $username ); $parent_path = "/".$username."/"; $calendar_path = $parent_path . $c->home_calendar_name."/"; $dav_etag = md5($usr->user_no . $calendar_path); $sql = 'INSERT INTO collection (user_no, parent_container, dav_name, dav_etag, dav_displayname, is_calendar, '; $sql .= 'created, modified, resourcetypes) VALUES( ?, ?, ?, ?, ?, true, current_timestamp, current_timestamp, ? );'; $qry = new PgQuery( $sql, $usr->user_no, $parent_path, $calendar_path, $dav_etag, $usr->fullname, ''); if ( $qry->Exec() ) { $c->messages[] = i18n("Home calendar added."); dbg_error_log("User",":Write: Created user's home calendar at '%s'", $calendar_path ); } else { $c->messages[] = i18n("There was an error writing to the database."); return false; } return true; } /** * Create default relationships * @param string $username The username of the user we are creating relationships for. */ function CreateDefaultRelationships( $username ) { global $session, $c; if ( ! isset($c->default_relationships) || !is_array($c->default_relationships) || count($c->default_relationships) == 0 ) return false; $usr = getUserByName( $username ); $sql = ""; foreach( $c->default_relationships AS $to_user => $permission ) { $sql .= "INSERT INTO relationship (from_user, to_user, rt_id) "; $sql .= "VALUES( $usr->user_no, $to_user, (select rt_id from relationship_type where confers = '$permission' order by rt_id limit 1) );"; } $qry = new PgQuery( $sql ); if ( $qry->Exec() ) { $c->messages[] = i18n("Default relationships added."); dbg_error_log("User",":Write: Added default relationships" ); } else { $c->messages[] = i18n("There was an error writing to the database."); return false; } return true; } /** * Update the local cache of the remote user details * @param object $usr The user details we read from the remote. */ function UpdateUserFromExternal( &$usr ) { /** * When we're doing the create we will usually need to generate a user number */ if ( !isset($usr->user_no) || intval($usr->user_no) == 0 ) { $qry = new PgQuery( "SELECT nextval('usr_user_no_seq');" ); $qry->Exec('Login',__LINE,__FILE__); $sequence_value = $qry->Fetch(true); // Fetch as an array $usr->user_no = $sequence_value[0]; } $qry = new PgQuery("SELECT * FROM usr WHERE user_no = $usr->user_no;" ); if ( $qry->Exec('Login',__LINE,__FILE__) && $qry->rows == 1 ) { $type = "UPDATE"; if ( $old = $qry->Fetch() ) { $changes = false; foreach( $usr AS $k => $v ) { if ( $old->{$k} != $v ) { $changes = true; dbg_error_log("Login","User '%s' field '%s' changed from '%s' to '%s'", $usr->username, $k, $old->{$k}, $v ); break; } } if ( !$changes ) { dbg_error_log("Login","No changes to user record for '%s' - leaving as-is.", $usr->username ); if ( isset($usr->active) && $usr->active == 'f' ) return false; return; // Normal case, if there are no changes } else { dbg_error_log("Login","Changes to user record for '%s' - updating.", $usr->username ); } } } else $type = "INSERT"; $qry = new PgQuery( sql_from_object( $usr, $type, 'usr', "WHERE user_no=$usr->user_no" ) ); $qry->Exec('Login',__LINE,__FILE__); /** * We disallow login by inactive users _after_ we have updated the local copy */ if ( isset($usr->active) && $usr->active == 'f' ) return false; if ( $type == 'INSERT' ) { CreateHomeCalendar($usr->username); CreateDefaultRelationships($usr->username); } } /** * Authenticate against a different PostgreSQL database which contains a usr table in * the AWL format. * * Use this as in the following example config snippet: * * require_once('auth-functions.php'); * $c->authenticate_hook = array( * 'call' => 'AuthExternalAwl', * 'config' => array( * // A PgSQL database connection string for the database containing user records * 'connection' => 'dbname=wrms host=otherhost port=5433 user=general', * // Which columns should be fetched from the database * 'columns' => "user_no, active, email_ok, joined, last_update AS updated, last_used, username, password, fullname, email", * // a WHERE clause to limit the records returned. * 'where' => "active AND org_code=7" * ) * ); * */ function AuthExternalAWL( $username, $password ) { global $c; $persistent = isset($c->authenticate_hook['config']['use_persistent']) && $c->authenticate_hook['config']['use_persistent']; $authconn = ( $persistent ? pg_pConnect($c->authenticate_hook['config']['connection']) : pg_Connect($c->authenticate_hook['config']['connection'])); if ( ! $authconn ) { echo <<Database Connection Failure

Database Error

Could not connect to PostgreSQL database

EOERRMSG; exit(1); } if ( isset($c->authenticate_hook['config']['columns']) ) $cols = $c->authenticate_hook['config']['columns']; else $cols = "*"; if ( isset($c->authenticate_hook['config']['where']) ) $andwhere = " AND ".$c->authenticate_hook['config']['where']; else $andwhere = ""; $qry = new PgQuery("SELECT $cols FROM usr WHERE lower(username) = ? $andwhere", strtolower($username) ); $qry->SetConnection($authconn); if ( $qry->Exec('Login',__LINE,__FILE__) && $qry->rows == 1 ) { $usr = $qry->Fetch(); if ( session_validate_password( $password, $usr->password ) ) { UpdateUserFromExternal($usr); return $usr; } } return false; }