EXTLDAP module : new LDAP implementaion with possibility of update at each login

skala
Noel Dieschburg 14 years ago
parent 76695e992e
commit 085e9c6414
  1. 1
      index.php
  2. 51
      main/auth/external_login/functions.inc.php
  3. 96
      main/auth/external_login/ldap.conf.php
  4. 165
      main/auth/external_login/ldap.inc.php
  5. 65
      main/auth/external_login/login.ldap.php
  6. 66
      main/auth/external_login/newUser.ldap.php

@ -23,7 +23,6 @@ $cidReset = true;
/** @todo Make all the library files consistent, use filename.lib.php and not filename.lib.inc.php. */ /** @todo Make all the library files consistent, use filename.lib.php and not filename.lib.inc.php. */
require_once 'main/inc/global.inc.php'; require_once 'main/inc/global.inc.php';
require_once api_get_path(LIBRARY_PATH).'course.lib.php'; require_once api_get_path(LIBRARY_PATH).'course.lib.php';
require_once api_get_path(LIBRARY_PATH).'events.lib.inc.php'; require_once api_get_path(LIBRARY_PATH).'events.lib.inc.php';
require_once api_get_path(LIBRARY_PATH).'system_announcements.lib.php'; require_once api_get_path(LIBRARY_PATH).'system_announcements.lib.php';

