From 1eddf95d955b2b259081bbd4bdf49c122d22f749 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Mon, 25 Feb 2013 16:46:31 +0100 Subject: [PATCH] LDAP : update user sync + add groups sync and users associated to group + add fetch by name on group class --- htdocs/user/class/usergroup.class.php | 18 +- scripts/user/sync_groups_ldap2dolibarr.php | 247 +++++++++++++++++++++ scripts/user/sync_users_ldap2dolibarr.php | 6 +- 3 files changed, 264 insertions(+), 7 deletions(-) create mode 100755 scripts/user/sync_groups_ldap2dolibarr.php diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index 206c8bffcf3..5876e05a213 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -66,18 +66,24 @@ class UserGroup extends CommonObject /** * Charge un objet group avec toutes ces caracteristiques (excpet ->members array) * - * @param int $id id du groupe a charger - * @return int <0 if KO, >0 if OK + * @param int $id id du groupe a charger + * @param string $groupname nom du groupe a charger + * @return int <0 if KO, >0 if OK */ - function fetch($id) + function fetch($id='', $groupname='') { global $conf; - $this->id = $id; - $sql = "SELECT g.rowid, g.entity, g.nom as name, g.note, g.datec, g.tms as datem"; $sql.= " FROM ".MAIN_DB_PREFIX."usergroup as g"; - $sql.= " WHERE g.rowid = ".$this->id; + if ($groupname) + { + $sql.= " WHERE g.nom = '".$this->db->escape($groupname)."'"; + } + else + { + $sql.= " WHERE g.rowid = ".$id; + } dol_syslog(get_class($this)."::fetch sql=".$sql); $result = $this->db->query($sql); diff --git a/scripts/user/sync_groups_ldap2dolibarr.php b/scripts/user/sync_groups_ldap2dolibarr.php new file mode 100755 index 00000000000..c19999c755f --- /dev/null +++ b/scripts/user/sync_groups_ldap2dolibarr.php @@ -0,0 +1,247 @@ +#!/usr/bin/php + + * Copyright (C) 2006-2012 Laurent Destailleur + * Copyright (C) 2013 Maxime Kohlhaas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file scripts/user/sync_groups_ldap2dolibarr.php + * \ingroup ldap member + * \brief Script to update groups into Dolibarr from LDAP + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit; +} + + + + +// Main + +$version='1.14'; +@set_time_limit(0); +$error=0; +$forcecommit=0; + +require_once($path."../../htdocs/master.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php"); +require_once(DOL_DOCUMENT_ROOT."/user/class/user.class.php"); +require_once(DOL_DOCUMENT_ROOT."/user/class/usergroup.class.php"); + +$langs->load("main"); +$langs->load("errors"); + +// List of fields to get from LDAP +$required_fields = array( + $conf->global->LDAP_KEY_GROUPS, + $conf->global->LDAP_GROUP_FIELD_FULLNAME, + $conf->global->LDAP_GROUP_FIELD_DESCRIPTION, + $conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS +); + +// Remove from required_fields all entries not configured in LDAP (empty) and duplicated +$required_fields=array_unique(array_values(array_filter($required_fields, "dolValidElement"))); + +if ($argv[2]) $conf->global->LDAP_SERVER_HOST=$argv[2]; + +print "***** $script_file ($version) *****\n"; + +if (! isset($argv[1])) { + //print "Usage: $script_file (nocommitiferror|commitiferror) [id_group]\n"; + print "Usage: $script_file (nocommitiferror|commitiferror) [ldapserverhost]\n"; + exit; +} +$groupid=$argv[3]; +if ($argv[1] == 'commitiferror') $forcecommit=1; + + +print "Mails sending disabled (useless in batch mode)\n"; +$conf->global->MAIN_DISABLE_ALL_MAILS=1; // On bloque les mails +print "\n"; +print "----- Synchronize all records from LDAP database:\n"; +print "host=".$conf->global->LDAP_SERVER_HOST."\n"; +print "port=".$conf->global->LDAP_SERVER_PORT."\n"; +print "login=".$conf->global->LDAP_ADMIN_DN."\n"; +print "pass=".preg_replace('/./i','*',$conf->global->LDAP_ADMIN_PASS)."\n"; +print "DN to extract=".$conf->global->LDAP_GROUP_DN."\n"; +print 'Filter=('.$conf->global->LDAP_KEY_GROUPS.'=*)'."\n"; +print "----- To Dolibarr database:\n"; +print "type=".$conf->db->type."\n"; +print "host=".$conf->db->host."\n"; +print "port=".$conf->db->port."\n"; +print "login=".$conf->db->user."\n"; +print "database=".$conf->db->name."\n"; +print "----- Options:\n"; +print "commitiferror=".$forcecommit."\n"; +print "Mapped LDAP fields=".join(',',$required_fields)."\n"; +print "\n"; +print "Press a key to confirm..."; +$input = trim(fgets(STDIN)); +print "Hit Enter to continue or CTRL+C to stop...\n"; +$input = trim(fgets(STDIN)); + + +if (empty($conf->global->LDAP_GROUP_DN)) +{ + print $langs->trans("Error").': '.$langs->trans("LDAP setup for groups not defined inside Dolibarr"); + exit(1); +} + + +$ldap = new Ldap(); +$result = $ldap->connect_bind(); +if ($result >= 0) +{ + $justthese=array(); + + + // We disable synchro Dolibarr-LDAP + $conf->global->LDAP_SYNCHRO_ACTIVE=0; + + $ldaprecords = $ldap->getRecords('*',$conf->global->LDAP_GROUP_DN, $conf->global->LDAP_KEY_GROUPS, $required_fields, 0, array($conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS)); + if (is_array($ldaprecords)) + { + $db->begin(); + + // Warning $ldapuser has a key in lowercase + foreach ($ldaprecords as $key => $ldapgroup) + { + $group = new UserGroup($db); + $group->fetch('', $ldapgroup[$conf->global->LDAP_KEY_GROUPS]); + $group->nom = $ldapgroup[$conf->global->LDAP_GROUP_FIELD_FULLNAME]; + $group->note = $ldapgroup[$conf->global->LDAP_GROUP_FIELD_DESCRIPTION]; + $group->entity = $conf->entity; + + //print_r($ldapgroup); + + if($group->id > 0) { // Group update + print $langs->transnoentities("GroupUpdate").' # '.$key.': name='.$group->nom; + $res=$group->update(); + + if ($res > 0) + { + print ' --> Updated group id='.$group->id.' name='.$group->nom; + } + else + { + $error++; + print ' --> '.$res.' '.$group->error; + } + print "\n"; + } else { // Group creation + print $langs->transnoentities("GroupCreate").' # '.$key.': name='.$group->nom; + $res=$group->create(); + + if ($res > 0) + { + print ' --> Created group id='.$group->id.' name='.$group->nom; + } + else + { + $error++; + print ' --> '.$res.' '.$group->error; + } + print "\n"; + } + + //print_r($group); + + // Gestion des utilisateurs associés au groupe + // 1 - Association des utilisateurs du groupe LDAP au groupe Dolibarr + $userList = array(); + $userIdList = array(); + foreach($ldapgroup[$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS] as $key => $userdn) { + if($key == 'count') continue; + if(empty($userList[$userdn])) { // Récupération de l'utilisateur + $userFilter = explode(',', $userdn); + $userKey = $ldap->getAttributeValues('('.$userFilter[0].')', $conf->global->LDAP_KEY_USERS); + + $fuser = new User($db); + + if($conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_SID) { + $fuser->fetch('','',$userKey[0]); // Chargement du user concerné par le SID + } else if($conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_LOGIN) { + $fuser->fetch('',$userKey[0]); // Chargement du user concerné par le login + } + + $userList[$userdn] = &$fuser; + } else { + $fuser = &$userList[$userdn]; + } + + $userIdList[$userdn] = $fuser->id; + + // Ajout de l'utilisateur dans le groupe + if(!in_array($fuser->id, array_keys($group->members))) $fuser->SetInGroup($group->id, $group->entity); + } + + // 2 - Suppression des utilisateurs du groupe Dolibarr qui ne sont plus dans le groupe LDAP + foreach ($group->members as $user_id => $infos) { + if(!in_array($user_id, $userIdList)) $fuser->RemoveFromGroup($group->id, $group->entity); + } + } + + if (! $error || $forcecommit) + { + if (! $error) print $langs->transnoentities("NoErrorCommitIsDone")."\n"; + else print $langs->transnoentities("ErrorButCommitIsDone")."\n"; + $db->commit(); + } + else + { + print $langs->transnoentities("ErrorSomeErrorWereFoundRollbackIsDone",$error)."\n"; + $db->rollback(); + } + print "\n"; + } + else + { + dol_print_error('',$ldap->error); + $error++; + } +} +else +{ + dol_print_error('',$ldap->error); + $error++; +} + + +return $error; + + +/** + * Function to say if a value is empty or not + * + * @param string $element Value to test + * @return boolean True of false + */ +function dolValidElement($element) +{ + return (trim($element) != ''); +} + +?> diff --git a/scripts/user/sync_users_ldap2dolibarr.php b/scripts/user/sync_users_ldap2dolibarr.php index 1f9360f013a..64bea3ca567 100755 --- a/scripts/user/sync_users_ldap2dolibarr.php +++ b/scripts/user/sync_users_ldap2dolibarr.php @@ -179,7 +179,11 @@ if ($result >= 0) { $fuser = new User($db); - $fuser->fetch('','',$ldapuser[$conf->global->LDAP_KEY_USERS]); // Chargement du user concerné + if($conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_SID) { + $fuser->fetch('','',$ldapuser[$conf->global->LDAP_KEY_USERS]); // Chargement du user concerné par le SID + } else if($conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_LOGIN) { + $fuser->fetch('',$ldapuser[$conf->global->LDAP_KEY_USERS]); // Chargement du user concerné par le login + } // Propriete membre $fuser->firstname=$ldapuser[$conf->global->LDAP_FIELD_FIRSTNAME];