Projet

Général

Profil

Paste
Télécharger (51 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ldap / ldap_user / LdapUserConf.class.php @ 32700c57

1 85ad3d82 Assos Assos
<?php
2
3
/**
4
 * @file
5
 * This class represents a ldap_user module's configuration
6 32700c57 Assos Assos
 * It is extended by LdapUserConfAdmin for configuration and other admin functions.
7 85ad3d82 Assos Assos
 */
8
9 32700c57 Assos Assos
require_once 'ldap_user.module';
10
/**
11
 *
12
 */
13 85ad3d82 Assos Assos
class LdapUserConf {
14
15
  /**
16 32700c57 Assos Assos
   * Server providing Drupal account provisioning.
17 85ad3d82 Assos Assos
   *
18
   * @var string
19
   *
20
   * @see LdapServer::sid
21
   */
22
  public $drupalAcctProvisionServer = LDAP_USER_NO_SERVER_SID;
23
24
  /**
25 32700c57 Assos Assos
   * Server providing LDAP entry provisioning.
26 85ad3d82 Assos Assos
   *
27
   * @var string
28
   *
29
   * @see LdapServer::sid
30
   */
31
  public $ldapEntryProvisionServer = LDAP_USER_NO_SERVER_SID;
32
33
  /**
34
   * Associative array mapping synch directions to ldap server instances.
35
   *
36
   * @var array
37
   */
38 32700c57 Assos Assos
  public $provisionSidFromDirection = [
39 85ad3d82 Assos Assos
    LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER => LDAP_USER_NO_SERVER_SID,
40
    LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY => LDAP_USER_NO_SERVER_SID,
41 32700c57 Assos Assos
  ];
42 85ad3d82 Assos Assos
43
  /**
44
   * Array of events that trigger provisioning of Drupal Accounts
45
   * Valid constants are:
46
   *   LDAP_USER_DRUPAL_USER_PROV_ON_AUTHENTICATE
47
   *   LDAP_USER_DRUPAL_USER_PROV_ON_USER_UPDATE_CREATE
48 32700c57 Assos Assos
   *   LDAP_USER_DRUPAL_USER_PROV_ON_ALLOW_MANUAL_CREATE.
49 85ad3d82 Assos Assos
   *
50
   * @var array
51
   */
52 32700c57 Assos Assos
  public $drupalAcctProvisionTriggers = [LDAP_USER_DRUPAL_USER_PROV_ON_AUTHENTICATE, LDAP_USER_DRUPAL_USER_PROV_ON_USER_UPDATE_CREATE, LDAP_USER_DRUPAL_USER_PROV_ON_ALLOW_MANUAL_CREATE];
53 85ad3d82 Assos Assos
54
  /**
55
   * Array of events that trigger provisioning of LDAP Entries
56
   * Valid constants are:
57
   *   LDAP_USER_LDAP_ENTRY_PROV_ON_USER_UPDATE_CREATE
58
   *   LDAP_USER_LDAP_ENTRY_PROV_ON_AUTHENTICATE
59 32700c57 Assos Assos
   *   LDAP_USER_LDAP_ENTRY_DELETE_ON_USER_DELETE.
60 85ad3d82 Assos Assos
   *
61
   * @var array
62
   */
63 32700c57 Assos Assos
  public $ldapEntryProvisionTriggers = [];
64 85ad3d82 Assos Assos
65
  /**
66 32700c57 Assos Assos
   * Server providing LDAP entry provisioning.
67 85ad3d82 Assos Assos
   *
68
   * @var string
69
   *
70
   * @see LdapServer::sid
71
   */
72
  public $userConflictResolve = LDAP_USER_CONFLICT_RESOLVE_DEFAULT;
73
74 b42754b9 Assos Assos
  /**
75
   * Whether to allow/disallow provisioning accounts that have the same email.
76
   * Depending on whether the "sharedemail" module is enabled, this variable
77
   * will (by default) be set accordingly.  It can be overridden by an admin.
78
   *
79
   * @var int
80
   *    LDAP_USER_ACCOUNTS_WITH_SAME_EMAIL_DISABLED (0)
81
   *    LDAP_USER_ACCOUNTS_WITH_SAME_EMAIL_ENABLED (1)
82
   */
83
  public $accountsWithSameEmail = LDAP_USER_ACCOUNTS_WITH_SAME_EMAIL_DISABLED;
84
85 85ad3d82 Assos Assos
  /**
86 32700c57 Assos Assos
   * Drupal account creation model.
87 85ad3d82 Assos Assos
   *
88
   * @var int
89
   *   LDAP_USER_ACCT_CREATION_LDAP_BEHAVIOR   /admin/config/people/accounts/settings do not affect "LDAP Associated" Drupal accounts.
90
   *   LDAP_USER_ACCT_CREATION_USER_SETTINGS_FOR_LDAP  use Account creation settings at /admin/config/people/accounts/settings
91
   */
92
  public $acctCreation = LDAP_USER_ACCT_CREATION_LDAP_BEHAVIOR_DEFAULT;
93
94
  /**
95 32700c57 Assos Assos
   * Has current object been saved to the database?
96 85ad3d82 Assos Assos
   *
97 32700c57 Assos Assos
   * @var bool
98 85ad3d82 Assos Assos
   */
99
  public $inDatabase = FALSE;
100
101
  /**
102 32700c57 Assos Assos
   * What to do when an ldap provisioned username conflicts with existing drupal user?
103 85ad3d82 Assos Assos
   *
104
   * @var int
105
   *   LDAP_USER_CONFLICT_LOG - log the conflict
106
   *   LDAP_USER_CONFLICT_RESOLVE - LDAP associate the existing drupal user
107
   */
108
  public $manualAccountConflict = LDAP_USER_MANUAL_ACCT_CONFLICT_REJECT;
109
110 32700c57 Assos Assos
  /**
111
   * @todo default to FALSE and check for mapping to set to true
112
   */
113
  public $setsLdapPassword = TRUE;
114 85ad3d82 Assos Assos
115
  public $loginConflictResolve = FALSE;
116
117
  public $disableAdminPasswordField = FALSE;
118
  /**
119 32700c57 Assos Assos
   * Array of field synch mappings provided by all modules (via hook_ldap_user_attrs_list_alter())
120 85ad3d82 Assos Assos
   * array of the form: array(
121
   * LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER | LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY => array(
122
   *   <server_id> => array(
123
   *     'sid' => <server_id> (redundant)
124
   *     'ldap_attr' => e.g. [sn]
125
   *     'user_attr'  => e.g. [field.field_user_lname] (when this value is set to 'user_tokens', 'user_tokens' value is used.)
126
   *     'user_tokens' => e.g. [field.field_user_lname], [field.field_user_fname]
127
   *     'convert' => 1|0 boolean indicating need to covert from binary
128
   *     'direction' => LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER | LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY (redundant)
129
   *     'config_module' => 'ldap_user'
130
   *     'prov_module' => 'ldap_user'
131
   *     'enabled' => 1|0 boolean
132
   *      prov_events' => array( of LDAP_USER_EVENT_* constants indicating during which synch actions field should be synched)
133
   *         - four permutations available
134
   *            to ldap:   LDAP_USER_EVENT_CREATE_LDAP_ENTRY,  LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY,
135
   *            to drupal: LDAP_USER_EVENT_CREATE_DRUPAL_USER, LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER
136
   *    )
137
   *  )
138
   */
139
  /**
140 32700c57 Assos Assos
   * Array of field synching directions for each operation.  should include ldapUserSynchMappings.
141
   */
142
  public $synchMapping = NULL;
143
  // Keyed on direction => property, ldap, or field token such as '[field.field_lname] with brackets in them.
144
  /**
145
   * Synch mappings configured in ldap user module (not in other modules)
146
   *   array of the form: array(
147
   * LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER | LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY => array(
148
   * 'sid' => <server_id> (redundant)
149
   * 'ldap_attr' => e.g. [sn]
150
   * 'user_attr'  => e.g. [field.field_user_lname] (when this value is set to 'user_tokens', 'user_tokens' value is used.)
151
   * 'user_tokens' => e.g. [field.field_user_lname], [field.field_user_fname]
152
   * 'convert' => 1|0 boolean indicating need to covert from binary
153
   * 'direction' => LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER | LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY (redundant)
154
   * 'config_module' => 'ldap_user'
155
   * 'prov_module' => 'ldap_user'
156
   * 'enabled' => 1|0 boolean
157
   * prov_events' => array( of LDAP_USER_EVENT_* constants indicating during which synch actions field should be synched)
158
   * - four permutations available
159
   * to ldap:   LDAP_USER_EVENT_CREATE_LDAP_ENTRY,  LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY,
160
   * to drupal: LDAP_USER_EVENT_CREATE_DRUPAL_USER, LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER
161
   * )
162
   * )
163
   * )
164
   */
165
  public $ldapUserSynchMappings = NULL;
166
  /**
167
   * Keyed on property, ldap, or field token such as '[field.field_lname] with brackets in them.
168
   */
169 85ad3d82 Assos Assos
  public $detailedWatchdog = FALSE;
170
  public $provisionsDrupalAccountsFromLdap = FALSE;
171
  public $provisionsLdapEntriesFromDrupalUsers = FALSE;
172
173 32700c57 Assos Assos
  /**
174
   * What should be done with ldap provisioned accounts that no longer have associated drupal accounts.
175
   */
176 85ad3d82 Assos Assos
  public $orphanedDrupalAcctBehavior = 'ldap_user_orphan_email';
177 32700c57 Assos Assos
  /**
178
   * Options are partially derived from user module account cancel options:.
179
   *
180
   * 'ldap_user_orphan_do_not_check' => Do not check for orphaned Drupal accounts.)
181
   * 'ldap_user_orphan_email' => Perform no action, but email list of orphaned accounts. (All the other options will send email summaries also.)
182
   * 'user_cancel_block' => Disable the account and keep its content.
183
   * 'user_cancel_block_unpublish' => Disable the account and unpublish its content.
184
   * 'user_cancel_reassign' => Delete the account and make its content belong to the Anonymous user.
185
   * 'user_cancel_delete' => Delete the account and its content.
186
   */
187 85ad3d82 Assos Assos
188
  public $orphanedCheckQty = 100;
189
190 32700c57 Assos Assos
  public $provisionsLdapEvents = [];
191
  public $provisionsDrupalEvents = [];
192 85ad3d82 Assos Assos
193 32700c57 Assos Assos
  public $saveable = [
194 85ad3d82 Assos Assos
    'drupalAcctProvisionServer',
195
    'ldapEntryProvisionServer',
196
    'drupalAcctProvisionTriggers',
197
    'ldapEntryProvisionTriggers',
198
    'orphanedDrupalAcctBehavior',
199
    'orphanedCheckQty',
200
    'userConflictResolve',
201 b42754b9 Assos Assos
    'accountsWithSameEmail',
202 85ad3d82 Assos Assos
    'manualAccountConflict',
203
    'acctCreation',
204
    'ldapUserSynchMappings',
205
    'disableAdminPasswordField',
206 32700c57 Assos Assos
  ];
207
208
  /**
209
   *
210
   */
211
  public function __construct() {
212 85ad3d82 Assos Assos
    $this->load();
213
214
    $this->provisionSidFromDirection[LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER] = $this->drupalAcctProvisionServer;
215
    $this->provisionSidFromDirection[LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY] = $this->ldapEntryProvisionServer;
216
217 32700c57 Assos Assos
    $this->provisionsLdapEvents = [
218 85ad3d82 Assos Assos
      LDAP_USER_EVENT_CREATE_LDAP_ENTRY => t('On LDAP Entry Creation'),
219
      LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY => t('On Synch to LDAP Entry'),
220 32700c57 Assos Assos
    ];
221 85ad3d82 Assos Assos
222 32700c57 Assos Assos
    $this->provisionsDrupalEvents = [
223 85ad3d82 Assos Assos
      LDAP_USER_EVENT_CREATE_DRUPAL_USER => t('On Drupal User Creation'),
224
      LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER => t('On Synch to Drupal User'),
225 32700c57 Assos Assos
    ];
226 85ad3d82 Assos Assos
227
    $this->provisionsDrupalAccountsFromLdap = (
228
      $this->drupalAcctProvisionServer &&
229
      $this->drupalAcctProvisionServer &&
230
      (count(array_filter(array_values($this->drupalAcctProvisionTriggers))) > 0)
231
    );
232
233
    $this->provisionsLdapEntriesFromDrupalUsers = (
234
      $this->ldapEntryProvisionServer
235
      && $this->ldapEntryProvisionServer
236
      && (count(array_filter(array_values($this->ldapEntryProvisionTriggers))) > 0)
237
      );
238
239
    $this->setSynchMapping(TRUE);
240
    $this->detailedWatchdog = variable_get('ldap_help_watchdog_detail', 0);
241
  }
242
243 32700c57 Assos Assos
  /**
244
   *
245
   */
246
  public function load() {
247 85ad3d82 Assos Assos
248
    if ($saved = variable_get("ldap_user_conf", FALSE)) {
249
      $this->inDatabase = TRUE;
250
      foreach ($this->saveable as $property) {
251
        if (isset($saved[$property])) {
252
          $this->{$property} = $saved[$property];
253
        }
254
      }
255
    }
256
    else {
257
      $this->inDatabase = FALSE;
258 b42754b9 Assos Assos
      // By default this variable should be 0 if the "sharedemail" module
259
      // is not enabled, or 1 if the module is.
260 32700c57 Assos Assos
      $this->accountsWithSameEmail = (int) module_exists('sharedemail');
261 85ad3d82 Assos Assos
    }
262 32700c57 Assos Assos
    // Determine account creation configuration.
263 85ad3d82 Assos Assos
    $user_register = variable_get('user_register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL);
264
    if ($this->acctCreation == LDAP_USER_ACCT_CREATION_LDAP_BEHAVIOR_DEFAULT || $user_register == USER_REGISTER_VISITORS) {
265
      $this->createLDAPAccounts = TRUE;
266
      $this->createLDAPAccountsAdminApproval = FALSE;
267
    }
268
    elseif ($user_register == USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL) {
269
      $this->createLDAPAccounts = FALSE;
270
      $this->createLDAPAccountsAdminApproval = TRUE;
271
    }
272
    else {
273
      $this->createLDAPAccounts = FALSE;
274
      $this->createLDAPAccountsAdminApproval = FALSE;
275
    }
276
  }
277
278
  /**
279 32700c57 Assos Assos
   * Destructor Method.
280 85ad3d82 Assos Assos
   */
281 32700c57 Assos Assos
  public function __destruct() {}
282 85ad3d82 Assos Assos
283
  /**
284 32700c57 Assos Assos
   * Util to fetch mappings for a given direction.
285 85ad3d82 Assos Assos
   *
286
   * @param string $sid
287 32700c57 Assos Assos
   *   The server id.
288
   * @param string $direction
289
   *   LDAP_USER_PROV_DIRECTION_* constant.
290 85ad3d82 Assos Assos
   * @param array $prov_events
291
   *
292 32700c57 Assos Assos
   * @return arraybool
293 85ad3d82 Assos Assos
   *   Array of mappings (may be empty array)
294 32700c57 Assos Assos
   */
295 85ad3d82 Assos Assos
  public function getSynchMappings($direction = LDAP_USER_PROV_DIRECTION_ALL, $prov_events = NULL) {
296
    if (!$prov_events) {
297
      $prov_events = ldap_user_all_events();
298
    }
299
300 32700c57 Assos Assos
    $mappings = [];
301 85ad3d82 Assos Assos
    if ($direction == LDAP_USER_PROV_DIRECTION_ALL) {
302 32700c57 Assos Assos
      $directions = [LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER, LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY];
303 85ad3d82 Assos Assos
    }
304
    else {
305 32700c57 Assos Assos
      $directions = [$direction];
306 85ad3d82 Assos Assos
    }
307
    foreach ($directions as $direction) {
308
      if (!empty($this->ldapUserSynchMappings[$direction])) {
309
        foreach ($this->ldapUserSynchMappings[$direction] as $attribute => $mapping) {
310
          if (!empty($mapping['prov_events'])) {
311
            $result = count(array_intersect($prov_events, $mapping['prov_events']));
312
            if ($result) {
313
              $mappings[$attribute] = $mapping;
314
            }
315
          }
316
        }
317
      }
318
    }
319
    return $mappings;
320
  }
321
322 32700c57 Assos Assos
  /**
323
   *
324
   */
325 85ad3d82 Assos Assos
  public function isDrupalAcctProvisionServer($sid) {
326
    if (!$sid || !$this->drupalAcctProvisionServer) {
327
      return FALSE;
328
    }
329 bc175c27 Assos Assos
    elseif ($this->drupalAcctProvisionServer == $sid) {
330 85ad3d82 Assos Assos
      return TRUE;
331
    }
332
    else {
333
      return FALSE;
334
    }
335
  }
336
337 32700c57 Assos Assos
  /**
338
   *
339
   */
340 85ad3d82 Assos Assos
  public function isLdapEntryProvisionServer($sid) {
341
    if (!$sid || !$this->ldapEntryProvisionServer) {
342
      return FALSE;
343
    }
344
    elseif ($this->ldapEntryProvisionServer == $sid) {
345
      return TRUE;
346
    }
347
    else {
348
      return FALSE;
349
    }
350
  }
351
352
  /**
353
   * Util to fetch attributes required for this user conf, not other modules.
354
   *
355 32700c57 Assos Assos
   * @param enum $direction
356
   *   LDAP_USER_PROV_DIRECTION_* constants.
357 85ad3d82 Assos Assos
   * @param string $ldap_context
358 32700c57 Assos Assos
   */
359 85ad3d82 Assos Assos
  public function getLdapUserRequiredAttributes($direction = LDAP_USER_PROV_DIRECTION_ALL, $ldap_context = NULL) {
360
361 32700c57 Assos Assos
    $attributes_map = [];
362
    $required_attributes = [];
363 85ad3d82 Assos Assos
    if ($this->drupalAcctProvisionServer) {
364
      $prov_events = $this->ldapContextToProvEvents($ldap_context);
365
      $attributes_map = $this->getSynchMappings($direction, $prov_events);
366 32700c57 Assos Assos
      $required_attributes = [];
367 85ad3d82 Assos Assos
      foreach ($attributes_map as $detail) {
368
        if (count(array_intersect($prov_events, $detail['prov_events']))) {
369
          // Add the attribute to our array.
370
          if ($detail['ldap_attr']) {
371 bc175c27 Assos Assos
            ldap_servers_token_extract_attributes($required_attributes, $detail['ldap_attr']);
372 85ad3d82 Assos Assos
          }
373
        }
374
      }
375
    }
376
    return $required_attributes;
377
  }
378
379 32700c57 Assos Assos
  /**
380
   * Converts the more general ldap_context string to its associated ldap user event.
381
   */
382 85ad3d82 Assos Assos
  public function ldapContextToProvEvents($ldap_context = NULL) {
383
384
    switch ($ldap_context) {
385
386
      case 'ldap_user_prov_to_drupal':
387 32700c57 Assos Assos
        $result = [LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER, LDAP_USER_EVENT_CREATE_DRUPAL_USER, LDAP_USER_EVENT_LDAP_ASSOCIATE_DRUPAL_ACCT];
388 85ad3d82 Assos Assos
        break;
389
390
      case 'ldap_user_prov_to_ldap':
391 32700c57 Assos Assos
        $result = [LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY, LDAP_USER_EVENT_CREATE_LDAP_ENTRY];
392 85ad3d82 Assos Assos
        break;
393
394
      default:
395
        $result = ldap_user_all_events();
396
397
    }
398
399
    return $result;
400
401
  }
402
403 32700c57 Assos Assos
  /**
404
   * Converts the more general ldap_context string to its associated ldap user prov direction.
405
   */
406 85ad3d82 Assos Assos
  public function ldapContextToProvDirection($ldap_context = NULL) {
407
408
    switch ($ldap_context) {
409
410
      case 'ldap_user_prov_to_drupal':
411
        $result = LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER;
412
        break;
413
414
      case 'ldap_user_prov_to_ldap':
415
      case 'ldap_user_delete_drupal_user':
416
        $result = LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY;
417
        break;
418
419 32700c57 Assos Assos
      // Provisioning is can hapen in both directions in most contexts.
420 85ad3d82 Assos Assos
      case 'ldap_user_insert_drupal_user':
421
      case 'ldap_user_update_drupal_user':
422
      case 'ldap_authentication_authenticate':
423
      case 'ldap_user_insert_drupal_user':
424
      case 'ldap_user_disable_drupal_user':
425
        $result = LDAP_USER_PROV_DIRECTION_ALL;
426
        break;
427
428
      default:
429
        $result = LDAP_USER_PROV_DIRECTION_ALL;
430
431
    }
432
433
    return $result;
434
  }
435
436
  /**
437 32700c57 Assos Assos
   * Derive mapping array from ldap user configuration and other configurations.
438
   * if this becomes a resource hungry function should be moved to ldap_user functions
439
   * and stored with static variable. should be cached also.
440
   *
441
   * This should be cached and modules implementing ldap_user_synch_mapping_alter
442
   * should know when to invalidate cache.
443
   */
444 85ad3d82 Assos Assos
445 32700c57 Assos Assos
  /**
446
   * @todo change default to false after development
447 85ad3d82 Assos Assos
   */
448 32700c57 Assos Assos
  public function setSynchMapping($reset = TRUE) {
449 85ad3d82 Assos Assos
450
    $synch_mapping_cache = cache_get('ldap_user_synch_mapping');
451
    if (!$reset && $synch_mapping_cache) {
452
      $this->synchMapping = $synch_mapping_cache->data;
453
    }
454
    else {
455 32700c57 Assos Assos
      $available_user_attrs = [];
456
      foreach ([LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER, LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY] as $direction) {
457 85ad3d82 Assos Assos
        $sid = $this->provisionSidFromDirection[$direction];
458 32700c57 Assos Assos
        $available_user_attrs[$direction] = [];
459 85ad3d82 Assos Assos
        $ldap_server = ($sid) ? ldap_servers_get_servers($sid, NULL, TRUE) : FALSE;
460
461 32700c57 Assos Assos
        $params = [
462 85ad3d82 Assos Assos
          'ldap_server' => $ldap_server,
463
          'ldap_user_conf' => $this,
464
          'direction' => $direction,
465 32700c57 Assos Assos
        ];
466 85ad3d82 Assos Assos
467
        drupal_alter('ldap_user_attrs_list', $available_user_attrs[$direction], $params);
468
      }
469
    }
470
    $this->synchMapping = $available_user_attrs;
471
472 bc175c27 Assos Assos
    cache_set('ldap_user_synch_mapping', $this->synchMapping);
473 85ad3d82 Assos Assos
  }
474
475
  /**
476 32700c57 Assos Assos
   * Given a $prov_event determine if ldap user configuration supports it.
477
   *   this is overall, not per field synching configuration.
478 85ad3d82 Assos Assos
   *
479 32700c57 Assos Assos
   * @param enum $direction
480
   *   LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER or LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY.
481 85ad3d82 Assos Assos
   *
482
   * @param enum $prov_event
483
   *   LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER, LDAP_USER_EVENT_CREATE_DRUPAL_USER
484
   *   LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY LDAP_USER_EVENT_CREATE_LDAP_ENTRY
485
   *   LDAP_USER_EVENT_LDAP_ASSOCIATE_DRUPAL_ACCT
486 32700c57 Assos Assos
   *   LDAP_USER_EVENT_ALL.
487
   *
488
   * @param enum $action
489
   *   'synch', 'provision', 'delete_ldap_entry', 'delete_drupal_entry', 'cancel_drupal_entry'.
490 85ad3d82 Assos Assos
   *
491 32700c57 Assos Assos
   * @return bool
492 85ad3d82 Assos Assos
   */
493
  public function provisionEnabled($direction, $provision_trigger) {
494
    $result = FALSE;
495
496
    if ($direction == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) {
497
498
      if (!$this->ldapEntryProvisionServer) {
499
        $result = FALSE;
500
      }
501
      else {
502
        $result = in_array($provision_trigger, $this->ldapEntryProvisionTriggers);
503
      }
504
505
    }
506
    elseif ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) {
507
      if (!$this->drupalAcctProvisionServer) {
508
        $result = FALSE;
509
      }
510
      else {
511
        $result = in_array($provision_trigger, $this->drupalAcctProvisionTriggers);
512
      }
513
    }
514
515
    return $result;
516
  }
517
518 32700c57 Assos Assos
  /**
519
   * Given a drupal account, provision an ldap entry if none exists.  if one exists do nothing.
520 85ad3d82 Assos Assos
   *
521 32700c57 Assos Assos
   * @param object $account
522
   *   drupal account object with minimum of name property.
523
   * @param array $ldap_user
524
   *   as prepopulated ldap entry.  usually not provided.
525 85ad3d82 Assos Assos
   *
526
   * @return array of form:
527 32700c57 Assos Assos
   *   array('status' => 'success', 'fail', or 'conflict'),
528 85ad3d82 Assos Assos
   *     array('ldap_server' => ldap server object),
529
   *     array('proposed' => proposed ldap entry),
530
   *     array('existing' => existing ldap entry),
531
   *     array('description' = > blah blah)
532
   */
533
  public function provisionLdapEntry($account, $ldap_user = NULL, $test_query = FALSE) {
534 32700c57 Assos Assos
    $watchdog_tokens = [];
535
    $result = [
536 85ad3d82 Assos Assos
      'status' => NULL,
537
      'ldap_server' => NULL,
538
      'proposed' => NULL,
539
      'existing' => NULL,
540
      'description' => NULL,
541 32700c57 Assos Assos
    ];
542 85ad3d82 Assos Assos
543
    if (is_scalar($account)) {
544
      $username = $account;
545
      $account = new stdClass();
546 be58a50c Assos Assos
      $account->name = $username;
547 85ad3d82 Assos Assos
    }
548
549
    list($account, $user_entity) = ldap_user_load_user_acct_and_entity($account->name);
550
551
    if (is_object($account) && property_exists($account, 'uid') && $account->uid == 1) {
552
      $result['status'] = 'fail';
553
      $result['error_description'] = 'can not provision drupal user 1';
554 32700c57 Assos Assos
      // Do not provision or synch user 1.
555
      return $result;
556 85ad3d82 Assos Assos
    }
557
558
    if ($account == FALSE || $account->uid == 0) {
559
      $result['status'] = 'fail';
560
      $result['error_description'] = 'can not provision ldap user unless corresponding drupal account exists first.';
561
      return $result;
562
    }
563
564
    if (!$this->ldapEntryProvisionServer || !$this->ldapEntryProvisionServer) {
565
      $result['status'] = 'fail';
566
      $result['error_description'] = 'no provisioning server enabled';
567
      return $result;
568
    }
569
570
    $ldap_server = ldap_servers_get_servers($this->ldapEntryProvisionServer, NULL, TRUE);
571 32700c57 Assos Assos
    $params = [
572 85ad3d82 Assos Assos
      'direction' => LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY,
573 32700c57 Assos Assos
      'prov_events' => [LDAP_USER_EVENT_CREATE_LDAP_ENTRY],
574 85ad3d82 Assos Assos
      'module' => 'ldap_user',
575
      'function' => 'provisionLdapEntry',
576
      'include_count' => FALSE,
577 32700c57 Assos Assos
    ];
578 85ad3d82 Assos Assos
579
    list($proposed_ldap_entry, $error) = $this->drupalUserToLdapEntry($account, $ldap_server, $params, $ldap_user);
580
    $proposed_dn = (is_array($proposed_ldap_entry) && isset($proposed_ldap_entry['dn']) && $proposed_ldap_entry['dn']) ? $proposed_ldap_entry['dn'] : NULL;
581
    $proposed_dn_lcase = drupal_strtolower($proposed_dn);
582
    $existing_ldap_entry = ($proposed_dn) ? $ldap_server->dnExists($proposed_dn, 'ldap_entry') : NULL;
583
584
    if ($error == LDAP_USER_PROV_RESULT_NO_PWD) {
585
      $result['status'] = 'fail';
586
      $result['description'] = 'Can not provision ldap account without user provided password.';
587
      $result['existing'] = $existing_ldap_entry;
588
      $result['proposed'] = $proposed_ldap_entry;
589
      $result['ldap_server'] = $ldap_server;
590
    }
591
    elseif (!$proposed_dn) {
592
      $result['status'] = 'fail';
593
      $result['description'] = t('failed to derive dn and or mappings');
594
      return $result;
595
    }
596
    elseif ($existing_ldap_entry) {
597
      $result['status'] = 'conflict';
598
      $result['description'] = 'can not provision ldap entry because exists already';
599
      $result['existing'] = $existing_ldap_entry;
600
      $result['proposed'] = $proposed_ldap_entry;
601
      $result['ldap_server'] = $ldap_server;
602
    }
603
    elseif ($test_query) {
604
      $result['status'] = 'fail';
605
      $result['description'] = 'not created because flagged as test query';
606
      $result['proposed'] = $proposed_ldap_entry;
607
      $result['ldap_server'] = $ldap_server;
608
    }
609
    else {
610 32700c57 Assos Assos
      // Stick $proposed_ldap_entry in $ldap_entries array for drupal_alter call.
611
      $ldap_entries = [$proposed_dn_lcase => $proposed_ldap_entry];
612
      $context = [
613 85ad3d82 Assos Assos
        'action' => 'add',
614 32700c57 Assos Assos
        'corresponding_drupal_data' => [$proposed_dn_lcase => $account],
615 85ad3d82 Assos Assos
        'corresponding_drupal_data_type' => 'user',
616 32700c57 Assos Assos
      ];
617 85ad3d82 Assos Assos
      drupal_alter('ldap_entry_pre_provision', $ldap_entries, $ldap_server, $context);
618 32700c57 Assos Assos
      // Remove altered $proposed_ldap_entry from $ldap_entries array.
619 85ad3d82 Assos Assos
      $proposed_ldap_entry = $ldap_entries[$proposed_dn_lcase];
620
621
      $ldap_entry_created = $ldap_server->createLdapEntry($proposed_ldap_entry, $proposed_dn);
622
      if ($ldap_entry_created) {
623
        module_invoke_all('ldap_entry_post_provision', $ldap_entries, $ldap_server, $context);
624
        $result['status'] = 'success';
625
        $result['description'] = 'ldap account created';
626
        $result['proposed'] = $proposed_ldap_entry;
627
        $result['created'] = $ldap_entry_created;
628
        $result['ldap_server'] = $ldap_server;
629
630 32700c57 Assos Assos
        // Need to store <sid>|<dn> in ldap_user_prov_entries field, which may contain more than one.
631 85ad3d82 Assos Assos
        $ldap_user_prov_entry = $ldap_server->sid . '|' . $proposed_ldap_entry['dn'];
632 7547bb19 Assos Assos
        if (!isset($user_entity->ldap_user_prov_entries[LANGUAGE_NONE])) {
633 32700c57 Assos Assos
          $user_entity->ldap_user_prov_entries = [LANGUAGE_NONE => []];
634 85ad3d82 Assos Assos
        }
635
        $ldap_user_prov_entry_exists = FALSE;
636 7547bb19 Assos Assos
        foreach ($user_entity->ldap_user_prov_entries[LANGUAGE_NONE] as $i => $field_value_instance) {
637 85ad3d82 Assos Assos
          if ($field_value_instance == $ldap_user_prov_entry) {
638
            $ldap_user_prov_entry_exists = TRUE;
639
          }
640
        }
641
        if (!$ldap_user_prov_entry_exists) {
642 32700c57 Assos Assos
          $user_entity->ldap_user_prov_entries[LANGUAGE_NONE][] = [
643 bc175c27 Assos Assos
            'value' => $ldap_user_prov_entry,
644 32700c57 Assos Assos
          ];
645 5136ce55 Assos Assos
646
          // Save the field without calling user_save()
647
          field_attach_presave('user', $user_entity);
648
          field_attach_update('user', $user_entity);
649 85ad3d82 Assos Assos
        }
650
651
      }
652
      else {
653
        $result['status'] = 'fail';
654
        $result['proposed'] = $proposed_ldap_entry;
655
        $result['created'] = $ldap_entry_created;
656
        $result['ldap_server'] = $ldap_server;
657
        $result['existing'] = NULL;
658
      }
659
    }
660
661 32700c57 Assos Assos
    $tokens = [
662 85ad3d82 Assos Assos
      '%dn' => isset($result['proposed']['dn']) ? $result['proposed']['dn'] : NULL,
663
      '%sid' => (isset($result['ldap_server']) && $result['ldap_server']) ? $result['ldap_server']->sid : 0,
664
      '%username' => @$account->name,
665
      '%uid' => @$account->uid,
666
      '%description' => @$result['description'],
667 32700c57 Assos Assos
    ];
668 85ad3d82 Assos Assos
    if (!$test_query && isset($result['status'])) {
669
      if ($result['status'] == 'success') {
670
        if ($this->detailedWatchdog) {
671
          watchdog('ldap_user', 'LDAP entry on server %sid created dn=%dn.  %description. username=%username, uid=%uid', $tokens, WATCHDOG_INFO);
672
        }
673
      }
674
      elseif ($result['status'] == 'conflict') {
675
        if ($this->detailedWatchdog) {
676
          watchdog('ldap_user', 'LDAP entry on server %sid not created because of existing ldap entry. %description. username=%username, uid=%uid', $tokens, WATCHDOG_WARNING);
677
        }
678
      }
679
      elseif ($result['status'] == 'fail') {
680
        watchdog('ldap_user', 'LDAP entry on server %sid not created because error.  %description. username=%username, uid=%uid', $tokens, WATCHDOG_ERROR);
681
      }
682
    }
683
    return $result;
684
  }
685
686
  /**
687 32700c57 Assos Assos
   * Given a drupal account, synch to related ldap entry.
688 85ad3d82 Assos Assos
   *
689 32700c57 Assos Assos
   * @param drupal user object $account
690
   *   Drupal user object.
691
   * @param array $user_edit
692
   *   Edit array for user_save.  generally null unless user account is being created or modified in same synching.
693
   * @param array $ldap_user
694
   *   current ldap data of user. @see README.developers.txt for structure.
695 85ad3d82 Assos Assos
   *
696
   * @return TRUE on success or FALSE on fail.
697
   */
698 32700c57 Assos Assos
  public function synchToLdapEntry($account, $user_edit = NULL, $ldap_user = [], $test_query = FALSE) {
699 85ad3d82 Assos Assos
700
    if (is_object($account) && property_exists($account, 'uid') && $account->uid == 1) {
701 32700c57 Assos Assos
      // Do not provision or synch user 1.
702
      return FALSE;
703 85ad3d82 Assos Assos
    }
704
705 32700c57 Assos Assos
    $watchdog_tokens = [];
706 85ad3d82 Assos Assos
    $result = FALSE;
707
    $proposed_ldap_entry = FALSE;
708
709
    if ($this->ldapEntryProvisionServer) {
710
      $ldap_server = ldap_servers_get_servers($this->ldapEntryProvisionServer, NULL, TRUE);
711
712 32700c57 Assos Assos
      $params = [
713 85ad3d82 Assos Assos
        'direction' => LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY,
714 32700c57 Assos Assos
        'prov_events' => [LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY],
715 85ad3d82 Assos Assos
        'module' => 'ldap_user',
716
        'function' => 'synchToLdapEntry',
717
        'include_count' => FALSE,
718 32700c57 Assos Assos
      ];
719 85ad3d82 Assos Assos
720
      list($proposed_ldap_entry, $error) = $this->drupalUserToLdapEntry($account, $ldap_server, $params, $ldap_user);
721
      if ($error != LDAP_USER_PROV_RESULT_NO_ERROR) {
722
        $result = FALSE;
723
      }
724
      elseif (is_array($proposed_ldap_entry) && isset($proposed_ldap_entry['dn'])) {
725
        $existing_ldap_entry = $ldap_server->dnExists($proposed_ldap_entry['dn'], 'ldap_entry');
726 32700c57 Assos Assos
        // This array represents attributes to be modified; not comprehensive list of attributes.
727
        $attributes = [];
728 85ad3d82 Assos Assos
        foreach ($proposed_ldap_entry as $attr_name => $attr_values) {
729
          if ($attr_name != 'dn') {
730
            if (isset($attr_values['count'])) {
731
              unset($attr_values['count']);
732
            }
733
            if (count($attr_values) == 1) {
734
              $attributes[$attr_name] = $attr_values[0];
735
            }
736
            else {
737
              $attributes[$attr_name] = $attr_values;
738
            }
739
          }
740
        }
741
742
        if ($test_query) {
743
          $proposed_ldap_entry = $attributes;
744 32700c57 Assos Assos
          $result = [
745 85ad3d82 Assos Assos
            'proposed' => $proposed_ldap_entry,
746
            'server' => $ldap_server,
747 32700c57 Assos Assos
          ];
748 85ad3d82 Assos Assos
        }
749
        else {
750 32700c57 Assos Assos
          // Stick $proposed_ldap_entry in $ldap_entries array for drupal_alter call.
751 85ad3d82 Assos Assos
          $proposed_dn_lcase = drupal_strtolower($proposed_ldap_entry['dn']);
752 32700c57 Assos Assos
          $ldap_entries = [$proposed_dn_lcase => $attributes];
753
          $context = [
754 85ad3d82 Assos Assos
            'action' => 'update',
755 32700c57 Assos Assos
            'corresponding_drupal_data' => [$proposed_dn_lcase => $attributes],
756 85ad3d82 Assos Assos
            'corresponding_drupal_data_type' => 'user',
757 32700c57 Assos Assos
          ];
758 85ad3d82 Assos Assos
          drupal_alter('ldap_entry_pre_provision', $ldap_entries, $ldap_server, $context);
759 32700c57 Assos Assos
          // Remove altered $proposed_ldap_entry from $ldap_entries array.
760 85ad3d82 Assos Assos
          $attributes = $ldap_entries[$proposed_dn_lcase];
761
          $result = $ldap_server->modifyLdapEntry($proposed_ldap_entry['dn'], $attributes);
762 32700c57 Assos Assos
          // Success.
763
          if ($result) {
764 85ad3d82 Assos Assos
            module_invoke_all('ldap_entry_post_provision', $ldap_entries, $ldap_server, $context);
765
          }
766
        }
767
      }
768 32700c57 Assos Assos
      // Failed to get acceptable proposed ldap entry.
769
      else {
770 85ad3d82 Assos Assos
        $result = FALSE;
771
      }
772
    }
773
774 32700c57 Assos Assos
    $tokens = [
775 85ad3d82 Assos Assos
      '%dn' => isset($proposed_ldap_entry['dn']) ? $proposed_ldap_entry['dn'] : NULL,
776
      '%sid' => $this->ldapEntryProvisionServer,
777
      '%username' => $account->name,
778
      '%uid' => ($test_query || !property_exists($account, 'uid')) ? '' : $account->uid,
779 32700c57 Assos Assos
    ];
780 85ad3d82 Assos Assos
781
    if ($result) {
782
      watchdog('ldap_user', 'LDAP entry on server %sid synched dn=%dn. username=%username, uid=%uid', $tokens, WATCHDOG_INFO);
783
    }
784
    else {
785
      watchdog('ldap_user', 'LDAP entry on server %sid not synched because error. username=%username, uid=%uid', $tokens, WATCHDOG_ERROR);
786
    }
787
788
    return $result;
789
790
  }
791
792
  /**
793 32700c57 Assos Assos
   * Given a drupal account, query ldap and get all user fields and create user account.
794 85ad3d82 Assos Assos
   *
795 32700c57 Assos Assos
   * @param array $account
796
   *   drupal account array with minimum of name.
797
   * @param array $user_edit
798
   *   drupal edit array in form user_save($account, $user_edit) would take,
799
   *   generally empty unless overriding synchToDrupalAccount derived values.
800
   * @param array $ldap_user
801
   *   as user's ldap entry.  passed to avoid requerying ldap in cases where already present.
802
   * @param bool $save
803
   *   indicating if drupal user should be saved.  generally depends on where function is called from.
804 85ad3d82 Assos Assos
   *
805 32700c57 Assos Assos
   * @return bool|object
806
   *   Result of user_save() function is $save is true, otherwise return TRUE
807 85ad3d82 Assos Assos
   *   $user_edit data returned by reference
808
   */
809 bc175c27 Assos Assos
  public function synchToDrupalAccount($drupal_user, &$user_edit, $prov_event = LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER, $ldap_user = NULL, $save = FALSE) {
810
811 32700c57 Assos Assos
    $debug = [
812 85ad3d82 Assos Assos
      'account' => $drupal_user,
813
      'user_edit' => $user_edit,
814
      'ldap_user' => $ldap_user,
815 32700c57 Assos Assos
    ];
816 85ad3d82 Assos Assos
817
    if (
818
        (!$ldap_user  && !isset($drupal_user->name)) ||
819
        (!$drupal_user && $save) ||
820
        ($ldap_user && !isset($ldap_user['sid']))
821
    ) {
822 32700c57 Assos Assos
      // Should throw watchdog error also.
823 85ad3d82 Assos Assos
      return FALSE;
824
    }
825
826
    if (!$ldap_user && $this->drupalAcctProvisionServer) {
827
      $ldap_user = ldap_servers_get_user_ldap_data($drupal_user->name, $this->drupalAcctProvisionServer, 'ldap_user_prov_to_drupal');
828
    }
829
830
    if (!$ldap_user) {
831
      return FALSE;
832
    }
833
834
    if ($this->drupalAcctProvisionServer) {
835
      $ldap_server = ldap_servers_get_servers($this->drupalAcctProvisionServer, NULL, TRUE);
836 32700c57 Assos Assos
      $this->entryToUserEdit($ldap_user, $user_edit, $ldap_server, LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER, [$prov_event]);
837 85ad3d82 Assos Assos
    }
838
839
    if ($save) {
840
      $account = user_load($drupal_user->uid);
841
      $result = user_save($account, $user_edit, 'ldap_user');
842
      return $result;
843
    }
844
    else {
845
      return TRUE;
846
    }
847
  }
848
849
  /**
850 32700c57 Assos Assos
   * Given a drupal account, delete user account.
851
   *
852
   * @param string $username
853
   *   drupal account name.
854 85ad3d82 Assos Assos
   *
855
   * @return TRUE or FALSE.  FALSE indicates failed or action not enabled in ldap user configuration
856
   */
857
  public function deleteDrupalAccount($username) {
858
    $user = user_load_by_name($username);
859
    if (is_object($user)) {
860
      user_delete($user->uid);
861
      return TRUE;
862
    }
863
    else {
864
      return FALSE;
865
    }
866
  }
867
868
  /**
869 32700c57 Assos Assos
   * Given a drupal account, find the related ldap entry.
870 85ad3d82 Assos Assos
   *
871
   * @param drupal user object $account
872
   *
873
   * @return FALSE or ldap entry
874
   */
875
  public function getProvisionRelatedLdapEntry($account, $prov_events = NULL) {
876
    if (!$prov_events) {
877
      $prov_events = ldap_user_all_events();
878
    }
879 32700c57 Assos Assos
    $sid = $this->ldapEntryProvisionServer;
880 85ad3d82 Assos Assos
    if (!$sid) {
881
      return FALSE;
882
    }
883 32700c57 Assos Assos
    // $user_entity->ldap_user_prov_entries,.
884 85ad3d82 Assos Assos
    $ldap_server = ldap_servers_get_servers($sid, NULL, TRUE);
885 32700c57 Assos Assos
    $params = [
886 85ad3d82 Assos Assos
      'direction' => LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY,
887
      'prov_events' => $prov_events,
888
      'module' => 'ldap_user',
889
      'function' => 'getProvisionRelatedLdapEntry',
890
      'include_count' => FALSE,
891 32700c57 Assos Assos
    ];
892 85ad3d82 Assos Assos
    list($proposed_ldap_entry, $error) = $this->drupalUserToLdapEntry($account, $ldap_server, $params);
893
    if (!(is_array($proposed_ldap_entry) && isset($proposed_ldap_entry['dn']) && $proposed_ldap_entry['dn'])) {
894
      return FALSE;
895
    }
896 32700c57 Assos Assos
    $ldap_entry = $ldap_server->dnExists($proposed_ldap_entry['dn'], 'ldap_entry', []);
897 85ad3d82 Assos Assos
    return $ldap_entry;
898
899
  }
900
901
  /**
902 32700c57 Assos Assos
   * Given a drupal account, delete ldap entry that was provisioned based on it
903 85ad3d82 Assos Assos
   *   normally this will be 0 or 1 entry, but the ldap_user_provisioned_ldap_entries
904 32700c57 Assos Assos
   *   field attached to the user entity track each ldap entry provisioned.
905
   *
906
   * @param object $account
907
   *   drupal account.
908 85ad3d82 Assos Assos
   *
909
   * @return TRUE or FALSE.  FALSE indicates failed or action not enabled in ldap user configuration
910
   */
911
  public function deleteProvisionedLdapEntries($account) {
912 32700c57 Assos Assos
    // Determine server that is associated with user.
913 85ad3d82 Assos Assos
    $boolean_result = FALSE;
914 be58a50c Assos Assos
    if (isset($account->ldap_user_prov_entries[LANGUAGE_NONE][0])) {
915
      foreach ($account->ldap_user_prov_entries[LANGUAGE_NONE] as $i => $field_instance) {
916 85ad3d82 Assos Assos
        $parts = explode('|', $field_instance['value']);
917
        if (count($parts) == 2) {
918
919
          list($sid, $dn) = $parts;
920
          $ldap_server = ldap_servers_get_servers($sid, NULL, TRUE);
921
          if (is_object($ldap_server) && $dn) {
922
            $boolean_result = $ldap_server->delete($dn);
923 32700c57 Assos Assos
            $tokens = ['%sid' => $sid, '%dn' => $dn, '%username' => $account->name, '%uid' => $account->uid];
924 85ad3d82 Assos Assos
            if ($boolean_result) {
925
              watchdog('ldap_user', 'LDAP entry on server %sid deleted dn=%dn. username=%username, uid=%uid', $tokens, WATCHDOG_INFO);
926
            }
927
            else {
928
              watchdog('ldap_user', 'LDAP entry on server %sid not deleted because error. username=%username, uid=%uid', $tokens, WATCHDOG_ERROR);
929
            }
930
          }
931
          else {
932
            $boolean_result = FALSE;
933
          }
934
        }
935
      }
936
    }
937
    return $boolean_result;
938
939
  }
940
941 32700c57 Assos Assos
  /**
942
   * Populate ldap entry array for provisioning.
943
   *
944
   * @param array $account
945
   *   drupal account.
946
   * @param \LdapServer $ldap_server
947
   * @param array $ldap_user
948
   *   ldap entry of user, returned by reference.
949
   * @param array $params
950
   *   with the following key values:
951
   *   'ldap_context' =>
952
   *   'module' => module calling function, e.g. 'ldap_user'
953
   *   'function' => function calling function, e.g. 'provisionLdapEntry'
954
   *   'include_count' => should 'count' array key be included
955
   *   'direction' => LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY || LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER.
956
   *
957
   * @return array(ldap entry, $result) in ldap extension array format.!THIS IS NOT THE ACTUAL LDAP ENTRY
958
   */
959
  public function drupalUserToLdapEntry($account, $ldap_server, $params, $ldap_user_entry = NULL) {
960 85ad3d82 Assos Assos
    $provision = (isset($params['function']) && $params['function'] == 'provisionLdapEntry');
961
    $result = LDAP_USER_PROV_RESULT_NO_ERROR;
962
    if (!$ldap_user_entry) {
963 32700c57 Assos Assos
      $ldap_user_entry = [];
964 85ad3d82 Assos Assos
    }
965
966
    if (!is_object($account) || !is_object($ldap_server)) {
967 32700c57 Assos Assos
      return [NULL, LDAP_USER_PROV_RESULT_BAD_PARAMS];
968 85ad3d82 Assos Assos
    }
969 32700c57 Assos Assos
    $watchdog_tokens = [
970 85ad3d82 Assos Assos
      '%drupal_username' => $account->name,
971 32700c57 Assos Assos
    ];
972 85ad3d82 Assos Assos
    $include_count = (isset($params['include_count']) && $params['include_count']);
973
974
    $direction = isset($params['direction']) ? $params['direction'] : LDAP_USER_PROV_DIRECTION_ALL;
975
    $prov_events = empty($params['prov_events']) ? ldap_user_all_events() : $params['prov_events'];
976
977
    $mappings = $this->getSynchMappings($direction, $prov_events);
978
    foreach ($mappings as $field_key => $field_detail) {
979 32700c57 Assos Assos
      list($ldap_attr_name, $ordinal, $conversion) = ldap_servers_token_extract_parts($field_key, TRUE);
980 85ad3d82 Assos Assos
      $ordinal = (!$ordinal) ? 0 : $ordinal;
981 32700c57 Assos Assos
      if ($ldap_user_entry && isset($ldap_user_entry[$ldap_attr_name]) && is_array($ldap_user_entry[$ldap_attr_name]) && isset($ldap_user_entry[$ldap_attr_name][$ordinal])) {
982
        // don't override values passed in.
983
        continue;
984 85ad3d82 Assos Assos
      }
985
986
      $synched = $this->isSynched($field_key, $params['prov_events'], LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY);
987
      if ($synched) {
988
        $token = ($field_detail['user_attr'] == 'user_tokens') ? $field_detail['user_tokens'] : $field_detail['user_attr'];
989
        $value = ldap_servers_token_replace($account, $token, 'user_account');
990
991 32700c57 Assos Assos
        // Deal with empty/unresolved password.
992
        if (substr($token, 0, 10) == '[password.' && (!$value || $value == $token)) {
993 85ad3d82 Assos Assos
          if (!$provision) {
994 32700c57 Assos Assos
            // don't overwrite password on synch if no value provided.
995
            continue;
996 85ad3d82 Assos Assos
          }
997
        }
998
999
        if ($ldap_attr_name == 'dn' && $value) {
1000
          $ldap_user_entry['dn'] = $value;
1001
        }
1002
        elseif ($value) {
1003
          if (!isset($ldap_user_entry[$ldap_attr_name]) || !is_array($ldap_user_entry[$ldap_attr_name])) {
1004 32700c57 Assos Assos
            $ldap_user_entry[$ldap_attr_name] = [];
1005 85ad3d82 Assos Assos
          }
1006
          $ldap_user_entry[$ldap_attr_name][$ordinal] = $value;
1007
          if ($include_count) {
1008
            $ldap_user_entry[$ldap_attr_name]['count'] = count($ldap_user_entry[$ldap_attr_name]);
1009
          }
1010
1011
        }
1012
1013
      }
1014
1015
    }
1016
1017
    /**
1018
     * 4. call drupal_alter() to allow other modules to alter $ldap_user
1019
     */
1020 bc175c27 Assos Assos
    $params['account'] = $account;
1021 85ad3d82 Assos Assos
    drupal_alter('ldap_entry', $ldap_user_entry, $params);
1022
1023 32700c57 Assos Assos
    return [$ldap_user_entry, $result];
1024 85ad3d82 Assos Assos
1025
  }
1026
1027 32700c57 Assos Assos
  /**
1028
   * Given a drupal account, query ldap and get all user fields and save user account
1029 85ad3d82 Assos Assos
   * (note: parameters are in odd order to match synchDrupalAccount handle)
1030
   *
1031 32700c57 Assos Assos
   * @param array $account
1032
   *   drupal account object or null.
1033
   * @param array $user_edit
1034
   *   drupal edit array in form user_save($account, $user_edit) would take.
1035
   * @param array $ldap_user
1036
   *   as user's ldap entry.  passed to avoid requerying ldap in cases where already present.
1037
   * @param bool $save
1038
   *   indicating if drupal user should be saved.  generally depends on where function is called from and if the.
1039 85ad3d82 Assos Assos
   *
1040 32700c57 Assos Assos
   * @return bool
1041
   *   Resultof user_save() function is $save is true, otherwise return TRUE on
1042
   *   success or FALSE on any problem
1043 85ad3d82 Assos Assos
   *
1044 32700c57 Assos Assos
   *   $user_edit data returned by reference
1045 85ad3d82 Assos Assos
   */
1046
  public function provisionDrupalAccount($account = FALSE, &$user_edit, $ldap_user = NULL, $save = TRUE) {
1047
1048 32700c57 Assos Assos
    $watchdog_tokens = [];
1049 85ad3d82 Assos Assos
    /**
1050
     * @todo
1051
     * -- add error catching for conflicts, conflicts should be checked before calling this function.
1052
     *
1053
     */
1054
1055
    if (!$account) {
1056
      $account = new stdClass();
1057
    }
1058
    $account->is_new = TRUE;
1059
1060
    if (!$ldap_user && !isset($user_edit['name'])) {
1061
      return FALSE;
1062
    }
1063
1064
    if (!$ldap_user) {
1065
      $watchdog_tokens['%username'] = $user_edit['name'];
1066
      if ($this->drupalAcctProvisionServer) {
1067
        $ldap_user = ldap_servers_get_user_ldap_data($user_edit['name'], $this->drupalAcctProvisionServer, 'ldap_user_prov_to_drupal');
1068
      }
1069
      if (!$ldap_user) {
1070
        if ($this->detailedWatchdog) {
1071
          watchdog('ldap_user', '%username : failed to find associated ldap entry for username in provision.', $watchdog_tokens, WATCHDOG_DEBUG);
1072
        }
1073
        return FALSE;
1074
      }
1075
    }
1076 59ae487e Assos Assos
1077 85ad3d82 Assos Assos
    if (!isset($user_edit['name']) && isset($account->name)) {
1078
      $user_edit['name'] = $account->name;
1079
      $watchdog_tokens['%username'] = $user_edit['name'];
1080
    }
1081 32700c57 Assos Assos
    // When using the multi-domain last authentication option
1082
    // $ldap_server breaks beacause $this->drupalAcctProvisionServer is set on LDAP_USER_AUTH_SERVER_SID
1083
    // So we need to check it's not the case before using ldap_servers_get_servers.
1084 dd54aff9 Assos Assos
    if ($this->drupalAcctProvisionServer && $this->drupalAcctProvisionServer != LDAP_USER_AUTH_SERVER_SID) {
1085 85ad3d82 Assos Assos
1086 32700c57 Assos Assos
      /** @var \LdapServer $ldap_server */
1087
      // $ldap_user['sid'].
1088
      $ldap_server = ldap_servers_get_servers($this->drupalAcctProvisionServer, 'enabled', TRUE);
1089 85ad3d82 Assos Assos
1090 32700c57 Assos Assos
      $params = [
1091 85ad3d82 Assos Assos
        'account' => $account,
1092
        'user_edit' => $user_edit,
1093
        'prov_event' => LDAP_USER_EVENT_CREATE_DRUPAL_USER,
1094
        'module' => 'ldap_user',
1095
        'function' => 'provisionDrupalAccount',
1096
        'direction' => LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER,
1097 32700c57 Assos Assos
      ];
1098 85ad3d82 Assos Assos
1099
      drupal_alter('ldap_entry', $ldap_user, $params);
1100
1101 32700c57 Assos Assos
      // Look for existing drupal account with same puid.  if so update username and attempt to synch in current context.
1102 85ad3d82 Assos Assos
      $puid = $ldap_server->userPuidFromLdapEntry($ldap_user['attr']);
1103 32700c57 Assos Assos
      $existing_account_from_puid = ($puid) ? $ldap_server->userUserEntityFromPuid($puid) : FALSE;
1104
1105
      // Synch drupal account, since drupal account exists.
1106
      if ($existing_account_from_puid) {
1107
        // 1. correct username and authmap.
1108
        $this->entryToUserEdit($ldap_user, $user_edit, $ldap_server, LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER, [LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER]);
1109
        $account = user_save($existing_account_from_puid, $user_edit, 'ldap_user');
1110
        user_set_authmaps($account, ["authname_ldap_user" => $user_edit['name']]);
1111
        // 2. attempt synch if appropriate for current context.
1112 85ad3d82 Assos Assos
        if ($account) {
1113
          $account = $this->synchToDrupalAccount($account, $user_edit, LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER, $ldap_user, TRUE);
1114
        }
1115
        return $account;
1116
      }
1117 32700c57 Assos Assos
      // Create drupal account.
1118
      else {
1119
        $this->entryToUserEdit($ldap_user, $user_edit, $ldap_server, LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER, [LDAP_USER_EVENT_CREATE_DRUPAL_USER]);
1120 85ad3d82 Assos Assos
        if ($save) {
1121 32700c57 Assos Assos
          $watchdog_tokens = ['%drupal_username' => $user_edit['name']];
1122 85ad3d82 Assos Assos
          if (empty($user_edit['name'])) {
1123
            drupal_set_message(t('User account creation failed because of invalid, empty derived Drupal username.'), 'error');
1124
            watchdog('ldap_user',
1125
              'Failed to create Drupal account %drupal_username because drupal username could not be derived.',
1126
              $watchdog_tokens,
1127
              WATCHDOG_ERROR
1128
            );
1129
            return FALSE;
1130
          }
1131
          if (!isset($user_edit['mail']) || !$user_edit['mail']) {
1132
            drupal_set_message(t('User account creation failed because of invalid, empty derived email address.'), 'error');
1133
            watchdog('ldap_user',
1134
              'Failed to create Drupal account %drupal_username because email address could not be derived by LDAP User module',
1135
              $watchdog_tokens,
1136
              WATCHDOG_ERROR
1137
            );
1138
            return FALSE;
1139
          }
1140 32700c57 Assos Assos
          if (($this->accountsWithSameEmail == LDAP_USER_ACCOUNTS_WITH_SAME_EMAIL_DISABLED) && ($account_with_same_email = user_load_by_mail($user_edit['mail']))) {
1141 85ad3d82 Assos Assos
            $watchdog_tokens['%email'] = $user_edit['mail'];
1142
            $watchdog_tokens['%duplicate_name'] = $account_with_same_email->name;
1143
            watchdog('ldap_user', 'LDAP user %drupal_username has email address
1144
              (%email) conflict with a drupal user %duplicate_name', $watchdog_tokens, WATCHDOG_ERROR);
1145
            drupal_set_message(t('Another user already exists in the system with the same email address. You should contact the system administrator in order to solve this conflict.'), 'error');
1146
            return FALSE;
1147
          }
1148
          $account = user_save(NULL, $user_edit, 'ldap_user');
1149
          if (!$account) {
1150
            drupal_set_message(t('User account creation failed because of system problems.'), 'error');
1151
          }
1152
          else {
1153 32700c57 Assos Assos
            user_set_authmaps($account, ['authname_ldap_user' => $account->name]);
1154 85ad3d82 Assos Assos
            ldap_user_ldap_provision_semaphore('drupal_created', 'set', $account->name);
1155
          }
1156
          return $account;
1157
        }
1158
        return TRUE;
1159
      }
1160
    }
1161
  }
1162
1163
  /**
1164 32700c57 Assos Assos
   * Set ldap associations of a drupal account by altering user fields.
1165 85ad3d82 Assos Assos
   *
1166
   * @param string $drupal_username
1167
   *
1168 32700c57 Assos Assos
   * @return bool
1169
   *   TRUE on success, FALSE on error or failure because of invalid user or ldap accounts
1170 85ad3d82 Assos Assos
   */
1171 32700c57 Assos Assos
  public function ldapAssociateDrupalAccount($drupal_username) {
1172 85ad3d82 Assos Assos
1173
    if ($this->drupalAcctProvisionServer) {
1174 32700c57 Assos Assos
      $prov_events = [LDAP_USER_EVENT_LDAP_ASSOCIATE_DRUPAL_ACCT];
1175
      // $ldap_user['sid'].
1176
      $ldap_server = ldap_servers_get_servers($this->drupalAcctProvisionServer, 'enabled', TRUE);
1177 85ad3d82 Assos Assos
      $account = user_load_by_name($drupal_username);
1178
      $ldap_user = ldap_servers_get_user_ldap_data($drupal_username, $this->drupalAcctProvisionServer, 'ldap_user_prov_to_drupal');
1179
      if (!$account) {
1180
        watchdog(
1181
          'ldap_user',
1182
          'Failed to LDAP associate drupal account %drupal_username because account not found',
1183 32700c57 Assos Assos
          ['%drupal_username' => $drupal_username],
1184 85ad3d82 Assos Assos
          WATCHDOG_ERROR
1185
        );
1186
        return FALSE;
1187
      }
1188
      elseif (!$ldap_user) {
1189
        watchdog(
1190
          'ldap_user',
1191
          'Failed to LDAP associate drupal account %drupal_username because corresponding LDAP entry not found',
1192 32700c57 Assos Assos
          ['%drupal_username' => $drupal_username],
1193 85ad3d82 Assos Assos
          WATCHDOG_ERROR
1194
        );
1195
        return FALSE;
1196
      }
1197
      else {
1198 32700c57 Assos Assos
        $user_edit = [];
1199
        $user_edit['data']['ldap_user']['init'] = [
1200 85ad3d82 Assos Assos
          'sid'  => $ldap_user['sid'],
1201
          'dn'   => $ldap_user['dn'],
1202
          'mail'   => $account->mail,
1203 32700c57 Assos Assos
        ];
1204 85ad3d82 Assos Assos
        $ldap_user_puid = $ldap_server->userPuidFromLdapEntry($ldap_user['attr']);
1205
        if ($ldap_user_puid) {
1206 32700c57 Assos Assos
          $user_edit['ldap_user_puid'][LANGUAGE_NONE][0]['value'] = $ldap_user_puid;
1207 85ad3d82 Assos Assos
        }
1208
        $user_edit['ldap_user_puid_property'][LANGUAGE_NONE][0]['value'] = $ldap_server->unique_persistent_attr;
1209
        $user_edit['ldap_user_puid_sid'][LANGUAGE_NONE][0]['value'] = $ldap_server->sid;
1210
        $user_edit['ldap_user_current_dn'][LANGUAGE_NONE][0]['value'] = $ldap_user['dn'];
1211
        $account = user_save($account, $user_edit, 'ldap_user');
1212 32700c57 Assos Assos
        return (boolean) $account;
1213 85ad3d82 Assos Assos
      }
1214
    }
1215
    else {
1216
      return FALSE;
1217
    }
1218
  }
1219
1220 32700c57 Assos Assos
  /**
1221
   * Populate $user edit array (used in hook_user_save, hook_user_update, etc)
1222
   * ... should not assume all attribues are present in ldap entry.
1223 85ad3d82 Assos Assos
   *
1224 32700c57 Assos Assos
   * @param $ldap_user
1225
   * @param array $edit
1226
   *   see hook_user_save, hook_user_update, etc.
1227
   * @param \LdapServer $ldap_server
1228
   * @param int $direction
1229 85ad3d82 Assos Assos
   * @param array $prov_events
1230
   */
1231 32700c57 Assos Assos
  public function entryToUserEdit($ldap_user, &$edit, $ldap_server, $direction = LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER, $prov_events = NULL) {
1232 85ad3d82 Assos Assos
1233 32700c57 Assos Assos
    // Need array of user fields and which direction and when they should be synched.
1234 85ad3d82 Assos Assos
    if (!$prov_events) {
1235
      $prov_events = ldap_user_all_events();
1236
    }
1237
    $mail_synched = $this->isSynched('[property.mail]', $prov_events, $direction);
1238
    if (!isset($edit['mail']) && $mail_synched) {
1239
      $derived_mail = $ldap_server->userEmailFromLdapEntry($ldap_user['attr']);
1240
      if ($derived_mail) {
1241
        $edit['mail'] = $derived_mail;
1242
      }
1243
    }
1244
1245
    $drupal_username = $ldap_server->userUsernameFromLdapEntry($ldap_user['attr']);
1246
1247
    if ($this->isSynched('[property.name]', $prov_events, $direction) && !isset($edit['name']) && $drupal_username) {
1248
      $edit['name'] = $drupal_username;
1249
    }
1250
1251
    if ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER && in_array(LDAP_USER_EVENT_CREATE_DRUPAL_USER, $prov_events)) {
1252
      $edit['mail'] = isset($edit['mail']) ? $edit['mail'] : $ldap_user['mail'];
1253
      if (!isset($edit['pass'])) {
1254
        $edit['pass'] = user_password(20);
1255 32700c57 Assos Assos
        watchdog('ldap_user', '20 character random password generated for the %username account that has been created.', ['%username' => $drupal_username], WATCHDOG_INFO);
1256 85ad3d82 Assos Assos
      }
1257
      $edit['init'] = isset($edit['init']) ? $edit['init'] : $edit['mail'];
1258
      $edit['status'] = isset($edit['status']) ? $edit['status'] : 1;
1259
      $edit['signature'] = isset($edit['signature']) ? $edit['signature'] : '';
1260
1261 32700c57 Assos Assos
      $edit['data']['ldap_user']['init'] = [
1262 85ad3d82 Assos Assos
        'sid'  => $ldap_user['sid'],
1263
        'dn'   => $ldap_user['dn'],
1264
        'mail' => $edit['mail'],
1265 32700c57 Assos Assos
      ];
1266 85ad3d82 Assos Assos
    }
1267
1268
    /*
1269
     * Make sure the user account has the latest ldap_user settings
1270
     * when syncing the profile.
1271
     */
1272
    if ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER && in_array(LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER, $prov_events)) {
1273 32700c57 Assos Assos
      $edit['data']['ldap_user']['init'] = [
1274 85ad3d82 Assos Assos
        'sid'  => $ldap_user['sid'],
1275
        'dn'   => $ldap_user['dn'],
1276
        'mail' => isset($edit['mail']) && !empty($edit['mail']) ? $edit['mail'] : $ldap_user['mail'],
1277 32700c57 Assos Assos
      ];
1278 85ad3d82 Assos Assos
    }
1279
1280 bc175c27 Assos Assos
    if ($this->isSynched('[property.picture]', $prov_events, $direction)) {
1281
      $picture = $ldap_server->userPictureFromLdapEntry($ldap_user['attr'], $drupal_username);
1282
      if ($picture) {
1283
        if (in_array(LDAP_USER_EVENT_CREATE_DRUPAL_USER, $prov_events)) {
1284
          $edit['picture'] = $picture->fid;
1285 32700c57 Assos Assos
        }
1286
        else {
1287 bc175c27 Assos Assos
          $edit['picture'] = $picture;
1288
        }
1289
        $edit['data']['ldap_user']['init']['thumb5md'] = $picture->md5Sum;
1290
      }
1291
    }
1292
1293 85ad3d82 Assos Assos
    /**
1294
     * basic $user ldap fields
1295
     */
1296
    if ($this->isSynched('[field.ldap_user_puid]', $prov_events, $direction)) {
1297
      $ldap_user_puid = $ldap_server->userPuidFromLdapEntry($ldap_user['attr']);
1298
      if ($ldap_user_puid) {
1299 32700c57 Assos Assos
        $edit['ldap_user_puid'][LANGUAGE_NONE][0]['value'] = $ldap_user_puid;
1300 85ad3d82 Assos Assos
      }
1301
    }
1302
    if ($this->isSynched('[field.ldap_user_puid_property]', $prov_events, $direction)) {
1303
      $edit['ldap_user_puid_property'][LANGUAGE_NONE][0]['value'] = $ldap_server->unique_persistent_attr;
1304
    }
1305
    if ($this->isSynched('[field.ldap_user_puid_sid]', $prov_events, $direction)) {
1306
      $edit['ldap_user_puid_sid'][LANGUAGE_NONE][0]['value'] = $ldap_server->sid;
1307
    }
1308
    if ($this->isSynched('[field.ldap_user_current_dn]', $prov_events, $direction)) {
1309
      $edit['ldap_user_current_dn'][LANGUAGE_NONE][0]['value'] = $ldap_user['dn'];
1310
    }
1311
1312
    // Get any additional mappings.
1313
    $mappings = $this->getSynchMappings($direction, $prov_events);
1314
1315 32700c57 Assos Assos
    // Loop over the mappings.
1316 85ad3d82 Assos Assos
    foreach ($mappings as $user_attr_key => $field_detail) {
1317
1318 32700c57 Assos Assos
      // Make sure this mapping is relevant to the sync context.
1319 85ad3d82 Assos Assos
      if (!$this->isSynched($user_attr_key, $prov_events, $direction)) {
1320
        continue;
1321
      }
1322 32700c57 Assos Assos
      /**
1323 85ad3d82 Assos Assos
        * if "convert from binary is selected" and no particular method is in token,
1324
        * default to ldap_servers_binary() function
1325
        */
1326
      if ($field_detail['convert'] && strpos($field_detail['ldap_attr'], ';') === FALSE) {
1327
        $field_detail['ldap_attr'] = str_replace(']', ';binary]', $field_detail['ldap_attr']);
1328
      }
1329
      $value = ldap_servers_token_replace($ldap_user['attr'], $field_detail['ldap_attr'], 'ldap_entry');
1330
      list($value_type, $value_name, $value_instance) = ldap_servers_parse_user_attr_name($user_attr_key);
1331
1332 32700c57 Assos Assos
      // $value_instance not used, may have future use case.
1333 85ad3d82 Assos Assos
      // Are we dealing with a field?
1334
      if ($value_type == 'field') {
1335
        // Field api field - first we get the field.
1336
        $field = field_info_field($value_name);
1337
        // Then the columns for the field in the schema.
1338
        $columns = array_keys($field['columns']);
1339
        // Then we convert the value into an array if it's scalar.
1340 32700c57 Assos Assos
        $values = $field['cardinality'] == 1 ? [$value] : (array) $value;
1341 85ad3d82 Assos Assos
1342 32700c57 Assos Assos
        $items = [];
1343 85ad3d82 Assos Assos
        // Loop over the values and set them in our $items array.
1344
        foreach ($values as $delta => $value) {
1345
          if (isset($value)) {
1346
            // We set the first column value only, this is consistent with
1347
            // the Entity Api (@see entity_metadata_field_property_set).
1348
            $items[$delta][$columns[0]] = $value;
1349
          }
1350
        }
1351
        // Add them to our edited item.
1352
        $edit[$value_name][LANGUAGE_NONE] = $items;
1353
      }
1354
      elseif ($value_type == 'property') {
1355
        // Straight property.
1356
        $edit[$value_name] = $value;
1357
      }
1358
    }
1359
1360
    // Allow other modules to have a say.
1361
    drupal_alter('ldap_user_edit_user', $edit, $ldap_user, $ldap_server, $prov_events);
1362 32700c57 Assos Assos
    // don't let empty 'name' value pass for user.
1363
    if (isset($edit['name']) && $edit['name'] == '') {
1364 85ad3d82 Assos Assos
      unset($edit['name']);
1365
    }
1366
1367
  }
1368 32700c57 Assos Assos
1369 85ad3d82 Assos Assos
  /**
1370 32700c57 Assos Assos
   * Given configuration of synching, determine is a given synch should occur.
1371 85ad3d82 Assos Assos
   *
1372 32700c57 Assos Assos
   * @param string $attr_token
1373
   *   e.g. [property.mail], [field.ldap_user_puid_property].
1374
   * @param array $prov_events
1375
   *   e.g. array(LDAP_USER_EVENT_CREATE_DRUPAL_USER).  typically array with 1
1376
   *   element.
1377
   * @param scalar $direction
1378
   *   LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER or
1379
   *   LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY.
1380
   *
1381
   * @return bool
1382 85ad3d82 Assos Assos
   */
1383
  public function isSynched($attr_token, $prov_events, $direction) {
1384 32700c57 Assos Assos
    $result = (boolean) (
1385 85ad3d82 Assos Assos
      isset($this->synchMapping[$direction][$attr_token]['prov_events']) &&
1386
      count(array_intersect($prov_events, $this->synchMapping[$direction][$attr_token]['prov_events']))
1387
    );
1388
    if (!$result) {
1389
      if (isset($this->synchMapping[$direction][$attr_token])) {
1390
      }
1391
      else {
1392
      }
1393
    }
1394
    return $result;
1395
  }
1396
1397 59ae487e Assos Assos
}