Artturi Markko
|
Sunday 14 May 2006 3:36:29 am
Hello,
I am working on a modified version of ldapusermanage.php in order to add/remove ldap originated users in the right ez groups (according to defined mappings, see post :
http://ez.no/community/forum/developer/contrib_ldap_group_mappings ) Adding a user to a group seems to be ok but not for the removal. Here's a code snippet :
$newVersion = $contentObject->createNewVersion();
$newVersionNr = $newVersion->attribute( 'version' );
$nodeAssignmentList =& $newVersion->attribute( 'node_assignments' );
//var_dump($nodeAssignmentList);
foreach ( array_keys( $nodeAssignmentList ) as $key )
{
$nodeAssignment =& $nodeAssignmentList[$key];
$nodeAssignment->remove();
}
I'm able to find out which groups each user has to be deleted from, even if that's not so important as the foreach loop mentioned above removes all nodeAssignments. In the new version of the user, all assignments are "re-created" from what has been computed in the script. My problem is that it does not seem to be taken into account at 100%. 1) When I connect to the Admin interface, in the Users section, I still see the users in the groups they should no longer be member of 2) On the other hand, when I check the user's properties, in the "location" box, removed groups don't show up. Seems the cleaning in only half way done. Anyone have a hint about how to finish that ? Thanks in advance, Artturi
|
Artturi Markko
|
Monday 15 May 2006 12:27:40 pm
Hi Kristof, Yes, the links are still valid
> What do you get when you click on such a child node that is supposed to be removed? I get the user properties. In those, I can see under "Locations [2]" a list of the groups the user belongs to (and this list is correct)
> Maybe it's some caching issue. I've cleared all the cache but user is still where it should not.
Anyway, i DO have caching issues with my ldap search. When I modify a group on the ldap server, I have to clear "content", "content node" and "content subtree" cache in order to detect my modifications. Any idea about that ? Here's the code if it can help :
$db->begin();
foreach ( array_keys ( $LDAPUsers ) as $key )
{
$LDAPUser =& $LDAPUsers[$key];
$login = $LDAPUser['login'];
$userID = $LDAPUser['contentobject_id'];
$LDAPFilter = "( &";
if ( count( $LDAPFilters ) > 0 )
{
foreach ( array_keys( $LDAPFilters ) as $key )
{
$LDAPFilter .= "(" . $LDAPFilters[$key] . ")";
}
}
$LDAPFilter .= "($LDAPLogin=$login)";
$LDAPFilter .= ")";
$LDAPFilter = str_replace( $LDAPEqualSign, "=", $LDAPFilter );
if ( $LDAPSearchScope == "one" )
$sr = ldap_list( $ds, $LDAPBaseDN, $LDAPFilter, $attributeArray );
else if ( $LDAPSearchScope == "base" )
$sr = ldap_read( $ds, $LDAPBaseDN, $LDAPFilter, $attributeArray );
else
$sr = ldap_search( $ds, $LDAPBaseDN, $LDAPFilter, $attributeArray );
$info = ldap_get_entries( $ds, $sr );
if ( $info["count"] != 1 )
{
$cli->output( "Disable user " . $cli->stylize( 'emphasize', $login ) );
// Disable the user
$userSetting = eZUserSetting::fetch( $userID );
$userSetting->setAttribute( "is_enabled", false );
$userSetting->store();
}
else
{
// Update user information
$contentObject =& eZContentObject::fetch( $userID );
$parentNodeID = $contentObject->attribute( 'main_parent_node_id' );
$currentVersion = $contentObject->attribute( 'current_version' );
$version =& $contentObject->attribute( 'current' );
$contentObjectAttributes =& $version->contentObjectAttributes();
if ( $isUtf8Encoding )
{
$firstName = utf8_decode( $info[0][$LDAPFirstNameAttribute][0] );
$lastName = utf8_decode( $info[0][$LDAPLastNameAttribute][0] );
$ldapEMail = utf8_decode( $info[0][$LDAPEmailAttribute][0] );
}
else
{
$firstName = $info[0][$LDAPFirstNameAttribute][0];
$lastName = $info[0][$LDAPLastNameAttribute][0];
$ldapEMail = $info[0][$LDAPEmailAttribute][0];
}
$contentObjectAttributes[0]->setAttribute( 'data_text', $firstName );
$contentObjectAttributes[0]->store();
$contentObjectAttributes[1]->setAttribute( 'data_text', $lastName );
$contentObjectAttributes[1]->store();
$contentClass =& $contentObject->attribute( 'content_class' );
$name = $contentClass->contentObjectName( $contentObject );
$contentObject->setName( $name );
$existUser = eZUser::fetch( $userID );
$existUser->setAttribute('email', $ldapEMail );
$existUser->setAttribute('password_hash', "" );
$existUser->setAttribute('password_hash_type', 0 );
$existUser->store();
/** DETECT if mappings are defined in ldap.ini **/
if ( $LDAPUserGroupAM != null )
{
$republishRequired = false;
$IsLDAPMain = true;
$hasOtherNodeType = false;
$hasLDAPNodeType = false;
$otherNodeArray = array();
$LDAPNodeArray = array();
$newLDAPNodeArray = array();
$parentNodes =& $contentObject->parentNodes( $currentVersion );;
foreach( array_keys( $parentNodes ) as $key )
{
$parentNode =& $parentNodes[$key];
$parentNodeID = $parentNode->attribute( 'node_id' );
$parentNodeName = $parentNode->attribute( 'name' );
$nodeAssignment = eZNodeAssignment::fetch( $contentObject->attribute( 'id' ), $currentVersion, $parentNodeID );
$isMain = $nodeAssignment->attribute( 'is_main' );
$remoteID = $nodeAssignment->attribute( 'parent_remote_id' );
if ( preg_match( "/LDAP/i", $remoteID ) )
{
$LDAPNodeArray[] = array( 'parent_node_name' => $parentNodeName, 'parent_node_id' => $parentNodeID, 'is_main' => $isMain );
}
else
{
$otherNodeArray[] = array( 'parent_node_name' => $parentNodeName, 'parent_node_id' => $parentNodeID, 'is_main' => $isMain );
$hasOtherNodeType = true;
if ( $isMain )
{
$IsLDAPMain = false;
}
}
}
/* Aim of the query : get all the node_id of the mapped groups in ldap.ini */
$query = "SELECT ezcontentobject_tree.node_id
FROM ezcontentobject, ezcontentobject_tree
WHERE ezcontentobject.name IN ( ";
foreach ( $LDAPUserGroupAML as $value)
{
$r = explode("--", $value);
$ldap2ez[$r[0]] = $r[1];
$query .= "'" . $r[1] . "',";
}
$query = substr($query,0, -1) . ") AND ezcontentobject.id=ezcontentobject_tree.contentobject_id AND ezcontentobject.contentclass_id=3";
$allMappedGroups = $db->arrayQuery( $query );
$extraNodeAssignments = array();
$removeAssignments = array();
$LDAPUserGroupCount = count( $LDAPNodeArray );
$filter = "(&(objectClass=group)(member=" . $info[0]['dn'] . "))";
mapInEzGroups($filter, $LDAPBaseDN, $ds, $db, $ldap2ez, $extraNodeAssignments);
/** Find out which groups the user must not belong to **/
foreach ( array_keys($allMappedGroups) as $key )
{
if ( in_array($allMappedGroups[$key]['node_id'], $extraNodeAssignments) )
{
continue;
}
foreach ( array_keys($LDAPNodeArray) as $key2 )
{
if ( in_array($allMappedGroups[$key]['node_id'], $LDAPNodeArray[$key2]) )
{
$removeAssignments[] = $allMappedGroups[$key]['node_id'];
}
}
}
var_dump($extraNodeAssignments, $removeAssignments);
// count the number of "ez mapped groups" the user has to belong to
$groupCount = count( $extraNodeAssignments );
for ( $i = 0; $i < $groupCount ; $i++ )
{
/* check for all "ldap originated groups" the user already belongs to,
with the assumption it does not exist in $extraNodeAssignments */
$exist = false;
foreach( $LDAPNodeArray as $LDAPNode )
{
$existGroupName = $LDAPNode['parent_node_name'];
$existGroupID = $LDAPNode['parent_node_id'];
if ( strcasecmp( $existGroupID, $extraNodeAssignments[$i] ) == 0 )
{
$exist = true;
$hasLDAPNodeType = true;
if ( $IsLDAPMain and count( $newLDAPNodeArray ) == 0 )
{
$newLDAPNodeArray[] = array( 'parent_node_name' => $existGroupName, 'parent_node_id' => $existGroupID, 'is_main' => 1 );
}
else
{
$newLDAPNodeArray[] = array( 'parent_node_name' => $existGroupName, 'parent_node_id' => $existGroupID, 'is_main' => 0 );
}
$LDAPUserGroupCount--;
}
}
if ( $exist == false )
{
// Get the name from the id : this differs in order to use already written 'mapInEzGroups' function which returns an array of ids
$groupQuery = "SELECT ezcontentobject.name
FROM ezcontentobject, ezcontentobject_tree
WHERE ezcontentobject_tree.node_id=$extraNodeAssignments[$i]
AND ezcontentobject.id=ezcontentobject_tree.contentobject_id
AND ezcontentobject.contentclass_id=3";
$groupObject = $db->arrayQuery( $groupQuery );
if ( count( $groupObject ) > 0 )
{
$hasLDAPNodeType = true;
if ( $IsLDAPMain and count( $newLDAPNodeArray ) == 0 )
{
$newLDAPNodeArray[] = array( 'parent_node_name' => $groupObject[0]['name'], 'parent_node_id' => $extraNodeAssignments[$i], 'is_main' => 1 );
}
else
{
$newLDAPNodeArray[] = array( 'parent_node_name' => $groupObject[0]['name'], 'parent_node_id' => $extraNodeAssignments[$i], 'is_main' => 0 );
}
$republishRequired = true;
}
}
}
if ( $LDAPUserGroupCount != 0 || count($removeAssignments) > 0)
{
$republishRequired = true;
}
if ( $republishRequired )
{
$newVersion = $contentObject->createNewVersion();
$newVersionNr = $newVersion->attribute( 'version' );
$nodeAssignmentList =& $newVersion->attribute( 'node_assignments' );
// ok, here should be the BIG CLEANUP, but seems incomplete by juding of the result in admin interface (user still sits in the group).
foreach ( array_keys( $nodeAssignmentList ) as $key )
{
$nodeAssignment =& $nodeAssignmentList[$key];
$nodeAssignment->remove();
}
if ( $hasOtherNodeType )
{
foreach ( $otherNodeArray as $otherNode )
{
$newVersion->assignToNode( $otherNode['parent_node_id'], $otherNode['is_main'] );
}
}
if ( $hasLDAPNodeType )
{
foreach ( $newLDAPNodeArray as $newLDAPNode )
{
$newVersion->assignToNode( $newLDAPNode['parent_node_id'], $newLDAPNode['is_main'] );
$assignment = eZNodeAssignment::fetch( $contentObject->attribute( 'id' ), $newVersionNr, $newLDAPNode['parent_node_id'] );
$assignment->setAttribute( 'parent_remote_id', "LDAP_" . $newLDAPNode['parent_node_id'] );
$assignment->store();
}
}
if ( !$hasOtherNodeType and !$hasLDAPNodeType )
{
$newVersion->assignToNode( $defaultUserPlacement, 1 );
}
include_once( 'lib/ezutils/classes/ezoperationhandler.php' );
$operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $userID,
'version' => $newVersionNr ) );
$cli->output( $cli->stylize( 'emphasize', $existUser->attribute('login') ) . " has changed group, updated." );
}
}
}
}
$db->commit();
|