Projet

Général

Profil

Paste
Télécharger (17,1 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ldap / ldap_authorization / LdapAuthorizationConsumerConfAdmin.class.php @ 7547bb19

1
<?php
2

    
3
/**
4
 * @file
5
 * class to encapsulate an ldap authorization ldap entry to authorization ids mapping
6
 *
7
 */
8

    
9
module_load_include('php', 'ldap_authorization', 'LdapAuthorizationConsumerConf.class');
10
  /**
11
   * LDAP Authorization Consumer Configration Admin Class
12
   */
13
class LdapAuthorizationConsumerConfAdmin extends LdapAuthorizationConsumerConf {
14

    
15

    
16
  public function save() {
17

    
18
    $op = $this->inDatabase ? 'edit' : 'insert';
19
    $values = new stdClass; // $this;
20
    $values->sid = $this->sid;
21
    $values->numeric_consumer_conf_id = $this->numericConsumerConfId;
22
    $values->consumer_type = $this->consumerType;
23
    $values->consumer_module = $this->consumer->consumerModule;
24
    $values->status = ($this->status) ? 1 : 0;
25
    $values->only_ldap_authenticated = (int)$this->onlyApplyToLdapAuthenticated;
26
    $values->use_first_attr_as_groupid = (int)$this->useFirstAttrAsGroupId;
27
    $values->mappings = serialize($this->mappings);
28
    $values->use_filter = (int)$this->useMappingsAsFilter;
29
    $values->synch_to_ldap = (int)$this->synchToLdap;
30
    $values->synch_on_logon = (int)$this->synchOnLogon;
31
    $values->revoke_ldap_provisioned = (int)$this->revokeLdapProvisioned;
32
    $values->create_consumers = (int)$this->createConsumers;
33
    $values->regrant_ldap_provisioned = (int)$this->regrantLdapProvisioned;
34

    
35
    if (module_exists('ctools')) {
36
      ctools_include('export');
37
      // Populate our object with ctool's properties
38
      $object = ctools_export_crud_new('ldap_authorization');
39
      foreach ($object as $property => $value) {
40
        if (!isset($values->$property)) {
41
          $values->$property = $value;
42
        }
43
      }
44
      try {
45
        $values->export_type = NULL;
46
        $result = ctools_export_crud_save('ldap_authorization', $values);
47
      } catch (Exception $e) {
48
        //  debug($e); Integrity constraint violation: 1062 Duplicate entry
49
        $values->export_type = EXPORT_IN_DATABASE;
50
        $result = ctools_export_crud_save('ldap_authorization', $values);
51
      }
52
      ctools_export_load_object_reset('ldap_authorization'); // ctools_export_crud_save doesn't invalidate cache
53
    }
54
    else {
55

    
56
      if ($op == 'edit') {
57
        $result = drupal_write_record('ldap_authorization', $values, 'consumer_type');
58
      }
59
      else { // insert
60
        $result = drupal_write_record('ldap_authorization', $values);
61
      }
62

    
63
      if ($result) {
64
        $this->inDatabase = TRUE;
65
      }
66
      else {
67
        drupal_set_message(t('Failed to write LDAP Authorization to the database.'));
68
      }
69
    }
70

    
71
  }
72

    
73
  public $fields;
74
  public $consumers;
75

    
76
  public function delete() {
77
    if ($this->consumerType) {
78
      $this->inDatabase = FALSE;
79
      return db_delete('ldap_authorization')->condition('consumer_type', $this->consumerType)->execute();
80
    }
81
    else {
82
      return FALSE;
83
    }
84
  }
85

    
86
  public function __construct(&$consumer = NULL, $new = FALSE) {
87
    parent::__construct($consumer, $new);
88
    $this->fields = $this->fields();
89
    $this->consumers = ldap_authorization_get_consumers(NULL, TRUE);
90

    
91
    if ($new) {
92
      foreach ($this->consumer->defaultConsumerConfProperties as $property => $value) {
93
        $this->$property = $value;
94
      }
95
    }
96
  }
97

    
98
  public function drupalForm($server_options, $op) {
99

    
100
    $consumer_tokens = ldap_authorization_tokens($this->consumer);
101
    $form['intro'] = array(
102
        '#type' => 'item',
103
        '#markup' => t('<h1>LDAP to !consumer_name Configuration</h1>', $consumer_tokens),
104
    );
105

    
106
    $form['status'] = array(
107
      '#type' => 'fieldset',
108
      '#title' => t('I.  Basics', $consumer_tokens),
109
      '#collapsible' => TRUE,
110
      '#collapsed' => FALSE,
111
    );
112

    
113
    $form['status']['sid'] = array(
114
      '#type' => 'radios',
115
      '#title' => t('LDAP Server used in !consumer_name configuration.', $consumer_tokens),
116
      '#required' => 1,
117
      '#default_value' => $this->sid,
118
      '#options' => $server_options,
119
    );
120

    
121
    $form['status']['consumer_type'] = array(
122
      '#type' => 'hidden',
123
      '#value' => $this->consumerType,
124
      '#required' => 1,
125
    );
126

    
127
    $form['status']['status'] = array(
128
      '#type' => 'checkbox',
129
      '#title' => t('Enable this configuration', $consumer_tokens),
130
      '#default_value' =>  $this->status,
131
    );
132

    
133
    $form['status']['only_ldap_authenticated'] = array(
134
      '#type' => 'checkbox',
135
      '#title' => t('Only apply the following LDAP to !consumer_name configuration to users authenticated via LDAP.  One uncommon reason for disabling this is when you are using Drupal authentication, but want to leverage LDAP for authorization; for this to work the Drupal username still has to map to an LDAP entry.', $consumer_tokens),
136
      '#default_value' =>  $this->onlyApplyToLdapAuthenticated,
137
    );
138

    
139

    
140
    if (method_exists($this->consumer, 'mappingExamples')) {
141
      $consumer_tokens['!examples'] = '<fieldset class="collapsible collapsed form-wrapper" id="authorization-mappings">
142
<legend><span class="fieldset-legend">' . t('Examples based on current !consumer_namePlural', $consumer_tokens) . '</span></legend>
143
<div class="fieldset-wrapper">'. $this->consumer->mappingExamples($consumer_tokens) . '<div class="fieldset-wrapper">
144
</fieldset>';
145
    }
146
    else {
147
      $consumer_tokens['!examples'] = '';
148
    }
149
    $form['filter_and_mappings'] = array(
150
      '#type' => 'fieldset',
151
      '#title' => t('II. LDAP to !consumer_name mapping and filtering', $consumer_tokens),
152
      '#description' => t('
153
Representations of groups derived from LDAP might initially look like:
154
<ul>
155
<li><code>cn=students,ou=groups,dc=hogwarts,dc=edu</code></li>
156
<li><code>cn=gryffindor,ou=groups,dc=hogwarts,dc=edu</code></li>
157
<li><code>cn=faculty,ou=groups,dc=hogwarts,dc=edu</code></li>
158
<li><code>cn=probation students,ou=groups,dc=hogwarts,dc=edu</code></li>
159
</ul>
160

161
<p><strong>Mappings are used to convert and filter these group representations to !consumer_namePlural.</strong></p>
162

163
!consumer_mappingDirections
164

165
!examples
166

167
', $consumer_tokens),
168
      '#collapsible' => TRUE,
169
      '#collapsed' => !($this->mappings || $this->useMappingsAsFilter || $this->useFirstAttrAsGroupId),
170
    );
171

    
172
    $form['filter_and_mappings']['use_first_attr_as_groupid'] = array(
173
      '#type' => 'checkbox',
174
      '#title' => t('Convert full dn to value of first attribute before mapping.  e.g.  <code>cn=students,ou=groups,dc=hogwarts,dc=edu</code> would be converted to <code>students</code>', $consumer_tokens),
175
      '#default_value' => $this->useFirstAttrAsGroupId,
176
    );
177
    $form['filter_and_mappings']['mappings'] = array(
178
      '#type' => 'textarea',
179
      '#title' => t('Mapping of LDAP to !consumer_name (one per line)', $consumer_tokens),
180
      '#default_value' => $this->mappingsToPipeList($this->mappings),
181
      '#cols' => 50,
182
      '#rows' => 5,
183
    );
184
    $form['filter_and_mappings']['use_filter'] = array(
185
      '#type' => 'checkbox',
186
      '#title' => t('Only grant !consumer_namePlural that match a filter above.', $consumer_tokens),
187
      '#default_value' => $this->useMappingsAsFilter,
188
      '#description' => t('If enabled, only above mapped !consumer_namePlural will be assigned (e.g. students and administrator).
189
        <strong>If not checked, !consumer_namePlural not mapped above also may be created and granted (e.g. gryffindor and probation students).  In some LDAPs this can lead to hundreds of !consumer_namePlural being created if "Create !consumer_namePlural if they do not exist" is enabled below.
190
        </strong>', $consumer_tokens)
191
    );
192

    
193

    
194
    $form['more'] = array(
195
      '#type' => 'fieldset',
196
      '#title' => t('Part III.  Even More Settings.'),
197
      '#collapsible' => TRUE,
198
      '#collapsed' => FALSE,
199
    );
200

    
201
    $synchronization_modes = array();
202
    if ($this->synchOnLogon)  {
203
      $synchronization_modes[] = 'user_logon';
204
    }
205
    $form['more']['synchronization_modes'] = array(
206
      '#type' => 'checkboxes',
207
      '#title' => t('When should !consumer_namePlural be granted/revoked from user?', $consumer_tokens),
208
      '#options' => array(
209
          'user_logon' => t('When a user logs on.'),
210
      ),
211
      '#default_value' => $synchronization_modes,
212
      '#description' => '',
213
    );
214

    
215
    $synchronization_actions = array();
216
    if ($this->revokeLdapProvisioned)  {
217
      $synchronization_actions[] = 'revoke_ldap_provisioned';
218
    }
219
    if ($this->createConsumers)  {
220
      $synchronization_actions[] = 'create_consumers';
221
    }
222
    if ($this->regrantLdapProvisioned)  {
223
      $synchronization_actions[] = 'regrant_ldap_provisioned';
224
    }
225

    
226
    $options =  array(
227
      'revoke_ldap_provisioned' => t('Revoke !consumer_namePlural previously granted by LDAP Authorization but no longer valid.', $consumer_tokens),
228
      'regrant_ldap_provisioned' => t('Re grant !consumer_namePlural previously granted by LDAP Authorization but removed manually.', $consumer_tokens),
229
    );
230
    if ($this->consumer->allowConsumerObjectCreation) {
231
      $options['create_consumers'] = t('Create !consumer_namePlural if they do not exist.', $consumer_tokens);
232
    }
233

    
234
    $form['more']['synchronization_actions'] = array(
235
      '#type' => 'checkboxes',
236
      '#title' => t('What actions would you like performed when !consumer_namePlural are granted/revoked from user?', $consumer_tokens),
237
      '#options' => $options,
238
      '#default_value' => $synchronization_actions,
239
    );
240
    /**
241
     * @todo  some general options for an individual mapping (perhaps in an advance tab).
242
     *
243
     * - on synchronization allow: revoking authorizations made by this module, authorizations made outside of this module
244
     * - on synchronization create authorization contexts not in existance when needed (drupal roles etc)
245
     * - synchronize actual authorizations (not cached) when granting authorizations
246
     */
247

    
248
    switch ($op) {
249
      case 'add':
250
      $action = 'Add';
251
      break;
252

    
253
      case 'edit':
254
      $action = 'Save';
255
      break;
256

    
257
      case 'delete':
258
      $action = 'Delete';
259
      break;
260
    }
261

    
262
    $form['submit'] = array(
263
      '#type' => 'submit',
264
      '#value' => $action,
265
    );
266

    
267
  return $form;
268
  }
269

    
270

    
271
  protected function loadFromForm($values, $op) {
272

    
273
  }
274

    
275
  public function getLdapAuthorizationConsumerActions() {
276
    $actions = array();
277
    $actions[] =  l(t('edit'), LDAP_SERVERS_MENU_BASE_PATH . '/authorization/edit/' . $this->consumerType);
278
    if (property_exists($this, 'type')) {
279
      if ($this->type == 'Overridden') {
280
          $actions[] = l(t('revert'), LDAP_SERVERS_MENU_BASE_PATH . '/authorization/delete/' . $this->consumerType);
281
      }
282
      if ($this->type == 'Normal') {
283
          $actions[] = l(t('delete'), LDAP_SERVERS_MENU_BASE_PATH . '/authorization/delete/' . $this->consumerType);
284
      }
285
    }
286
    else {
287
        $actions[] = l(t('delete'), LDAP_SERVERS_MENU_BASE_PATH . '/authorization/delete/' . $this->consumerType);
288
    }
289
    $actions[] = l(t('test'), LDAP_SERVERS_MENU_BASE_PATH . '/authorization/test/' . $this->consumerType);
290
    return $actions;
291
  }
292

    
293
  public function drupalFormValidate($op, $values)  {
294
    $errors = array();
295

    
296
    if ($op == 'delete') {
297
      if (!$this->consumerType) {
298
        $errors['consumer_type_missing'] = 'Consumer type is missing from delete form.';
299
      }
300
    }
301
    else {
302

    
303
      $this->populateFromDrupalForm($op, $values);
304
      $errors = $this->validate($values);
305
      if (count($this->mappings) == 0 && trim($values['mappings'])) {
306
        $errors['mappings'] = t('Bad mapping syntax.  Text entered but not able to convert to array.');
307
      }
308

    
309
    }
310
    return $errors;
311
  }
312

    
313
  public function validate($form_values = array()) {
314
    $errors = array();
315

    
316
    if (!$this->consumerType) {
317
      $errors['consumer_type'] = t('Consumer type is missing.');
318
    }
319

    
320
    if ($this->inDatabase  && (!$this->consumerType)) {
321
      $errors['consumer_type'] = t('Edit or delete called without consumer type in form.');
322
    }
323

    
324
    if (count($this->mappings) > 0) {
325
      foreach ($this->mappings as $mapping_item) {
326
        list($type, $text) = $this->consumer->validateAuthorizationMappingTarget($mapping_item, $form_values);
327
        if ($type == 'error') {
328
          $errors['mappings'] = $text;
329
        }
330
        elseif ($type == 'warning' ||  $type == 'status') {
331
          drupal_set_message(check_plain($text), $type);
332
        }
333
      }
334
    }
335
    if ($this->useMappingsAsFilter && !count($this->mappings)) {
336
      $errors['mappings'] = t('Mappings are missing.  Mappings must be supplied if filtering is enabled.');
337
    }
338
    return $errors;
339
  }
340

    
341
  protected function populateFromDrupalForm($op, $values) {
342

    
343
    $this->inDatabase = (drupal_strtolower($op) == 'edit' || drupal_strtolower($op) == 'save');
344
    $this->consumerType = $values['consumer_type'];
345

    
346
    $this->sid = $values['sid'];
347

    
348
    $this->status = (bool)$values['status'];
349
    $this->onlyApplyToLdapAuthenticated  = (bool)(@$values['only_ldap_authenticated']);
350
    $this->useFirstAttrAsGroupId  = (bool)($values['use_first_attr_as_groupid']);
351

    
352
    $this->mappings = $this->consumer->normalizeMappings($this->pipeListToArray($values['mappings'], FALSE));
353
    $this->useMappingsAsFilter  = (bool)(@$values['use_filter']);
354

    
355
    $this->synchOnLogon = (bool)(@$values['synchronization_modes']['user_logon']);
356
    $this->regrantLdapProvisioned = (bool)(@$values['synchronization_actions']['regrant_ldap_provisioned']);
357
    $this->revokeLdapProvisioned = (bool)(@$values['synchronization_actions']['revoke_ldap_provisioned']);
358
    $this->createConsumers = (bool)(@$values['synchronization_actions']['create_consumers']);
359

    
360
  }
361

    
362
  public function drupalFormSubmit($op, $values) {
363

    
364
    $this->populateFromDrupalForm($op, $values);
365
    if ($op == 'delete') {
366
      $this->delete();
367
    }
368
    else { // add or edit
369

    
370
      try {
371
        $save_result = $this->save();
372
      }
373
      catch (Exception $e) {
374
        $this->errorName = 'Save Error';
375
        $this->errorMsg = t('Failed to save object.  Your form data was not saved.');
376
        $this->hasError = TRUE;
377
      }
378
    }
379
  }
380

    
381

    
382
  public static function fields() {
383

    
384
     /**
385
     * consumer_type is tag (unique alphanumeric id) of consuming authorization such as
386
     *   drupal_roles, og_groups, civicrm_memberships
387
     */
388
    $fields = array(
389
      'numeric_consumer_conf_id' => array(
390
          'schema' => array(
391
            'type' => 'serial',
392
            'unsigned' => TRUE,
393
            'not null' => TRUE,
394
            'description' => 'Primary ID field for the table.  Only used internally.',
395
            'no export' => TRUE,
396
          ),
397
        ),
398
      'sid' => array(
399
        'schema' => array(
400
          'type' => 'varchar',
401
          'length' => 20,
402
          'not null' => TRUE,
403
        )
404
      ),
405
      'consumer_type' => array(
406
         'schema' => array(
407
            'type' => 'varchar',
408
            'length' => 20,
409
            'not null' => TRUE,
410
        )
411
      ),
412
     'consumer_module' => array(
413
         'schema' => array(
414
            'type' => 'varchar',
415
            'length' => 30,
416
            'not null' => TRUE,
417
        )
418
      ),
419

    
420
      'status' => array(
421
          'schema' => array(
422
            'type' => 'int',
423
            'size' => 'tiny',
424
            'not null' => TRUE,
425
            'default' => 0,
426
          )
427
      ),
428
      'only_ldap_authenticated' => array(
429
        'schema' => array(
430
          'type' => 'int',
431
          'size' => 'tiny',
432
          'not null' => TRUE,
433
          'default' => 1,
434
        )
435
      ),
436

    
437
      'use_first_attr_as_groupid' => array(
438
        'schema' => array(
439
          'type' => 'int',
440
          'size' => 'tiny',
441
          'not null' => TRUE,
442
          'default' => 0,
443
        )
444
      ),
445

    
446
      'mappings'  => array(
447
        'form_default' => array(),
448
        'schema' => array(
449
          'type' => 'text',
450
          'size' => 'medium',
451
          'not null' => FALSE,
452
          'default' => NULL,
453
        )
454
      ),
455

    
456
      'use_filter' => array(
457
        'schema' => array(
458
          'type' => 'int',
459
          'size' => 'tiny',
460
          'not null' => TRUE,
461
          'default' => 1,
462
        )
463
      ),
464

    
465
      'synchronization_modes' => array(
466
        'form_default' =>  array('user_logon'),
467
      ),
468

    
469
      'synchronization_actions' => array(
470
        'form_default' =>  array('revoke_ldap_provisioned', 'create_consumers'),
471
      ),
472

    
473
      'synch_to_ldap'  => array(
474
        'schema' => array(
475
          'type' => 'int',
476
          'size' => 'tiny',
477
          'not null' => TRUE,
478
          'default' => 0,
479
        ),
480
      ),
481

    
482
      'synch_on_logon'  => array(
483
        'schema' => array(
484
          'type' => 'int',
485
          'size' => 'tiny',
486
          'not null' => TRUE,
487
          'default' => 0,
488
        ),
489
      ),
490

    
491
      'revoke_ldap_provisioned'  => array(
492
        'schema' => array(
493
          'type' => 'int',
494
          'size' => 'tiny',
495
          'not null' => TRUE,
496
          'default' => 0,
497
        ),
498
      ),
499

    
500
     'create_consumers'  => array(
501
        'schema' => array(
502
          'type' => 'int',
503
          'size' => 'tiny',
504
          'not null' => TRUE,
505
          'default' => 0,
506
        ),
507
      ),
508

    
509
     'regrant_ldap_provisioned'  => array(
510
        'schema' => array(
511
          'type' => 'int',
512
          'size' => 'tiny',
513
          'not null' => TRUE,
514
          'default' => 0,
515
        ),
516
      ),
517
    );
518
    return $fields;
519
  }
520

    
521

    
522
  protected function mappingsToPipeList($mappings) {
523
    $result_text = "";
524
    foreach ($mappings as $map) {
525
      $result_text .= $map['from'] . '|' . $map['user_entered'] . "\n";
526
    }
527
    return $result_text;
528
  }
529

    
530

    
531
}