contrib : ldap group mappings

Author Message

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

Artturi Markko

Sunday 14 May 2006 3:38:47 am

Reply to myself : I've found that an existing cronjob script is in charge of the update :

cronjobs/ldapusermanage.php

However, things are not 100% ok for me as group removal does not work as I expect.
If interested, see this post :
http://ez.no/community/forum/developer/node_group_assignment_how_to_remove_correctly

Regards,

Artturi

Powered by eZ Publish™ CMS Open Source Web Content Management. Copyright © 1999-2014 eZ Systems AS (except where otherwise noted). All rights reserved.

eZ debug

Timing: Jan 18 2025 20:58:49
Script start
Timing: Jan 18 2025 20:58:49
Module start 'layout'
Timing: Jan 18 2025 20:58:49
Module start 'content'
Timing: Jan 18 2025 20:58:49
Module end 'content'
Timing: Jan 18 2025 20:58:49
Script end

Main resources:

Total runtime0.7610 sec
Peak memory usage4,096.0000 KB
Database Queries55

Timing points:

CheckpointStart (sec)Duration (sec)Memory at start (KB)Memory used (KB)
Script start 0.00000.0042 587.9141152.6250
Module start 'layout' 0.00420.0028 740.539139.4453
Module start 'content' 0.00700.7526 779.9844462.2578
Module end 'content' 0.75950.0014 1,242.242212.1641
Script end 0.7610  1,254.4063 

Time accumulators:

 Accumulator Duration (sec) Duration (%) Count Average (sec)
Ini load
Load cache0.00330.4381160.0002
Check MTime0.00140.1899160.0001
Mysql Total
Database connection0.00060.079610.0006
Mysqli_queries0.708993.1462550.0129
Looping result0.00050.0607530.0000
Template Total0.732696.320.3663
Template load0.00180.238820.0009
Template processing0.730796.021020.3654
Template load and register function0.00030.035010.0003
states
state_id_array0.00070.091710.0007
state_identifier_array0.00070.097620.0004
Override
Cache load0.00160.2060360.0000
Sytem overhead
Fetch class attribute can translate value0.00060.076310.0006
Fetch class attribute name0.00120.154130.0004
XML
Image XML parsing0.00010.014710.0001
class_abstraction
Instantiating content class attribute0.00000.001230.0000
General
dbfile0.00150.1930100.0001
String conversion0.00000.000840.0000
Note: percentages do not add up to 100% because some accumulators overlap

Templates used to render the page:

UsageRequested templateTemplateTemplate loadedEditOverride
1node/view/full.tplfull/forum_topic.tplextension/sevenx/design/simple/override/templates/full/forum_topic.tplEdit templateOverride template
3content/datatype/view/ezxmltext.tpl<No override>extension/community_design/design/suncana/templates/content/datatype/view/ezxmltext.tplEdit templateOverride template
12content/datatype/view/ezxmltags/paragraph.tpl<No override>extension/ezwebin/design/ezwebin/templates/content/datatype/view/ezxmltags/paragraph.tplEdit templateOverride template
6content/datatype/view/ezxmltags/line.tpl<No override>design/standard/templates/content/datatype/view/ezxmltags/line.tplEdit templateOverride template
3content/datatype/view/ezxmltags/literal.tpl<No override>extension/community/design/standard/templates/content/datatype/view/ezxmltags/literal.tplEdit templateOverride template
1print_pagelayout.tpl<No override>extension/community/design/community/templates/print_pagelayout.tplEdit templateOverride template
 Number of times templates used: 26
 Number of unique templates used: 6

Time used to render debug report: 0.0001 secs