LDAP Nested groups

#1

Hello,

As the documentation states that to get that feature, we need to do a PR, I expect things to be more complicated that what I may have found. So I would like more insights before proposing something.

To avoid way too much modifications, I was just planning on flattening groups: getting members like today, but also recursively adding groups members of the first one.

For the resolution User => Groups (Core/Ldap/User::getGroups): search all direct group from the user (same as currently). then, recursively process every found group

For the resolution Group => Users, that seems to be done from database. So is there any change to be made ?

From what I dug, the authentication sequence is done like this :

Controller/AuthController :: check
  Validator/AuthValidator :: validateCredentials
    Core/Security/AuthenticationManager :: passwordAuthentication($formUser, $formPassword, $fireEvent=true)
      Auth/LdapAuth :: authenticate
        Core/Ldap/Client.php :: authenticate( userDn, formPassword)
      Core/User/UserProfile :: initialize( Core/Ldap/User :: getUser($formUser) )
          Core/User/UserSync :: synchronize($userProviderObject)
          Core/User/GroupSync :: synchronize($userId, $user::getExternalGroupIds() )
          Core/User/UserSession :: initialize($profile)
          dispatch(EVENT_USER_PROFILE_AFTER_SYNC, new UserProfileSyncEvent($profile, $user) )

Seems the group membership resolution is done when the user logs-on, So, the stubs we are looking for are Core/Ldap/User::getGroups, called from :

Core/User/GroupSync :: synchronize($userId, $user::getExternalGroupIds() )
  Core/Ldap/User::getGroups()

Is there any way to do the sync of users & groups during cronjob ?
And it would be nice to add the users that are members of some groups, that way we won’t have to wait for them to login to see them in the groups.

Thanks for your insights.

Adrien.

0 Likes

#2

Ok, something like this seems to be working for me :

protected function getGroupsRecursive(Entry $entry, $member, &$groupsAll)  
{    
        
    $groups = $this->group->find(sprintf($this->getGroupUserFilter(), $member));    

    foreach ($groups as $group) {    
        $groupId = $group->getExternalId();    

        if (!isset($groupsAll[$groupId])) {    
            $groupsAll[$groupId] = $member;    
            $this->getGroupsRecursive($entry, $groupId, $groupsAll);       
        }    
    }    
}    
protected function getGroups(Entry $entry, $username)    
{    
    $groupIds = array();    

    if (! empty($username) && $this->group !== null && $this->hasGroupUserFilter()) {    
        $this->getGroupsRecursive($entry, $entry->getDn(), $groupIds);     
        $groupIds = array_keys($groupIds);      
    } else {    
        $groupIds = $entry->getAll($this->getAttributeGroup());    
    }    

    return $groupIds;    
  }

Note that I have changed the “$username” used in fields like “memberUid” by “$entry->getDn()” to get the DN, that is used for “member” & “memberOf” overlay.
To keep it working in all cases, I’ll try to add an array_merge between the 2 groups (username & userDn) that will be filtered by the LDAP_GROUP_USER_FILTER configured by user.

Adrien.

0 Likes