From ac2b35e2670ba33c76f9389b589fa9772b7a7f01 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?I=C3=B1aki=20Arenaza?= <iarenaza@mondragon.edu>
Date: Thu, 1 Sep 2011 22:17:03 +0200
Subject: [PATCH] Patch for MDL-24252 from Pawel Suwinski updated for 1.9.13+ (Build: 20110831)

---
 admin/auth_config.php                    |   12 +++
 auth/ldap/auth.php                       |   28 +++++++-
 auth/ldap/auth_ldap_sync_local_users.php |  112 ++++++++++++++++++++++++++++++
 lib/authlib.php                          |   22 ++++++-
 lib/moodlelib.php                        |   25 +++++++
 5 files changed, 197 insertions(+), 2 deletions(-)
 create mode 100644 auth/ldap/auth_ldap_sync_local_users.php

diff --git a/admin/auth_config.php b/admin/auth_config.php
index 0281b12..3df9ba5 100644
--- a/admin/auth_config.php
+++ b/admin/auth_config.php
@@ -2,6 +2,14 @@
 /**
  * Edit configuration for an individual auth plugin
  */
+# -----------------------------------------------------------------
+# CHANGELOG, Pawel Suwinski
+#
+# 2010-09-16:
+# 	[mod201009161040]
+# 		added refactored patch2.patch from  MDL-10908 
+#		to map custom user profile fields in auth ldap
+# -----------------------------------------------------------------
 
 require_once '../config.php';
 require_once $CFG->libdir.'/adminlib.php';
@@ -138,6 +146,10 @@ function print_auth_lock_options ($auth, $user_fields, $helptext, $retrieveopts,
             $fieldname =  get_string($matches[1]) . ' ' . $matches[2];
         } elseif ($fieldname == 'url') {
             $fieldname = get_string('webpage');
+        # 	[mod201009161040]
+        } elseif (preg_match('/^profile_field_.*/', $fieldname)) {
+            $fieldname = get_field('user_info_field', 'name', 'shortname', preg_replace('/^profile_field_(.*)/','\1',$fieldname));
+        #	[end mod201009161040]
         } else {
             $fieldname = get_string($fieldname);
         } 
diff --git a/auth/ldap/auth.php b/auth/ldap/auth.php
index d1ce83b..d64d547 100644
--- a/auth/ldap/auth.php
+++ b/auth/ldap/auth.php
@@ -11,6 +11,14 @@
  *
  * 2006-08-28  File created.
  */
+# -----------------------------------------------------------------
+# CHANGELOG, Pawel Suwinski
+#
+# 2010-09-16:
+# 	[mod201009161040]
+# 		added refactored patch2.patch from  MDL-10908 
+#		to map custom user profile fields in auth ldap
+# -----------------------------------------------------------------
 
 if (!defined('MOODLE_INTERNAL')) {
     die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
@@ -58,6 +66,8 @@ class auth_plugin_ldap extends auth_plugin_base {
             }
         }
 
+        $this->addCustomToUserFields(); # [mod201009161040]
+
         // Hack prefix to objectclass
         if (empty($this->config->objectclass)) {
             // Can't send empty filter
@@ -233,7 +243,11 @@ class auth_plugin_ldap extends auth_plugin_base {
                 } else {
                     $newval = $textlib->convert($user_entry[0][$value], $this->config->ldapencoding, 'utf-8');
                 }
-                if (!empty($newval)) { // favour ldap entries that are set
+                # [mod201009161040]
+                #if (!empty($newval)) { // favour ldap entries that are set
+                //need to allow for 0 or '0' will ldap ever return an empty string or will the array_key_exists catch such things?
+                if (isset($newval) || $newval !== '') { // favour ldap entries that are set
+                # [end mod201009161040]
                     $ldapval = $newval;
                 }
             }
@@ -913,12 +927,24 @@ class auth_plugin_ldap extends auth_plugin_base {
                     $value = '';
                 }
 
+                # 	[mod201009161040]
+                if (preg_match('/^profile_field_.*/', $key)) {
+                    $newuser->$key = addslashes($value);
+                    continue;
+                }
+                # 	[end mod201009161040]
+
                 if (!empty($this->config->{'field_updatelocal_' . $key})) {
                     if ($user->{$key} != $value) { // only update if it's changed
                         set_field('user', $key, addslashes($value), 'id', $userid);
                     }
                 }
             }
