Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 310 and 400] [Versions 39 and 400] [Versions 400 and 402] [Versions 400 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  namespace enrol_ldap;
  18  
  19  /**
  20   * LDAP enrolment plugin tests.
  21   *
  22   * NOTE: in order to execute this test you need to set up
  23   *       OpenLDAP server with core, cosine, nis and internet schemas
  24   *       and add configuration constants to config.php or phpunit.xml configuration file:
  25   *
  26   * define('TEST_ENROL_LDAP_HOST_URL', 'ldap://127.0.0.1');
  27   * define('TEST_ENROL_LDAP_BIND_DN', 'cn=someuser,dc=example,dc=local');
  28   * define('TEST_ENROL_LDAP_BIND_PW', 'somepassword');
  29   * define('TEST_ENROL_LDAP_DOMAIN', 'dc=example,dc=local');
  30   *
  31   * @package    enrol_ldap
  32   * @category   test
  33   * @copyright  2013 Petr Skoda {@link http://skodak.org}
  34   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  class ldap_test extends \advanced_testcase {
  37  
  38      /**
  39       * Data provider for enrol_ldap tests
  40       *
  41       * Used to ensure that all the paged stuff works properly, irrespectively
  42       * of the pagesize configured (that implies all the chunking and paging
  43       * built in the plugis is doing its work consistently). Both searching and
  44       * not searching within subcontexts.
  45       *
  46       * @return array[]
  47       */
  48      public function enrol_ldap_provider() {
  49          $pagesizes = [1, 3, 5, 1000];
  50          $subcontexts = [0, 1];
  51          $combinations = [];
  52          foreach ($pagesizes as $pagesize) {
  53              foreach ($subcontexts as $subcontext) {
  54                  $combinations["pagesize {$pagesize}, subcontexts {$subcontext}"] = [$pagesize, $subcontext];
  55              }
  56          }
  57          return $combinations;
  58      }
  59  
  60      /**
  61       * General enrol_ldap testcase
  62       *
  63       * @dataProvider enrol_ldap_provider
  64       * @param int $pagesize Value to be configured in settings controlling page size.
  65       * @param int $subcontext Value to be configured in settings controlling searching in subcontexts.
  66       */
  67      public function test_enrol_ldap(int $pagesize, int $subcontext) {
  68          global $CFG, $DB;
  69  
  70          if (!extension_loaded('ldap')) {
  71              $this->markTestSkipped('LDAP extension is not loaded.');
  72          }
  73  
  74          $this->resetAfterTest();
  75  
  76          require_once($CFG->dirroot.'/enrol/ldap/lib.php');
  77          require_once($CFG->libdir.'/ldaplib.php');
  78  
  79          if (!defined('TEST_ENROL_LDAP_HOST_URL') or !defined('TEST_ENROL_LDAP_BIND_DN') or !defined('TEST_ENROL_LDAP_BIND_PW') or !defined('TEST_ENROL_LDAP_DOMAIN')) {
  80              $this->markTestSkipped('External LDAP test server not configured.');
  81          }
  82  
  83          // Make sure we can connect the server.
  84          $debuginfo = '';
  85          if (!$connection = ldap_connect_moodle(TEST_ENROL_LDAP_HOST_URL, 3, 'rfc2307', TEST_ENROL_LDAP_BIND_DN, TEST_ENROL_LDAP_BIND_PW, LDAP_DEREF_NEVER, $debuginfo, false)) {
  86              $this->markTestSkipped('Can not connect to LDAP test server: '.$debuginfo);
  87          }
  88  
  89          $this->enable_plugin();
  90  
  91          // Create new empty test container.
  92          $topdn = 'dc=moodletest,'.TEST_ENROL_LDAP_DOMAIN;
  93  
  94          $this->recursive_delete($connection, TEST_ENROL_LDAP_DOMAIN, 'dc=moodletest');
  95  
  96          $o = array();
  97          $o['objectClass'] = array('dcObject', 'organizationalUnit');
  98          $o['dc']         = 'moodletest';
  99          $o['ou']         = 'MOODLETEST';
 100          if (!ldap_add($connection, 'dc=moodletest,'.TEST_ENROL_LDAP_DOMAIN, $o)) {
 101              $this->markTestSkipped('Can not create test LDAP container.');
 102          }
 103  
 104          // Configure enrol plugin.
 105          /** @var enrol_ldap_plugin $enrol */
 106          $enrol = enrol_get_plugin('ldap');
 107          $enrol->set_config('host_url', TEST_ENROL_LDAP_HOST_URL);
 108          $enrol->set_config('start_tls', 0);
 109          $enrol->set_config('ldap_version', 3);
 110          $enrol->set_config('ldapencoding', 'utf-8');
 111          $enrol->set_config('pagesize', $pagesize);
 112          $enrol->set_config('bind_dn', TEST_ENROL_LDAP_BIND_DN);
 113          $enrol->set_config('bind_pw', TEST_ENROL_LDAP_BIND_PW);
 114          $enrol->set_config('course_search_sub', $subcontext);
 115          $enrol->set_config('memberattribute_isdn', 0);
 116          $enrol->set_config('user_contexts', '');
 117          $enrol->set_config('user_search_sub', 0);
 118          $enrol->set_config('user_type', 'rfc2307');
 119          $enrol->set_config('opt_deref', LDAP_DEREF_NEVER);
 120          $enrol->set_config('objectclass', '(objectClass=posixGroup)');
 121          $enrol->set_config('course_idnumber', 'cn');
 122          $enrol->set_config('course_shortname', 'cn');
 123          $enrol->set_config('course_fullname', 'cn');
 124          $enrol->set_config('course_summary', '');
 125          $enrol->set_config('ignorehiddencourses', 0);
 126          $enrol->set_config('nested_groups', 0);
 127          $enrol->set_config('autocreate', 0);
 128          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_KEEP);
 129  
 130          $roles = get_all_roles();
 131          foreach ($roles as $role) {
 132              $enrol->set_config('contexts_role'.$role->id, '');
 133              $enrol->set_config('memberattribute_role'.$role->id, '');
 134          }
 135  
 136          // Create group for teacher enrolments.
 137          $teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
 138          $this->assertNotEmpty($teacherrole);
 139          $o = array();
 140          $o['objectClass'] = array('organizationalUnit');
 141          $o['ou']          = 'teachers';
 142          ldap_add($connection, 'ou=teachers,'.$topdn, $o);
 143          $enrol->set_config('contexts_role'.$teacherrole->id, 'ou=teachers,'.$topdn);
 144          $enrol->set_config('memberattribute_role'.$teacherrole->id, 'memberuid');
 145  
 146          // Create group for student enrolments.
 147          $studentrole = $DB->get_record('role', array('shortname'=>'student'));
 148          $this->assertNotEmpty($studentrole);
 149          $o = array();
 150          $o['objectClass'] = array('organizationalUnit');
 151          $o['ou']          = 'students';
 152          ldap_add($connection, 'ou=students,'.$topdn, $o);
 153          $enrol->set_config('contexts_role'.$studentrole->id, 'ou=students,'.$topdn);
 154          $enrol->set_config('memberattribute_role'.$studentrole->id, 'memberuid');
 155  
 156          // Create some users and courses.
 157          $user1 = $this->getDataGenerator()->create_user(array('idnumber'=>'user1', 'username'=>'user1'));
 158          $user2 = $this->getDataGenerator()->create_user(array('idnumber'=>'user2', 'username'=>'user2'));
 159          $user3 = $this->getDataGenerator()->create_user(array('idnumber'=>'user3', 'username'=>'user3'));
 160          $user4 = $this->getDataGenerator()->create_user(array('idnumber'=>'user4', 'username'=>'user4'));
 161          $user5 = $this->getDataGenerator()->create_user(array('idnumber'=>'user5', 'username'=>'user5'));
 162          $user6 = $this->getDataGenerator()->create_user(array('idnumber'=>'user6', 'username'=>'user6'));
 163  
 164          $course1 = $this->getDataGenerator()->create_course(array('idnumber'=>'course1', 'shortname'=>'course1'));
 165          $course2 = $this->getDataGenerator()->create_course(array('idnumber'=>'course2', 'shortname'=>'course2'));
 166          $course3 = $this->getDataGenerator()->create_course(array('idnumber'=>'course3', 'shortname'=>'course3'));
 167  
 168          // Set up some ldap data.
 169          $o = array();
 170          $o['objectClass'] = array('posixGroup');
 171          $o['cn']          = 'course1';
 172          $o['gidNumber']   = '1';
 173          $o['memberUid']   = array('user1', 'user2', 'user3', 'userx');
 174          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 175          $o = array();
 176          $o['objectClass'] = array('posixGroup');
 177          $o['cn']          = 'course1';
 178          $o['gidNumber']   = '2';
 179          $o['memberUid']   = array('user5');
 180          ldap_add($connection, 'cn='.$o['cn'].',ou=teachers,'.$topdn, $o);
 181  
 182          $o = array();
 183          $o['objectClass'] = array('posixGroup');
 184          $o['cn']          = 'course2';
 185          $o['gidNumber']   = '3';
 186          $o['memberUid']   = array('user1', 'user2', 'user3', 'user4');
 187          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 188  
 189          $o = array();
 190          $o['objectClass'] = array('posixGroup');
 191          $o['cn']          = 'course4';
 192          $o['gidNumber']   = '4';
 193          $o['memberUid']   = array('user1', 'user2');
 194          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 195          $o = array();
 196          $o['objectClass'] = array('posixGroup');
 197          $o['cn']          = 'course4';
 198          $o['gidNumber']   = '5';
 199          $o['memberUid']   = array('user5', 'user6');
 200          ldap_add($connection, 'cn='.$o['cn'].',ou=teachers,'.$topdn, $o);
 201  
 202  
 203          // Test simple test without creation.
 204  
 205          $this->assertEquals(0, $DB->count_records('user_enrolments'));
 206          $this->assertEquals(0, $DB->count_records('role_assignments'));
 207          $this->assertEquals(4, $DB->count_records('course'));
 208  
 209          $enrol->sync_enrolments(new \null_progress_trace());
 210  
 211          $this->assertEquals(8, $DB->count_records('user_enrolments'));
 212          $this->assertEquals(8, $DB->count_records('role_assignments'));
 213          $this->assertEquals(4, $DB->count_records('course'));
 214  
 215          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id);
 216          $this->assertIsEnrolled($course1->id, $user2->id, $studentrole->id);
 217          $this->assertIsEnrolled($course1->id, $user3->id, $studentrole->id);
 218          $this->assertIsEnrolled($course1->id, $user5->id, $teacherrole->id);
 219  
 220          $this->assertIsEnrolled($course2->id, $user1->id, $studentrole->id);
 221          $this->assertIsEnrolled($course2->id, $user2->id, $studentrole->id);
 222          $this->assertIsEnrolled($course2->id, $user3->id, $studentrole->id);
 223          $this->assertIsEnrolled($course2->id, $user4->id, $studentrole->id);
 224  
 225  
 226          // Test course creation.
 227          $enrol->set_config('autocreate', 1);
 228  
 229          $enrol->sync_enrolments(new \null_progress_trace());
 230  
 231          $this->assertEquals(12, $DB->count_records('user_enrolments'));
 232          $this->assertEquals(12, $DB->count_records('role_assignments'));
 233          $this->assertEquals(5, $DB->count_records('course'));
 234  
 235          $course4 = $DB->get_record('course', array('idnumber'=>'course4'), '*', MUST_EXIST);
 236  
 237          $this->assertIsEnrolled($course4->id, $user1->id, $studentrole->id);
 238          $this->assertIsEnrolled($course4->id, $user2->id, $studentrole->id);
 239          $this->assertIsEnrolled($course4->id, $user5->id, $teacherrole->id);
 240          $this->assertIsEnrolled($course4->id, $user6->id, $teacherrole->id);
 241  
 242  
 243          // Test unenrolment.
 244          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 245          $o = array();
 246          $o['objectClass'] = array('posixGroup');
 247          $o['cn']          = 'course1';
 248          $o['gidNumber']   = '1';
 249          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 250  
 251          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_KEEP);
 252          $enrol->sync_enrolments(new \null_progress_trace());
 253          $this->assertEquals(12, $DB->count_records('user_enrolments'));
 254          $this->assertEquals(12, $DB->count_records('role_assignments'));
 255          $this->assertEquals(5, $DB->count_records('course'));
 256  
 257          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPEND);
 258          $enrol->sync_enrolments(new \null_progress_trace());
 259          $this->assertEquals(12, $DB->count_records('user_enrolments'));
 260          $this->assertEquals(12, $DB->count_records('role_assignments'));
 261          $this->assertEquals(5, $DB->count_records('course'));
 262          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_SUSPENDED);
 263          $this->assertIsEnrolled($course1->id, $user2->id, $studentrole->id, ENROL_USER_SUSPENDED);
 264          $this->assertIsEnrolled($course1->id, $user3->id, $studentrole->id, ENROL_USER_SUSPENDED);
 265  
 266          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 267          $o = array();
 268          $o['objectClass'] = array('posixGroup');
 269          $o['cn']          = 'course1';
 270          $o['gidNumber']   = '1';
 271          $o['memberUid']   = array('user1', 'user2', 'user3');
 272          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 273  
 274          $enrol->sync_enrolments(new \null_progress_trace());
 275          $this->assertEquals(12, $DB->count_records('user_enrolments'));
 276          $this->assertEquals(12, $DB->count_records('role_assignments'));
 277          $this->assertEquals(5, $DB->count_records('course'));
 278          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_ACTIVE);
 279          $this->assertIsEnrolled($course1->id, $user2->id, $studentrole->id, ENROL_USER_ACTIVE);
 280          $this->assertIsEnrolled($course1->id, $user3->id, $studentrole->id, ENROL_USER_ACTIVE);
 281  
 282          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 283          $o = array();
 284          $o['objectClass'] = array('posixGroup');
 285          $o['cn']          = 'course1';
 286          $o['gidNumber']   = '1';
 287          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 288  
 289          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
 290          $enrol->sync_enrolments(new \null_progress_trace());
 291          $this->assertEquals(12, $DB->count_records('user_enrolments'));
 292          $this->assertEquals(9, $DB->count_records('role_assignments'));
 293          $this->assertEquals(5, $DB->count_records('course'));
 294          $this->assertIsEnrolled($course1->id, $user1->id, 0, ENROL_USER_SUSPENDED);
 295          $this->assertIsEnrolled($course1->id, $user2->id, 0, ENROL_USER_SUSPENDED);
 296          $this->assertIsEnrolled($course1->id, $user3->id, 0, ENROL_USER_SUSPENDED);
 297  
 298          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 299          $o = array();
 300          $o['objectClass'] = array('posixGroup');
 301          $o['cn']          = 'course1';
 302          $o['gidNumber']   = '1';
 303          $o['memberUid']   = array('user1', 'user2', 'user3');
 304          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 305  
 306          $enrol->sync_enrolments(new \null_progress_trace());
 307          $this->assertEquals(12, $DB->count_records('user_enrolments'));
 308          $this->assertEquals(12, $DB->count_records('role_assignments'));
 309          $this->assertEquals(5, $DB->count_records('course'));
 310          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_ACTIVE);
 311          $this->assertIsEnrolled($course1->id, $user2->id, $studentrole->id, ENROL_USER_ACTIVE);
 312          $this->assertIsEnrolled($course1->id, $user3->id, $studentrole->id, ENROL_USER_ACTIVE);
 313  
 314          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 315          $o = array();
 316          $o['objectClass'] = array('posixGroup');
 317          $o['cn']          = 'course1';
 318          $o['gidNumber']   = '1';
 319          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 320  
 321          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
 322          $enrol->sync_enrolments(new \null_progress_trace());
 323          $this->assertEquals(9, $DB->count_records('user_enrolments'));
 324          $this->assertEquals(9, $DB->count_records('role_assignments'));
 325          $this->assertEquals(5, $DB->count_records('course'));
 326          $this->assertIsNotEnrolled($course1->id, $user1->id);
 327          $this->assertIsNotEnrolled($course1->id, $user2->id);
 328          $this->assertIsNotEnrolled($course1->id, $user3->id);
 329  
 330  
 331          // Individual user enrolments-
 332  
 333          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 334          $o = array();
 335          $o['objectClass'] = array('posixGroup');
 336          $o['cn']          = 'course1';
 337          $o['gidNumber']   = '1';
 338          $o['memberUid']   = array('user1', 'user2', 'user3');
 339          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 340  
 341          $enrol->sync_user_enrolments($user1);
 342          $this->assertEquals(10, $DB->count_records('user_enrolments'));
 343          $this->assertEquals(10, $DB->count_records('role_assignments'));
 344          $this->assertEquals(5, $DB->count_records('course'));
 345          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_ACTIVE);
 346  
 347          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 348          $o = array();
 349          $o['objectClass'] = array('posixGroup');
 350          $o['cn']          = 'course1';
 351          $o['gidNumber']   = '1';
 352          $o['memberUid']   = array('user2', 'user3');
 353          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 354  
 355          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_KEEP);
 356          $enrol->sync_user_enrolments($user1);
 357          $this->assertEquals(10, $DB->count_records('user_enrolments'));
 358          $this->assertEquals(10, $DB->count_records('role_assignments'));
 359          $this->assertEquals(5, $DB->count_records('course'));
 360          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_ACTIVE);
 361  
 362          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPEND);
 363          $enrol->sync_user_enrolments($user1);
 364          $this->assertEquals(10, $DB->count_records('user_enrolments'));
 365          $this->assertEquals(10, $DB->count_records('role_assignments'));
 366          $this->assertEquals(5, $DB->count_records('course'));
 367          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_SUSPENDED);
 368  
 369          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 370          $o = array();
 371          $o['objectClass'] = array('posixGroup');
 372          $o['cn']          = 'course1';
 373          $o['gidNumber']   = '1';
 374          $o['memberUid']   = array('user1', 'user2', 'user3');
 375          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 376  
 377          $enrol->sync_user_enrolments($user1);
 378          $this->assertEquals(10, $DB->count_records('user_enrolments'));
 379          $this->assertEquals(10, $DB->count_records('role_assignments'));
 380          $this->assertEquals(5, $DB->count_records('course'));
 381          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_ACTIVE);
 382  
 383          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 384          $o = array();
 385          $o['objectClass'] = array('posixGroup');
 386          $o['cn']          = 'course1';
 387          $o['gidNumber']   = '1';
 388          $o['memberUid']   = array('user2', 'user3');
 389          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 390  
 391          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
 392          $enrol->sync_user_enrolments($user1);
 393          $this->assertEquals(10, $DB->count_records('user_enrolments'));
 394          $this->assertEquals(9, $DB->count_records('role_assignments'));
 395          $this->assertEquals(5, $DB->count_records('course'));
 396          $this->assertIsEnrolled($course1->id, $user1->id, 0, ENROL_USER_SUSPENDED);
 397  
 398          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 399          $o = array();
 400          $o['objectClass'] = array('posixGroup');
 401          $o['cn']          = 'course1';
 402          $o['gidNumber']   = '1';
 403          $o['memberUid']   = array('user1', 'user2', 'user3');
 404          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 405  
 406          $enrol->sync_user_enrolments($user1);
 407          $this->assertEquals(10, $DB->count_records('user_enrolments'));
 408          $this->assertEquals(10, $DB->count_records('role_assignments'));
 409          $this->assertEquals(5, $DB->count_records('course'));
 410          $this->assertIsEnrolled($course1->id, $user1->id, $studentrole->id, ENROL_USER_ACTIVE);
 411  
 412          ldap_delete($connection, 'cn=course1,ou=students,'.$topdn);
 413          $o = array();
 414          $o['objectClass'] = array('posixGroup');
 415          $o['cn']          = 'course1';
 416          $o['gidNumber']   = '1';
 417          $o['memberUid']   = array('user2', 'user3');
 418          ldap_add($connection, 'cn='.$o['cn'].',ou=students,'.$topdn, $o);
 419  
 420          $enrol->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
 421          $enrol->sync_user_enrolments($user1);
 422          $this->assertEquals(9, $DB->count_records('user_enrolments'));
 423          $this->assertEquals(9, $DB->count_records('role_assignments'));
 424          $this->assertEquals(5, $DB->count_records('course'));
 425          $this->assertIsNotEnrolled($course1->id, $user1->id);
 426  
 427          $this->recursive_delete($connection, TEST_ENROL_LDAP_DOMAIN, 'dc=moodletest');
 428          ldap_close($connection);
 429  
 430          // NOTE: multiple roles in one course is not supported, sorry
 431      }
 432  
 433      public function assertIsEnrolled($courseid, $userid, $roleid, $status=null) {
 434          global $DB;
 435  
 436          $context = \context_course::instance($courseid);
 437          $instance = $DB->get_record('enrol', array('courseid'=>$courseid, 'enrol'=>'ldap'));
 438          $this->assertNotEmpty($instance);
 439          $ue = $DB->get_record('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$userid));
 440          $this->assertNotEmpty($ue);
 441          if (isset($status)) {
 442              $this->assertEquals($status, $ue->status);
 443          }
 444          if ($roleid) {
 445              $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>$context->id, 'userid'=>$userid, 'roleid'=>$roleid, 'component'=>'enrol_ldap')));
 446          } else {
 447              $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>$context->id, 'userid'=>$userid, 'component'=>'enrol_ldap')));
 448          }
 449      }
 450  
 451      public function assertIsNotEnrolled($courseid, $userid) {
 452          $context = \context_course::instance($courseid);
 453          $this->assertFalse(is_enrolled($context, $userid));
 454      }
 455  
 456      protected function enable_plugin() {
 457          $enabled = enrol_get_plugins(true);
 458          $enabled['ldap'] = true;
 459          $enabled = array_keys($enabled);
 460          set_config('enrol_plugins_enabled', implode(',', $enabled));
 461      }
 462  
 463      protected function disable_plugin() {
 464          $enabled = enrol_get_plugins(true);
 465          unset($enabled['ldap']);
 466          $enabled = array_keys($enabled);
 467          set_config('enrol_plugins_enabled', implode(',', $enabled));
 468      }
 469  
 470      protected function recursive_delete($connection, $dn, $filter) {
 471          if ($res = ldap_list($connection, $dn, $filter, array('dn'))) {
 472              $info = ldap_get_entries($connection, $res);
 473              ldap_free_result($res);
 474              if ($info['count'] > 0) {
 475                  if ($res = ldap_search($connection, "$filter,$dn", 'cn=*', array('dn'))) {
 476                      $info = ldap_get_entries($connection, $res);
 477                      ldap_free_result($res);
 478                      foreach ($info as $i) {
 479                          if (isset($i['dn'])) {
 480                              ldap_delete($connection, $i['dn']);
 481                          }
 482                      }
 483                  }
 484                  if ($res = ldap_search($connection, "$filter,$dn", 'ou=*', array('dn'))) {
 485                      $info = ldap_get_entries($connection, $res);
 486                      ldap_free_result($res);
 487                      foreach ($info as $i) {
 488                          if (isset($i['dn']) and $info[0]['dn'] != $i['dn']) {
 489                              ldap_delete($connection, $i['dn']);
 490                          }
 491                      }
 492                  }
 493                  ldap_delete($connection, "$filter,$dn");
 494              }
 495          }
 496      }
 497  
 498      /**
 499       * Test that normalisation of the use objectclass is completed successfully.
 500       *
 501       * @dataProvider objectclass_fetch_provider
 502       * @param string $usertype The supported user type
 503       * @param string $expected The expected filter value
 504       */
 505      public function test_objectclass_fetch($usertype, $expected) {
 506          $this->resetAfterTest();
 507          // Set the user type - this must be performed before the plugin is instantiated.
 508          set_config('user_type', $usertype, 'enrol_ldap');
 509  
 510          // Fetch the plugin.
 511          $instance = enrol_get_plugin('ldap');
 512  
 513          // Use reflection to sneak a look at the plugin.
 514          $rc = new \ReflectionClass('enrol_ldap_plugin');
 515          $rcp = $rc->getProperty('userobjectclass');
 516          $rcp->setAccessible(true);
 517  
 518          // Fetch the current userobjectclass value.
 519          $value = $rcp->getValue($instance);
 520          $this->assertEquals($expected, $value);
 521      }
 522  
 523      /**
 524       * Data provider for the test_objectclass_fetch testcase.
 525       *
 526       * @return array of testcases.
 527       */
 528      public function objectclass_fetch_provider() {
 529          return array(
 530              // This is the list of values from ldap_getdefaults() normalised.
 531              'edir' => array(
 532                  'edir',
 533                  '(objectClass=user)'
 534              ),
 535              'rfc2307' => array(
 536                  'rfc2307',
 537                  '(objectClass=posixaccount)'
 538              ),
 539              'rfc2307bis' => array(
 540                  'rfc2307bis',
 541                  '(objectClass=posixaccount)'
 542              ),
 543              'samba' => array(
 544                  'samba',
 545                  '(objectClass=sambasamaccount)'
 546              ),
 547              'ad' => array(
 548                  'ad',
 549                  '(samaccounttype=805306368)'
 550              ),
 551              'default' => array(
 552                  'default',
 553                  '(objectClass=*)'
 554              ),
 555          );
 556      }
 557  }