View source
<?php
define('CAS_ROLES_DRUPAL_ROLES_ONLY', 0);
define('CAS_ROLES_CREATE_NEW_ROLES', 1);
define('CAS_ROLES_MATCH_REGEX', 2);
function cas_roles_menu() {
$items = array();
$items['admin/config/people/cas/roles'] = array(
'title' => 'Roles',
'description' => 'Settings for CAS roles.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'cas_roles_admin_settings',
),
'access arguments' => array(
'administer cas',
),
'file' => 'cas_roles.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => -7,
);
return $items;
}
function cas_roles_cas_user_presave(&$edit, $account) {
$sync_every_login = variable_get('cas_roles_sync_every_login');
$behavior = variable_get('cas_roles_behavior');
$relations = variable_get('cas_roles_relations', array(
'2' => NULL,
));
if ($account->login && !$sync_every_login) {
return;
}
$role_candidates = cas_roles_candidates($edit['cas_user']);
if ($behavior == CAS_ROLES_CREATE_NEW_ROLES) {
$new_roles = array_diff($role_candidates, user_roles());
foreach ($new_roles as $new) {
$role = (object) array(
'name' => $new,
);
user_role_save($role);
}
}
if ($behavior == CAS_ROLES_MATCH_REGEX) {
$custom_roles = cas_roles_cutsom_user_roles();
$new_user_roles = $edit['roles'];
foreach ($custom_roles as $rid => $role) {
if (array_key_exists($role, $relations) && $relations[$role]) {
$matches = preg_grep($relations[$role], $role_candidates);
if (!empty($matches)) {
$new_user_roles[$rid] = $role;
}
else {
unset($new_user_roles[$rid]);
}
}
}
}
else {
$new_user_roles = array_intersect(cas_roles_cutsom_user_roles(), $role_candidates);
}
$new_user_roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user';
$edit['roles'] = $new_user_roles;
}
function cas_roles_cas_user_alter(&$cas_user) {
$behavior = variable_get('cas_roles_behavior');
$require_a_role_create = variable_get('cas_roles_require_a_role_create', FALSE);
$require_a_role_login = variable_get('cas_roles_require_a_role_login', FALSE);
$relations = variable_get('cas_roles_relations', array(
'2' => NULL,
));
if ($behavior == CAS_ROLES_MATCH_REGEX) {
$role_candidates = cas_roles_candidates($cas_user);
$one_matches = FALSE;
foreach (user_roles(TRUE) as $role) {
if (array_key_exists($role, $relations) && $relations[$role]) {
$matches = preg_grep($relations[$role], $role_candidates);
if (!empty($matches)) {
$one_matches = TRUE;
break;
}
}
}
if ($require_a_role_create && !$one_matches) {
$cas_user['register'] = FALSE;
}
if ($require_a_role_login && !$one_matches) {
$cas_user['login'] = FALSE;
}
}
}
function cas_roles_candidates($cas_user) {
$role_candidates =& drupal_static(__FUNCTION__);
if (!isset($role_candidates)) {
$roles = variable_get('cas_roles_roles');
if (!isset($cas_user['attributes'])) {
return array();
}
$cas_attributes = $cas_user['attributes'];
$tokens = token_scan($roles);
if (!is_array($tokens) || !array_key_exists('cas', $tokens)) {
return array();
}
$tokens = token_find_with_prefix($tokens['cas'], 'attribute');
$arr = array();
foreach ($tokens as $name => $original) {
$chain = explode(':', strtolower($name));
$branch = array_change_key_case($cas_attributes);
$found = TRUE;
foreach ($chain as $link) {
if (isset($branch[$link])) {
if (is_array($branch[$link])) {
$branch[$link] = array_change_key_case($branch[$link]);
}
$branch = $branch[$link];
}
else {
$found = FALSE;
}
}
if ($found) {
$arr[$original] = $branch;
}
}
$role_candidates = array(
$roles,
);
foreach ($arr as $token => $elements) {
$new_candidates = array();
foreach ($role_candidates as $pattern) {
$new_pattern = array();
_cas_roles_recursive_str_replace($new_pattern, $token, $elements, $pattern);
$new_candidates = array_merge($new_candidates, $new_pattern);
}
$role_candidates = $new_candidates;
}
if (module_exists('cas_attributes')) {
$data = array(
'cas' => $cas_user['name'],
);
}
else {
$data = array();
}
foreach ($role_candidates as $key => $pattern) {
$pattern = trim(token_replace($pattern, $data, array(
'clear' => TRUE,
)));
$role_candidates[$key] = html_entity_decode($pattern);
}
$role_candidates = array_unique($role_candidates);
}
return $role_candidates;
}
function cas_roles_user_role_presave($role) {
$relations = variable_get('cas_roles_relations', array());
$all_roles = user_roles(TRUE);
if (isset($role->rid)) {
if (isset($all_roles[$role->rid]) && isset($relations[$all_roles[$role->rid]])) {
if ($role->name != $all_roles[$role->rid]) {
$relations[$role->name] = $relations[$all_roles[$role->rid]];
unset($relations[$all_roles[$role->rid]]);
}
}
}
variable_set('cas_roles_relations', $relations);
}
function _cas_roles_preg_validate($element, &$form_state, $form) {
if (!empty($element['#value']) && @preg_match($element['#value'], "CAS") === FALSE) {
form_error($element, t('This field is not a valid preg pattern.'));
}
}
function cas_roles_cutsom_user_roles($permission = NULL) {
return array_diff_key(user_roles(TRUE, $permission), array(
DRUPAL_AUTHENTICATED_RID => 'authenticated user',
));
}
function _cas_roles_recursive_str_replace(&$pattern_array, $token, $elements, $pattern) {
if (!is_array($elements)) {
$pattern_array[] = str_replace($token, $elements, $pattern);
}
else {
foreach ($elements as $element) {
_cas_roles_recursive_str_replace($pattern_array, $token, $element, $pattern);
}
}
}