Artturi Markko
|
Saturday 13 May 2006 6:26:03 am
Hello,
I have set up EzPublish with ldap authentication and I had to map existing ldap groups to the groups I have created in Ez. From what I've read in the forums, mappings can only be achieved by retrieving an attribute on the ldap user object (employeetype is mentionned).
In consequence, I have written a small piece of code in kernel/classes/datatypes/ezuser/ezldapuser.php in order to retrieve the group memberships of the user who logs in. <b>With the mappings defined in ldap.ini, this code fills the $extraNodeAssignments variable</b>.
<i>The contrib is in three parts</i> :
- additionnal settings in ldap.ini
- a recursive function that looks for groups (it's recursive to handle the case of nested groups). This function is placed outside of the "eZLDAPUser" class. - a call to this function in the "loginUser" method of "eZLDAPUser" class First, here is what I've added in ldap.ini :
LDAPUserGroupAM[]
LDAPUserGroupAM[]=ldapgroup1--ezgroup1
LDAPUserGroupAM[]=ldapgroup2--ezgrp2
Here's the function :
function mapInEzGroups($filter, $LDAPBaseDN, &$ds, &$db, &$ldap2ez, &$extraNodeAssignments, $depth = 0)
{
$retrieve = array("cn"); // that's the groups name
$sr2 = ldap_search( $ds, $LDAPBaseDN, $filter, $retrieve );
$info2 = ldap_get_entries( $ds, $sr2 );
$newfilter = '(&(objectClass=group)(|';
$max = count($info2);
// I loop on the found groups and check if I have a mapping defined for it
for ( $i = 0; $i < $max; $i++ )
{
if ( is_null( $info2[ $i ] ) ) continue;
$ldapGroupName = $info2[$i]['cn'][0];
if ( array_key_exists($ldapGroupName, $ldap2ez) ) // is there a mapping ? --> ldap2ez holds the mappings
{
$groupName = $ldap2ez[$ldapGroupName];
$groupQuery = "SELECT ezcontentobject_tree.node_id
FROM ezcontentobject, ezcontentobject_tree
WHERE ezcontentobject.name like '$groupName'
AND ezcontentobject.id=ezcontentobject_tree.contentobject_id
AND ezcontentobject.contentclass_id=3";
$groupObject = $db->arrayQuery( $groupQuery );
if ( count( $groupObject ) > 0 )
{
$extraNodeAssignments[] = $groupObject[0]['node_id'];
}
}
$newfilter .= '(member=' . $info2[$i]['dn'] . ')';
}
// If groups are found, I also check if they are nested in other groups, limited to a depth of 30
if ( $depth < 30 && $max > 0 )
{
$newfilter .= '))';
mapInEzGroups($newfilter, $LDAPBaseDN, $ds, $db, $ldap2ez, $extraNodeAssignments, ( $depth + 1));
}
}
And in the "eZLDAPUser" class :
$LDAPUserGroupAML = $LDAPIni->variable( 'LDAPSettings', 'LDAPUserGroupAML' );
// ...
// ** existing code, just to show where it happens ***//
// authenticated user
if ( !@ldap_bind( $ds, $info[0]['dn'], $password ) )
{
$user = false;
return $user;
}
// ** added code follows :
if ( $LDAPUserGroupAM != null )
{
foreach ( $LDAPUserGroupAM as $value)
{
$r = explode("--", $value);
$ldap2ez[$r[0]] = $r[1];
}
// filter looking for groups the user is member of
$filter = "(&(objectClass=group)(member=" . $info[0]['dn'] . "))";
// this function fills the $extraNodeAssignments variable
mapInEzGroups($filter, $LDAPBaseDN, $ds, $db, $ldap2ez, $extraNodeAssignments);
}
Artturi
|
Artturi Markko
|
Saturday 13 May 2006 6:37:56 am
Just a note to mention that while I've tested this code, I would welcome some critics about it.
There's also a catch about how it works in this form :
- upon user creation, mappings are done as I expect - <b>if user exists in EZ before a mapping is created</b>, this mapping won't apply
This is due to the fact that $extraNodeAssignments is not used when user is updated. It is only used when user is created. Would somebody know how to improve that because I'm a total newbie in Ez developpment and can't see how to do that ? Best regards, Artturi
|