@ -1,6 +1,8 @@
<?php <?php
define('USERINFO_TABLE', 'danone_userinfo'); require_once(api_get_path(LIBRARY_PATH).'usermanager.lib.php');
define('DEFAULT_PASSWORD', 'danonelearning'); require_once(api_get_path(LIBRARY_PATH).'course.lib.php');
//define('USERINFO_TABLE', 'danone_userinfo');
//define('DEFAULT_PASSWORD', 'danonelearning');
//TODO : Please implements this function for this module to work. //TODO : Please implements this function for this module to work.
/** /**
@ -120,23 +122,52 @@ function external_add_user($u){
return $chamilo_uid; return $chamilo_uid;
} }
/** /**
* update user info in database * Update the user in chamilo database. It upgrade only info that is present in the
* new_user array
*
* @param $new_user associative array with the value to upgrade
* WARNING user_id key is MANDATORY
* Possible keys are :
* - firstname
* - lastname
* - username
* - auth_source
* - email
* - status
* - official_code
* - phone
* - picture_uri
* - expiration_date
* - active
* - creator_id
* - hr_dept_id
* - extra : array of custom fields
* - language
* - courses : string of all courses code separated by '|'
* - admin : boolean
* @return boolean
* @author ndiechburg <noel@cblue.be>
**/ **/
function external_update_user($u){ function external_update_user($new_user){
$old_user = UserManager::get_user_info_by_id($new_user['user_id']);
$u = array_merge($old_user, $new_user);
$updated = UserManager::update_user($u['user_id'], $u['firstname'], $u['lastname'], $u['username'], null, $u['auth_source'], $u['email'], $u['status'], $u['official_code'], $u['phone'], $u['picture_uri'], $u['expiration_date'], $u['active'], $u['creator_id'], $u['hr_dept_id'], $u['extra'], $u['language'],''); $updated = UserManager::update_user($u['user_id'], $u['firstname'], $u['lastname'], $u['username'], null, $u['auth_source'], $u['email'], $u['status'], $u['official_code'], $u['phone'], $u['picture_uri'], $u['expiration_date'], $u['active'], $u['creator_id'], $u['hr_dept_id'], $u['extra'], $u['language'],'');
if(!empty($user['courses'])){ if(isset($u['courses']) && !empty($u['courses'])){
$autoSubscribe = explode('|', $u['courses']); $autoSubscribe = explode('|', $u['courses']);
foreach ($autoSubscribe as $code) { foreach ($autoSubscribe as $code) {
if (CourseManager::course_exists($code)) { if (CourseManager::course_exists($code)) {
CourseManager::subscribe_user($_user['user_id'], $code); CourseManager::subscribe_user($u['user_id'], $code);
} }
} }
} }
// Is User Admin ? // Is User Admin ?
if ($user['admin']){ //TODO decomments and check that user_is is not already in admin table
$is_platformAdmin = true; /*
Database::query("INSERT INTO admin values ('$chamilo_uid')"); if (isset($u['admin']) && $u['admin']){
}
$table = Database::get_main_table(TABLE_MAIN_ADMIN);
$res = Database::query("SELECT * from $table WHERE user_id = ".$u['user_id']);
}*/
} }

@ -0,0 +1,96 @@
<?php // External login module : LDAP
/**
* Configuration file
* Please edit this file to match with your LDAP settings
**/
require_once(dirname(__FILE__).'/ldap.inc.php');
/**
* Array of connection parameters
**/
$extldap_config = array(
//base dommain string
'base_dn' => 'dc=cblue,dc=be',
//admin distinguished name
'admin_dn' => 'cn=admin,dc=cblue,dc=be',
//admin password
'admin_password' => 'Im2ocEGish',
//ldap host
'host' => '192.168.61.1',
//'port' => , default on 389
//protocl version (2 or 3)
'protocol_version' => 3,
//String used to search the user in ldap. %username will ber replaced by the username.
//See extldap_get_user_search_string() function below
'user_search' => 'uid=%username%',
//encoding used in ldap (most common are UTF-8 and ISO-8859-1
'encoding' => 'UTF-8',
//Set to true if user info have to be update at each login
'update_userinfo' => true
);
/**
* return the string used to search a user in ldap
*
* @param string username
* @return string the serach string
* @author ndiechburg <noel@cblue.be>
**/
function extldap_get_user_search_string($username)
{
global $extldap_config;
return str_replace('%username%',$username,$extldap_config['user_search']);
}
/**
* Correspondance array between chamilo user info and ldap user info
* This array is of this form :
* '<chamilo_field> => <ldap_field>
*
* If <ldap_field> is "func", then the value of <chamilo_field> will be the return value of the function
* extldap_get_<chamilo_field>($ldap_array)
* In this cas you will have to declare the extldap_get_<chamilo_field> function
*
* If <ldap_field> is a string beginning with "!", then the value will be this string without "!"
*
* If <ldap_field> is any other string then the value of <chamilo_field> will be
* $ldap_array[<ldap_field>][0]
*
* If <ldap_field> is an array then its value will be an array of values with the same rules as above
*
**/
$extldap_user_correspondance = array(
'firstname' => 'cn',
'lastname' => 'sn',
'status' => 'func',
'admin' => 'func',
'email' => 'mail',
'auth_source' => '!extldap',
//'username' => ,
'language' => '!english',
'password' => '!PLACEHOLDER',
'extra' => array(
'phone' => 'phone')
);
/**
* Please declare here all the function you use in extldap_user_correspondance
* All these functions must have an $ldap_user parameter. This parameter is the
* array returned by the ldap for the user
**/
/**
* example function for email
**/
/*
function extldap_get_email($ldap_user){
return $ldap_user['cn'].$ldap['sn'].'@gmail.com';
}
*/
function extldap_get_status($ldap_user){
return STUDENT;
}
function extldap_get_admin($ldap_user){
return false;
}
?>

@ -0,0 +1,165 @@
<?php // External login module : LDAP
/**
* This files is included by newUser.ldap.php and login.ldap.php
* It implements the functions nedded by both files
**/
//Includes the configuration file
require_once(dirname(__FILE__).'/../../inc/global.inc.php');
require_once(dirname(__FILE__).'/ldap.conf.php');
/**
* Returns a transcoded and trimmed string
*
* @param string
* @return string
* @author ndiechburg <noel@cblue.be>
**/
function extldap_purify_string($string)
{
global $extldap_config;
if(isset($extldap_config['encoding'])) {
return trim(api_to_system_encoding($string, $extldap_config['encoding']));
}
else {
return trim($string);
}
}
/**
* Establishes a connection to the LDAP server and sets the protocol version
*
* @return resource ldap link identifier or false
* @author ndiechburg <noel@cblue.be>
**/
function extldap_connect()
{
global $extldap_config;
//Trying to connect
if (isset($extldap_config['port'])) {
$ds = ldap_connect($extldap_config['host'],$extldap_config['port']);
} else {
$ds = ldap_connect($extldap_config['host']);
}
if (!$ds) {
$port = isset($extldap_config['port']) ? $ldap_config['port'] : 389;
error_log('EXTLDAP ERROR : cannot connect to '.$extldap_config['host'].':'. $port);
return false;
}
//Setting protocol version
if (isset($extldap_config['protocol_version'])) {
if ( ! ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $extldap_config['protocol_version'])) {
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 2);
}
}
return $ds;
}
/**
* Authenticate user on external ldap server and return user ldap entry if that succeeds
*
* @return mixed false if user cannot authenticate on ldap, user ldap entry if tha succeeds
* @author ndiechburg <noel@cblue.be>
**/
function extldap_authenticate($username, $password)
{
global $extldap_config;
if (empty($username) or empty($password)){
return false;
}
$ds = extldap_connect();
if (!$ds) {
return false;
}
//Connection as admin to search dn of user
$ldapbind = @ldap_bind($ds, $extldap_config['admin_dn'], $extldap_config['admin_password']);
if ($ldapbind === false){
error_log('EXTLDAP ERROR : cannot connect with admin login/password');
return false;
}
$user_search = extldap_get_user_search_string($username);
//Search distinguish name of user
$sr = ldap_search($ds, $extldap_config['base_dn'], $user_search);
if ( !$sr ){
error_log('EXTLDAP ERROR : ldap_search(ds, '.$extldap_config['base_dn'].", $user_search) failed");
return false;
}
$entries_count = ldap_count_entries($ds,$sr);
if ($entries_count > 1) {
error_log('EXTLDAP ERROR : more than one entry for that user ( ldap_search(ds, '.$extldap_config['base_dn'].", $user_search) )");
return false;
}
if ($entries_count < 1) {
error_log('EXTLDAP ERROR : No entry for that user ( ldap_search(ds, '.$extldap_config['base_dn'].", $user_search) )");
return false;
}
$users = ldap_get_entries($ds,$sr);
$user = $users[0];
//now we try to autenthicate the user in the ldap
$ubind = @ldap_bind($ds, $user['dn'], $password);
if($ubind !== false){
return $user;
}
else {
error_log('EXTLDAP : Wrong password for '.$user['dn']);
}
}
/**
* Return an array with userinfo compatible with chamilo using $extldap_user_correspondance
* configuration array declared in ldap.conf.php file
*
* @param array ldap user
* @param array correspondance array (if not set use extldap_user_correspondance declared
* in ldap.conf.php
* @return array userinfo array
* @author ndiechburg <noel@cblue.be>
**/
function extldap_get_chamilo_user($ldap_user, $cor = null)
{
global $extldap_user_correspondance;
if ( is_null($cor) ) {
$cor = $extldap_user_correspondance;
}
$chamilo_user =array();
foreach ($cor as $chamilo_field => $ldap_field) {
if (is_array($ldap_field)){
$chamilo_user[$chamilo_field] = extldap_get_chamilo_user($ldap_user, $ldap_field);
continue;
}
switch ($ldap_field) {
case 'func':
$func = "extldap_get_$chamilo_field";
if (function_exists($func)) {
$chamilo_user[$chamilo_field] = extldap_purify_string($func($ldap_user));
} else {
error_log("EXTLDAP WARNING : You forgot to declare $func");
}
break;
default:
//if string begins with "!", then this is a constant
if($ldap_field[0] === '!' ){
$chamilo_user[$chamilo_field] = trim($ldap_field, "!\t\n\r\0");
break;
}
if ( isset($ldap_user[$ldap_field][0]) ) {
$chamilo_user[$chamilo_field] = extldap_purify_string($ldap_user[$ldap_field][0]);
} else {
error_log('EXTLDAP WARNING : '.$ldap_field. '[0] field is not set in ldap array');
}
break;
}
}
return $chamilo_user;
}
?>