+            # 	[mod201009161040]
+            $newuser->id=$userid;
+            // save custom profile fields data
+            profile_save_data($newuser);
+            # 	[end mod201009161040]
         } else {
             return false;
         }
diff --git a/auth/ldap/auth_ldap_sync_local_users.php b/auth/ldap/auth_ldap_sync_local_users.php
new file mode 100644
index 0000000..c346cd6
--- /dev/null
+++ b/auth/ldap/auth_ldap_sync_local_users.php
@@ -0,0 +1,112 @@
+<?php
+/** auth_ldap_sync_local_users.php
+ * 
+ *  Script synchronize only locally existing users accounts width external LDAP.
+ *  There is no new account creation or any LDAP update.
+ *
+ * This script is meant to be called from a cronjob to sync moodle with the LDAP
+ * backend in those setups where the LDAP backend acts as 'master'.
+ *
+ * Recommended cron entry:
+ * # 5 minutes past 4am
+ * 5 4 * * * /usr/bin/php -c /etc/php4/cli/php.ini /var/www/moodle/auth/ldap/auth_ldap_sync_users.php
+ *
+ *  Pawel Suwinski, 2010-09-20
+ */
+
+
+if (isset($_SERVER['REMOTE_ADDR'])) {
+    error_log("should not be called from web server!");
+    exit;
+}
+
+$nomoodlecookie = true; // cookie not needed
+
+require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); // global moodle config file.
+
+require_once($CFG->libdir.'/blocklib.php');
+require_once($CFG->dirroot.'/course/lib.php');
+require_once($CFG->dirroot.'/mod/resource/lib.php');
+require_once($CFG->dirroot.'/mod/forum/lib.php');
+require_once($CFG->dirroot.'/user/profile/lib.php');
+
+if (!is_enabled_auth('ldap')) {
+    echo "Plugin not enabled!";
+    die;
+}
+
+# LDAP AUTH CONFIG 
+$ldapauth = get_auth_plugin('ldap');
+$ldapauth->ldap_connect(); # make connection
+
+$all_keys = array_keys(get_object_vars($ldapauth->config));
+$updatekeys = array();
+foreach ($all_keys as $key) {
+    if (preg_match('/^field_updatelocal_(.+)$/',$key, $match)) {
+        // if we have a field to update it from
+        // and it must be updated 'onlogin' we
+        // update it on cron
+        if ( !empty($ldapauth->config->{'field_map_'.$match[1]})
+             and $ldapauth->config->{$match[0]} === 'onlogin') {
+            array_push($updatekeys, $match[1]); // the actual key name
+        }
+    }
+}
+unset($all_keys); unset($key);
+
+$syncCounter=array(
+                'updated' => 0,
+                'removed' => 0,
+                'suspended' =>0,
+                );
+# --------------------------------------------
+
+echo "\nAccounts synchro: ";
+    
+$users = get_users_listing('username', 'ASC', 0, 0, '', '', '', "auth = 'ldap' AND mnethostid = '".$CFG->mnet_localhost_id."'");
+
+echo count($users)."\n";
+
+foreach($users as $user):
+
+   $user->auth='ldap';
+   echo '--> '.$user->username.' ('.$user->id.'):';
+
+   if($ldapauth->update_user_record($user->username,$updatekeys))
+   {
+        echo "\t\t[updated]\n";
+        $syncCounter['updated']++;
+        continue;
+   }
+
+    # user does not exist in ldap so it should be removed
+    if ($ldapauth->config->removeuser == 2) {
+        if (delete_user($user)) {
+            echo "\t\t[deleted]\n";
+            $syncCounter['removed']++;
+        } else {
+            echo "\t"; print_string('auth_dbdeleteusererror', 'auth', $user->username); echo "\n";
+        }
+    } else if ($ldapauth->config->removeuser == 1) {
+        $updateuser = new object();
+        $updateuser->id = $user->id;
+        $updateuser->auth = 'nologin';
+        if (update_record('user', $updateuser)) {
+            echo "\t\t[suspended]\n";
+            $syncCounter['suspended']++;
+        } else {
+            echo "\t"; print_string('auth_dbsuspendusererror', 'auth', $user->username); echo "\n";
+        }
+    }
+
+endforeach;
+
+echo "\n";
+
+foreach ($syncCounter as $key => $val)
+{
+    echo "$key:\t$val\n";
+}
+
+
+?>
diff --git a/lib/authlib.php b/lib/authlib.php
index 076242a..9a26734 100644
--- a/lib/authlib.php
+++ b/lib/authlib.php
@@ -9,6 +9,14 @@
  *
  * 2006-08-28  File created, AUTH return values defined.
  */
