array(
'title' => t('Web service authentication settings'),
'description' => t('Settings for the WS-auth service.'),
'page callback' => 'drupal_get_form',
'page arguments' => array('wsauth_config_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_NORMAL_ITEM,
'file' => 'wsauth.admin.inc',
),
'wsauth/authenticate' => array(
'page callback' => 'wsauth_authenticate_page',
'access callback' => 'wsauth_authenticate_access',
'delivery callback' => 'wsauth_authenticate_delivery',
'type' => MENU_CALLBACK,
),
'wsauth/resources' => array(
'page callback' => 'wsauth_resources_page',
'delivery callback' => 'wsauth_authenticate_delivery',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
),
'wsauth/permissions' => array(
'title' => t('Resource read permissions'),
'page callback' => 'drupal_get_form',
'page arguments' => array('wsauth_permissions_form'),
'access callback' => 'wsauth_permissions_access',
'type' => MENU_NORMAL_ITEM,
'menu_name' => 'user-menu',
'weight' => -50,
'file' => 'wsauth.permissions.inc',
),
);
}
function wsauth_authenticate_page() {
$username = $_POST['username'];
$password = $_POST['password'];
$authenticated = false;
$permitted_resources = array();
require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');
if ((!($user = user_load_by_name($username))) /* User doesn't exist */ ||
(!$user->status) /* Blocked */ ||
(!user_check_password($password, $user)) /* Wrong password */ ) {
watchdog('wsauth', 'Login attempt failed for %user.', array('%user' => $username));
$authenticated = false;
} else {
watchdog('wsauth', 'Session opened for %name.', array('%name' => $user->name));
$authenticated = true;
$resources = _wsauth_get_all_resources_with_permission($user);
foreach ($resources as $resource) {
if (($machine_names = field_get_items('node', $resource, 'field_machine_name')) &&
($terms = field_get_items('node', $resource, 'field_resource_type'))) {
$term = taxonomy_term_load($terms[0]['tid']);
foreach ($machine_names as $machine_name) {
$permitted_resources[$term->name][$machine_name['safe_value']] = _wsauth_get_user_resource_permissions($user, $resource);
if(isset($_REQUEST['include_edit_users']) && $_REQUEST['include_edit_users'] == 'true'){
$permitted_resources[$term->name][$machine_name['safe_value']]['users'] = wsauth_get_edit_usernames($resource);
}
}
}
}
}
if(isset($_REQUEST['include_open_resources']) && $_REQUEST['include_open_resources'] == 'true'){
$permitted_resources = wsauth_extend_open_resources($permitted_resources);
}
return array(
'authenticated' => $authenticated,
'username' => $username,
'permitted_resources' => (object) $permitted_resources,
);
}
function wsauth_get_edit_usernames($node){
$uids = [];
if(array_key_exists('und', $node->field_permitted_users_edit) && is_array($node->field_permitted_users_edit['und'])){
foreach($node->field_permitted_users_edit['und'] as $user_reference){
$uids[] = $user_reference['target_id'];
}
}
$usernames = [];
$users = user_load_multiple($uids);
foreach($users as $edit_user){
$usernames[] = $edit_user->name;
}
return $usernames;
}
function wsauth_resources_page(){
$user = drupal_anonymous_user();
$permitted_resources = array();
foreach (_wsauth_get_all_resources_with_permission($user) as $resource) {
if (($machine_names = field_get_items('node', $resource, 'field_machine_name')) &&
($terms = field_get_items('node', $resource, 'field_resource_type'))) {
$term = taxonomy_term_load($terms[0]['tid']);
foreach ($machine_names as $machine_name) {
$permitted_resources[$term->name][$machine_name['safe_value']] = _wsauth_get_user_resource_permissions($user, $resource);
}
}
}
if(isset($_REQUEST['include_open_resources']) && $_REQUEST['include_open_resources'] == 'true'){
$permitted_resources = wsauth_extend_open_resources($permitted_resources);
}
return array(
'authenticated' => FALSE,
'permitted_resources' => (object) $permitted_resources,
);
}
function wsauth_authenticate_access() {
$wsauth_secret_key = variable_get('wsauth_secret_key', '');
return (isset($_POST['username']) &&
isset($_POST['password']) &&
isset($_POST['checksum']) &&
md5($_POST['username'] . $_POST['password'] . $wsauth_secret_key) == $_POST['checksum']);
}
function wsauth_authenticate_delivery($page_callback_result) {
if (is_array($page_callback_result)) {
$content_type = _wsauth_decode_accept_header($_SERVER['HTTP_ACCEPT']);
drupal_add_http_header('Content-type', $content_type);
switch($content_type) {
case 'text/xml':
case 'application/xml':
// FIXA: Flytta till funktion?
$xml = new SimpleXMLElement('');
$xml->addChild('authenticated', $page_callback_result['authenticated'] ? 'true' : 'false');
if (isset($page_callback_result['permitted_resources'])) {
$permitted_resources = $xml->addChild('permitted_resources');
foreach ($page_callback_result['permitted_resources'] as $resource_type => $resources) {
$type = $permitted_resources->addChild($resource_type);
foreach ($resources as $key=>$resource) {
$resourceElement = $type->addChild('resource', $key);
$resourceElement->addAttribute('read', $resource['read'] ? 'true': 'false');
$resourceElement->addAttribute('write', $resource['write'] ? 'true': 'false');
$resourceElement->addAttribute('admin', $resource['admin'] ? 'true': 'false');
}
}
}
echo $xml->asXML();
break;
default:
echo json_encode($page_callback_result);
break;
}
} else {
return drupal_deliver_html_page($page_callback_result);
}
}
function wsauth_extend_open_resources($permitted_resources){
require_once 'sb.resources.inc';
// Why "Corpus"? Other code uses "corpora".
if(!array_key_exists('Corpus', $permitted_resources)){
$permitted_resources['Corpus'] = array();
}
if(!array_key_exists('lexica', $permitted_resources)){
$permitted_resources['lexica'] = array();
}
$lexicon_list = get_sb_resource_list('lexicon');
// Get all protected lexica
// FIXA: Move to function.
$query = new EntityFieldQuery();
$entities = $query->entityCondition('entity_type', 'node')
->propertyCondition('type', 'wsauth_resource')
->propertyCondition('status', NODE_PUBLISHED)
->fieldCondition('field_resource_type', 'tid', 2) // Lexicon
->fieldCondition('field_public_view', 'value', FALSE)
->execute();
$nodes = entity_load('node', array_keys($entities['node']));
$protected_lexicon_list = array_map(
function ($node) {
$machine_name = field_get_items('node', $node, 'field_machine_name')[0]['safe_value'];
return $machine_name;
},
$nodes
);
$unprotected_lexicon_list = array_diff($lexicon_list, $protected_lexicon_list);
foreach ($unprotected_lexicon_list as $lexicon) {
if (!array_key_exists($lexicon, $permitted_resources['lexica'])) {
$permitted_resources['lexica'][$lexicon] = array(
'read' => TRUE,
'write' => FALSE,
'admin' => FALSE,
);
}
}
// FIXA: Rewrite this like lexica above.
$corpus_list = get_sb_resource_list('corpus');
// CJS: This takes no time at all...
foreach($corpus_list as $corpus){
if(array_key_exists($corpus, $permitted_resources['Corpus']) == false){
$permitted_resources['Corpus'][$corpus] = array('read'=>true, 'write'=>false, 'admin'=>false);
}
}
return $permitted_resources;
}
function wsauth_permissions_access() {
return (bool) _wsauth_get_owned_resources($GLOBALS['user']);
}
function _wsauth_get_resources_for_user($user, $field) {
$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node')
->propertyCondition('type', 'wsauth_resource')
->propertyCondition('status', NODE_PUBLISHED);
if (($field == 'field_permitted_users' && user_access('access all wsauth resources', $user)) ||
($field == 'field_owners' && user_access('administer all wsauth resources', $user))) {
// Do not add a fieldCondition when user has special access
} else {
$q->fieldCondition($field, 'target_id', array($user->uid));
}
$res = $q->execute();
return isset($res['node']) ? entity_load('node', array_keys($res['node'])) : array();
}
function _wsauth_get_resource_by_machine_name($machine_name){
$query = new EntityFieldQuery();
$entities = $query->entityCondition('entity_type', 'node')
->propertyCondition('type', 'wsauth_resource')
->propertyCondition('type', 'wsauth_resource')
->propertyCondition('status', NODE_PUBLISHED)
->fieldCondition('field_machine_name', 'value', $machine_name)
->execute();
return isset($entities['node']) ? array_values(entity_load('node', array_keys($entities['node'])))[0] : false;
}
/**
* Get array of permissions for a resource
* @param object $user drupal user object
* @param object $resource resource node
* @return array permissions for the specified resource
*/
function _wsauth_get_user_resource_permissions($user, $resource) {
$permissions = [
'read' => false,
'write' => false,
'admin' => false
];
//read
if (user_access('access all wsauth resources', $user) || _resource_have_public_read($resource)) {
$permissions['read'] = true;
} else {
$permissions['read'] = _wsauth_user_in_list($user->uid, $resource->field_permitted_users);
}
//write
if(_wsauth_user_in_list($user->uid, $resource->field_permitted_users_edit)){
$permissions['read'] = true;
$permissions['write'] = true;
$permissions['admin'] = false;
//$permissions['is_editor'] = true;
}
//admin
if (user_access('administer all wsauth resources', $user)) {
$permissions['read'] = true;
$permissions['write'] = true;
$permissions['admin'] = true;
//$permissions['is_superadmin'] = true;
}
if(_wsauth_user_in_list($user->uid, $resource->field_permitted_users_admin)){
$permissions['read'] = true;
$permissions['write'] = true;
$permissions['admin'] = true;
//$permissions['is_admin'] = true;
}
if(_wsauth_user_in_list($user->uid, $resource->field_owners)){
$permissions['read'] = true;
$permissions['write'] = true;
$permissions['admin'] = true;
//$permissions['is_owner'] = true;
}
return $permissions;
}
function _resource_have_public_read($resource){
if(is_string($resource)){
$resource = _wsauth_get_resource_by_machine_name($resource);
}
if(array_key_exists('und', $resource->field_public_view) && $resource->field_public_view['und'][0]['value'] == 0){
return false;
}else{
return true;
}
}
/**
* Helper function to look for user in field list
* @param int $uid user id
* @param array $list field list containing user references
* @return boolean true if user is in list
*/
function _wsauth_user_in_list($uid, $list) {
if (is_array($list) && array_key_exists('und', $list)) {
foreach ($list['und'] as $value) {
if ($value['target_id'] == $uid) {
return true;
}
}
}
return false;
}
function _wsauth_get_permitted_resources($user) {
return _wsauth_get_resources_for_user($user, 'field_permitted_users');
}
function _wsauth_get_all_resources_with_permission($user) {
$result = _wsauth_get_resources_for_user($user, 'field_permitted_users');
$result = array_merge($result, _wsauth_get_resources_for_user($user, 'field_permitted_users_edit'));
$result = array_merge($result, _wsauth_get_resources_for_user($user, 'field_permitted_users_admin'));
$result = array_merge($result, _wsauth_get_resources_for_user($user, 'field_owners'));
return $result;
}
function _wsauth_get_owned_resources($user) {
return _wsauth_get_resources_for_user($user, 'field_owners');
}
/*
* Implementation of hook_permission.
*/
function wsauth_permission() {
return array(
'view wsauth resources' => array(
'title' => t('View WS-Auth resources'),
),
'access all wsauth resources' => array(
'title' => t('Access all WS-Auth resources'),
),
'administer all wsauth resources' => array(
'title' => t('Administer all WS-Auth resources'),
),
);
}
/*
* Implementation of hook_theme.
*/
function wsauth_theme($existing, $type, $theme, $path) {
return array(
'wsauth_permissions_table' => array(
'render element' => 'table',
),
'wsauth_permissions_form_userinfo' => array(
'variables' => array('user' => NULL),
),
);
}
/*
* Implementation of hook_node_access.
*/
function wsauth_node_access($node, $op, $account) {
$type = is_string($node) ? $node : $node->type;
if ($type == 'wsauth_resource') {
switch ($op) {
case 'view':
if (!user_access('view wsauth resources', $account)) {
return NODE_ACCESS_DENY;
}
break;
}
}
return NODE_ACCESS_IGNORE;
}
function _wsauth_decode_accept_header($accept) {
// The first element is the default content type
$allowed_content_types = array(
'application/json',
'text/xml',
'application/xml',
);
// Copied from
$requested_types = array();
foreach (explode(',', $accept) as $item) {
$media_range = array_map('trim', explode(';', $item));
$type = $media_range[0];
$q = (count($media_range) > 1 && substr($media_range[1], 0, 2) == 'q=') ?
floatval(substr($media_range[1], 2)) :
1; // q default is 1
if ($q < 0 || $q > 1) { continue; } // qvalue = 0..1
if (substr($type, -1) == '*') { $q -= 0.0001; } // type/*
if (substr($type, 0, 1) == '*') { $q -= 0.0001; } // */subtype
$requested_types[$type] = $q;
}
arsort($requested_types);
foreach (array_keys($requested_types) as $type) {
if (in_array($type, $allowed_content_types)) {
return $type;
}
}
return $allowed_content_types[0];
}