code changes for user_ldap Dynamic Group Membership
Added new setting of “Dynamic Group Member URL” (ldapDynamicGroupMemberURL) - see LDAP settings advanced tab. Added public function getDynamicGroupMembers. Updated function _groupMembers. Updated function getUserGroups.
This commit is contained in:
parent
da04620155
commit
0d797637f3
|
@ -12,6 +12,7 @@
|
|||
* @author Robin McCorkell <robin@mccorkell.me.uk>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
* @author Richard Bentley <rbentley@e2advance.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
|
@ -146,6 +147,46 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
|
|||
return $isInGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dnGroup
|
||||
* @return array
|
||||
*
|
||||
* For a group that has user membership defined by an LDAP search url attribute returns the users
|
||||
* that match the search url otherwise returns an empty array.
|
||||
*/
|
||||
public function getDynamicGroupMembers($dnGroup) {
|
||||
$dynamicGroupMemberURL = strtolower($this->access->connection->ldapDynamicGroupMemberURL);
|
||||
|
||||
if (empty($dynamicGroupMemberURL)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$dynamicMembers = array();
|
||||
$memberURLs = $this->access->readAttribute(
|
||||
$dnGroup,
|
||||
$dynamicGroupMemberURL,
|
||||
$this->access->connection->ldapGroupFilter
|
||||
);
|
||||
if ($memberURLs !== false) {
|
||||
// this group has the 'memberURL' attribute so this is a dynamic group
|
||||
// example 1: ldap:///cn=users,cn=accounts,dc=dcsubbase,dc=dcbase??one?(o=HeadOffice)
|
||||
// example 2: ldap:///cn=users,cn=accounts,dc=dcsubbase,dc=dcbase??one?(&(o=HeadOffice)(uidNumber>=500))
|
||||
$pos = strpos($memberURLs[0], '(');
|
||||
if ($pos !== false) {
|
||||
$memberUrlFilter = substr($memberURLs[0], $pos);
|
||||
$foundMembers = $this->access->searchUsers($memberUrlFilter,'dn');
|
||||
$dynamicMembers = array();
|
||||
foreach($foundMembers as $value) {
|
||||
$dynamicMembers[$value['dn'][0]] = 1;
|
||||
}
|
||||
} else {
|
||||
\OCP\Util::writeLog('user_ldap', 'No search filter found on member url '.
|
||||
'of group ' . $dnGroup, \OCP\Util::DEBUG);
|
||||
}
|
||||
}
|
||||
return $dynamicMembers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dnGroup
|
||||
* @param array|null &$seen
|
||||
|
@ -180,6 +221,9 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
$allMembers = array_merge($allMembers, $this->getDynamicGroupMembers($dnGroup));
|
||||
|
||||
$this->access->connection->writeToCache($cacheKey, $allMembers);
|
||||
return $allMembers;
|
||||
}
|
||||
|
@ -387,6 +431,8 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
|
|||
*
|
||||
* This function fetches all groups a user belongs to. It does not check
|
||||
* if the user exists at all.
|
||||
*
|
||||
* This function includes groups based on dynamic group membership.
|
||||
*/
|
||||
public function getUserGroups($uid) {
|
||||
if(!$this->enabled) {
|
||||
|
@ -405,6 +451,8 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
|
|||
$groups = [];
|
||||
$primaryGroup = $this->getUserPrimaryGroup($userDN);
|
||||
|
||||
$dynamicGroupMemberURL = strtolower($this->access->connection->ldapDynamicGroupMemberURL);
|
||||
|
||||
// if possible, read out membership via memberOf. It's far faster than
|
||||
// performing a search, which still is a fallback later.
|
||||
if(intval($this->access->connection->hasMemberOfFilterSupport) === 1
|
||||
|
@ -422,11 +470,15 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
|
|||
}
|
||||
}
|
||||
|
||||
if($primaryGroup !== false) {
|
||||
$groups[] = $primaryGroup;
|
||||
if (empty($dynamicGroupMemberURL)) {
|
||||
// if dynamic group membership is not enabled then we can return
|
||||
// straight away
|
||||
if($primaryGroup !== false) {
|
||||
$groups[] = $primaryGroup;
|
||||
}
|
||||
$this->access->connection->writeToCache($cacheKey, $groups);
|
||||
return $groups;
|
||||
}
|
||||
$this->access->connection->writeToCache($cacheKey, $groups);
|
||||
return $groups;
|
||||
}
|
||||
|
||||
//uniqueMember takes DN, memberuid the uid, so we need to distinguish
|
||||
|
@ -458,6 +510,39 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
|
|||
$groups[] = $primaryGroup;
|
||||
}
|
||||
|
||||
if (!empty($dynamicGroupMemberURL)) {
|
||||
// look through dynamic groups to add them to the result array if needed
|
||||
$groupsToMatch = $this->access->fetchListOfGroups(
|
||||
$this->access->connection->ldapGroupFilter,array('dn',$dynamicGroupMemberURL));
|
||||
foreach($groupsToMatch as $value) {
|
||||
if (!array_key_exists($dynamicGroupMemberURL, $value)) {
|
||||
continue;
|
||||
}
|
||||
$pos = strpos($value[$dynamicGroupMemberURL][0], '(');
|
||||
if ($pos !== false) {
|
||||
$memberUrlFilter = substr($value[$dynamicGroupMemberURL][0],$pos);
|
||||
// apply filter via ldap search to see if this user is in this
|
||||
// dynamic group
|
||||
$userMatch = $this->access->readAttribute(
|
||||
$uid,
|
||||
$this->access->connection->ldapUserDisplayName,
|
||||
$memberUrlFilter
|
||||
);
|
||||
if ($userMatch !== false) {
|
||||
// match found so this user is in this group
|
||||
$pos = strpos($value['dn'][0], ',');
|
||||
if ($pos !== false) {
|
||||
$membershipGroup = substr($value['dn'][0],3,$pos-3);
|
||||
$groups[] = $membershipGroup;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
\OCP\Util::writeLog('user_ldap', 'No search filter found on member url '.
|
||||
'of group ' . $dnGroup, \OCP\Util::DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$groups = array_unique($groups, SORT_LOCALE_STRING);
|
||||
$this->access->connection->writeToCache($cacheKey, $groups);
|
||||
|
||||
|
|
|
@ -79,6 +79,10 @@ OCA = OCA || {};
|
|||
$element: $('#ldap_group_member_assoc_attribute'),
|
||||
setMethod: 'setGroupMemberAssociationAttribute'
|
||||
},
|
||||
ldap_dynamic_group_member_url: {
|
||||
$element: $('#ldap_dynamic_group_member_url'),
|
||||
setMethod: 'setDynamicGroupMemberURL'
|
||||
},
|
||||
ldap_nested_groups: {
|
||||
$element: $('#ldap_nested_groups'),
|
||||
setMethod: 'setUseNestedGroups'
|
||||
|
@ -244,6 +248,15 @@ OCA = OCA || {};
|
|||
this.setElementValue(this.managedItems.ldap_group_member_assoc_attribute.$element, attribute);
|
||||
},
|
||||
|
||||
/**
|
||||
* sets the dynamic group member url attribute
|
||||
*
|
||||
* @param {string} attribute
|
||||
*/
|
||||
setDynamicGroupMemberURL: function(attribute) {
|
||||
this.setElementValue(this.managedItems.ldap_dynamic_group_member_url.$element, attribute);
|
||||
},
|
||||
|
||||
/**
|
||||
* enabled or disables the use of nested groups (groups in groups in
|
||||
* groups…)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* @author Lukas Reschke <lukas@owncloud.com>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Robin McCorkell <robin@mccorkell.me.uk>
|
||||
* @author Richard Bentley <rbentley@e2advance.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
|
@ -83,6 +84,7 @@ class Configuration {
|
|||
'lastJpegPhotoLookup' => null,
|
||||
'ldapNestedGroups' => false,
|
||||
'ldapPagingSize' => null,
|
||||
'ldapDynamicGroupMemberURL' => null,
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -439,6 +441,7 @@ class Configuration {
|
|||
'ldap_nested_groups' => 0,
|
||||
'ldap_paging_size' => 500,
|
||||
'ldap_experienced_admin' => 0,
|
||||
'ldap_dynamic_group_member_url' => '',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -492,7 +495,8 @@ class Configuration {
|
|||
'last_jpegPhoto_lookup' => 'lastJpegPhotoLookup',
|
||||
'ldap_nested_groups' => 'ldapNestedGroups',
|
||||
'ldap_paging_size' => 'ldapPagingSize',
|
||||
'ldap_experienced_admin' => 'ldapExperiencedAdmin'
|
||||
'ldap_experienced_admin' => 'ldapExperiencedAdmin',
|
||||
'ldap_dynamic_group_member_url' => 'ldapDynamicGroupMemberURL',
|
||||
);
|
||||
return $array;
|
||||
}
|
||||
|
|
|
@ -90,6 +90,7 @@ style('user_ldap', 'settings');
|
|||
<p><label for="ldap_base_groups"><?php p($l->t('Base Group Tree'));?></label><textarea id="ldap_base_groups" name="ldap_base_groups" placeholder="<?php p($l->t('One Group Base DN per line'));?>" data-default="<?php p($_['ldap_base_groups_default']); ?>" title="<?php p($l->t('Base Group Tree'));?>"></textarea></p>
|
||||
<p><label for="ldap_attributes_for_group_search"><?php p($l->t('Group Search Attributes'));?></label><textarea id="ldap_attributes_for_group_search" name="ldap_attributes_for_group_search" placeholder="<?php p($l->t('Optional; one attribute per line'));?>" data-default="<?php p($_['ldap_attributes_for_group_search_default']); ?>" title="<?php p($l->t('Group Search Attributes'));?>"></textarea></p>
|
||||
<p><label for="ldap_group_member_assoc_attribute"><?php p($l->t('Group-Member association'));?></label><select id="ldap_group_member_assoc_attribute" name="ldap_group_member_assoc_attribute" data-default="<?php p($_['ldap_group_member_assoc_attribute_default']); ?>" ><option value="uniqueMember"<?php if (isset($_['ldap_group_member_assoc_attribute']) && ($_['ldap_group_member_assoc_attribute'] === 'uniqueMember')) p(' selected'); ?>>uniqueMember</option><option value="memberUid"<?php if (isset($_['ldap_group_member_assoc_attribute']) && ($_['ldap_group_member_assoc_attribute'] === 'memberUid')) p(' selected'); ?>>memberUid</option><option value="member"<?php if (isset($_['ldap_group_member_assoc_attribute']) && ($_['ldap_group_member_assoc_attribute'] === 'member')) p(' selected'); ?>>member (AD)</option></select></p>
|
||||
<p><label for="ldap_dynamic_group_member_url"><?php p($l->t('Dynamic Group Member URL'));?></label><input type="text" id="ldap_dynamic_group_member_url" name="ldap_dynamic_group_member_url" title="<?php p($l->t('The LDAP attribute that on group objects contains an LDAP search URL that determines what objects belong to the group. (An empty setting disables dynamic group membership functionality.)'));?>" data-default="<?php p($_['ldap_dynamic_group_member_url_default']); ?>" /></p>
|
||||
<p><label for="ldap_nested_groups"><?php p($l->t('Nested Groups'));?></label><input type="checkbox" id="ldap_nested_groups" name="ldap_nested_groups" value="1" data-default="<?php p($_['ldap_nested_groups_default']); ?>" title="<?php p($l->t('When switched on, groups that contain groups are supported. (Only works if the group member attribute contains DNs.)'));?>" /></p>
|
||||
<p><label for="ldap_paging_size"><?php p($l->t('Paging chunksize'));?></label><input type="number" id="ldap_paging_size" name="ldap_paging_size" title="<?php p($l->t('Chunksize used for paged LDAP searches that may return bulky results like user or group enumeration. (Setting it 0 disables paged LDAP searches in those situations.)'));?>" data-default="<?php p($_['ldap_paging_size_default']); ?>" /></p>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue