Skip to content
Merged
Prev Previous commit
Next Next commit
Reduce queries to LDAP by caching nested groups
Nested groups are now cached in a CappedMemoryCache object to reduce
queries to the LDAP backend.

Signed-off-by: Roland Tapken <[email protected]>
  • Loading branch information
Roland Tapken authored and blizzz committed Mar 5, 2019
commit e7c506cff100b588e1943bd7dbaef2ef687a1bfb
24 changes: 18 additions & 6 deletions apps/user_ldap/lib/Group_LDAP.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ class Group_LDAP extends BackendUtility implements \OCP\GroupInterface, IGroupLD
*/
protected $cachedGroupsByMember;

/**
* @var string[] $cachedNestedGroups array of groups with gid (DN) as key
*/
protected $cachedNestedGroups;

/** @var GroupPluginManager */
protected $groupPluginManager;

Expand All @@ -71,6 +76,7 @@ public function __construct(Access $access, GroupPluginManager $groupPluginManag

$this->cachedGroupMembers = new CappedMemoryCache();
$this->cachedGroupsByMember = new CappedMemoryCache();
$this->cachedNestedGroups = new CappedMemoryCache();
$this->groupPluginManager = $groupPluginManager;
}

Expand Down Expand Up @@ -257,8 +263,8 @@ private function _getGroupDNsFromMemberOf($DN) {
if (!is_array($groups)) {
return array();
}
$nestedGroups = $this->access->connection->ldapNestedGroups;
if ((int)$nestedGroups === 1) {
$nestedGroups = (int) $this->access->connection->ldapNestedGroups;
if ($nestedGroups === 1) {
$seen = array();
while ($group = array_pop($groups)) {
if ($group === $DN || array_key_exists($group, $seen)) {
Expand All @@ -268,11 +274,17 @@ private function _getGroupDNsFromMemberOf($DN) {
$seen[$group] = 1;

// Resolve nested groups
$nestedGroups = $this->access->readAttribute($group, 'memberOf');
if (is_array($nestedGroups)) {
foreach ($nestedGroups as $nestedGroup) {
array_push($groups, $nestedGroup);
if (isset($cachedNestedGroups[$group])) {
$nestedGroups = $cachedNestedGroups[$group];
} else {
$nestedGroups = $this->access->readAttribute($group, 'memberOf');
if (!is_array($nestedGroups)) {
$nestedGroups = [];
}
$cachedNestedGroups[$group] = $nestedGroups;
}
foreach ($nestedGroups as $nestedGroup) {
array_push($groups, $nestedGroup);
}
}
// Get unique group DN's from those we have visited in the loop
Expand Down