+# -----------------------------------------------------------------
+# CHANGELOG, Pawel Suwinski
+#
+# 2010-09-16:
+# 	[mod201009161040]
+# 		added refactored patch2.patch from  MDL-10908 
+#		to map custom user profile fields in auth ldap
+# -----------------------------------------------------------------
 
 /**
  * Returned when the login was successful.
@@ -77,8 +85,20 @@ class auth_plugin_base {
         'address'
     );
 
-    /**
+    # [mod201009161040]
+    function addCustomToUserFields(){
+        $custom_fields = array();
+        if ($prof_fields = get_records('user_info_field', '', '', 'sortorder', 'shortname')) {
+            foreach ($prof_fields as $prof_field) {
+                $custom_fields[] = 'profile_field_'.$prof_field->shortname;
+            }
+            unset($prof_fields);
+        }
+        $this->userfields = array_merge($this->userfields, $custom_fields);
+    }
+    # [end mod201009161040]
 
+    /**
      * This is the primary method that is used by the authenticate_user_login()
      * function in moodlelib.php. This method should return a boolean indicating
      * whether or not the username and password authenticate successfully.
diff --git a/lib/moodlelib.php b/lib/moodlelib.php
index cac0785..2cd2a84 100644
--- a/lib/moodlelib.php
+++ b/lib/moodlelib.php
@@ -34,6 +34,14 @@
  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
  * @package moodlecore
  */
+# -----------------------------------------------------------------
+# CHANGELOG, Pawel Suwinski
+#
+# 2010-09-16:
+# 	[mod201009161040]
+# 		added refactored patch2.patch from  MDL-10908 
+#		to map custom user profile fields in auth ldap
+# -----------------------------------------------------------------
 
 /// CONSTANTS (Encased in phpdoc proper comments)/////////////////////////
 
@@ -2990,6 +2998,11 @@ function create_user_record($username, $password, $auth='manual') {
             set_user_preference('auth_forcepasswordchange', 1, $user->id);
         }
         update_internal_user_password($user, $password);
+        # 	[mod201009161040]
+        $newuser->id=$user->id;
+        // save custom profile fields data
+        profile_save_data($newuser);
+        # 	[end mod201009161040]
         return $user;
     }
     return false;
@@ -3017,6 +3030,13 @@ function update_user_record($username, $unused) {
                 // these fields must not be changed
                 continue;
             }
+            # 	[mod201009161040]
+            if (preg_match('/^profile_field_.*/', $key)) {
+                $newuser->$key = addslashes($value);
+                continue;
+            }
+            # 	[end mod201009161040]
+
             $confval = $userauth->config->{'field_updatelocal_' . $key};
             $lockval = $userauth->config->{'field_lock_' . $key};
             if (empty($confval) || empty($lockval)) {
@@ -3036,6 +3056,11 @@ function update_user_record($username, $unused) {
                 }
             }
         }
+        # 	[mod201009161040]
+        $newuser->id=$oldinfo->id;
+        // save custom profile fields data
+        profile_save_data($newuser);
+        # 	[end mod201009161040]
     }
 
     return get_complete_user_data('username', $username, $CFG->mnet_localhost_id);
-- 
1.7.2.5

