ILIAS  trunk Revision v11.0_alpha-1723-g8e69f309bab
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilSamlSettingsGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
26 
27 final class ilSamlSettingsGUI
28 {
29  private const VIEW_MODE_GLOBAL = 1;
30  private const VIEW_MODE_SINGLE = 2;
31 
32  public const DEFAULT_CMD = 'listIdps';
33 
34  private const PERMISSION_WRITE = 'write';
35 
36  private const REQUEST_PARAM_SAML_IDP_ID = 'saml_idp_id';
37  private const REQUEST_PARAM_SAML_IDP_IDS = 'saml_idp_ids';
38 
39  private const MESSAGE_TYPE_FAILURE = 'failure';
40  private const MESSAGE_TYPE_SUCCESS = 'success';
41 
42  private const LNG_SAVED_SUCCESSFULLY = 'saved_successfully';
43  private const LNG_AUTH_SAML_USER_MAPPING = 'auth_saml_user_mapping';
44  private const LNG_LOGIN_FORM = 'login_form';
45  private const LNG_CANCEL = 'cancel';
46 
47  private const CMD_SHOW_SETTINGS = 'showSettings';
48  private const CMD_SAVE_NEW_IDP = 'saveNewIdp';
49  private const CMD_SAVE_SETTINGS = 'saveSettings';
50  private const CMD_SHOW_IDP_SETTINGS = 'showIdpSettings';
51  private const CMT_SAVE_IDP_SETTINGS = 'saveIdpSettings';
52  private const CMD_SAVE = 'save';
53  private const CMD_SAVE_USER_ATTRIBUTE_MAPPING = 'saveUserAttributeMapping';
54 
55  private const PROP_UPDATE_SUFFIX = '_update';
56 
57  private const METADATA_STORAGE_KEY = 'metadata';
58 
62  private const GLOBAL_COMMANDS = [
63  self::DEFAULT_CMD,
64  'showAddIdpForm',
65  self::CMD_SHOW_SETTINGS,
66  self::CMD_SAVE_SETTINGS,
67  'showNewIdpForm',
68  'saveNewIdp',
69  ];
70 
74  private const GLOBAL_ENTITY_COMMANDS = [
75  'deactivateIdp',
76  'activateIdp',
77  'confirmDeleteIdp',
78  'deleteIdp',
79  ];
80 
84  private const IGNORED_USER_FIELDS = [
85  'mail_incoming_mail',
86  'preferences',
87  'hide_own_online_status',
88  'show_users_online',
89  'roles',
90  'upload',
91  'password',
92  'username',
93  'language',
94  'skin_style',
95  'interests_general',
96  'interests_help_offered',
97  'interests_help_looking',
98  'bs_allow_to_contact_me',
99  'chat_osc_accept_msg',
100  'chat_broadcast_typing',
101  ];
102 
103  private readonly ilCtrlInterface $ctrl;
104  private readonly ilLanguage $lng;
105  private readonly ilGlobalTemplateInterface $tpl;
106  private readonly RBACServices $rbac;
107  private readonly ilErrorHandling $error_handler;
108  private readonly ilTabsGUI $tabs;
109  private readonly ilToolbarGUI $toolbar;
110  private readonly GlobalHttpState $httpState;
111  private readonly Refinery $refinery;
112  private readonly ilHelpGUI $help;
114  private ?ilSamlIdp $idp = null;
116  private readonly \ILIAS\UI\Factory $ui_factory;
117  private readonly \ILIAS\UI\Renderer $ui_renderer;
118 
119  public function __construct(private readonly int $ref_id)
120  {
121  global $DIC;
122 
123  $this->ctrl = $DIC->ctrl();
124  $this->tpl = $DIC->ui()->mainTemplate();
125  $this->lng = $DIC->language();
126  $this->rbac = $DIC->rbac();
127  $this->error_handler = $DIC['ilErr'];
128  $this->tabs = $DIC->tabs();
129  $this->toolbar = $DIC['ilToolbar'];
130  $this->help = $DIC['ilHelp'];
131  $this->httpState = $DIC->http();
132  $this->refinery = $DIC->refinery();
133  $this->ui_factory = $DIC->ui()->factory();
134  $this->ui_renderer = $DIC->ui()->renderer();
135 
136  $this->lng->loadLanguageModule('auth');
137  }
138 
139  private function ensureAccess(string $operation): void
140  {
141  if (!$this->rbac->system()->checkAccess($operation, $this->ref_id)) {
142  $this->error_handler->raiseError($this->lng->txt('msg_no_perm_read'), $this->error_handler->WARNING);
143  }
144  }
145 
146  private function ensureWriteAccess(): void
147  {
148  $this->ensureAccess(self::PERMISSION_WRITE);
149  }
150 
151  private function ensureReadAccess(): void
152  {
153  $this->ensureAccess('read');
154  }
155 
156  public function getRefId(): int
157  {
158  return $this->ref_id;
159  }
160 
161  private function getIdpIdOrZero(): int
162  {
163  $idpId = 0;
164  if ($this->httpState->wrapper()->query()->has(self::REQUEST_PARAM_SAML_IDP_ID)) {
165  $idpId = $this->httpState->wrapper()->query()->retrieve(
166  self::REQUEST_PARAM_SAML_IDP_ID,
167  $this->refinery->kindlyTo()->int()
168  );
169  } elseif ($this->httpState->wrapper()->post()->has(self::REQUEST_PARAM_SAML_IDP_ID)) {
170  $idpId = $this->httpState->wrapper()->post()->retrieve(
171  self::REQUEST_PARAM_SAML_IDP_ID,
172  $this->refinery->kindlyTo()->int()
173  );
174  }
175 
176  if ($this->httpState->wrapper()->query()->has('saml_idps_table_action')) {
177  if ($this->httpState->wrapper()->query()->has('saml_idps_idp_id')) {
178  $idpIds = $this->httpState->wrapper()->query()->retrieve(
179  'saml_idps_idp_id',
180  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
181  );
182  if (count($idpIds) === 1) {
183  $idpId = current($idpIds);
184  }
185  }
186  }
187 
188  if ($this->httpState->wrapper()->post()->has(self::REQUEST_PARAM_SAML_IDP_IDS)) {
189  $idpIds = $this->httpState->wrapper()->post()->retrieve(
190  self::REQUEST_PARAM_SAML_IDP_IDS,
191  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
192  );
193  if (count($idpIds) === 1) {
194  $idpId = current($idpIds);
195  }
196  }
197 
198  return $idpId;
199  }
200 
201  private function initIdp(): void
202  {
203  try {
204  $this->idp = ilSamlIdp::getInstanceByIdpId($this->getIdpIdOrZero());
205  } catch (Exception) {
206  $this->tpl->setOnScreenMessage(self::MESSAGE_TYPE_FAILURE, $this->lng->txt('auth_saml_unknow_idp'), true);
207  $this->ctrl->setParameter($this, self::REQUEST_PARAM_SAML_IDP_ID, null);
208  $this->ctrl->redirect($this, self::DEFAULT_CMD);
209  }
210  }
211 
212  public function executeCommand(): void
213  {
214  $this->ensureReadAccess();
215 
216  try {
217  $factory = new ilSamlAuthFactory();
218  $this->samlAuth = $factory->auth();
219  } catch (Throwable $e) {
220  if ('Database error: could not find driver' === $e->getMessage()) {
221  $this->tpl->setOnScreenMessage(
222  self::MESSAGE_TYPE_FAILURE,
223  $this->lng->txt('auth_saml_err_sqlite_driver')
224  );
225  } else {
226  $this->tpl->setOnScreenMessage(self::MESSAGE_TYPE_FAILURE, $e->getMessage());
227  }
228  }
229 
230  $this->help->setScreenIdComponent('auth');
231  $cmd = $this->ctrl->getCmd();
232  if ($cmd === null || $cmd === '' || !method_exists($this, $cmd)) {
233  $cmd = self::DEFAULT_CMD;
234  }
235  $ipdId = $this->getIdpIdOrZero();
236  if ($ipdId > 0) {
237  $this->ctrl->saveParameter($this, self::REQUEST_PARAM_SAML_IDP_ID);
238  }
239  if (!in_array(strtolower($cmd), array_map('strtolower', self::GLOBAL_COMMANDS), true)) {
240  if (0 === $ipdId) {
241  $this->ctrl->redirect($this, self::DEFAULT_CMD);
242  }
243 
244  $this->initIdp();
245  $this->initUserAttributeMapping();
246  }
247  if (
248  in_array(strtolower($cmd), array_map('strtolower', self::GLOBAL_COMMANDS), true) ||
249  in_array(strtolower($cmd), array_map('strtolower', self::GLOBAL_ENTITY_COMMANDS), true)
250  ) {
251  $this->setSubTabs(self::VIEW_MODE_GLOBAL);
252  } else {
253  $this->setSubTabs(self::VIEW_MODE_SINGLE);
254  }
255  $this->$cmd();
256  }
257 
258  private function listIdps(): void
259  {
260  if ($this->samlAuth && $this->rbac->system()->checkAccess(self::PERMISSION_WRITE, $this->ref_id)) {
261  $this->toolbar->addStickyItem(
262  $this->ui_factory->button()->standard(
263  $this->lng->txt('auth_saml_add_idp_btn'),
264  $this->ctrl->getLinkTarget($this, 'showNewIdpForm')
265  )
266  );
267  }
268 
269  $federationMdUrl = rtrim(
270  ILIAS_HTTP_PATH,
271  '/'
272  ) . '/metadata.php?client_id=' . CLIENT_ID;
273  $info = $this->ui_factory->messageBox()->info(
274  sprintf(
275  $this->lng->txt('auth_saml_idps_info'),
276  'auth/saml/config/config.php',
277  'auth/saml/config/authsources.php',
278  $this->ui_renderer->render(
279  $this->ui_factory->link()->standard(
280  'https://simplesamlphp.org/docs/stable/simplesamlphp-sp',
281  'https://simplesamlphp.org/docs/stable/simplesamlphp-sp'
282  )
283  ),
284  $this->ui_renderer->render($this->ui_factory->link()->standard($federationMdUrl, $federationMdUrl))
285  )
286  );
287 
288  $table = new ilSamlIdpTableGUI(
289  $this,
290  $this->ui_factory,
291  $this->ui_renderer,
292  $this->lng,
293  $this->ctrl,
294  $this->httpState->request(),
295  new Factory(),
296  'handleTableActions',
297  $this->rbac->system()->checkAccess(self::PERMISSION_WRITE, $this->ref_id)
298  );
299  $this->tpl->setContent($this->ui_renderer->render([$info, $table->get()]));
300  }
301 
302  private function handleTableActions(): void
303  {
304  $action = $this->httpState->wrapper()->query()->retrieve(
305  'saml_idps_table_action',
306  $this->refinery->byTrying([
307  $this->refinery->kindlyTo()->string(),
308  $this->refinery->always('')
309  ])
310  );
311  match ($action) {
312  'showIdpSettings' => $this->showIdpSettings(),
313  'activateIdp' => $this->activateIdp(),
314  'deactivateIdp' => $this->deactivateIdp(),
315  'confirmDeleteIdp' => $this->confirmDeleteIdp(),
316  default => $this->ctrl->redirect($this, self::DEFAULT_CMD),
317  };
318  }
319 
320  private function deactivateIdp(): void
321  {
322  $this->ensureWriteAccess();
323 
324  $this->idp->setActive(false);
325  $this->idp->persist();
326 
327  $this->tpl->setOnScreenMessage(self::MESSAGE_TYPE_SUCCESS, $this->lng->txt(self::LNG_SAVED_SUCCESSFULLY), true);
328  $this->ctrl->redirect($this, self::DEFAULT_CMD);
329  }
330 
331  private function activateIdp(): void
332  {
333  $this->ensureWriteAccess();
334 
335  $this->idp->setActive(true);
336  $this->idp->persist();
337 
338  $this->tpl->setOnScreenMessage(self::MESSAGE_TYPE_SUCCESS, $this->lng->txt(self::LNG_SAVED_SUCCESSFULLY), true);
339  $this->ctrl->redirect($this, self::DEFAULT_CMD);
340  }
341 
342  private function setSubTabs(int $a_view_mode): void
343  {
344  switch ($a_view_mode) {
345  case self::VIEW_MODE_GLOBAL:
346  $this->tabs->addSubTabTarget(
347  'auth_saml_idps',
348  $this->ctrl->getLinkTarget($this, self::DEFAULT_CMD),
349  array_merge(
350  self::GLOBAL_ENTITY_COMMANDS,
351  [self::DEFAULT_CMD, 'showNewIdpForm', self::CMD_SAVE_NEW_IDP]
352  ),
353  self::class
354  );
355 
356  $this->tabs->addSubTabTarget(
357  'settings',
358  $this->ctrl->getLinkTarget($this, self::CMD_SHOW_SETTINGS),
359  [self::CMD_SHOW_SETTINGS, self::CMD_SAVE_SETTINGS],
360  self::class
361  );
362  break;
363 
364  case self::VIEW_MODE_SINGLE:
365  $this->tabs->clearTargets();
366  $this->tabs->setBackTarget(
367  $this->lng->txt('back'),
368  $this->ctrl->getLinkTarget($this, self::DEFAULT_CMD)
369  );
370 
371  $this->tabs->addSubTabTarget(
372  'auth_saml_idp_settings',
373  $this->ctrl->getLinkTarget($this, self::CMD_SHOW_IDP_SETTINGS),
374  [self::CMD_SHOW_IDP_SETTINGS, self::CMT_SAVE_IDP_SETTINGS],
375  self::class
376  );
377 
378  $this->tabs->addSubTabTarget(
379  self::LNG_AUTH_SAML_USER_MAPPING,
380  $this->ctrl->getLinkTarget($this, 'showUserAttributeMappingForm'),
381  ['showUserAttributeMappingForm', self::CMD_SAVE_USER_ATTRIBUTE_MAPPING],
382  self::class
383  );
384  break;
385  }
386  }
387 
388  private function initUserAttributeMapping(): void
389  {
390  $this->mapping = new ilExternalAuthUserAttributeMapping('saml', $this->idp->getIdpId());
391  }
392 
394  {
395  $form = new ilPropertyFormGUI();
396  $form->setFormAction($this->ctrl->getFormAction($this, self::CMD_SAVE_USER_ATTRIBUTE_MAPPING));
397  $form->setTitle($this->lng->txt(self::LNG_AUTH_SAML_USER_MAPPING));
398 
399  $usr_profile = new ilUserProfile();
400  foreach (array_keys($usr_profile->getStandardFields()) as $id) {
401  if (in_array($id, self::IGNORED_USER_FIELDS, true)) {
402  continue;
403  }
404 
405  $this->addAttributeRuleFieldToForm($form, $this->lng->txt($id), $id);
406  }
407 
408  foreach (ilUserDefinedFields::_getInstance()->getDefinitions() as $definition) {
409  $this->addAttributeRuleFieldToForm($form, $definition['field_name'], 'udf_' . $definition['field_id']);
410  }
411 
412  if (!$this->rbac->system()->checkAccess(self::PERMISSION_WRITE, $this->ref_id)) {
413  foreach ($form->getItems() as $item) {
414  $item->setDisabled(true);
415  }
416  } else {
417  $form->addCommandButton(self::CMD_SAVE_USER_ATTRIBUTE_MAPPING, $this->lng->txt(self::CMD_SAVE));
418  }
419 
420  return $form;
421  }
422 
423  private function addAttributeRuleFieldToForm(
424  ilPropertyFormGUI $form,
425  string $field_label,
426  string $field_name
427  ): void {
428  $field = new ilTextInputGUI($field_label, $field_name);
429  $form->addItem($field);
430 
431  $update_automatically = new ilCheckboxInputGUI('', $field_name . self::PROP_UPDATE_SUFFIX);
432  $update_automatically->setOptionTitle($this->lng->txt('auth_saml_update_field_info'));
433  $update_automatically->setValue('1');
434  $form->addItem($update_automatically);
435  }
436 
437  private function saveUserAttributeMapping(): void
438  {
439  $this->ensureWriteAccess();
440 
441  $form = $this->getUserAttributeMappingForm();
442  if ($form->checkInput()) {
443  $this->mapping->delete();
444 
445  $usr_profile = new ilUserProfile();
446  foreach (array_keys($usr_profile->getStandardFields()) as $id) {
447  if (in_array($id, self::IGNORED_USER_FIELDS, true)) {
448  continue;
449  }
450 
451  $rule = $this->mapping->getEmptyRule();
452  $rule->setAttribute($id);
453  $rule->setExternalAttribute((string) $form->getInput($rule->getAttribute()));
454  $rule->updateAutomatically((bool) $form->getInput($rule->getAttribute() . self::PROP_UPDATE_SUFFIX));
455  $this->mapping[$rule->getAttribute()] = $rule;
456  }
457 
458  foreach (ilUserDefinedFields::_getInstance()->getDefinitions() as $definition) {
459  $rule = $this->mapping->getEmptyRule();
460  $rule->setAttribute('udf_' . $definition['field_id']);
461  $rule->setExternalAttribute((string) $form->getInput($rule->getAttribute()));
462  $rule->updateAutomatically((bool) $form->getInput($rule->getAttribute() . self::PROP_UPDATE_SUFFIX));
463  $this->mapping[$rule->getAttribute()] = $rule;
464  }
465 
466  $this->mapping->save();
467 
468  $this->tpl->setOnScreenMessage(self::MESSAGE_TYPE_SUCCESS, $this->lng->txt(self::LNG_SAVED_SUCCESSFULLY));
469  }
470 
471  $form->setValuesByPost();
472 
473  $this->showUserAttributeMappingForm($form);
474  }
475 
476  private function showUserAttributeMappingForm(?ilPropertyFormGUI $form = null): void
477  {
478  $this->tabs->setSubTabActive(self::LNG_AUTH_SAML_USER_MAPPING);
479 
480  if (!($form instanceof ilPropertyFormGUI)) {
481  $form = $this->getUserAttributeMappingForm();
482  $data = [];
483  foreach ($this->mapping as $rule) {
484  $data[$rule->getAttribute()] = $rule->getExternalAttribute();
485  $data[$rule->getAttribute() . self::PROP_UPDATE_SUFFIX] = $rule->isAutomaticallyUpdated();
486  }
487  $form->setValuesByArray($data);
488  }
489 
490  $this->tpl->setContent($form->getHTML());
491  }
492 
496  private function getSettingsForm(array $values = []): StandardForm
497  {
498  $access = $this->rbac->system()->checkAccess(self::PERMISSION_WRITE, $this->ref_id);
499  $form = $this->ui_factory->input()->container()->form()->standard(
500  $this->ctrl->getFormAction($this, $access ? self::CMD_SAVE_SETTINGS : self::CMD_SHOW_SETTINGS),
501  [
502  self::LNG_LOGIN_FORM => $this->ui_factory->input()->field()->checkbox(
503  $this->lng->txt('auth_saml_login_form'),
504  $this->lng->txt('auth_saml_login_form_info')
505  )
506  ->withValue((bool) ($values[self::LNG_LOGIN_FORM] ?? true))
507  ->withDisabled(!$access),
508  ]
509  );
510 
511  if (!$access) {
512  $form = $form->withSubmitLabel($this->lng->txt('refresh'));
513  }
514 
515  return $form;
516  }
517 
521  private function prepareRoleSelection(): array
522  {
523  $select = [];
524  $global_roles = array_map(
525  'intval',
527  $this->rbac->review()->getGlobalRoles(),
528  'object_data',
529  'title',
530  'obj_id'
531  )
532  );
533 
534  $select[0] = $this->lng->txt('links_select_one');
535  foreach ($global_roles as $role_id) {
536  $select[$role_id] = ilObject::_lookupTitle($role_id);
537  }
538 
539  return $select;
540  }
541 
542  private function saveSettings(): void
543  {
544  $this->ensureWriteAccess();
545 
546  $form = $this->getSettingsForm()->withRequest($this->httpState->request());
547  if (!$form->getError()) {
548  $data = $form->getData();
549  ilSamlSettings::getInstance()->setLoginFormStatus($data[self::LNG_LOGIN_FORM]);
550  $this->tpl->setOnScreenMessage(self::MESSAGE_TYPE_SUCCESS, $this->lng->txt(self::LNG_SAVED_SUCCESSFULLY));
551  }
552 
553  $this->showSettings($form);
554  }
555 
556  private function showSettings(?StandardForm $form = null): void
557  {
558  if (!$form) {
559  $form = $this->getSettingsForm([
560  self::LNG_LOGIN_FORM => ilSamlSettings::getInstance()->isDisplayedOnLoginPage()
561  ]);
562  }
563 
564  $title = $this->ui_factory->item()->standard($this->lng->txt('auth_saml_configure'));
565  $this->tpl->setContent($this->ui_renderer->render([
566  $title,
567  $form
568  ]));
569  }
570 
572  {
573  $form = new ilPropertyFormGUI();
574  $form->setFormAction($this->ctrl->getFormAction($this, self::CMT_SAVE_IDP_SETTINGS));
575  $form->setTitle(sprintf($this->lng->txt('auth_saml_configure_idp'), $this->idp->getEntityId()));
576 
577  $idp = new ilTextInputGUI($this->lng->txt('auth_saml_idp'), 'entity_id');
578  $idp->setDisabled(true);
579  $form->addItem($idp);
580 
581  $this->addMetadataElement($form);
582 
583  $local = new ilCheckboxInputGUI($this->lng->txt('auth_allow_local'), 'allow_local_auth');
584  $local->setValue('1');
585  $local->setInfo($this->lng->txt('auth_allow_local_info'));
586  $form->addItem($local);
587 
588  $uid_claim = new ilTextInputGUI($this->lng->txt('auth_saml_uid_claim'), 'uid_claim');
589  $uid_claim->setInfo($this->lng->txt('auth_saml_uid_claim_info'));
590  $uid_claim->setRequired(true);
591  $form->addItem($uid_claim);
592 
593  $sync = new ilCheckboxInputGUI($this->lng->txt('auth_saml_sync'), 'sync_status');
594  $sync->setInfo($this->lng->txt('auth_saml_sync_info'));
595  $sync->setValue('1');
596 
597  $username_claim = new ilTextInputGUI($this->lng->txt('auth_saml_username_claim'), 'login_claim');
598  $username_claim->setInfo($this->lng->txt('auth_saml_username_claim_info'));
599  $username_claim->setRequired(true);
600  $sync->addSubItem($username_claim);
601 
602  $role = new ilSelectInputGUI($this->lng->txt('auth_saml_role_select'), 'default_role_id');
603  $role->setOptions($this->prepareRoleSelection());
604  $role->setRequired(true);
605  $sync->addSubItem($role);
606 
607  $migr = new ilCheckboxInputGUI($this->lng->txt('auth_saml_migration'), 'account_migr_status');
608  $migr->setInfo($this->lng->txt('auth_saml_migration_info'));
609  $migr->setValue('1');
610  $sync->addSubItem($migr);
611  $form->addItem($sync);
612 
613  if (!$this->rbac->system()->checkAccess(self::PERMISSION_WRITE, $this->ref_id)) {
614  foreach ($form->getItems() as $item) {
615  $item->setDisabled(true);
616  }
617  } else {
618  $form->addCommandButton(self::CMT_SAVE_IDP_SETTINGS, $this->lng->txt(self::CMD_SAVE));
619  }
620  $form->addCommandButton(self::DEFAULT_CMD, $this->lng->txt(self::LNG_CANCEL));
621 
622  return $form;
623  }
624 
625  private function showIdpSettings(?ilPropertyFormGUI $form = null): void
626  {
627  $this->tabs->setSubTabActive('auth_saml_idp_settings');
628 
629  if (null === $form) {
630  $form = $this->getIdpSettingsForm();
631  $data = $this->idp->toArray();
632  $this->populateWithMetadata($this->idp, $data);
633  $form->setValuesByArray($data);
634  } else {
635  $form->setValuesByPost();
636  }
637 
638  $this->help->setSubScreenId('edit_idp');
639 
640  $this->tpl->setContent($form->getHTML());
641  }
642 
643  private function saveIdpSettings(): void
644  {
645  $this->ensureWriteAccess();
646 
647  $form = $this->getIdpSettingsForm();
648  if ($form->checkInput()) {
649  $this->idp->bindForm($form);
650  $this->idp->persist();
651  $this->tpl->setOnScreenMessage(self::MESSAGE_TYPE_SUCCESS, $this->lng->txt(self::LNG_SAVED_SUCCESSFULLY));
652 
653  $this->storeMetadata($this->idp, $form->getInput(self::METADATA_STORAGE_KEY));
654  }
655 
656  $this->showIdpSettings($form);
657  }
658 
659  private function getIdpForm(): ilPropertyFormGUI
660  {
661  $form = new ilPropertyFormGUI();
662  $form->setFormAction($this->ctrl->getFormAction($this, self::CMD_SAVE_NEW_IDP));
663  $form->setTitle($this->lng->txt('auth_saml_add_idp_btn'));
664 
665  $this->addMetadataElement($form);
666 
667  $form->addCommandButton(self::CMD_SAVE_NEW_IDP, $this->lng->txt(self::CMD_SAVE));
668  $form->addCommandButton('listIdps', $this->lng->txt(self::LNG_CANCEL));
669 
670  return $form;
671  }
672 
673  private function saveNewIdp(): void
674  {
675  $this->ensureWriteAccess();
676 
677  $form = $this->getIdpForm();
678  if ($form->checkInput()) {
679  $idp = new ilSamlIdp();
680  $idp->bindForm($form);
681  $idp->persist();
682 
683  $this->storeMetadata($idp, $form->getInput(self::METADATA_STORAGE_KEY));
684 
685  $this->tpl->setOnScreenMessage(
686  self::MESSAGE_TYPE_SUCCESS,
687  $this->lng->txt(self::LNG_SAVED_SUCCESSFULLY),
688  true
689  );
690  $this->ctrl->setParameter($this, self::REQUEST_PARAM_SAML_IDP_ID, $idp->getIdpId());
691  $this->ctrl->redirect($this, self::CMD_SHOW_IDP_SETTINGS);
692  }
693 
694  $this->showNewIdpForm($form);
695  }
696 
697  private function showNewIdpForm(?ilPropertyFormGUI $form = null): void
698  {
699  $this->ensureWriteAccess();
700 
701  if (null === $form) {
702  $form = $this->getIdpForm();
703  } else {
704  $form->setValuesByPost();
705  }
706 
707  $this->help->setSubScreenId('create_idp');
708 
709  $this->tpl->setContent($form->getHTML());
710  }
711 
712  private function addMetadataElement(ilPropertyFormGUI $form): void
713  {
714  $metadata = new ilSamlIdpMetadataInputGUI(
715  $this->lng->txt('auth_saml_add_idp_md_label'),
716  self::METADATA_STORAGE_KEY,
718  new Factory(),
720  )
721  );
722  $metadata->setInfo($this->lng->txt('auth_saml_add_idp_md_info'));
723  $metadata->setRows(20);
724  $metadata->setRequired(true);
725 
726  $purifier = new ilHtmlPurifierComposite();
727  $purifier->addPurifier(new ilSamlIdpMetadataPurifier());
728 
729  $metadata->setPurifier($purifier);
730  $metadata->usePurifier(true);
731  $form->addItem($metadata);
732  }
733 
734  private function populateWithMetadata(ilSamlIdp $idp, array &$data): void
735  {
736  $idpDisco = $this->samlAuth->getIdpDiscovery();
737 
738  $data[self::METADATA_STORAGE_KEY] = $idpDisco->fetchIdpMetadata($idp->getIdpId());
739  }
740 
741  private function storeMetadata(ilSamlIdp $idp, string $metadata): void
742  {
743  $idpDisco = $this->samlAuth->getIdpDiscovery();
744  $idpDisco->storeIdpMetadata($idp->getIdpId(), $metadata);
745  }
746 
747  private function confirmDeleteIdp(): void
748  {
749  $this->ensureWriteAccess();
750 
751  $confirmation = new ilConfirmationGUI();
752  $confirmation->setFormAction($this->ctrl->getFormAction($this, 'deleteIdp'));
753  $confirmation->setConfirm($this->lng->txt('confirm'), 'deleteIdp');
754  $confirmation->setCancel($this->lng->txt(self::LNG_CANCEL), self::DEFAULT_CMD);
755  $confirmation->setHeaderText($this->lng->txt('auth_saml_sure_delete_idp'));
756  $confirmation->addItem(self::REQUEST_PARAM_SAML_IDP_IDS, (string) $this->idp->getIdpId(), $this->idp->getEntityId());
757 
758  $this->tpl->setContent($confirmation->getHTML());
759  }
760 
761  private function deleteIdp(): void
762  {
763  $this->ensureWriteAccess();
764 
765  $idpDisco = $this->samlAuth->getIdpDiscovery();
766  $idpDisco->deleteIdpMetadata($this->idp->getIdpId());
767 
768  $this->idp->delete();
769 
770  $this->tpl->setOnScreenMessage(self::MESSAGE_TYPE_SUCCESS, $this->lng->txt('auth_saml_deleted_idp'), true);
771 
772  $this->ctrl->setParameter($this, self::REQUEST_PARAM_SAML_IDP_ID, null);
773  $this->ctrl->redirect($this, self::DEFAULT_CMD);
774  }
775 }
storeMetadata(ilSamlIdp $idp, string $metadata)
readonly ilErrorHandling $error_handler
This class represents a selection list property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
readonly GlobalHttpState $httpState
readonly ilHelpGUI $help
setSubTabs(int $a_view_mode)
showSettings(?StandardForm $form=null)
Help GUI class.
Composite for nesting multiple purifiers.
Class ilUserProfile.
setOptions(array $a_options)
populateWithMetadata(ilSamlIdp $idp, array &$data)
static getInstanceByIdpId(int $a_idp_id)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
$ref_id
Definition: ltiauth.php:65
Class ilExternalAuthUserAttributeMapping.
readonly RBACServices $rbac
static _lookupTitle(int $obj_id)
readonly ilGlobalTemplateInterface $tpl
getSettingsForm(array $values=[])
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
readonly ilToolbarGUI $toolbar
const CLIENT_ID
Definition: constants.php:41
global $DIC
Definition: shib_login.php:22
Provides fluid interface to RBAC services.
readonly ILIAS UI Renderer $ui_renderer
Builds data types.
Definition: Factory.php:35
ilExternalAuthUserAttributeMapping $mapping
ensureAccess(string $operation)
withValue($value)
Get an input like this with another value displayed on the client side.
Definition: Group.php:61
__construct(private readonly int $ref_id)
static _sortIds(array $a_ids, string $a_table, string $a_field, string $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.
readonly ilCtrlInterface $ctrl
readonly Refinery $refinery
readonly ILIAS UI Factory $ui_factory
showIdpSettings(?ilPropertyFormGUI $form=null)
readonly ilLanguage $lng
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addAttributeRuleFieldToForm(ilPropertyFormGUI $form, string $field_label, string $field_name)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
readonly ilTabsGUI $tabs
showNewIdpForm(?ilPropertyFormGUI $form=null)
showUserAttributeMappingForm(?ilPropertyFormGUI $form=null)
addMetadataElement(ilPropertyFormGUI $form)