@ -0,0 +1,65 @@
<?php // External login module : LDAP
/**
*
* This file is included in main/inc/local.inc.php at user login if the user have 'external_ldap' in
* his auth_source field insted of platform
*
* Variables that can be used :
* - $login : string containing the username posted by the user
* - $password : string containing the password posted by the user
* - $uData : associative array with those keys :
* -username
* -password
* -auth_source
* -active
* -expiration_date
*
* If login succeeds, we have 2 choices :
* 1. - set $loginFailed to false,
* - set $_SESSION['_user']['user_id'] with the dokeos user_id
* - set $uidReset to true
* - upgrade user info in dokeos database if needeed
* - let the script local.inc.php continue
*
* 2. - set $_SESSION['_user']['user_id'] with the dokeos user_id
* - set $_SESSION['_user']['uidReset'] to true
* - upgrade user info in dokeos database if needeed
* - redirect to any page and let local.inc.php do the magic
*
* If login fails we have to redirect to index.php with the right message
* Possible messages are :
* - index.php?loginFailed=1&error=access_url_inactive
* - index.php?loginFailed=1&error=account_expired
* - index.php?loginFailed=1&error=account_inactive
* - index.php?loginFailed=1&error=user_password_incorrect
* - index.php?loginFailed=1&error=unrecognize_sso_origin');
*
**/
require_once(dirname(__FILE__).'/ldap.conf.php');
require_once(dirname(__FILE__).'/functions.inc.php');
$ldap_user = extldap_authenticate($login,$password);
if ($ldap_user !== false) {
$chamilo_user = extldap_get_chamilo_user($ldap_user);
//userid is not on the ldap, we have to use $uData variable from local.inc.php
$chamilo_user['user_id'] = $uData['user_id'];
//Update user info
if(isset($extldap_config['update_userinfo']) && $extldap_config['update_userinfo'])
{
external_update_user($chamilo_user);
}
$loginFailed = false;
$_user['user_id'] = $chamilo_user['user_id'];
$_user['uidReset'] = true;
api_session_register('_user');
$uidReset=true;
event_login();
} else {
$loginFailed = true;
$uidReset = false;
unset($_user['user_id']);
}
?>

