Skip to content
Snippets Groups Projects
Commit 52dc4e05 authored by John Barclay's avatar John Barclay
Browse files

ldap authorization combined with temp api and temp ldap_servers modules. API...

ldap authorization combined with temp api and temp ldap_servers modules.  API will replace temp api in long run and ldap_servers may or may not be in api module proper.
parent 7c87eeb8
No related branches found
No related tags found
No related merge requests found
Showing with 1971 additions and 34 deletions
<?php
/**
* @file
* abstract class to represent an ldap_authorization consumer
* such as drupal_role, og_group, etc. each authorization comsumer
* will extend this class with its own class named
* LdapAuthorizationConsumer<consumer type> such as LdapAuthorizationConsumerDrupalRole
*
*/
class LdapAuthorizationConsumerAbstract {
public $name; // e.g. drupal role, og group
public $namePlural; // e.g. drupal roles, og groups
public $shortName; // e.g. role, group
public $shortNamePlural; // e.g. roles, groups
public $description;
/**
* @property boolean $allowSynchBothDirections
*
* Does this consumer module support synching in both directions?
*
*/
public $allowSynchBothDirections = FALSE;
/**
* @property boolean $allowConsumerObjectCreation
*
* Does this consumer module support creating consumer objects
* (drupal roles, og groups, etc.)
*
**/
public $allowConsumerObjectCreation = FALSE;
/**
* default mapping property values for this consumer type.
* Should be overridden by child classes as appropriate
*/
public $onlyApplyToLdapAuthenticatedDefault = TRUE;
public $useMappingsAsFilterDefault = TRUE;
public $synchOnLogonDefault = TRUE;
public $synchManuallyDefault = TRUE;
public $revokeLdapProvisionedDefault = TRUE;
public $regrantLdapProvisioned = TRUE;
public $createTargetsDefault = TRUE;
/**
* @property array $defaultableMappingProperties
* mapping properties a consumer may provide defaults for
* should include every item in "default mapping property values" above
*/
public $defaultableMappingProperties = array(
'onlyApplyToLdapAuthenticated',
'useMappingsAsFilter',
'synchOnLogon',
'synchManually',
'revokeLdapProvisioned',
'regrantLdapProvisioned',
'createTargets'
);
/**
* @property array $translateableProperties
* properties which have string values that should be passed into the token array
* and used in drupal t() functions.
*/
public $translateableProperties = array('name', 'namePlural', 'shortName','shortNamePlural','description');
public function tokens() {
$tokens = array();
foreach (array('%','!','@') as $symbol) {
foreach (array('name','namePlural','shortName','shortNamePlural','description') as $property) {
$tokens[$symbol . 'consumer_'. $property] = $this->$property;
}
}
return $tokens;
}
/**
* get list of all authorization target ids available to a this authorization consumer. For
* example for drupal_roles, this would be an array of drupal roles such
* as array('admin', 'author', 'reviewer',... ). For organic groups in
* might be all the names of organic groups.
*
* return array in form array(id1, id2, id3,...)
*
*/
public function getAvailableTargetIDs() {
}
/**
*
* create authorization targets
*
* @param array $creates an array of authorization target ids in form array(id1, id2, id3,...)
*
* return array in form array(id1, id2, id3,...) representing all
* existing target ids ($this->getAvailableTargetIDs())
*
*/
public function createTargets($creates) {
}
/**
* grant authorizations to a user
*
* @param object $user drupal user object
*
* @param $target_ids string or array of strings that are authorization target ids
*
* @param array $ldap_entry is ldap data from ldap entry which drupal user is mapped to
*
* @param boolean $user_save. should user object be saved by authorizationGrant method
*
* @return array $results. Array of form
* array(
* <authz target id1> => 1,
* <authz target id2> => 0,
* )
* where 1s and 0s represent success and failure to grant
*
*/
public function authorizationGrant(&$user, &$user_edit, $target_ids, &$ldap_entry, $user_save = TRUE) {
if (!is_array($target_ids)) {
$target_ids = array($target_ids);
}
foreach ($target_ids as $target_id) {
print $target_id;
$results[$target_id] = $this->_authorizationGrant($user, $user_edit, $target_id, $ldap_entry);
}
//print "<pre>results $user_save"; print_r($target_ids); print_r($results); print_r($user); print_r($user_edit); die;
if ($user_save) {
user_save($user, $user_edit);
}
return $results;
}
/**
* revoke authorizations to a user
*
* @param object $user drupal user object
*
* @param $authz_id string or array of strings that are authorization target ids
*
* @param array $ldap_entry is ldap data from ldap entry which drupal user is mapped to
*
* @param boolean $user_save. should user object be saved by authorizationGrant method
*
* @return array $results. Array of form
* array(
* <authz target id1> => 1,
* <authz target id2> => 0,
* )
* where 1s and 0s represent success and failure to revoke
*
*/
public function authorizationRevoke(&$user, &$user_edit, $target_ids, &$ldap_entry, $user_save = TRUE) {
if (!is_array($target_ids)) {
$target_ids = array($target_ids);
}
foreach ($target_ids as $target_id) {
$results[$target_id] = $this->_authorizationRevoke($user, $user_edit, $target_id, $ldap_entry);
}
if ($user_save) {
user_save($user, $user_edit);
}
return $results;
}
/**
* adjusts $user->data['ldap_authorizations'][<consumer_type>] data to reflect actual
* actual consumer authorizations and saves user object if changes made
*
* @param object $user drupal user object
*
* @param boolean $user_save. should user object be saved by authorizationGrant method
*
*/
public function authorizationUserDataSync(&$user, $user_save = TRUE) {
}
}
<?php
/**
* @file
* class to encapsulate an ldap entry to authorization target ids mapping configuration
*
* this is the lightweight version of the class for use on logon etc.
* the LdapAuthorizationMappingAdmin extends this class and has save,
* iterate, etc methods.
*/
/**
* LDAP Authorization Mapping
*/
class LdapAuthorizationMapping {
public $mappingID;
public $sid = NULL;
public $consumerModule = NULL; // id of module providing consumer
public $inDatabase = FALSE;
public $consumerType = NULL;
public $description = NULL;
public $status = NULL;
public $onlyApplyToLdapAuthenticated = TRUE;
public $deriveFromDn = FALSE;
public $deriveFromDnAttr = NULL;
public $deriveFromAttr = FALSE;
public $deriveFromAttrAttr = NULL;
public $deriveFromEntry = FALSE;
public $deriveFromEntryEntries = NULL;
public $deriveFromEntryAttr = NULL;
public $mappings = array();
public $useMappingsAsFilter = TRUE;
public $synchToLdap = FALSE;
public $synchOnLogon = TRUE;
public $synchManually = TRUE;
public $revokeLdapProvisioned = TRUE;
public $revokeNonLdapProvisioned = FALSE;
public $regrantLdapProvisioned = TRUE;
public $createTargets = TRUE;
public $errorMsg = NULL;
public $hasError = FALSE;
public $errorName = NULL;
public function clearError() {
$this->hasError = FALSE;
$this->errorMsg = NULL;
$this->errorName = NULL;
}
/**
* Constructor Method
*/
function __construct($_mid, $_new = FALSE, $_sid = NULL, $_consumer_type = NULL, $_consumer_module = NULL) {
$this->load($_mid, $_new, $_sid, $_consumer_type, $_consumer_module);
}
/**
* Load Method
*/
function load($_mid, $_new = FALSE, $_sid = NULL, $_consumer_type = NULL, $_consumer_module = NULL) {
if (!is_scalar($_mid)) {
return;
}
$this->consumerType = $_consumer_type;
$this->consumerModule = $_consumer_module;
$this->mappingID = $_mid;
$this->sid = $_sid;
if ($_new) {
$this->inDatabase = FALSE;
return;
}
$this->inDatabase = TRUE;
$saved = variable_get("ldap_authorization_map_". $this->mappingID, array());
foreach ($this->saveable as $property) {
if (isset($saved[$property])) {
$this->{$property} = $saved[$property];
}
}
}
/**
* Destructor Method
*/
function __destruct() {
}
protected $_mid;
protected $_sid;
protected $_new;
protected $saveable = array(
'mappingID',
'sid',
'consumerType',
'consumerModule',
'description',
'status',
'onlyApplyToLdapAuthenticated',
'deriveFromDn',
'deriveFromDnAttr',
'deriveFromAttr',
'deriveFromAttrAttr',
'deriveFromEntry',
'deriveFromEntryEntries',
'deriveFromEntryAttr',
'mappings',
'useMappingsAsFilter',
'synchToLdap',
'synchOnLogon',
'synchManually',
'revokeLdapProvisioned',
'revokeNonLdapProvisioned',
'createTargets',
'regrantLdapProvisioned',
);
}
This diff is collapsed.
----------------------
Authorization Consumer
----------------------
The "target" or entity that membership or authorization
is being granted to. Represented by LdapAuthorizationConsumer<consumer_type>
class which is provided by consumer modules such as ldap_authorization_drupal_role
e.g. for drupal roles, the authorization consumer would be drupal roles
e.g. for og, , the authorization consumer would be organic groups
----------------------
Consumer Type
----------------------
Id of a consumer type. A module articulates which consumer_types
it provides in hook_ldap_authorization_consumer and must provide a class
for each consumer it provides.
e.g. drupal_role, og_group, etc.
----------------------
Authorization Consumer Module
----------------------
A module which provides an authorization consumer.
The module will provide the LdapAuthorizationConsumer<consumer_type> class and
implement the hook_ldap_authorization_consumer hook.
----------------------
Authorization Target.
----------------------
The object representing a single authorization for a given Authorization Consumer.
e.g. a drupal role, or og group
----------------------
Target ID.
----------------------
The id representing a single authorization for a given Authorization Consumer.
e.g. for drupal roles, the Target ID would be the drupal role name
e.g. for og, the Target ID might be the og name.
----------------------
Authorization Mapping.
----------------------
Configuration of how a users ldap attributes will
determine a set of Target ids the user should be granted.
Represented by LdapAuthorizationMapping and LdapAuthorizationMappingAdmin classes
and managed at /admin/config/people/ldap/authorization
---------------------
LDAP Server.
---------------------
Each Authorization Mapping will use a single ldap server configuration to bind
and query ldap. The ldap server configuration is also used to map the drupal
username to an ldap user entry.
<?php
// $Id$
/**
* @file
......@@ -7,5 +6,135 @@
*/
/**
* index of ldap authorization mappings
*
* @return string html table
*/
function ldap_authorizations_admin_index() {
require_once('LdapAuthorizationMappingAdmin.class.php');
$mappings = LdapAuthorizationMappingAdmin::getMappings();
$consumers = ldap_authorization_get_consumers();
if (!is_array($consumers) || count($consumers) == 0) {
drupal_set_message('No authorization consumer modules are enabled. Enable
LDAP Authorization Drupal Roles, OG LDAP, or another LDAP Authorization consuming module','warning');
}
return theme('ldap_authorization_admin_index',
array('mappings' => $mappings, 'consumers' => $consumers));
}
/**
* form for adding, updating, and deleting a single ldap authorization mapping
*
* @param <type> $form
* @param <type> $form_state
* @param string $map_id unique identifier for authorization mapping
* @param string $op add, update, delete
* @param string $consumer_type drupal_roles, og_group, etc. Only needed for adds
* @return array drupal form array
*/
function ldap_authorization_admin_form($form, &$form_state, $map_id = NULL, $op = NULL, $consumer_type = NULL) {
require_once('LdapAuthorizationMappingAdmin.class.php');
$consumers = ldap_authorization_get_consumers($consumer_type);
if ($op == 'add') {
if (!$consumer_type || (count($consumers) == 0)) {
drupal_set_message(t('Bad URL with incorrect authorization type'), 'error');
} else {
$mapping = new LdapAuthorizationMappingAdmin(check_plain($map_id), TRUE, NULL, $consumer_type, $consumers['consumer_module']);
}
} elseif ($op == 'update' || $op == 'delete') {
if ($mapping = new LdapAuthorizationMappingAdmin(check_plain($map_id), FALSE)) {
} else {
drupal_set_message(t('Bad LDAP Authorization Mapping URL. No mapping for mapping id = !id', array('!id' => $map_id)), 'error');
drupal_goto(LDAP_API_MENU_BASE_PATH .'/authorization');
}
}
$servers = ldap_servers_get_servers_conf();
foreach ($servers as $sid => $server) {
$server_options[$sid] = $server['name'];
}
return $mapping->drupalForm($server_options, $op);
}
/**
* validate handler for the ldap_authorization_admin_form
*/
function ldap_authorization_admin_form_validate($form, &$form_state) {
list($consumer, $op, $op_past, $new, $values) = _ldap_authorization_admin_parse_form($form, $form_state);
require_once('LdapAuthorizationMappingAdmin.class.php');
// create as new simply for validation
$mapping = new LdapAuthorizationMappingAdmin($values['map_id'], TRUE, $values['sid'], $consumer->consumerType, $consumer->consumerModule);
$errors = $mapping->drupalFormValidate($op, $values);
foreach ($errors as $error_name => $error_text) {
form_set_error($error_name, t($error_text));
}
}
/**
* submit handler function for ldap_authorization_admin_form
*/
function ldap_authorization_admin_form_submit($form, &$form_state) {
list($consumer, $op, $op_past, $new, $values) = _ldap_authorization_admin_parse_form($form, $form_state);
require_once('LdapAuthorizationMappingAdmin.class.php');
$mapping = new LdapAuthorizationMappingAdmin($values['map_id'], $new, $values['sid'], $consumer->consumerType, $consumer->consumerModule);
$mapping->drupalFormSubmit($op, $values); // add form data to object and save or create
if ($mapping->hasError == FALSE) {
drupal_set_message(t('LDAP Authorization %name !verb', array('!verb' => $op_past, '%name' => $values['description'])), 'status');
drupal_goto(LDAP_API_MENU_BASE_PATH .'/authorization');
} else {
form_set_error($mapping->errorName, $mapping->errorMsg);
$mapping->clearError();
}
}
function _ldap_authorization_admin_parse_form($form, &$form_state) {
$op = strtolower($form_state['clicked_button']['#value']);
$values = $form_state['values'];
if ($values['consumer_type']) {
$consumer_type = $values['consumer_type'];
$consumer = ldap_authorization_get_consumer_object(array('consumer_type' => $consumer_type));
} else {
return FALSE;
}
switch($op) {
case 'add':
$op_past = 'Added';
$new = TRUE;
break;
case 'update':
$op_past = 'Updated';
$new = FALSE;
break;
case 'delete':
$op_past = 'Deleted';
$new = FALSE;
break;
}
return array($consumer, $op, $op_past, $new, $form_state['values']);
}
// vim:fenc=utf-8:ft=php:ai:si:ts=2:sw=2:et:
<?php
// $Id$
/**
* @file
* form to test ldap mapping configuration
*/
/**
* form for adding, updating, and deleting a single ldap authorization mapping
*
* @param <type> $form
* @param <type> $form_state
* @param string $map_id unique identifier for authorization mapping
* @return array drupal form array
*/
function ldap_authorization_mapping_test_form($form, &$form_state, $map_id) {
$consumer = ldap_authorization_get_consumer_object(array('map_id' => $map_id));
$consumer_tokens = $consumer->tokens();
if (isset($_SESSION['ldap_authorization_test_result'])) {
$form['result'] = array(
'#type' => 'item',
'#markup' => $_SESSION['ldap_authorization_test_result'],
);
unset($_SESSION['ldap_authorization_test_result']);
}
$form['intro'] = array(
'#type' => 'item',
'#markup' => t('<h1>Test LDAP to !consumer_name Mapping Configuration</h1>
<p>This form will not actually grant any authorizations, its just to show
what authorizations would be granted with this mapping.</p>', $consumer_tokens),
);
$form['map_id'] = array(
'#type' => 'hidden',
'#default_value' => $map_id,
);
$form['usernames'] = array(
'#type' => 'textarea',
'#title' => t('Drupal usernames to test !consumer_shortName mapping results for. One per line.', $consumer_tokens),
'#default_value' => @$_SESSION['ldap_authorization_mapping_test_form']['usernames'] ,
'#cols' => 50,
'#rows' => 6,
'#description' => t('', $consumer_tokens),
);
$form['random_users'] = array(
'#type' => 'checkbox',
'#default_value' => @$_SESSION['ldap_authorization_mapping_test_form']['random_users'],
'#title' => t('Use 10 random users', $consumer_tokens),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'test',
);
return $form;
}
/**
* validate handler for the ldap_authorization_mapping_test
*/
function ldap_authorization_mapping_test_form_validate($form, &$form_state) {
$values = $form_state['values'];
if (!($values['usernames'] || $values['random_users'])) {
form_set_error('No options chosen', t('Usernames must be given or random users checked.'));
}
}
/**
* submit handler function for ldap_authorization_mapping_test
*/
function ldap_authorization_mapping_test_form_submit($form, &$form_state) {
$map_id = $form_state['values']['map_id'];
$consumer = ldap_authorization_get_consumer_object(array('map_id' => $map_id));
$consumer_tokens = $consumer->tokens();
$results = array();
$users_listed = explode("\n", $form_state['values']['usernames']);
$random_users = array();
$_SESSION['ldap_authorization_mapping_test_form']['random_users'] = $form_state['values']['random_users'];
$_SESSION['ldap_authorization_mapping_test_form']['usernames'] = $form_state['values']['usernames'];
if ($form_state['values']['random_users']) { // add 10 random usernames to test
// not using user_load_multiple because need randomness outside of query
$select = db_select('users', 'u');
$select->fields('u');
try {
$random_users = $select->execute()->fetchAllAssoc('name', PDO::FETCH_ASSOC);
}
catch(Exception $e) {
drupal_set_message(t('db users query failed. Message = %message, query= %query',
array('%message' => $e->getMessage(), '%query' => $e->query_string)), 'error');
return "";
}
}
$user_names = array_unique(array_merge(array_keys($random_users),$users_listed));
foreach ($user_names as $username) {
if ($username) { // ingore user 0
if ($user = user_load_by_name($username)) {
$new_authorizations = ldap_authorizations_user_authorizations($user, 'query', $map_id, 'logon');
$results[$username]['authorizations'] = $new_authorizations;
} else {
$results[$username]['message'] = t('Failed to find user with username %username.', array('%username' => $username));
}
}
}
$mapping = ldap_authorizations_mappings($map_id, NULL, TRUE);
$table = theme('ldap_authorization_test_results', array('data' => $results, 'consumer' => $consumer, 'mapping' => $mapping));
$_SESSION['ldap_authorization_test_result'] = $table;
$form_state['redirect'] = LDAP_API_MENU_BASE_PATH .'/authorization/test/'. $map_id;
}
<?php
/**
* return all desired authorizations for a given user based on ldap authorization mapping and filtering rules
*
* @param object $user
*
* @param string $op = set, query, debug
*
* @param string $_mapping_id
* if empty, will check all mappings
*
* @param string $context 'logon'
*
* @param boolean $query_only only determine authorizations, don't apply them.
*
* @return
*
* LDAP_AUTHORIZATION_NO_LDAP_SERVERS if no servers configured
* LDAP_AUTHORIZATION_LDAP_ERROR if ldap error
* TRUE if servers configured but no roles derived from ldap
* array of potential authorizations (user may or may not already have these)
*
* by reference $user->data[<mapping id>][<authorization_id>] = array();
* e.g. $var['drupal_role']['content_admin'] = array('rid' => 4)
* e.g. $var['og_membership']['bakers club'] = array('expires' => '01/01/2012');
*
*/
function _ldap_authorizations_user_authorizations(&$user, $op, $_mapping_id, $context) {
$debug = array('function' => '_ldap_authorizations_user_authorizations', 'user' => $user, 'op' => $op, 'ldap_mapping_id' => $_mapping_id );
$authorizations = array();
if ($mappings = ldap_authorizations_mappings($_mapping_id)) {
$consumers = ldap_authorization_get_consumers();
foreach ($mappings as $mapping_id => $mapping) {
$debug[$mapping_id] = $mapping;
if ($context == 'logon' && !$mapping->synchOnLogon) {
$authorizations[$ldap_mapping_id] = LDAP_AUTHORIZATION_MAP_NOT_CONF_FOR_LOGON;
continue;
}
if ($mapping->onlyApplyToLdapAuthenticated && (!isset($user->data['ldap_authentified']) || $user->data['ldap_authentified'] == FALSE)) {
$authorizations[$mapping_id] = LDAP_AUTHORIZATION_USER_NOT_LDAP_AUTHENTICATED;
continue;
}
elseif (! ($user_ldap_entry = ldap_servers_get_user_ldap_data($user, $mapping->sid))) {
$authorizations[$mapping_id] = LDAP_AUTHORIZATION_USER_LDAP_NOT_FOUND;
continue;
}
$ldap_servers = ldap_servers_get_servers_conf($mapping->sid);
$ldap_server = $ldap_servers[$mapping->sid];
$user_edit = array(); // all user data is stored here until user_save is called.
$proposed_ldap_authorizations = array();
/**
* 1. first just need to figure out what authz_ids are generated from this ldap auth mapping configuration
*
* goal here is simply to build an array of authorizations for this ldap authz mapping
* $proposed_ldap_authorizations[<consumer_type>][<authorization id>] = properties associative array or empty array
* e.g. $proposed_ldap_authorizations['drupal_role']['admin'] = array()
* the authorization ids may represent drupal roles, organic groups, civicrm groups, etc.
* these mappings are a function of:
* - drupal user entry, $user
* - a user ldap entry, $user_ldap_entry
* - an ldap server configuration, $ldap_server
* - a mapping configuration ($ldap_authz_map_config)
*/
ldap_authorization_maps_alter_invoke($user, $user_ldap_entry, $ldap_server, $mapping, $proposed_ldap_authorizations, 'query');
$debug['proposed_ldap_authorizations'] = $proposed_ldap_authorizations;
/**
* 2. filter is both a whitelist and a mapping of an ldap results
* to an authorization id.
*/
if ($mapping->useMappingsAsFilter) {
$filtered_ldap_authorizations = array();
foreach($mapping->mappings as $mapping_filter) {
$map_from = $mapping_filter[0];
$map_to = $mapping_filter[1];
if(isset($proposed_ldap_authorizations[$map_from]) || isset($proposed_ldap_authorizations[strtolower($map_from)])) {
$filtered_ldap_authorizations[] = $map_to;
}
}
} else {
$filtered_ldap_authorizations = array_keys($proposed_ldap_authorizations);
}
$debug['filtered_ldap_authorizations'] = $filtered_ldap_authorizations;
if ($op == 'set') {
$consumer = ldap_authorization_get_consumer_object(array('consumer_type' => $mapping->consumerType));
/**
* 3. third, grant any proposed authorizations not already granted
*/
/**
* 3.A. Determine what authorizations have been granted in the past
* if regrantLdapProvisionedDefault is false
* and remove them
*
*/
if (isset($user->data['ldap_authorizations'][$mapping->consumerType]) && $mapping->regrantLdapProvisionedDefault === FALSE) {
$existing_ldap_authorizations = $user->data['ldap_authorizations'][$mapping->consumerType];
$creates = array_diff($filtered_ldap_authorizations, $existing_ldap_authorizations);
} else {
$existing_ldap_authorizations = array();
$creates = $filtered_ldap_authorizations
}
/**
* 3.C. query or create existing authorization target ids (drupal roles, og groups etc)
*/
$consumer_containers_existing = array();
if ($mapping->createTargets) {
$consumer->createTargets($creates);
}
$consumer_containers_existing = $consumer->getAvailableTargetIDs();
/**
* 3.D. Only grant to authorization target ids that exist
* requerying getAvailableTargetIDs() in 3.C. accounts for
* failure in 3.C. createTargets() to create a targetm id
*/
$grants = array_intersect($consumer_containers_existing, $creates); //
$debug['grants'] = $grants;
/**
* 3.E. Do grants
*/
$consumer->authorizationGrant($user, $user_edit, $grants, $ldap_entry, FALSE);
$debug['user_edit after authorizationGrant'] = $user_edit;
/**
* 3.F take away any authorizations not in proposed authorization,
* but previously granted by ldap
*/
$revokes_result = array();
if ($mapping->revokeLdapProvisioned) {
$revokes = array_diff($existing_ldap_authorizations, $filtered_ldap_authorizations);
if (count($revokes)) {
$consumer->authorizationRevoke($user, $user_edit, $revokes, $ldap_entry, FALSE);
}
}
$debug['user_edit after authorizationRevoke'] = $user_edit;
/**
* 3.G save user object and user data
*/
$debug['user_edit to save'] = $user_edit;
$user = user_save($user, $user_edit);
// $consumer->authorizationUserDataSync($user, $ldap_entry);
}
else {
}// end if query only
$authorizations[$mapping_id] = $filtered_ldap_authorizations;
} // end foreach ($ldap_authz_map_configs
return $authorizations;
} else {
return LDAP_AUTHORIZATION_NO_LDAP_SERVERS;
}
}
function _ldap_authorization_ldap_authorization_maps_alter(&$user, &$user_ldap_entry, &$ldap_server, &$mapping, &$authz_ids, $op) {
$debug = array(
'hook' => 'ldap_authorization_ldap_authorization_maps_alter',
'user' => $user,
'user_ldap_entry' => $user_ldap_entry,
'ldap_server' => $ldap_server,
'ldap_authz_map_config' => $mapping
);
// Strategy 1: group extracted from user's DN.
$derive_from_dn_authorizations = array();
if ($mapping->deriveFromDn) {
$pairs = explode(',', $user_ldap_entry['dn']);
foreach ($pairs as $p) {
$pair = explode('=', $p);
if (drupal_strtolower(trim($pair[0])) == drupal_strtolower($mapping->deriveFromDnAttr)) {
$id = trim($pair[1]);
$derive_from_dn_authorizations[$id] = $id;
}
}
$debug['Strategy group extracted from users DN'] = array(
'pairs' => $pairs,
'attribute' => $mapping->deriveFromDnAttr,
'authz_ids' => $derive_from_dn_authorizations
);
}
// Strategy 2: groups in user attributes
$derive_from_attr_authorizations = array();
if ($mapping->deriveFromAttr) {
foreach ($mapping->deriveFromAttrAttr as $attribute) {
if (isset($user_ldap_entry['attr'][strtolower($attribute)])) {
foreach ($user_ldap_entry['attr'][strtolower($attribute)] as $i => $value) {
if ($i != 'count') {
$derive_from_attr_authorizations[$value] = $value;
}
}
//array_merge($authz_ids, $attrib_authorizations); // do outside of loop
}
// $attributes = ldap_api_retrieveMultiAttribute($user_ldap_entry['ldap_dn'], $attribute);
// $attrib_authorizations = array_combine($attrib_authorizations, $attrib_authorizations);
$debug['Strategy groups in user attributes'] = array(
'attributes' => $mapping->deriveFromAttrAttr,
'user attributes' => $user_ldap_entry['attr'],
'derive_from_attr_authorizations' => $derive_from_attr_authorizations
);
}
}
// Strategy 3: groups as entries.
$derive_from_entry_authorizations = array();
// $ldap_mapping->ldapgroups_entries_attribute
if ($mapping->deriveFromEntry) {
foreach ($mapping->deriveFromEntryEntries as $branch) {
// ?????????? on next line
// $entries = $ldap_server->search($branch, $mapping->deriveFromEntryAttr .'='. $user->name, array($mapping->deriveFromEntryAttr));
// if (empty($entries) || $entries['count'] == 0)
// $entries = $ldap_server->search($branch, $mapping->deriveFromEntryAttr .'='. $user->name, array($mapping->deriveFromEntryAttr));
// foreach ($entries as $entry) {
// if (isset($entry['dn']))
// $derive_from_entry_authorizations[$entry['dn']] = $entry['dn'];
// }
}
}
$authz_ids = array_merge($derive_from_dn_authorizations, $derive_from_attr_authorizations, $derive_from_entry_authorizations);
}
; $Id$
name = Authorization
description = Implements LDAP authorization (previously LDAP Groups)
package = Lightweight Directory Access Protocol
dependencies[] = ldap_api
core = 6.x
name = LDAP Authorization
description = "Implements LDAP authorization (previously LDAP Groups)"
package = "Lightweight Directory Access Protocol"
dependencies[] = ldap_api_temp
dependencies[] = ldap_servers
core = 7.x
files[] = ldap_authorization.install
files[] = ldap_authorization.module
files[] = ldap_authorization.admin.inc
configure = admin/config/people/ldap/authorization
......@@ -9,23 +9,18 @@
/**
* Implementation of hook_install().
*/
function ldap_authorizaton_install() {
drupal_install_schema('ldap_authorization');
function ldap_authorization_install() {
}
/**
* Implementation of hook_uninstall().
*/
function ldap_authorization_uninstall() {
drupal_uninstall_schema('ldap_authorization');
$result = db_query('DELETE FROM {variables} WHERE name like "ldap_authorization_%"');
}
/**
* Implementation of hook_schema().
*/
function ldap_authorization_schema() {
}
// vim:fenc=utf-8:ft=php:ai:si:ts=2:sw=2:et:
......@@ -3,38 +3,223 @@
/**
* @file
* This module provides LDAP-based access control (roles)
* ldap authorization module
*
* @todo add caching
* @todo support exportables
* @todo unit testing
* @todo delete confirm form
*/
/**
* Implementation of hook_init().
*/
function ldap_authorization_init() {
}
/**
* Implementation of hook_theme().
*/
function ldap_authorization_theme() {
}
define('LDAP_AUTHORIZATION_PROJECT_TAG', 'ldap_authorization');
define('LDAP_AUTHORIZATION_USER_LDAP_NOT_FOUND', 101);
define('LDAP_AUTHORIZATION_USER_NOT_LDAP_AUTHENTICATED', 102);
define('LDAP_AUTHORIZATION_MAP_NOT_CONF_FOR_LOGON', 103);
define('LDAP_AUTHORIZATION_NO_LDAP_SERVERS', 'ldap_authorization_no_ldap_servers');
/**
* Implementation of hook_menu().
*/
function ldap_authorization_menu() {
$items = array();
$items['admin/settings/ldap/authorization'] = array(
'title' => 'Authorization',
'description' => 'Configure LDAP authorization',
$items[LDAP_API_MENU_BASE_PATH .'/authorization'] = array(
'title' => t('4. Authorization'),
'description' => t('Map User LDAP properties to Authorizations'),
'page callback' => 'ldap_authorizations_admin_index',
'page arguments' => array(),
'access arguments' => array('administer site configuration'),
'file' => 'ldap_authorization.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
$items[LDAP_API_MENU_BASE_PATH .'/authorization/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items[LDAP_API_MENU_BASE_PATH .'/authorization/update'] = array(
'title' => t('update'),
'description' => t('Update an ldap authorization mapping'),
'page callback' => 'drupal_get_form',
'page arguments' => array('ldap_authorization_admin_form', LDAP_API_MENU_BASE_PATH_PARTS + 2, 'update', LDAP_API_MENU_BASE_PATH_PARTS + 3),
'access arguments' => array('administer site configuration'),
'type' => MENU_CALLBACK + MENU_LINKS_TO_PARENT + MENU_IS_LOCAL_ACTION,
'weight' => 3,
'file' => 'ldap_authorization.admin.inc',
);
$items[LDAP_API_MENU_BASE_PATH .'/authorization/delete'] = array(
'title' => t('delete'),
'description' => t('Delete an ldap authorization mapping'),
'page callback' => 'drupal_get_form',
'page arguments' => array('ldap_authorization_admin_form', LDAP_API_MENU_BASE_PATH_PARTS + 2, 'delete', LDAP_API_MENU_BASE_PATH_PARTS + 3),
'access arguments' => array('administer site configuration'),
'type' => MENU_CALLBACK + MENU_LINKS_TO_PARENT + MENU_IS_LOCAL_ACTION,
'weight' => 3,
'file' => 'ldap_authorization.admin.inc',
);
$items[LDAP_API_MENU_BASE_PATH .'/authorization/test'] = array(
'title' => t('test'),
'description' => t('Test an ldap authorization mapping'),
'page callback' => 'drupal_get_form',
'page arguments' => array('ldap_authorization_mapping_test_form', LDAP_API_MENU_BASE_PATH_PARTS + 2, 'test', LDAP_API_MENU_BASE_PATH_PARTS + 3),
'access arguments' => array('administer site configuration'),
'weight' => 1,
'type' => MENU_CALLBACK + MENU_LINKS_TO_PARENT + MENU_IS_LOCAL_ACTION,
'weight' => 3,
'file' => 'ldap_authorization.admin.mapping_test.inc',
);
$consumers = ldap_authorization_get_consumers();
//print_r($consumers); die;
foreach ($consumers as $consumer_type => $consumer) {
$items[LDAP_API_MENU_BASE_PATH .'/authorization/add/'. $consumer_type] = array(
'title' => t('Add !name Mapping', array('!name' => $consumer['consumer_name'])),
'page callback' => 'drupal_get_form',
'page arguments' => array('ldap_authorization_admin_form', NULL, 'add', $consumer_type),
'access arguments' => array('administer site configuration'),
'type' => MENU_LOCAL_TASK + MENU_IS_LOCAL_ACTION,
'weight' => 4,
'file' => 'ldap_authorization.admin.inc',
);
}
return $items;
}
/**
* Implements hook_user_login() login operation.
*/
function ldap_authorization_user_login(&$edit, $user) {
ldap_authorizations_user_authorizations($user, 'set', NULL, 'logon');
}
/**
* Invokes hook_ldap_authorization_maps_alter() in every module.
*
* We cannot use module_invoke() for this, because the arguments need to
* be passed by reference.
*/
function ldap_authorization_maps_alter_invoke(&$user, &$user_ldap_entry, &$ldap_server, &$ldap_authz_map_config, &$proposed_ldap_authorizations, $op) {
foreach (module_implements('ldap_authorization_maps_alter') as $module) {
$function = $module . '_ldap_authorization_maps_alter';
$function($user, $user_ldap_entry, $ldap_server, $ldap_authz_map_config, $proposed_ldap_authorizations, $op);
}
}
/**
* implements hook_ldap_authorization_maps_alter to suggest authorization ids to grant (drupal roles in this case)
*
* @param object $user drupal user object
*
* @param array $user_ldap_entry is ldap data from ldap entry which drupal user is mapped to
*
* @param object $ldap_server
*
* @param array $ldap_authz_map_config is the particular ldap authorization mapping in use.
*
* @param array $authz_ids. any new authorization ids (drupal user role names in this case) in form array('rolename1', 'rolename2',....)
*
* @param string $op = 'set' or 'query'
*
*/
function ldap_authorization_ldap_authorization_maps_alter(&$user, &$user_ldap_entry, &$ldap_server, &$ldap_authz_map_config, &$authz_ids, $op) {
require_once('ldap_authorization.inc');
_ldap_authorization_ldap_authorization_maps_alter($user, $user_ldap_entry, $ldap_server, $ldap_authz_map_config, $authz_ids, $op);
}
function ldap_authorization_theme() {
return array(
'ldap_authorization_test_results' => array(
'variables' => array('data' => NULL),
'render element' => 'element',
'file' => 'ldap_authorization.theme.inc'
),
'ldap_authorization_admin_index' => array(
'variables' => array('mappings' => NULL, 'consumers' => NULL),
'render element' => 'element',
'file' => 'ldap_authorization.theme.inc'
),
);
}
/**
*
* @param <type> $param of form 'map_id' => <map_id> or 'consumer_type' => <consumer_type>
* @return consumer object
*/
function ldap_authorization_get_consumer_object($param) {
extract($param);
$consumers = ldap_authorization_get_consumers();
if (@$map_id) {
require_once('LdapAuthorizationMappingAdmin.class.php');
$mappings = LdapAuthorizationMappingAdmin::getMappings($map_id);
// $mapping = $mappings[$map_id];
$consumer_type = $mappings[$map_id]->consumerType;
}
// print "<pre>- $consumer_type - "; print_r($consumers);
if (isset($consumers[$consumer_type])) {
$consumer = $consumers[$consumer_type];
require_once(drupal_get_path('module', $consumer['consumer_module']) . '/' . $consumer['consumer_class_file']);
$class = $consumer['consumer_class_name'];
$consumer = new $class();
// print_r($consumer);
return $consumer;
} else {
return FALSE;
}
}
/*
* return authorization mappings
*
* @param $map_id id of mapping
* @param $consumer_type
* @param boolean $flatten. if only on element in array, return sub array.
*
* @return array of mapping configuration keyed on map_id
*/
function ldap_authorizations_mappings($map_id = null, $consumer_type = NULL, $flatten = FALSE) {
require_once('LdapAuthorizationMappingAdmin.class.php');
return LdapAuthorizationMappingAdmin::getMappings($map_id, $consumer_type, $flatten);
}
function ldap_authorization_get_consumers($consumer_type = NULL) {
static $consumers;
if (!is_array($consumers)) {
$consumers = module_invoke_all('ldap_authorization_consumer');
}
return ($consumer_type) ? $consumers[$consumer_type] : $consumers;
}
/**
* @rationale need not be called from hook_user, so this function separated out
* so it can be called from a batch synchronization process for example
*/
function ldap_authorizations_user_authorizations(&$user, $op = 'query', $mapping_id = NULL, $context = NULL) {
require_once('ldap_authorization.inc');
// print "<pre>";
$new_authorizations = _ldap_authorizations_user_authorizations($user, $op, $mapping_id, $context);
// print_r($user); print_r($new_authorizations); print_r(user_roles()); die;
// @rationale hooks invoked for grant and revoke should make actual changes in roles, og membership, etc
// but user_save here is for saving $user->data['ldap_authorizations']
// if ($op == 'set' ) {
// $user = user_save($user);
// }
// print "<pre>"; print_r($user); die;
return $new_authorizations;
}
// vim:fenc=utf-8:ft=php:ai:si:ts=2:sw=2:et:
<?php
function theme_ldap_authorization_admin_index(&$variables) {
extract($variables); //
$table = array(
'header' => array("Mapping ID", "LDAP Server ID", "Description", "Module", "Consumer Type", "Enabled","Actions"),
'attributes' => array('id' => 'ldap_authorization_mappings', 'class' => 'data'),
'colgroups' => array(),
'sticky' => FALSE,
'empty' => '',
'caption' => 'LDAP Authorization Mappings',
);
if (count($mappings)) {
foreach($mappings as $map_id => $mapping) {
$consumer = ldap_authorization_get_consumer_object(array('consumer_type' => $mapping->consumerType));
if ($consumer) {
$actions = ' | '. l('update', LDAP_API_MENU_BASE_PATH .'/authorization/update/'. $mapping->mappingID) . ' | ' .
l('delete', LDAP_API_MENU_BASE_PATH .'/authorization/delete/'. $mapping->mappingID) . ' | ' .
l('test', LDAP_API_MENU_BASE_PATH .'/authorization/test/'. $mapping->mappingID) . ' | ';
} else {
$actions = "Failed to create consumer object for !consumer_name. Make sure appropriate module is enabled.";
}
$consumer_name = (isset($consumers[$mapping->consumerType]['consumer_name'])) ? $consumers[$mapping->consumerType]['consumer_name']
: t("module providing type %name disabled", array('%name' => $mapping->consumerType));
$table['rows'][] = array(
$mapping->mappingID,
$mapping->sid,
$mapping->description,
$mapping->consumerModule,
$consumer_name,
($mapping->status) ? t('Yes') : t('No'),
$actions
);
}
} else {
$table['rows'] = array();
}
$table = theme_table($table);
return $table;
}
function theme_ldap_authorization_test_results($variables) {
extract($variables);
$table = array(
'header' => array("Drupal Username", "Authorization Type", "Authorization IDs", "Mapping Configuration", "LDAP Server Configuration"),
'attributes' => array('id' => 'ldap_authorization_authorizations', 'class' => 'data'),
'colgroups' => array(),
'sticky' => FALSE,
'empty' => '',
'caption' => t('LDAP Authorizations Test Results for consumer %consumer and mapping %mapping_id', array('%consumer' => $consumer->name, '%mapping_id' => $mapping->description)),
);
if (count($data)) {
foreach($data as $username => $result) {
$row = array();
if (isset($result['message'])) {
$row = array($username, $result['message']);
} else {
foreach ($result as $consumer_type => $authorization) {
foreach ($authorization as $mapping_id => $result) {
$map_link = l($mapping->mappingID, LDAP_API_MENU_BASE_PATH .'/authorization/update/'. $mapping->mappingID);
$server_link = l($mapping->sid, LDAP_API_MENU_BASE_PATH .'/servers/edit/'. $mapping->sid);
if (is_array($result)) {
$authorizations = theme_item_list(array('items' => $result, 'title' => NULL, 'type' => 'ul', 'attributes' => array()));
} else {
switch ($result) {
case LDAP_AUTHORIZATION_USER_LDAP_NOT_FOUND:
$authorizations = "LDAP entry for drupal user not found.";
break;
case LDAP_AUTHORIZATION_USER_NOT_LDAP_AUTHENTICATED:
$authorizations = "LDAP Authorizations not applied because user is not authenticated via LDAP and authorization mapping configuration requires is ($map_link).";
break;
case LDAP_AUTHORIZATION_MAP_NOT_CONF_FOR_LOGON:
$authorizations = "LDAP Authorizations not configured to be executed on logon in ($map_link).";
break;
}
}
if ($user = user_load_by_name($username)) {
$username = l($username, 'user/'. $user->uid .'/edit');
}
$row = array($username, $consumer->name, $authorizations, $map_link, $server_link);
}
$table['rows'][] = $row;
}
}
}
} else {
$table['rows'] = array();
}
$output = theme('table', $table);
return $output;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment