ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilSamlSettingsGUI.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2016 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 require_once 'Services/Saml/classes/class.ilSamlSettings.php';
5 require_once 'Services/Saml/classes/class.ilSamlIdp.php';
6 
12 {
13  const VIEW_MODE_GLOBAL = 1;
14  const VIEW_MODE_SINGLE = 2;
15 
16  const DEFAULT_CMD = 'listIdps';
17 
21  protected static $globalCommands = array(
22  'showAddIdpForm', self::DEFAULT_CMD, 'showSettings', 'saveSettings', 'showNewIdpForm', 'saveNewIdp'
23  );
24 
28  protected static $globalEntityCommands = array(
29  'deactivateIdp', 'activateIdp', 'confirmDeleteIdp', 'deleteIdp'
30  );
31 
35  protected static $ignoredUserFields = array(
36  'mail_incoming_mail', 'preferences', 'hide_own_online_status',
37  'show_users_online', 'hits_per_page',
38  'roles', 'upload', 'password',
39  'username', 'language', 'skin_style',
40  'interests_general', 'interests_help_offered', 'interests_help_looking',
41  'bs_allow_to_contact_me', 'chat_osc_accept_msg'
42  );
43 
47  protected $ref_id;
48 
52  protected $ctrl;
53 
57  protected $lng;
58 
62  protected $tpl;
63 
67  protected $access;
68 
72  protected $error_handler;
73 
77  protected $tabs;
78 
82  protected $rbacreview;
83 
87  protected $toolbar;
88 
92  protected $help;
93 
97  protected $mapping;
98 
102  protected $idp;
103 
107  protected $samlAuth;
108 
113  public function __construct($ref_id)
114  {
115  global $DIC;
116 
117  $this->ctrl = $DIC->ctrl();
118  $this->tpl = $DIC->ui()->mainTemplate();
119  $this->lng = $DIC->language();
120  $this->access = $DIC->access();
121  $this->error_handler = $DIC['ilErr'];
122  $this->tabs = $DIC->tabs();
123  $this->rbacreview = $DIC->rbac()->review();
124  $this->toolbar = $DIC['ilToolbar'];
125  $this->help = $DIC['ilHelp'];
126 
127  $this->lng->loadLanguageModule('auth');
128  $this->ref_id = $ref_id;
129  }
130 
134  protected function ensureAccess($operation)
135  {
136  if (!$this->access->checkAccess($operation, '', $this->getRefId())) {
137  $this->error_handler->raiseError($this->lng->txt('msg_no_perm_read'), $this->error_handler->WARNING);
138  }
139  }
140 
144  protected function ensureWriteAccess()
145  {
146  $this->ensureAccess('write');
147  }
148 
152  protected function ensureReadAccess()
153  {
154  $this->ensureAccess('read');
155  }
156 
160  public function getRefId()
161  {
162  return $this->ref_id;
163  }
164 
168  public function setRefId($ref_id)
169  {
170  $this->ref_id = $ref_id;
171  }
172 
176  protected function initIdp()
177  {
178  try {
179  $this->idp = ilSamlIdp::getInstanceByIdpId((int) $_REQUEST['saml_idp_id']);
180  } catch (\Exception $e) {
181  ilUtil::sendFailure($this->lng->txt('auth_saml_unknow_idp'), true);
182  $this->ctrl->setParameter($this, 'saml_idp_id', null);
183  $this->ctrl->redirect($this, self::DEFAULT_CMD);
184  }
185  }
186 
190  public function executeCommand()
191  {
192  $this->ensureReadAccess();
193 
194  try {
195  $factory = new ilSamlAuthFactory();
196  $this->samlAuth = $factory->auth();
197  } catch (\Throwable $e) {
198  \ilUtil::sendFailure($e->getMessage());
199  } catch (\Exception $e) {
200  \ilUtil::sendFailure($e->getMessage());
201  }
202 
203  $this->help->setScreenIdComponent('auth');
204 
205  switch ($this->ctrl->getNextClass()) {
206  default:
207  $cmd = $this->ctrl->getCmd();
208  if (!strlen($cmd) || !method_exists($this, $cmd)) {
209  $cmd = self::DEFAULT_CMD;
210  }
211 
212  if (isset($_REQUEST['saml_idp_id'])) {
213  $this->ctrl->saveParameter($this, 'saml_idp_id');
214  }
215 
216  if (!in_array(strtolower($cmd), array_map('strtolower', self::$globalCommands))) {
217  if (!isset($_REQUEST['saml_idp_id'])) {
218  $this->ctrl->redirect($this, self::DEFAULT_CMD);
219  }
220 
221  $this->initIdp();
222  $this->initUserAttributeMapping();
223  }
224 
225  if (
226  in_array(strtolower($cmd), array_map('strtolower', self::$globalCommands)) ||
227  in_array(strtolower($cmd), array_map('strtolower', self::$globalEntityCommands))
228  ) {
229  $this->setSubTabs(self::VIEW_MODE_GLOBAL);
230  } else {
231  $this->setSubTabs(self::VIEW_MODE_SINGLE);
232  }
233 
234  $this->$cmd();
235  break;
236  }
237  }
238 
242  protected function listIdps()
243  {
244  if ($this->samlAuth) {
245  $addIdpButton = ilLinkButton::getInstance();
246  $addIdpButton->setCaption('auth_saml_add_idp_btn');
247  $addIdpButton->setUrl($this->ctrl->getLinkTarget($this, 'showNewIdpForm'));
248  $this->toolbar->addStickyItem($addIdpButton);
249  }
250 
251  require_once 'Services/Saml/classes/class.ilSamlIdpTableGUI.php';
252  $table = new ilSamlIdpTableGUI($this, self::DEFAULT_CMD, $this->samlAuth);
253  $this->tpl->setContent($table->getHTML());
254  return;
255  }
256 
260  protected function deactivateIdp()
261  {
262  $this->ensureWriteAccess();
263 
264  $this->idp->setActive(0);
265  $this->idp->persist();
266 
267  ilUtil::sendSuccess($this->lng->txt('saved_successfully'));
268  $this->listIdps();
269  }
270 
274  protected function activateIdp()
275  {
276  $this->ensureWriteAccess();
277 
278  $this->idp->setActive(1);
279  $this->idp->persist();
280 
281  ilUtil::sendSuccess($this->lng->txt('saved_successfully'));
282  $this->listIdps();
283  }
284 
288  protected function setSubTabs($a_view_mode)
289  {
290  switch ($a_view_mode) {
291  case self::VIEW_MODE_GLOBAL:
292  $this->tabs->addSubTabTarget(
293  'auth_saml_idps',
294  $this->ctrl->getLinkTarget($this, self::DEFAULT_CMD),
295  array_merge(self::$globalEntityCommands, array(self::DEFAULT_CMD, 'showNewIdpForm', 'saveNewIdp')),
296  get_class($this)
297  );
298 
299  $this->tabs->addSubTabTarget(
300  'settings',
301  $this->ctrl->getLinkTarget($this, 'showSettings'),
302  array('showSettings', 'saveSettings'),
303  get_class($this)
304  );
305  break;
306 
307  case self::VIEW_MODE_SINGLE:
308  $this->tabs->clearTargets();
309  $this->tabs->setBackTarget($this->lng->txt('back'), $this->ctrl->getLinkTarget($this, self::DEFAULT_CMD));
310 
311  $this->tabs->addSubTabTarget(
312  'auth_saml_idp_settings',
313  $this->ctrl->getLinkTarget($this, 'showIdpSettings'),
314  array('showIdpSettings', 'saveIdpSettings'),
315  get_class($this)
316  );
317 
318  $this->tabs->addSubTabTarget(
319  'auth_saml_user_mapping',
320  $this->ctrl->getLinkTarget($this, 'showUserAttributeMappingForm'),
321  array('showUserAttributeMappingForm', 'saveUserAttributeMapping'),
322  get_class($this)
323  );
324  break;
325  }
326  }
327 
331  private function initUserAttributeMapping()
332  {
333  require_once 'Services/Authentication/classes/External/UserAttributeMapping/class.ilExternalAuthUserAttributeMapping.php';
334  $this->mapping = new ilExternalAuthUserAttributeMapping('saml', $this->idp->getIdpId());
335  }
336 
340  protected function getUserAttributeMappingForm()
341  {
342  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
343  $form = new ilPropertyFormGUI();
344  $form->setFormAction($this->ctrl->getFormAction($this, 'saveUserAttributeMapping'));
345  $form->setTitle($this->lng->txt('auth_saml_user_mapping'));
346 
347  require_once 'Services/User/classes/class.ilUserProfile.php';
348  $usr_profile = new ilUserProfile();
349  foreach ($usr_profile->getStandardFields() as $id => $definition) {
350  if (in_array($id, self::$ignoredUserFields)) {
351  continue;
352  }
353 
354  $this->addAttributeRuleFieldToForm($form, $this->lng->txt($id), $id);
355  }
356 
357  require_once 'Services/User/classes/class.ilUserDefinedFields.php';
358  foreach (ilUserDefinedFields::_getInstance()->getDefinitions() as $definition) {
359  $this->addAttributeRuleFieldToForm($form, $definition['field_name'], 'udf_' . $definition['field_id']);
360  }
361 
362  if (!$this->access->checkAccess('write', '', $this->getRefId())) {
363  foreach ($form->getItems() as $item) {
364  $item->setDisabled(true);
365  }
366  } else {
367  $form->addCommandButton('saveUserAttributeMapping', $this->lng->txt('save'));
368  }
369 
370  return $form;
371  }
372 
378  protected function addAttributeRuleFieldToForm($form, $field_label, $field_name)
379  {
380  $field = new ilTextInputGUI($field_label, $field_name);
381  $form->addItem($field);
382 
383  $update_automatically = new ilCheckboxInputGUI('', $field_name . '_update');
384  $update_automatically->setOptionTitle($this->lng->txt('auth_saml_update_field_info'));
385  $update_automatically->setValue(1);
386  $form->addItem($update_automatically);
387  }
388 
392  protected function saveUserAttributeMapping()
393  {
394  $this->ensureWriteAccess();
395 
397  if ($form->checkInput()) {
398  $this->mapping->delete();
399 
400  require_once 'Services/User/classes/class.ilUserProfile.php';
401  $usr_profile = new ilUserProfile();
402  foreach ($usr_profile->getStandardFields() as $id => $definition) {
403  if (in_array($id, self::$ignoredUserFields)) {
404  continue;
405  }
406 
407  $rule = $this->mapping->getEmptyRule();
408  $rule->setAttribute($id);
409  $rule->setExternalAttribute($form->getInput($rule->getAttribute()));
410  $rule->updateAutomatically((bool) $form->getInput($rule->getAttribute() . '_update'));
411  $this->mapping[$rule->getAttribute()] = $rule;
412  }
413 
414  require_once 'Services/User/classes/class.ilUserDefinedFields.php';
415  foreach (ilUserDefinedFields::_getInstance()->getDefinitions() as $definition) {
416  $rule = $this->mapping->getEmptyRule();
417  $rule->setAttribute('udf_' . $definition['field_id']);
418  $rule->setExternalAttribute($form->getInput($rule->getAttribute()));
419  $rule->updateAutomatically((bool) $form->getInput($rule->getAttribute() . '_update'));
420  $this->mapping[$rule->getAttribute()] = $rule;
421  }
422 
423  $this->mapping->save();
424 
425  ilUtil::sendSuccess($this->lng->txt('saved_successfully'));
426  }
427 
428  $form->setValuesByPost();
429 
431  }
432 
437  {
438  $this->tabs->setSubTabActive('auth_saml_user_mapping');
439 
440  if (!($form instanceof ilPropertyFormGUI)) {
442  $data = array();
443  foreach ($this->mapping as $rule) {
444  $data[$rule->getAttribute()] = $rule->getExternalAttribute();
445  $data[$rule->getAttribute() . '_update'] = (bool) $rule->isAutomaticallyUpdated();
446  }
447  $form->setValuesByArray($data);
448  }
449 
450  $this->tpl->setContent($form->getHTML());
451  }
452 
456  protected function getSettingsForm()
457  {
458  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
459  $form = new ilPropertyFormGUI();
460  $form->setFormAction($this->ctrl->getFormAction($this, 'saveSettings'));
461  $form->setTitle($this->lng->txt('auth_saml_configure'));
462 
463  $show_login_form = new ilCheckboxInputGUI($this->lng->txt('auth_saml_login_form'), 'login_form');
464  $show_login_form->setInfo($this->lng->txt('auth_saml_login_form_info'));
465  $show_login_form->setValue(1);
466  $form->addItem($show_login_form);
467 
468  if (!$this->access->checkAccess('write', '', $this->getRefId())) {
469  foreach ($form->getItems() as $item) {
470  $item->setDisabled(true);
471  }
472  } else {
473  $form->addCommandButton('saveSettings', $this->lng->txt('save'));
474  }
475 
476  return $form;
477  }
478 
482  protected function prepareRoleSelection()
483  {
484  $global_roles = ilUtil::_sortIds(
485  $this->rbacreview->getGlobalRoles(),
486  'object_data',
487  'title',
488  'obj_id'
489  );
490 
491  $select[0] = $this->lng->txt('links_select_one');
492  foreach ($global_roles as $role_id) {
493  $select[$role_id] = ilObject::_lookupTitle($role_id);
494  }
495 
496  return $select;
497  }
498 
502  protected function saveSettings()
503  {
504  $this->ensureWriteAccess();
505 
506  $form = $this->getSettingsForm();
507  if ($form->checkInput()) {
508  ilSamlSettings::getInstance()->setLoginFormStatus((bool) $form->getInput('login_form'));
509  ilUtil::sendSuccess($this->lng->txt('saved_successfully'));
510  }
511 
512  $form->setValuesByPost();
513 
514  $this->showSettings($form);
515  }
516 
520  protected function showSettings(ilPropertyFormGUI $form = null)
521  {
522  if (!($form instanceof ilPropertyFormGUI)) {
523  $form = $this->getSettingsForm();
524  $form->setValuesByArray(array(
525  'login_form' => ilSamlSettings::getInstance()->isDisplayedOnLoginPage()
526  ));
527  }
528 
529  $this->tpl->setContent($form->getHTML());
530  }
531 
535  protected function getIdpSettingsForm()
536  {
537  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
538  $form = new ilPropertyFormGUI();
539  $form->setFormAction($this->ctrl->getFormAction($this, 'saveIdpSettings'));
540  $form->setTitle(sprintf($this->lng->txt('auth_saml_configure_idp'), $this->idp->getEntityId()));
541 
542  $idp = new ilTextInputGUI($this->lng->txt('auth_saml_idp'), 'entity_id');
543  $idp->setDisabled(true);
544  $form->addItem($idp);
545 
546  $this->addMetadataElement($form);
547 
548  $local = new ilCheckboxInputGUI($this->lng->txt('auth_allow_local'), 'allow_local_auth');
549  $local->setValue(1);
550  $local->setInfo($this->lng->txt('auth_allow_local_info'));
551  $form->addItem($local);
552 
553  $uid_claim = new ilTextInputGUI($this->lng->txt('auth_saml_uid_claim'), 'uid_claim');
554  $uid_claim->setInfo($this->lng->txt('auth_saml_uid_claim_info'));
555  $uid_claim->setRequired(true);
556  $form->addItem($uid_claim);
557 
558  $sync = new ilCheckboxInputGUI($this->lng->txt('auth_saml_sync'), 'sync_status');
559  $sync->setInfo($this->lng->txt('auth_saml_sync_info'));
560  $sync->setValue(1);
561 
562  $username_claim = new ilTextInputGUI($this->lng->txt('auth_saml_username_claim'), 'login_claim');
563  $username_claim->setInfo($this->lng->txt('auth_saml_username_claim_info'));
564  $username_claim->setRequired(true);
565  $sync->addSubItem($username_claim);
566 
567  $role = new ilSelectInputGUI($this->lng->txt('auth_saml_role_select'), 'default_role_id');
568  $role->setOptions($this->prepareRoleSelection());
569  $role->setRequired(true);
570  $sync->addSubItem($role);
571 
572  $migr = new ilCheckboxInputGUI($this->lng->txt('auth_saml_migration'), 'account_migr_status');
573  $migr->setInfo($this->lng->txt('auth_saml_migration_info'));
574  $migr->setValue(1);
575  $sync->addSubItem($migr);
576  $form->addItem($sync);
577 
578  if (!$this->access->checkAccess('write', '', $this->getRefId())) {
579  foreach ($form->getItems() as $item) {
580  $item->setDisabled(true);
581  }
582  } else {
583  $form->addCommandButton('saveIdpSettings', $this->lng->txt('save'));
584  }
585  $form->addCommandButton(self::DEFAULT_CMD, $this->lng->txt('cancel'));
586 
587  return $form;
588  }
589 
593  protected function showIdpSettings(ilPropertyFormGUI $form = null)
594  {
595  $this->tabs->setSubTabActive('auth_saml_idp_settings');
596 
597  if (null === $form) {
598  $form = $this->getIdpSettingsForm();
599  $data = $this->idp->toArray();
600  $this->populateWithMetadata($this->idp, $data);
601  $form->setValuesByArray($data);
602  } else {
603  $form->setValuesByPost();
604  }
605 
606  $this->help->setSubScreenId('edit_idp');
607 
608  $this->tpl->setContent($form->getHTML());
609  }
610 
614  protected function saveIdpSettings()
615  {
616  $this->ensureWriteAccess();
617 
618  $form = $this->getIdpSettingsForm();
619  if ($form->checkInput()) {
620  $this->idp->bindForm($form);
621  $this->idp->persist();
622  ilUtil::sendSuccess($this->lng->txt('saved_successfully'));
623 
624  $this->storeMetadata($this->idp, $form->getInput('metadata'));
625  }
626 
627  $this->showIdpSettings($form);
628  }
629 
633  protected function getIdpForm()
634  {
635  $form = new \ilPropertyFormGUI();
636  $form->setFormAction($this->ctrl->getFormAction($this, 'saveNewIdp'));
637  $form->setTitle($this->lng->txt('auth_saml_add_idp_btn'));
638 
639  $this->addMetadataElement($form);
640 
641  $form->addCommandButton('saveNewIdp', $this->lng->txt('save'));
642  $form->addCommandButton('listIdps', $this->lng->txt('cancel'));
643 
644  return $form;
645  }
646 
650  protected function saveNewIdp()
651  {
652  $this->ensureWriteAccess();
653 
654  $form = $this->getIdpForm();
655  if ($form->checkInput()) {
656  $idp = new ilSamlIdp();
657  $idp->bindForm($form);
658  $idp->persist();
659 
660  $this->storeMetadata($idp, $form->getInput('metadata'));
661 
662  ilUtil::sendSuccess($this->lng->txt('saved_successfully'), true);
663  $this->ctrl->setParameter($this, 'saml_idp_id', $idp->getIdpId());
664  $this->ctrl->redirect($this, 'showIdpSettings');
665  }
666 
667  $this->showNewIdpForm($form);
668  }
669 
673  protected function showNewIdpForm(\ilPropertyFormGUI $form = null)
674  {
675  $this->ensureWriteAccess();
676 
677  if (null === $form) {
678  $form = $this->getIdpForm();
679  } else {
680  $form->setValuesByPost();
681  }
682 
683  $this->help->setSubScreenId('create_idp');
684 
685  $this->tpl->setContent($form->getHTML());
686  }
687 
692  {
693  require_once 'Services/Saml/classes/form/class.ilSamlIdpMetadataInputGUI.php';
694  require_once 'Services/Saml/classes/form/class.ilSamlIdpMetadataPurifier.php';
695  require_once 'Services/Saml/classes/class.ilSamlIdpXmlMetadataParser.php';
696  require_once 'Services/Html/classes/class.ilHtmlPurifierComposite.php';
697 
698  $metadata = new \ilSamlIdpMetadataInputGUI(
699  $this->lng->txt('auth_saml_add_idp_md_label'),
700  'metadata',
702  );
703  $metadata->setInfo($this->lng->txt('auth_saml_add_idp_md_info'));
704  $metadata->setRows(20);
705  $metadata->setRequired(true);
706 
707  $purifier = new ilHtmlPurifierComposite();
708  $purifier->addPurifier(new ilSamlIdpMetadataPurifier());
709 
710  $metadata->setPurifier($purifier);
711  $metadata->usePurifier(true);
712  $form->addItem($metadata);
713  }
714 
715  protected function populateWithMetadata(\ilSamlIdp $idp, &$data)
716  {
717  $idpDisco = $this->samlAuth->getIdpDiscovery();
718 
719  $data['metadata'] = $idpDisco->fetchIdpMetadata($idp->getIdpId());
720  }
721 
726  protected function storeMetadata(\ilSamlIdp $idp, $metadata)
727  {
728  $idpDisco = $this->samlAuth->getIdpDiscovery();
729  $idpDisco->storeIdpMetadata($idp->getIdpId(), $metadata);
730  }
731 
735  protected function confirmDeleteIdp()
736  {
737  $this->ensureWriteAccess();
738 
739  require_once 'Services/Utilities/classes/class.ilConfirmationGUI.php';
740  $confirmation = new \ilConfirmationGUI();
741  $confirmation->setFormAction($this->ctrl->getFormAction($this, 'deleteIdp'));
742  $confirmation->setConfirm($this->lng->txt('confirm'), 'deleteIdp');
743  $confirmation->setCancel($this->lng->txt('cancel'), self::DEFAULT_CMD);
744  $confirmation->setHeaderText($this->lng->txt('auth_saml_sure_delete_idp'));
745  $confirmation->addItem('saml_idp_ids', $this->idp->getIdpId(), $this->idp->getEntityId());
746 
747  $this->tpl->setContent($confirmation->getHTML());
748  }
749 
753  protected function deleteIdp()
754  {
755  $this->ensureWriteAccess();
756 
757  $idpDisco = $this->samlAuth->getIdpDiscovery();
758  $idpDisco->deleteIdpMetadata($this->idp->getIdpId());
759 
760  $this->idp->delete();
761 
762  ilUtil::sendSuccess($this->lng->txt('auth_saml_deleted_idp'), true);
763 
764  $this->ctrl->setParameter($this, 'saml_idp_id', null);
765  $this->ctrl->redirect($this, self::DEFAULT_CMD);
766  }
767 }
static sendSuccess($a_info="", $a_keep=false)
Send Success Message to Screen.
Class ilSamlIdpTableGUI.
static _getInstance()
Get instance.
This class represents a selection list property in a property form.
This class represents a property form user interface.
populateWithMetadata(\ilSamlIdp $idp, &$data)
global $DIC
Definition: saml.php:7
Composite for nesting multiple purifiers.
Class ilSamlIdpXmlMetadataParser.
showSettings(ilPropertyFormGUI $form=null)
$factory
Definition: metadata.php:47
if(!array_key_exists('StateId', $_REQUEST)) $id
Class ilUserProfile.
static getInstanceByIdpId($a_idp_id)
This class represents a checkbox property in a property form.
static _lookupTitle($a_id)
lookup object title
addItem($a_item)
Add Item (Property, SectionHeader).
$metadata['__DYNAMIC:1__']
storeMetadata(\ilSamlIdp $idp, $metadata)
setInfo($a_info)
Set Information Text.
Class ilExternalAuthUserAttributeMapping.
showIdpSettings(ilPropertyFormGUI $form=null)
if(isset($_POST['submit'])) $form
$rule
Definition: showstats.php:43
static _sortIds($a_ids, $a_table, $a_field, $a_id_name)
Function that sorts ids by a given table field using WHERE IN E.g: __sort(array(6,7),&#39;usr_data&#39;,&#39;lastname&#39;,&#39;usr_id&#39;) => sorts by lastname.
setValue($a_value)
Set Value.
This class represents a text property in a property form.
$sync
setOptions($a_options)
Set Options.
Create styles array
The data for the language used.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
showNewIdpForm(\ilPropertyFormGUI $form=null)
Class ilSamlIdp.
Class ilSamlSettingsGUI.
addAttributeRuleFieldToForm($form, $field_label, $field_name)
Class ilSamlAuthFactory.
showUserAttributeMappingForm(ilPropertyFormGUI $form=null)
if(empty($password)) $table
Definition: pwgen.php:24
Class ilSamlIdpMetadataPurifier.
__construct($ref_id)
ilSamlSettingsGUI constructor.
addMetadataElement(\ilPropertyFormGUI $form)