@ -0,0 +1,66 @@
<?php // External login module : LDAP
/**
* This file is included by main/inc/local.inc.php when extldap is activated, a user try to login
* and chamilo does not find his user
* Variables that can be used :
* - $login : string containing the username posted by the user
* - $password : string containing the password posted by the user
*
* Please configure the exldap module in main/auth/external_login/ldap.conf.php
*
* If login succeeds, we have to add the user in the chamilo database and then
* we have 2 choices :
* 1. - set $loginFailed to false,
* - set $_SESSION['_user']['user_id'] with the dokeos user_id
* - set $uidReset to true
* - let the script local.inc.php continue
*
* 2. - set $_SESSION['_user']['user_id'] with the dokeos user_id
* - set $_SESSION['_user']['uidReset'] to true
* - upgrade user info in dokeos database if needeed
* - redirect to any page and let local.inc.php do the magic
*
* If login fails we have also 2 choices :
* 1. - unset $_user['user_id']
* - set $loginFailed=true
* - set $uidReset = false
* User wil then have the user password incorrect message
*
* 2. We redirect the user to index.php with appropriate message :
* Possible messages are :
* - index.php?loginFailed=1&error=access_url_inactive
* - index.php?loginFailed=1&error=account_expired
* - index.php?loginFailed=1&error=account_inactive
* - index.php?loginFailed=1&error=user_password_incorrect
* - index.php?loginFailed=1&error=unrecognize_sso_origin');
**/
require_once(dirname(__FILE__).'/ldap.conf.php');
require_once(dirname(__FILE__).'/functions.inc.php');
$ldap_user = extldap_authenticate($login,$password);
if ($ldap_user !== false) {
$chamilo_user = extldap_get_chamilo_user($ldap_user);
//username is not on the ldap, we have to use $login variable
$chamilo_user['username'] = $login;
$chamilo_uid = external_add_user($chamilo_user);
if ($chamilo_uid !==false) {
$loginFailed = false;
$_user['user_id'] = $chamilo_uid;
$_user['uidReset'] = true;
api_session_register('_user');
$uidReset=true;
// Is user admin?
if ($chamilo_user['admin']=== true){
$is_platformAdmin = true;
Database::query("INSERT INTO admin values ('$chamilo_uid')");
}
}
event_login();
} else {
$loginFailed = true;
$uidReset = false;
unset($_user['user_id']);
}
?>
Loading…
Cancel
Save