diff --git cas.api.php cas.api.php index e7568cb..bb7033a 100644 --- cas.api.php +++ cas.api.php @@ -62,16 +62,30 @@ function hook_cas_user_alter(&$cas_user) { } /** - * Modify a Drupal user account before a CAS user is registered. + * A CAS user has authenticated and the login is about to be finalized. * - * This hook is called after the user array has been assembled, but before - * user_save() is called. + * This allows modules to react to a CAS user logging in and alter their + * account properties. For example, modules may want to synchronize Drupal + * user roles or profile information with LDAP properties. + * + * The 'cas_first_login' flag in $edit will be set to TRUE if the CAS user was + * just registered and this is their first login. This is useful if you want + * to only synchronize information when an account is created instead of on + * every login. + * + * The 'cas_user' key in $edit contains all information returned from + * hook_cas_user_alter(). + * + * The CAS module promises to call user_save() and user_login_finalize() with + * this $edit data. * * @param $edit * An array of values corresponding to the Drupal user to be created. + * @param $account + * A Druapl user object. */ -function hook_cas_user_register_alter(&$edit) { - $cas_name = $edit['name']; +function hook_cas_user_presave(&$edit, $account) { + $cas_name = $edit['cas_user']['name']; // Look up the user's real name using LDAP. $ldap_connection = ldap_connect('ldap.example.com', 389); @@ -85,32 +99,6 @@ function hook_cas_user_register_alter(&$edit) { } /** - * A CAS user just logged in. - * - * This is called immediately after hook_user_login(). Use `global $user' to - * access the logged in Drupal user object. - * - * @param $cas_user - * An associative array, with the following keys: - * - 'user': The CAS machine-readable user name. - * - Any other keys added by hook_cas_user_alter(). - */ -function hook_cas_user_login($cas_user) { - global $user; - - // Update the Drupal account data with values extracted from the CAS user. - // The following example is silly, as $cas_user['name'] won't change between - // logins, but information queried from an external LDAP server might. - $edit['mail'] = $cas_user['name'] . '@example.com'; - $account = user_save($user, $edit); - - // Update $user if the save was successful. - if ($account) { - $user = $account; - } -} - -/** * Modify phpCAS authentication properties. * * This is called after phpCAS has been configured with the basic server diff --git cas.module cas.module index 32adbb2..5b05224 100644 --- cas.module +++ cas.module @@ -244,8 +244,6 @@ function cas_login_check() { // Set a session variable to denote this the initial login $_SESSION['cas_first_login'] = TRUE; - drupal_alter('cas_user_register', $edit); - // now save the user and become the new user. $acct = user_save(drupal_anonymous_user(), $edit); if ($cas_authmap == CAS_AUTHMAP_EXTERNAL) { @@ -257,6 +255,10 @@ function cas_login_check() { ->execute(); } watchdog("user", 'new user: %n (CAS)', array('%n' => $acct->name), WATCHDOG_NOTICE, l(t("edit user"), "admin/user/edit/$acct->uid")); + + // Reset $edit for use later, recording that the user was just + // registered. + $edit = array('cas_first_login' => TRUE); } } @@ -267,25 +269,16 @@ function cas_login_check() { if (!empty($_SESSION['cas_ticket']) && variable_get('cas_signout', FALSE)) { _cas_single_sign_out_save_token($acct); } - - // update the roles and reset the password - $roles = $acct->roles; - foreach ($cas_roles as $role) { - $roles[$role] = $role; - } - /* Removing password cause it cases problems with phpcas. */ - $user_up = array( - "roles" => $roles, - ); - $acct = user_save($acct, $user_up); - - $edit = array(); + + // Populate $edit with some basic properties. + $edit['cas_user'] = $cas_user; + $edit['roles'] = $acct->roles + $cas_roles; if (module_exists('persistent_login') && $_SESSION['cas_remember']) { $edit['persistent_login'] = 1; } - $user = $acct; + cas_user_module_invoke('presave', $edit, $acct); + $user = user_save($acct, $edit); user_login_finalize($edit); - module_invoke_all('cas_user_login', $cas_user); drupal_set_message(t(variable_get('cas_login_message', 'Logged in via CAS as %cas_username.'), array('%cas_username' => $user->name))); if (!empty($edit['persistent_login']) && $edit['persistent_login']== 1) { drupal_set_message(t('You will remain logged in on this computer even after you close your browser.')); @@ -897,3 +890,15 @@ function _cas_external_user_is_blocked($name) { return $deny; } +/** + * Invokes hook_cas_user() in every module. + * + * We cannot use module_invoke() because the arguments need to be passed by + * reference. + */ +function cas_user_module_invoke($type, &$edit, $account) { + foreach (module_implements('cas_user_' . $type) as $module) { + $function = $module . '_cas_user_' . $type; + $function($edit, $account); + } +}