Projet

Général

Profil

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

root / drupal7 / sites / all / modules / ldap / ldap_user / LdapUserConfAdmin.class.php @ be58a50c

1
<?php
2

    
3
/**
4
 * @file
5
 * This classextends by LdapUserConf for configuration and other admin functions
6
 */
7

    
8
module_load_include('php', 'ldap_user', 'LdapUserConf.class');
9
module_load_include('inc', 'user', 'user.pages');
10

    
11
class LdapUserConfAdmin extends LdapUserConf {
12

    
13
  /**
14
   * basic settings
15
   */
16

    
17
  protected $drupalAcctProvisionServerDescription;
18
  protected $drupalAcctProvisionServerOptions = array();
19
  protected $ldapEntryProvisionServerOptions = array();
20

    
21
  protected $drupalAccountProvisionEventsDescription;
22
  protected $drupalAccountProvisionEventsOptions = array();
23

    
24
  protected $ldapEntryProvisionTriggersDescription;
25
  protected $ldapEntryProvisionTriggersOptions = array();
26

    
27
  protected $synchFormRow = 0;
28

    
29
  /*
30
   * 3. Drupal Account Provisioning and Syncing
31
   */
32
  public $userConflictResolveDescription;
33
  public $userConflictResolveDefault = LDAP_USER_CONFLICT_RESOLVE_DEFAULT;
34
  public $userConflictOptions;
35

    
36
  public $acctCreationDescription = '';
37
  public $acctCreationDefault = LDAP_USER_ACCT_CREATION_LDAP_BEHAVIOR_DEFAULT;
38
  public $acctCreationOptions;
39

    
40

    
41
  public $errorMsg = NULL;
42
  public $hasError = FALSE;
43
  public $errorName = NULL;
44

    
45
  public function clearError() {
46
    $this->hasError = FALSE;
47
    $this->errorMsg = NULL;
48
    $this->errorName = NULL;
49
  }
50

    
51
  public function save() {
52
    foreach ($this->saveable as $property) {
53
      $save[$property] = $this->{$property};
54
    }
55
    variable_set('ldap_user_conf', $save);
56
    ldap_user_conf_cache_clear();
57
  }
58

    
59
  static public function uninstall() {
60
    variable_del('ldap_user_conf');
61
  }
62

    
63
  public function __construct() {
64
    parent::__construct();
65
    $this->setTranslatableProperties();
66

    
67
    if ($servers = ldap_servers_get_servers(NULL, 'enabled')) {
68
      $this->drupalAcctProvisionServerOptions[LDAP_USER_AUTH_SERVER_SID] = t('Use server which performed the authentication. Useful for multi-domain environments.');
69
      foreach ($servers as $sid => $ldap_server) {
70
        $enabled = ($ldap_server->status) ? 'Enabled' : 'Disabled';
71
        $this->drupalAcctProvisionServerOptions[$sid] = $ldap_server->name . ' (' . $ldap_server->address . ') Status: ' . $enabled;
72
        $this->ldapEntryProvisionServerOptions[$sid] = $ldap_server->name . ' (' . $ldap_server->address . ') Status: ' . $enabled;
73
      }
74
    }
75
    $this->drupalAcctProvisionServerOptions['none'] = t('None');
76
    $this->ldapEntryProvisionServerOptions['none'] = t('None');
77

    
78
  }
79

    
80

    
81
/**
82
 * generate admin form for ldapUserConf object
83
 *
84
 * @return array $form as drupal form api form array
85
 */
86
  public function drupalForm() {
87
    if (count($this->drupalAcctProvisionServerOptions) == 0) {
88
      $message = ldap_servers_no_enabled_servers_msg('configure LDAP User');
89
      $form['intro'] = array(
90
        '#type' => 'item',
91
        '#markup' => t('<h1>LDAP User Settings</h1>') . $message,
92
      );
93
      return $form;
94
    }
95
    $form['#storage'] = array();
96
    $form['#theme'] = 'ldap_user_conf_form';
97

    
98
    $form['intro'] = array(
99
      '#type' => 'item',
100
      '#markup' => t('<h1>LDAP User Settings</h1>'),
101
    );
102

    
103
    $form['manual_drupal_account_editing'] = array(
104
      '#type' => 'fieldset',
105
      '#title' => t('Manual Drupal Account Creation and Updates'),
106
      '#collapsible' => TRUE,
107
      '#collapsed' => FALSE,
108
    );
109

    
110
    $form['manual_drupal_account_editing']['manualAccountConflict'] = array(
111
      '#type' => 'radios',
112
      '#options' => $this->manualAccountConflictOptions,
113
      '#title' => t('How to resolve LDAP conflicts with manually  created Drupal accounts.'),
114
      '#description' => t('This applies only to accounts created manually through admin/people/create
115
        for which an LDAP entry can be found on the LDAP server selected in "LDAP Servers Providing Provisioning Data"'),
116
      '#default_value' => $this->manualAccountConflict,
117
    );
118

    
119
    $form['basic_to_drupal'] = array(
120
      '#type' => 'fieldset',
121
      '#title' => t('Basic Provisioning to Drupal Account Settings'),
122
      '#collapsible' => TRUE,
123
      '#collapsed' => FALSE,
124
    );
125

    
126
    $default_value = ($this->drupalAcctProvisionServer) ? $this->drupalAcctProvisionServer : 'none';
127
    $form['basic_to_drupal']['drupalAcctProvisionServer'] = array(
128
      '#type' => 'radios',
129
      '#title' => t('LDAP Servers Providing Provisioning Data'),
130
      '#required' => 1,
131
      '#default_value' => $default_value,
132
      '#options' => $this->drupalAcctProvisionServerOptions,
133
      '#description' => $this->drupalAcctProvisionServerDescription,
134
      '#states' => array(
135
        'enabled' => array(   // action to take.
136
          ':input[name=drupalAcctProvisionTriggers]' => array('value' => LDAP_USER_DRUPAL_USER_PROV_ON_AUTHENTICATE),
137
        ),
138
      ),
139
    );
140

    
141

    
142
    $form['basic_to_drupal']['drupalAcctProvisionTriggers'] = array(
143
      '#type' => 'checkboxes',
144
      '#title' => t('Drupal Account Provisioning Events'),
145
      '#required' => FALSE,
146
      '#default_value' => $this->drupalAcctProvisionTriggers,
147
      '#options' => $this->drupalAccountProvisionEventsOptions,
148
      '#description' => $this->drupalAccountProvisionEventsDescription,
149
    );
150

    
151
    $form['basic_to_drupal']['disableAdminPasswordField'] = array(
152
      '#type' => 'checkbox',
153
      '#title' => t('Disable the password fields at /admin/create/people since the password is going to be randomly generated anyway. This is useful if you are synching data to Drupal from LDAP, and not bringing the user password from LDAP.'),
154
      '#default_value' => $this->disableAdminPasswordField,
155
    );
156

    
157
    $form['basic_to_drupal']['userConflictResolve'] = array(
158
      '#type' => 'radios',
159
      '#title' => t('Existing Drupal User Account Conflict'),
160
      '#required' => 1,
161
      '#default_value' => $this->userConflictResolve,
162
      '#options' => $this->userConflictOptions,
163
      '#description' => t( $this->userConflictResolveDescription),
164
    );
165

    
166
    $form['basic_to_drupal']['acctCreation'] = array(
167
      '#type' => 'radios',
168
      '#title' => t('Application of Drupal Account settings to LDAP Authenticated Users'),
169
      '#required' => 1,
170
      '#default_value' => $this->acctCreation,
171
      '#options' => $this->acctCreationOptions,
172
      '#description' => t($this->acctCreationDescription),
173
    );
174

    
175
    $account_options = array();
176
    $account_options['ldap_user_orphan_do_not_check'] = t('Do not check for orphaned Drupal accounts.');
177
    $account_options['ldap_user_orphan_email'] = t('Perform no action, but email list of orphaned accounts. (All the other options will send email summaries also.)');
178
    foreach (user_cancel_methods() as $option_name => $option) {
179
      $account_options[$option_name] = $option['#title'];
180
    }
181

    
182
    //@todo these 2 options are removed until this feature is better tested in
183
    // actual production environments; it has potentially disastrous effects
184
    unset($account_options['user_cancel_reassign']);
185
    unset($account_options['user_cancel_delete']);
186

    
187
    $form['basic_to_drupal']['orphanedDrupalAcctBehavior'] = array(
188
      '#type' => 'radios',
189
      '#title' => t('Action to perform on Drupal account that no longer have a
190
        corresponding LDAP entry'),
191
      '#required' => 0,
192
      '#default_value' => $this->orphanedDrupalAcctBehavior,
193
      '#options' => $account_options,
194
      '#description' => t($this->orphanedDrupalAcctBehaviorDescription),
195
    );
196

    
197

    
198
    $form['basic_to_drupal']['orphanedCheckQty'] = array(
199
      '#type' => 'textfield',
200
      '#size' => 10,
201
      '#title' => t('Number of users to check each cron run.'),
202
      '#description' => t(''),
203
      '#default_value' => $this->orphanedCheckQty,
204
      '#required' => FALSE,
205
    );
206

    
207

    
208
    $form['basic_to_ldap'] = array(
209
      '#type' => 'fieldset',
210
      '#title' => t('Basic Provisioning to LDAP Settings'),
211
      '#collapsible' => TRUE,
212
      '#collapsed' => !($this->ldapEntryProvisionServer),
213
    );
214

    
215
    $default_value = ($this->ldapEntryProvisionServer) ? $this->ldapEntryProvisionServer : 'none';
216
    $form['basic_to_ldap']['ldapEntryProvisionServer'] = array(
217
      '#type' => 'radios',
218
      '#title' => t('LDAP Servers to Provision LDAP Entries on'),
219
      '#required' => 1,
220
      '#default_value' => $default_value,
221
      '#options' => $this->ldapEntryProvisionServerOptions,
222
      '#description' => $this->ldapEntryProvisionServerDescription,
223
    );
224

    
225
    $form['basic_to_ldap']['ldapEntryProvisionTriggers'] = array(
226
      '#type' => 'checkboxes',
227
      '#title' => t('LDAP Entry Provisioning Events'),
228
      '#required' => FALSE,
229
      '#default_value' => $this->ldapEntryProvisionTriggers,
230
      '#options' => $this->ldapEntryProvisionTriggersOptions,
231
      '#description' => $this->ldapEntryProvisionTriggersDescription
232
    );
233

    
234
/**
235
    $form['ws'] = array(
236
      '#type' => 'fieldset',
237
      '#title' => t('[Untested and Unfinished Code] REST Webservice for Provisioning and Synching.'),
238
      '#collapsible' => TRUE,
239
      '#collapsed' => !$this->wsEnabled,
240
      '#description' => t('Once configured, this webservice can be used to trigger creation, synching, deletion, etc of an LDAP associated Drupal account.'),
241
    );
242

243
    $form['ws']['wsEnabled'] = array(
244
      '#type' => 'checkbox',
245
      '#title' => t('Enable REST Webservice'),
246
      '#required' => FALSE,
247
      '#default_value' => $this->wsEnabled,
248
    );
249

250
    $form['ws']['wsUserIps'] = array(
251
      '#type' => 'textarea',
252
      '#title' => t('Allowed IP Addresses to request webservice.'),
253
      '#required' => FALSE,
254
      '#default_value' => join("\n", $this->wsUserIps),
255
      '#description' => t('One Per Line. The current server address is LOCAL_ADDR and the client ip requesting this page is REMOTE_ADDR .', $_SERVER),
256
      '#cols' => 20,
257
      '#rows' => 2,
258
      '#states' => array(
259
        'visible' => array(   // action to take.
260
          ':input[name="wsEnabled"]' => array('checked' => TRUE),
261
        ),
262
      ),
263
    );
264

265
    if (!$this->wsKey) {
266
      $urls = t('URLs are not available until a key is create a key and urls will be generated');
267
    }
268
    else {
269
      $urls = theme('item_list',
270
        array(
271
          'items' => ldap_user_ws_urls_item_list(),
272
          'title' => 'REST urls',
273
          'type' => 'ul',
274
        ));
275
    }
276

277
    $form['ws']['wsKey'] = array(
278
      '#type' => 'textfield',
279
      '#title' => t('Key for webservice'),
280
      '#required' => FALSE,
281
      '#default_value' => $this->wsKey,
282
      '#description' => t('Any random string of characters.') . $urls,
283
      '#states' => array(
284
        'visible' => array(   // action to take.
285
          ':input[name="wsEnabled"]' => array('checked' => TRUE),
286
        ),
287
      ),
288
    );
289
*/
290

    
291
    $form['basic_to_drupal']['server_mapping_preamble'] = array(
292
      '#type' => 'markup',
293
      '#markup' => t('
294
The relationship between a Drupal user and an LDAP entry is defined within the LDAP server configurations.
295

296

297
The mappings below are for user fields, properties, and profile2 data that are not automatically mapped elsewhere.
298
Mappings such as username or email address that are configured elsewhere are shown at the top for clarity.
299
When more than one ldap server is enabled for provisioning data (or simply more than one configuration for the same ldap server),
300
mappings need to be setup for each server.  If no tables are listed below, you have not enabled any provisioning servers at
301
the top of this form.
302
'),
303
    );
304

    
305
    foreach (array(LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER, LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) as $direction) {
306
      $sid = $this->provisionSidFromDirection[$direction];
307
      $ldap_server = ($sid) ? ldap_servers_get_servers($sid, NULL, TRUE) : FALSE;
308
      $ldap_server_selected = (boolean)$ldap_server;
309

    
310
      if ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) {
311
        $parent_fieldset = 'basic_to_drupal';
312
        $description =  t('Provisioning from LDAP to Drupal Mappings:');
313
      }
314
      elseif ($direction == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) {
315
        $parent_fieldset = 'basic_to_ldap';
316
        $description =   t('Provisioning from Drupal to LDAP Mappings:');
317
      }
318

    
319
      $form[$parent_fieldset]['mappings__' . $direction] = array(
320
        '#type' => 'fieldset',
321
        '#title' =>  $description,
322
        '#collapsible' => TRUE,
323
        '#collapsed' => FALSE,
324
        '#description' => '',
325
        'table__' . $direction => array(
326
          '#type' => 'markup',
327
          '#markup' => '[replace_with_table__' . $direction . ']',
328
        ),
329
      );
330

    
331

    
332
$password_notes = '<h3>' . t('Password Tokens') . '</h3><ul>' .
333
'<li>' . t('Pwd: Random -- Uses a random Drupal generated password') . '</li>' .
334
'<li>' . t('Pwd: User or Random -- Uses password supplied on user forms.
335
  If none available uses random password.') . '</li></ul>' .
336
'<h3>' . t('Password Concerns') . '</h3>' .
337
'<ul>' .
338
'<li>' . t('Provisioning passwords to LDAP means passwords must meet the LDAP\'s
339
password requirements.  Password Policy module can be used to add requirements.') . '</li>' .
340
'<li>' . t('Some LDAPs require a user to reset their password if it has been changed
341
by someone other that user.  Consider this when provisioning LDAP passwords.') . '</li>' .
342
'</ul></p>';
343

    
344

    
345
      $source_drupal_token_notes = <<<EOT
346
<p>Examples in form: Source Drupal User token => Target LDAP Token (notes)</p>
347
<ul>
348
<li>Source Drupal User token => Target LDAP Token</li>
349
<li>cn=[property.name],ou=test,dc=ad,dc=mycollege,dc=edu => [dn] (example of token and constants)</li>
350
<li>top => [objectclass:0] (example of constants mapped to multivalued attribute)</li>
351
<li>person => [objectclass:1] (example of constants mapped to multivalued attribute)</li>
352
<li>organizationalPerson => [objectclass:2] (example of constants mapped to multivalued attribute)</li>
353
<li>user => [objectclass:3] (example of constants mapped to multivalued attribute)</li>
354
<li>Drupal Provisioned LDAP Account => [description] (example of constant)</li>
355
<li>[field.field_lname] => [sn]</li>
356

357
</ul>
358
EOT;
359

    
360
      if ($direction == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) { // add some password notes
361
        $form[$parent_fieldset]['password_notes'] = array(
362
          '#type' => 'fieldset',
363
          '#title' =>  t('Password Notes'),
364
          '#collapsible' => TRUE,
365
          '#collapsed' => TRUE,
366
          'directions' => array(
367
            '#type' => 'markup',
368
            '#markup' => $password_notes,
369
          ),
370
        );
371
        $form[$parent_fieldset]['source_drupal_token_notes'] = array(
372
          '#type' => 'fieldset',
373
          '#title' =>  t('Source Drupal User Tokens and Corresponding Target LDAP Tokens'),
374
          '#collapsible' => TRUE,
375
          '#collapsed' => TRUE,
376
          'directions' => array(
377
            '#type' => 'markup',
378
            '#markup' => $source_drupal_token_notes,
379
          ),
380
        );
381
      }
382
      $this->addServerMappingFields($form, $direction);
383
    }
384

    
385
    foreach (array('orphanedCheckQty', 'orphanedDrupalAcctBehavior', 'acctCreation', 'userConflictResolve', 'drupalAcctProvisionTriggers', 'mappings__' . LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) as $input_name) {
386
      $form['basic_to_drupal'][$input_name]['#states']['invisible'] =
387
        array(
388
          ':input[name=drupalAcctProvisionServer]' => array('value' => 'none'),
389
        );
390
    }
391

    
392
    foreach (array('ldapEntryProvisionTriggers', 'password_notes', 'source_drupal_token_notes', 'mappings__' . LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) as $input_name) {
393
      $form['basic_to_ldap'][$input_name]['#states']['invisible'] =
394
        array(
395
          ':input[name=ldapEntryProvisionServer]' => array('value' => 'none'),
396
        );
397
    }
398

    
399
    $form['submit'] = array(
400
      '#type' => 'submit',
401
      '#value' => 'Save',
402
    );
403

    
404
  return $form;
405
}
406

    
407

    
408

    
409
/**
410
 * validate submitted form
411
 *
412
 * @param array $values as $form_state['values'] from drupal form api
413
 * @param array $storage as $form_state['storage'] from drupal form api
414
 *
415
 * @return array in form array($errors, $warnings)to be thrown by form api
416
 */
417
  public function drupalFormValidate($values, $storage)  {
418
    $this->populateFromDrupalForm($values, $storage);
419
    list($errors, $warnings) = $this->validate($values);
420

    
421
    // since failed mapping rows in form, don't populate ->ldapUserSynchMappings, need to validate these from values
422
    foreach ($values as $field => $value) {
423
      $parts = explode('__', $field);
424
      // since synch mapping fields are in n-tuples, process entire n-tuple at once (on field == configurable_to_drupal)
425
      if (count($parts) != 4 || $parts[1] !== 'sm' || $parts[2] != 'configurable_to_drupal') {
426
        continue;
427
      }
428
      list($direction, $discard, $column_name, $i) = $parts;
429
      $action = $storage['synch_mapping_fields'][$direction][$i]['action'];
430
      $tokens = array();
431
      $row_mappings = array();
432
      foreach (array('remove', 'configurable_to_drupal', 'configurable_to_ldap', 'convert', 'direction', 'ldap_attr', 'user_attr', 'user_tokens') as $column_name) {
433
        $input_name = join('__', array('sm', $column_name, $i));
434
        $row_mappings[$column_name] = isset($values[$input_name]) ? $values[$input_name] : NULL;
435
      }
436

    
437
      $has_values = $row_mappings['ldap_attr'] || $row_mappings['user_attr'];
438
      if ($has_values) {
439
        $tokens['%ldap_attr'] = $row_mappings['ldap_attr'];
440
        $row_descriptor = t("server %sid row mapping to ldap attribute %ldap_attr", $tokens);
441
        $tokens['!row_descriptor'] = $row_descriptor;
442
        if (!$row_mappings['direction']) {
443
          $input_name = join('__', array('sm', 'direction', $i));
444
          $errors[$input_name] = t('No mapping direction given in !row_descriptor', $tokens);
445
        }
446
        if ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER && $row_mappings['user_attr'] == 'user_tokens') {
447
          $input_name = join('__', array('sm', 'user_attr', $i));
448
          $errors[$input_name] =  t('User tokens not allowed when mapping to Drupal user.  Location: !row_descriptor', $tokens);
449
        }
450
        if (!$row_mappings['ldap_attr']) {
451
          $input_name = join('__', array('sm', 'ldap_attr', $i));
452
          $errors[$input_name] = t('No ldap attribute given in !row_descriptor', $tokens);
453
        }
454
        if (!$row_mappings['user_attr']) {
455
          $input_name = join('__', array('sm', 'user_attr', $i));
456
          $errors[$input_name] = t('No user attribute given in !row_descriptor', $tokens);
457
        }
458
      }
459

    
460
    }
461
    return array($errors, $warnings);
462
  }
463

    
464
/**
465
 * validate object, not form
466
 * @param array $values as $form_state['values'] from drupal form api
467
 * @return array in form array($errors, $warnings)to be thrown by form api
468
 *
469
 * @todo validate that a user field exists, such as field.field_user_lname
470
 *
471
 */
472
  public function validate($values) {
473
    $errors = array();
474
    $warnings = array();
475
    $tokens = array();
476

    
477
    $has_drupal_acct_prov_servers  = (boolean)($this->drupalAcctProvisionServer);
478
    $has_drupal_acct_prov_settings_options  = (count(array_filter($this->drupalAcctProvisionTriggers)) > 0);
479

    
480
    if (!$has_drupal_acct_prov_servers && $has_drupal_acct_prov_settings_options) {
481
      $warnings['drupalAcctProvisionServer'] =  t('No Servers are enabled to provide provisioning to Drupal, but Drupal Account Provisioning Options are selected.', $tokens);
482
    }
483
    if ($has_drupal_acct_prov_servers && !$has_drupal_acct_prov_settings_options) {
484
      $warnings['drupalAcctProvisionTriggers'] =  t('Servers are enabled to provide provisioning to Drupal, but no Drupal Account Provisioning Options are selected.  This will result in no synching happening.', $tokens);
485
    }
486

    
487
    $has_ldap_prov_servers = (boolean)($this->ldapEntryProvisionServer);
488
    $has_ldap_prov_settings_options = (count(array_filter($this->ldapEntryProvisionTriggers)) > 0);
489
    if (!$has_ldap_prov_servers && $has_ldap_prov_settings_options) {
490
      $warnings['ldapEntryProvisionServer'] =  t('No Servers are enabled to provide provisioning to ldap, but LDAP Entry Options are selected.', $tokens);
491
    }
492
    if ($has_ldap_prov_servers && !$has_ldap_prov_settings_options) {
493
      $warnings['ldapEntryProvisionTriggers'] =  t('Servers are enabled to provide provisioning to ldap, but no LDAP Entry Options are selected.  This will result in no synching happening.', $tokens);
494
    }
495

    
496
    if (isset($this->ldapUserSynchMappings)) {
497
      $to_ldap_entries_mappings_exist = FALSE;
498
      foreach ($this->ldapUserSynchMappings as $synch_direction => $mappings) {
499
        $map_index = array();
500
        $tokens = array(); // array('%sid' => $sid);
501
        $to_drupal_user_mappings_exist = FALSE;
502
        $to_ldap_entries_mappings_exist = FALSE;
503

    
504
        foreach ($mappings as $target_attr => $mapping) {
505
          if ($mapping['direction'] == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) {
506
            $attr_value = $mapping['user_attr'];
507
            $attr_name = 'user_attr';
508
          }
509
          if ($mapping['direction'] == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) {
510
            $attr_value = $mapping['ldap_attr'];
511
            $attr_name = 'ldap_attr';
512
          }
513
          foreach ($values as $field => $value) {
514
            $parts = explode('__', $field);
515
            if (count($parts) == 4 && $parts[2] == $attr_name && $value == $attr_value) {
516
              $map_index[$attr_value] = $parts[3];
517
            }
518
          }
519
        }
520

    
521
        foreach ($mappings as $target_attr => $mapping) {
522
          foreach ($mapping as $key => $value) {
523
            if (is_scalar($value)) {
524
              $tokens['%' . $key] = $value;
525
            }
526
          }
527
          $row_descriptor = t("server %sid row mapping to ldap attribute %ldap_attr", $tokens);
528
          $tokens['!row_descriptor'] = $row_descriptor;
529
          $ldap_attribute_maps_in_token = array();
530
         // debug('calling ldap_servers_token_extract_attributes from validate, mapping='); debug($mapping['ldap_attr']);
531
          ldap_servers_token_extract_attributes($ldap_attribute_maps_in_token, $mapping['ldap_attr']);
532

    
533
          if ($mapping['direction'] == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) {
534
            $row_id = $map_index[$mapping['user_attr']];
535
            $to_drupal_user_mappings_exist = TRUE;
536
          //  if (!$is_drupal_user_prov_server) {
537
           //   $errors['mappings__'. $sid] =  t('Mapping rows exist for provisioning to drupal user, but server %sid is not enabled for provisioning
538
            //    to drupal users.', $tokens);
539
          //  }
540
          }
541
          if ($mapping['direction'] == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) {
542
            $row_id = $map_index[$mapping['ldap_attr']];
543
            $to_ldap_entries_mappings_exist = TRUE;
544
           // if (!$is_ldap_entry_prov_server) {
545
            //  $errors['mappings__'. $sid] =  t('Mapping rows exist for provisioning to ldap entries,
546
            //    but server %sid is not enabled for provisioning
547
             //   to ldap entries.', $tokens);
548
           // }
549

    
550
            if (count(array_keys($ldap_attribute_maps_in_token)) != 1) {
551
              $token_field_id = join('__', array('sm', 'user_tokens', $row_id));
552
              $errors[$token_field_id] =  t('When provisioning to ldap, ldap attribute column must be singular token such as [cn]. %ldap_attr is not.
553
                Do not use compound tokens such as "[displayName] [sn]" or literals such as "physics". Location: !row_descriptor', $tokens);
554
            }
555

    
556
          }
557
          $ldap_attr_field_id = join('__', array('sm', 'ldap_attr', $row_id));
558
          $user_attr_field_id = join('__', array('sm', 'user_attr', $row_id));
559
          $first_context_field_id = join('__', array('sm', 1, $row_id));
560
          $user_tokens_field_id = join('__', array('sm', 'user_tokens', $row_id));
561

    
562
          if (!$mapping['ldap_attr']) {
563
            $errors[$ldap_attr_field_id] =  t('No LDAP Attribute given in !row_descriptor', $tokens);
564
          }
565
          if ($mapping['user_attr'] == 'user_tokens' && !$mapping['user_tokens']) {
566
            $errors[$user_tokens_field_id] =  t('User tokens selected in !row_descriptor, but user tokens column empty.', $tokens);
567
          }
568

    
569
          if (isset($mapping['prov_events']) && count($mapping['prov_events']) == 0) {
570
            $warnings[$first_context_field_id] =  t('No synchronization events checked in !row_descriptor.
571
              This field will not be synchronized until some are checked.', $tokens);
572
          }
573
        }
574
      }
575
      if ($to_ldap_entries_mappings_exist && !isset($mappings['[dn]'])) {
576
        $errors['mappings__' . $synch_direction] =  t('Mapping rows exist for provisioning to ldap, but no ldap attribute is targetted for [dn].
577
          One row must map to [dn].  This row will have a user token like cn=[property.name],ou=users,dc=ldap,dc=mycompany,dc=com');
578
      }
579
    }
580
    return array($errors, $warnings);
581
  }
582

    
583
  /**
584
   * populate object with data from form values
585
   *
586
   * @param array $values as $form_state['values'] from drupal form api
587
   * @param array $storage as $form_state['storage'] from drupal form api
588
   */
589
  protected function populateFromDrupalForm($values, $storage) {
590
    $this->drupalAcctProvisionServer = ($values['drupalAcctProvisionServer'] == 'none') ? 0 : $values['drupalAcctProvisionServer'];
591
    $this->ldapEntryProvisionServer = ($values['ldapEntryProvisionServer']  == 'none') ? 0 : $values['ldapEntryProvisionServer'];
592

    
593
    $this->drupalAcctProvisionTriggers = $values['drupalAcctProvisionTriggers'];
594
    $this->ldapEntryProvisionTriggers = $values['ldapEntryProvisionTriggers'];
595
    $this->orphanedDrupalAcctBehavior = $values['orphanedDrupalAcctBehavior'];
596
    $this->orphanedCheckQty = $values['orphanedCheckQty'];
597

    
598
    $this->manualAccountConflict = $values['manualAccountConflict'];
599
    $this->userConflictResolve  = ($values['userConflictResolve']) ? (int)$values['userConflictResolve'] : NULL;
600
    $this->acctCreation  = ($values['acctCreation']) ? (int)$values['acctCreation'] : NULL;
601
    $this->disableAdminPasswordField = $values['disableAdminPasswordField'];
602
   // $this->wsKey  = ($values['wsKey']) ? $values['wsKey'] : NULL;
603

    
604
   // $this->wsUserIps  = ($values['wsUserIps']) ? explode("\n", $values['wsUserIps']) : array();
605
  //  foreach ($this->wsUserIps as $i => $ip) {
606
  //    $this->wsUserIps[$i] = trim($ip);
607
  //  }
608
   // $this->wsEnabled  = ($values['wsEnabled']) ? (int)$values['wsEnabled'] : 0;
609

    
610
    $this->ldapUserSynchMappings = $this->synchMappingsFromForm($values, $storage);
611

    
612
  }
613

    
614

    
615

    
616
/**
617
 *  Extract synch mappings array from mapping table in admin form.
618
 *
619
 * @param array $values as $form_state['values'] from drupal form api
620
 * @param array $storage as $form_state['storage'] from drupal form api
621
 *
622
 * $values input names in form:
623
 *   1__sm__configurable__5,
624
 *   1__sm__remove__5,
625
 *   1__sm__ldap_attr__5,
626
 *   1__sm__convert__5,
627
 *   1__sm__direction__5,
628
 *   1__sm__user_attr__5,
629
 *   1__sm__user_tokens__5
630
 *   1__sm__1__5,
631
 *   1__sm__2__5,
632
    ...where
633
      -- first arg is direction, eg 1 or 2 LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER or LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY
634
      -- second arg is discarded ('sm')
635
      -- third part is field, e.g. user_attr
636
      -- fourth is the row in the configuration form, e.g. 5
637

638
   where additiond data is in $form['#storage'][<direction>]['synch_mapping_fields'][N]
639
    $form['#storage']['synch_mapping_fields'][<direction>][N] = array(
640
      'sid' => $sid,
641
      'action' => 'add',
642
    );
643
 */
644
  private function synchMappingsFromForm($values, $storage) {
645

    
646
    $mappings = array();
647
    foreach ($values as $field => $value) {
648

    
649
      $parts = explode('__', $field);
650
      // since synch mapping fields are in n-tuples, process entire n-tuple at once
651
      if (count($parts) != 4 || $parts[1] !== 'sm') {
652
        continue;
653
      }
654

    
655
      list($direction, $discard, $column_name, $i) = $parts;
656
      $action = $storage['synch_mapping_fields'][$direction][$i]['action'];
657

    
658
      $row_mappings = array();
659
      foreach (array('remove', 'configurable_to_drupal', 'configurable_to_ldap', 'convert', 'ldap_attr', 'user_attr', 'user_tokens') as $column_name) {
660
        $input_name = join('__', array($direction, 'sm', $column_name, $i));
661
        $row_mappings[$column_name] = isset($values[$input_name]) ? $values[$input_name] : NULL;
662
      }
663

    
664
      if ($row_mappings['remove']) {
665
        continue;
666
      }
667

    
668
      $key = ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) ? $row_mappings['user_attr'] : $row_mappings['ldap_attr'];
669
      if ($row_mappings['configurable_to_drupal'] && $row_mappings['ldap_attr'] && $row_mappings['user_attr']) {
670
        $mappings[$direction][$key] = array(
671
          'ldap_attr' => $row_mappings['ldap_attr'],
672
          'user_attr' => $row_mappings['user_attr'],
673
          'convert' => $row_mappings['convert'],
674
          'direction' => $direction,
675
          'user_tokens' => $row_mappings['user_tokens'],
676
          'config_module' => 'ldap_user',
677
          'prov_module' => 'ldap_user',
678
          'enabled' => 1,
679
          );
680

    
681
        $synchEvents = ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) ? $this->provisionsDrupalEvents : $this->provisionsLdapEvents;
682
        foreach ($synchEvents as $prov_event => $discard) {
683
          $input_name = join('__', array($direction, 'sm', $prov_event, $i));
684
          if (isset($values[$input_name]) && $values[$input_name]) {
685
            $mappings[$direction][$key]['prov_events'][] = $prov_event;
686
          }
687
        }
688
      }
689
    }
690

    
691
    return $mappings;
692
  }
693

    
694
  /**
695
   * method to respond to successfully validated form submit.
696
   *
697
   * @param array $values as $form_state['values'] from drupal form api
698
   * @param array $storage as $form_state['storage'] from drupal form api
699
   *
700
   * @return by reference to $form array
701
   */
702
  public function drupalFormSubmit($values, $storage) {
703

    
704
    $this->populateFromDrupalForm($values, $storage);
705

    
706
    try {
707
      $save_result = $this->save();
708
    }
709
    catch (Exception $e) {
710
      $this->errorName = 'Save Error';
711
      $this->errorMsg = t('Failed to save object.  Your form data was not saved.');
712
      $this->hasError = TRUE;
713
    }
714

    
715
  }
716

    
717
  /**
718
   * add existing mappings to ldap user provisioning mapping admin form table
719
   *
720
   * @param drupal form array $form
721
   * @param enum $direction LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER or LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY
722
   *
723
   * @return by reference to $form array
724
   */
725

    
726
  private function addServerMappingFields(&$form, $direction) {
727

    
728
    if ($direction == LDAP_USER_PROV_DIRECTION_NONE) {
729
      return;
730
    }
731

    
732
    $text = ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) ? 'target' : 'source';
733
    $user_attr_options = array('0' => t('Select') . ' ' . $text);
734

    
735
    if (!empty($this->synchMapping[$direction])) {
736
      foreach ($this->synchMapping[$direction] as $target_id => $mapping) {
737
        if (!isset($mapping['name']) || isset($mapping['exclude_from_mapping_ui']) && $mapping['exclude_from_mapping_ui']) {
738
          continue;
739
        }
740
        if (
741
          (isset($mapping['configurable_to_drupal']) && $mapping['configurable_to_drupal'] && $direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER)
742
          ||
743
          (isset($mapping['configurable_to_ldap']) && $mapping['configurable_to_ldap']  && $direction == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY)
744
          ) {
745
          $user_attr_options[$target_id] = substr($mapping['name'], 0, 25);
746
        }
747
      }
748
    }
749
    $user_attr_options['user_tokens'] = '-- user tokens --';
750

    
751
    $row = 0;
752

    
753
    // 1. non configurable mapping rows
754
    foreach ($this->synchMapping[$direction] as $target_id => $mapping) {
755
      if (isset($mapping['exclude_from_mapping_ui']) && $mapping['exclude_from_mapping_ui']) {
756
        continue;
757
      }
758
      if ( !$this->isMappingConfigurable($mapping, 'ldap_user') && ($mapping['direction'] == $direction || $mapping['direction'] == LDAP_USER_PROV_DIRECTION_ALL)) { // is configurable by ldap_user module (not direction to ldap_user)
759
        $this->addSynchFormRow($form, 'nonconfigurable', $direction, $mapping, $user_attr_options, $row);
760
        $row++;
761
      }
762
    }
763

    
764
    // 2. existing configurable mappings rows
765
    if (!empty($this->ldapUserSynchMappings[$direction])) {
766
      foreach ($this->ldapUserSynchMappings[$direction] as $target_attr_token => $mapping) {  // key could be ldap attribute name or user attribute name
767
        if (isset($mapping['enabled']) && $mapping['enabled'] && $this->isMappingConfigurable($this->synchMapping[$direction][$target_attr_token], 'ldap_user')) {
768
          $this->addSynchFormRow($form, 'update', $direction, $mapping, $user_attr_options, $row);
769
          $row++;
770
        }
771
      }
772
    }
773

    
774
    // 3. leave 4 rows for adding more mappings
775
    for ($i=0; $i<4; $i++) {
776
      $this->addSynchFormRow($form, 'add', $direction, NULL, $user_attr_options, $row);
777
      $row++;
778
    }
779

    
780
  }
781

    
782
  /**
783
   * add mapping form row to ldap user provisioning mapping admin form table
784
   *
785
   * @param drupal form array $form
786
   * @param string $action is 'add', 'update', or 'nonconfigurable'
787
   * @param enum $direction LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER or LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY
788
   * @param array $mapping is current setting for updates or nonconfigurable items
789
   * @param array $user_attr_options of drupal user target options
790
   * @param int $row is current row in table
791

792
   *
793
   * @return by reference to $form
794
   */
795
  private function addSynchFormRow(&$form, $action, $direction, $mapping, $user_attr_options, $row) {
796

    
797
    $id_prefix = $direction . '__';
798

    
799
    $id = $id_prefix . 'sm__remove__' . $row;
800
    $form[$id] = array(
801
      '#id' => $id,
802
      '#row' => $row,
803
      '#col' => 0,
804
      '#type' => 'checkbox',
805
      '#default_value' => NULL,
806
      '#disabled' => ($action == 'add' || $action == 'nonconfigurable'),
807
    );
808

    
809
    $id =  $id_prefix . 'sm__convert__' . $row;
810
    $form[$id] = array(
811
      '#id' => $id,
812
      '#row' => $row,
813
      '#col' => ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) ? 2 : 3,
814
      '#type' => 'checkbox',
815
      '#default_value' =>  isset($mapping['convert']) ? $mapping['convert'] : '',
816
      '#disabled' => ($action == 'nonconfigurable'),
817
      '#attributes' => array('class' => array('convert')),
818
    );
819

    
820
    $id =  $id_prefix . 'sm__ldap_attr__' . $row;
821
    $col = ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) ? 1 : 4;
822
    if ($action == 'nonconfigurable') {
823
      $form[$id] = array(
824
        '#id' => $id,
825
        '#row' => $row,
826
        '#col' => $col,
827
        '#type' => 'item',
828
        '#markup' => isset($mapping['source']) ? $mapping['source'] : '?',
829
        '#attributes' => array('class' => array('source')),
830
      );
831
    }
832
    else {
833
      $form[$id] = array(
834
        '#id' => $id,
835
        '#row' => $row,
836
        '#col' => $col,
837
        '#type' => 'textfield',
838
        '#default_value' => isset($mapping['ldap_attr']) ? $mapping['ldap_attr'] : '',
839
        '#size' => 20,
840
        '#maxlength' => 255,
841
        '#attributes' => array('class' => array('ldap-attr')),
842
      );
843
    }
844

    
845
    $user_attr_input_id =  $id_prefix . 'sm__user_attr__' . $row;
846
    $col = ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) ? 3 : 1;
847
    if ($action == 'nonconfigurable') {
848
      $form[$user_attr_input_id] = array(
849
        '#id' => $user_attr_input_id,
850
        '#row' => $row,
851
        '#col' => $col,
852
        '#type' => 'item',
853
        '#markup' => isset($mapping['name']) ? $mapping['name'] : '?',
854
      );
855
    }
856
    else {
857
      $form[$user_attr_input_id] = array(
858
        '#id' => $user_attr_input_id,
859
        '#row' => $row,
860
        '#col' => $col,
861
        '#type' => 'select',
862
        '#default_value' => isset($mapping['user_attr']) ? $mapping['user_attr'] : '',
863
        '#options' => $user_attr_options,
864
      );
865
    }
866

    
867
    if ($direction == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) {
868
      $id =  $id_prefix . 'sm__user_tokens__' . $row;
869
      $form[$id] = array(
870
        '#id' => $id,
871
        '#row' => $row,
872
        '#col' =>  2,
873
        '#type' => 'textfield',
874
        '#default_value' => isset($mapping['user_tokens']) ? $mapping['user_tokens'] : '',
875
        '#size' => 40,
876
        '#maxlength' => 255,
877
        '#disabled' => ($action == 'nonconfigurable'),
878
        '#states' => array(
879
          'visible' => array(   // action to take.
880
            ':input[name="' . $user_attr_input_id . '"]' => array('value' => 'user_tokens'),
881
          )
882
        ),
883
        '#attributes' => array('class' => array('tokens')),
884
      );
885
    }
886

    
887
    $form['#storage']['synch_mapping_fields'][$direction][$row] = array(
888
      'action' => $action,
889
      'direction' => $direction,
890
    );
891

    
892
    $id = $id_prefix . 'sm__configurable_to_drupal__' . $row;
893
    $form[$id] = array(
894
      '#id' => $id,
895
      '#type' => 'hidden',
896
      '#default_value' => ($action != 'nonconfigurable'),
897
    );
898

    
899

    
900
    $col = ($direction == LDAP_USER_PROV_DIRECTION_TO_LDAP_ENTRY) ? 5 : 4;
901
    $synchEvents = ($direction == LDAP_USER_PROV_DIRECTION_TO_DRUPAL_USER) ? $this->provisionsDrupalEvents : $this->provisionsLdapEvents;
902

    
903
    foreach ($synchEvents as $prov_event => $prov_event_name) {
904
      $col++;
905
      $id =  $id_prefix . join('__', array('sm', $prov_event, $row));
906
      $form[$id] = array(
907
        '#id' => $id ,
908
        '#type' => 'checkbox',
909
        '#default_value' => isset($mapping['prov_events']) ? (int)(in_array($prov_event, $mapping['prov_events'])) : '',
910
        '#row' => $row,
911
        '#col' => $col,
912
        '#disabled' => (!$this->provisionEventConfigurable($prov_event, $mapping) || ($action == 'nonconfigurable')),
913
        '#attributes' => array('class' => array('synch-method')),
914
      );
915
    }
916
  }
917

    
918
  /**
919
   * Is a mapping configurable by a given module?
920
   *
921
   * @param array $mapping as mapping configuration for field, attribute, property, etc.
922
   * @param string $module machine name such as ldap_user
923
   *
924
   * @return boolean
925
   */
926
  private function isMappingConfigurable($mapping = NULL, $module = 'ldap_user') {
927
    $configurable = (
928
      (
929
        (!isset($mapping['configurable_to_drupal']) && !isset($mapping['configurable_to_ldap'])) ||
930
        (isset($mapping['configurable_to_drupal']) && $mapping['configurable_to_drupal']) ||
931
        (isset($mapping['configurable_to_ldap']) && $mapping['configurable_to_ldap'])
932
      )
933
      &&
934
      (
935
        !isset($mapping['config_module']) ||
936
        (isset($mapping['config_module']) && $mapping['config_module'] == $module)
937
      )
938
    );
939
    return $configurable;
940
  }
941

    
942

    
943
  /**
944
   * Is a particular synch method viable for a given mapping?
945
   * That is, Can it be enabled in the UI by admins?
946
   *
947
   * @param int $prov_event
948
   * @param array $mapping is array of mapping configuration.
949
   *
950
   * @return boolean
951
   */
952

    
953
  private function provisionEventConfigurable($prov_event, $mapping = NULL) {
954

    
955
    if ($mapping) {
956
      if ($prov_event == LDAP_USER_EVENT_CREATE_LDAP_ENTRY || $prov_event == LDAP_USER_EVENT_SYNCH_TO_LDAP_ENTRY) {
957
        $configurable = (boolean)(!isset($mapping['configurable_to_ldap']) || $mapping['configurable_to_ldap']);
958
      }
959
      elseif ($prov_event == LDAP_USER_EVENT_CREATE_DRUPAL_USER || $prov_event == LDAP_USER_EVENT_SYNCH_TO_DRUPAL_USER) {
960
        $configurable = (boolean)(!isset($mapping['configurable_to_drupal']) || $mapping['configurable_to_drupal']);
961
      }
962
    }
963
    else {
964
      $configurable = TRUE;
965
    }
966

    
967
    return $configurable;
968
  }
969

    
970
  protected function setTranslatableProperties() {
971

    
972
    $values['drupalAcctProvisionServerDescription'] = t('Check ONE LDAP server configuration to use
973
      in provisioning Drupal users and their user fields.');
974
    $values['ldapEntryProvisionServerDescription'] = t('Check ONE LDAP server configuration to create ldap entries on.');
975

    
976
    $values['drupalAccountProvisionEventsDescription'] = t('Which user fields and properties are synched on create or synch is determined in the
977
      "Provisioning from LDAP to Drupal mappings" table below in the right two columns. If you are synching only from LDAP to Drupal, and not 
978
      retrieving the user password from LDAP into their Drupal account, a 20 character random password will be generated automatically for
979
      the user\'s Drupal account since Drupal requires a password for the "users" table. Check the watchdog at /admin/reports/dblog to
980
      confirm that a random password was generated when the user account was created.');
981

    
982
    $values['drupalAccountProvisionEventsOptions'] = array(
983
      LDAP_USER_DRUPAL_USER_PROV_ON_AUTHENTICATE => t('Create or Synch to Drupal user on successful authentication with LDAP
984
        credentials. (Requires LDAP Authentication module).'),
985
      LDAP_USER_DRUPAL_USER_PROV_ON_USER_UPDATE_CREATE => t('Create or Synch to Drupal user anytime a Drupal user account
986
        is created or updated. Requires a server with binding method of "Service Account Bind" or "Anonymous Bind".'),
987
      );
988

    
989
    $values['ldapEntryProvisionTriggersDescription'] = t('Which LDAP attributes are synched on create or synch is determined in the
990
      "Provisioning from Drupal to LDAP mappings" table below in the right two columns.');
991

    
992
    $values['ldapEntryProvisionTriggersOptions'] = array(
993
      LDAP_USER_LDAP_ENTRY_PROV_ON_USER_UPDATE_CREATE => t('Create or Synch to LDAP entry when a Drupal account is created or updated.
994
        Only applied to accounts with a status of approved.'),
995
      LDAP_USER_LDAP_ENTRY_PROV_ON_AUTHENTICATE => t('Create or Synch to LDAP entry when a user authenticates.'),
996
      LDAP_USER_LDAP_ENTRY_DELETE_ON_USER_DELETE => t('Delete LDAP entry when the corresponding Drupal Account is deleted.  This only applies when the LDAP entry was provisioned by Drupal by the LDAP User module.'),
997
      LDAP_USER_DRUPAL_USER_PROV_ON_ALLOW_MANUAL_CREATE => t('Provide option on admin/people/create to create corresponding LDAP Entry.'),
998

    
999
    );
1000

    
1001
    $values['orphanedDrupalAcctBehaviorDescription'] = t('It is highly recommended to use the "Perform no action, but email list of orphaned accounts" for some time before considering switching to "Disable the account" options.');
1002

    
1003

    
1004
    $values['manualAccountConflictOptions'] =  array(
1005
      LDAP_USER_MANUAL_ACCT_CONFLICT_REJECT => t('Reject manual creation of Drupal accounts that conflict with LDAP Accounts. This only applies to accounts created on user logon;  Account conflicts can still be generated by manually creating users that conflict with ldap users and these users will have their data synched with LDAP data.'),
1006
      LDAP_USER_MANUAL_ACCT_CONFLICT_LDAP_ASSOCIATE => t('Associate manually created Drupal accounts with related LDAP Account if one exists.'),
1007
      LDAP_USER_MANUAL_ACCT_CONFLICT_SHOW_OPTION_ON_FORM => t('Show option on user create form to determine how account conflict is resolved.'),
1008
    );
1009

    
1010
    /**
1011
    *  Drupal Account Provisioning and Synching
1012
    */
1013
    $values['userConflictResolveDescription'] = t('What should be done if a local Drupal or other external
1014
      user account already exists with the same login name.');
1015
    $values['userConflictOptions'] = array(
1016
      LDAP_USER_CONFLICT_LOG => t('Don\'t associate Drupal account with LDAP.  Require user to use Drupal password. Log the conflict'),
1017
      LDAP_USER_CONFLICT_RESOLVE => t('Associate Drupal account with the LDAP entry.  This option
1018
      is useful for creating accounts and assigning roles before an LDAP user authenticates.'),
1019
      );
1020

    
1021
    $values['acctCreationOptions'] = array(
1022
      LDAP_USER_ACCT_CREATION_LDAP_BEHAVIOR => t('Account creation settings at
1023
        /admin/config/people/accounts/settings do not affect "LDAP Associated" Drupal accounts.'),
1024
      LDAP_USER_ACCT_CREATION_USER_SETTINGS_FOR_LDAP => t('Account creation policy
1025
         at /admin/config/people/accounts/settings applies to both Drupal and LDAP Authenticated users.
1026
         "Visitors" option automatically creates and account when they successfully LDAP authenticate.
1027
         "Admin" and "Admin with approval" do not allow user to authenticate until the account is approved.'),
1028

    
1029
      );
1030

    
1031
      foreach ($values as $property => $default_value) {
1032
        $this->$property = $default_value;
1033
      }
1034
    }
1035

    
1036
}