19declare(strict_types=1);
25use Psr\Http\Message\ServerRequestInterface;
82 $this->ref_id = $a_ref_id;
84 $this->
lng = $DIC->language();
85 $this->
lng->loadLanguageModule(
'auth');
88 $this->
tabs = $DIC->tabs();
89 $this->
ctrl = $DIC->ctrl();
90 $this->
logger = $DIC->logger()->auth();
91 $this->
access = $DIC->access();
92 $this->review =
$DIC->rbac()->review();
93 $this->
error = $DIC[
'ilErr'];
94 $this->
upload = $DIC->upload();
95 $this->body =
$DIC->http()->request()->getParsedBody();
97 $http_wrapper =
$DIC->http()->wrapper();
98 $this->
toolbar = $DIC->toolbar();
100 $this->tpl =
$DIC->ui()->mainTemplate();
101 $this->
http = $DIC->http();
102 $this->
ui = $DIC->ui()->factory();
103 $this->
renderer = $DIC->ui()->renderer();
105 $this->
factory = $DIC->ui()->factory();
106 $this->request =
$DIC->http()->request();
107 $this->
profile = $DIC[
'user']->getProfile();
110 if ($http_wrapper->query()->has(self::POST_VALUE) && $http_wrapper->query()->retrieve(
114 $this->mapping_template = $http_wrapper->query()->retrieve(self::POST_VALUE,
$refinery->kindlyTo()->int());
121 $this->
error->raiseError($this->
lng->txt(
'msg_no_perm_read'), $this->error->WARNING);
127 return $this->
access->checkAccess($a_permission,
'', $this->ref_id);
134 switch ($this->
ctrl->getNextClass()) {
136 $cmd = $this->
ctrl->getCmd(self::DEFAULT_CMD);
158 $form->setTitle($this->
lng->txt(
'auth_oidc_settings_title'));
159 $form->setFormAction($this->
ctrl->getFormAction($this));
162 $this->
lng->txt(
'auth_oidc_settings_activation'),
165 $activation->setChecked($this->
settings->getActive());
166 $form->addItem($activation);
169 $this->
lng->txt(
'auth_oidc_settings_provider'),
177 $this->
lng->txt(
'auth_oidc_settings_client_id'),
185 $this->
lng->txt(
'auth_oidc_settings_secret'),
188 $secret->setSkipSyntaxCheck(
true);
189 $secret->setRetype(
false);
190 $secret->setRequired(
false);
191 if ($this->
settings->getSecret() !==
'') {
192 $secret->setValue(
'******');
194 $form->addItem($secret);
197 $this->
lng->txt(
'auth_oidc_settings_le'),
200 $login_element->setRequired(
true);
201 $login_element->setValue((
string) $this->
settings->getLoginElementType());
202 $form->addItem($login_element);
205 $this->
lng->txt(
'auth_oidc_settings_txt'),
208 $login_element->addOption($text_option);
214 $text->setValue($this->
settings->getLoginElemenText());
215 $text->setMaxLength(120);
216 $text->setInfo($this->
lng->txt(
'auth_oidc_settings_txt_val_info'));
217 $text_option->addSubItem($text);
220 $this->
lng->txt(
'auth_oidc_settings_img'),
223 $login_element->addOption($img_option);
229 $image->setAllowDeletion(
false);
231 if ($this->
settings->hasImageFile()) {
232 $image->setImage($this->
settings->getImageFilePath());
234 $image->setInfo($this->
lng->txt(
'auth_oidc_settings_img_file_info'));
235 $img_option->addSubItem($image);
238 $this->
lng->txt(
'auth_oidc_settings_login_options'),
241 $login_options->setValue((
string) $this->
settings->getLoginPromptType());
244 $this->
lng->txt(
'auth_oidc_settings_login_option_enforce'),
247 $enforce->setInfo($this->
lng->txt(
'auth_oidc_settings_login_option_enforce_info'));
248 $login_options->addOption($enforce);
251 $this->
lng->txt(
'auth_oidc_settings_login_option_default'),
254 $default->setInfo($this->
lng->txt(
'auth_oidc_settings_login_option_default_info'));
255 $login_options->addOption($default);
257 $form->addItem($login_options);
260 $this->
lng->txt(
'auth_oidc_settings_logout_scope'),
263 $logout_scope->setValue((
string) $this->
settings->getLogoutScope());
266 $this->
lng->txt(
'auth_oidc_settings_logout_scope_global'),
269 $global_scope->setInfo($this->
lng->txt(
'auth_oidc_settings_logout_scope_global_info'));
270 $logout_scope->addOption($global_scope);
273 $this->
lng->txt(
'auth_oidc_settings_logout_scope_local'),
276 $ilias_scope->setInfo($this->
lng->txt(
'auth_oidc_settings_logout_scope_local_info'));
277 $logout_scope->addOption($ilias_scope);
279 $form->addItem($logout_scope);
282 $this->
lng->txt(
'auth_oidc_settings_custom_session_duration_type'),
285 $use_custom_session->setOptionTitle(
286 $this->
lng->txt(
'auth_oidc_settings_custom_session_duration_option')
288 $use_custom_session->setChecked($this->
settings->isCustomSession());
289 $form->addItem($use_custom_session);
292 $this->
lng->txt(
'auth_oidc_settings_session_duration'),
295 $session->setValue((
string) $this->
settings->getSessionDuration());
296 $session->setSuffix($this->
lng->txt(
'minutes'));
297 $session->setMinValue(5);
298 $session->setMaxValue(1440);
299 $session->setRequired(
true);
300 $use_custom_session->addSubItem($session);
303 $form->addCommandButton(
'saveSettings', $this->
lng->txt(
'save'));
307 $user_sync->setTitle($this->
lng->txt(
'auth_oidc_settings_section_user_sync'));
308 $form->addItem($user_sync);
311 $this->
lng->txt(
'auth_oidc_settings_user_sync'),
314 $sync->setChecked($this->
settings->isSyncAllowed());
315 $sync->setInfo($this->
lng->txt(
'auth_oidc_settings_user_sync_info'));
316 $sync->setValue(
'1');
317 $form->addItem($sync);
320 $this->
lng->txt(
'auth_oidc_settings_default_role'),
323 $roles->setValue((
string) $this->
settings->getRole());
324 $roles->setInfo($this->
lng->txt(
'auth_oidc_settings_default_role_info'));
326 $roles->setRequired(
true);
327 $sync->addSubItem($roles);
330 $this->
lng->txt(
'auth_oidc_settings_user_attr'),
333 $user_attr->setValue($this->
settings->getUidField());
334 $user_attr->setRequired(
true);
335 $form->addItem($user_attr);
345 if (!$form->checkInput()) {
346 $this->
mainTemplate->setOnScreenMessage(
'failure', $this->
lng->txt(
'err_check_input'));
347 $form->setValuesByPost();
352 $this->
settings->setActive((
bool) $form->getInput(
'activation'));
353 $this->
settings->setProvider((
string) $form->getInput(
'provider'));
354 $this->
settings->setClientId((
string) $form->getInput(
'client_id'));
355 if ((
string) $form->getInput(
'secret') !==
'' && strcmp($form->getInput(
'secret'),
'******') !== 0) {
356 $this->
settings->setSecret((
string) $form->getInput(
'secret'));
359 $this->
settings->setLoginElementType((
int) $form->getInput(
'le'));
360 $this->
settings->setLoginElementText((
string) $form->getInput(
'le_text'));
361 $this->
settings->setLoginPromptType((
int) $form->getInput(
'login_prompt'));
362 $this->
settings->setLogoutScope((
int) $form->getInput(
'logout_scope'));
363 $this->
settings->useCustomSession((
bool) $form->getInput(
'custom_session'));
364 $this->
settings->setSessionDuration((
int) $form->getInput(
'session_duration'));
365 $this->
settings->allowSync((
bool) $form->getInput(
'sync'));
366 $this->
settings->setRole((
int) $form->getInput(
'role'));
367 $this->
settings->setUidField((
string) $form->getInput(
'username'));
369 $fileData = (array) $form->getInput(
'le_img');
371 if ((
string) ($fileData[
'tmp_name'] ??
'') !==
'') {
377 $this->
mainTemplate->setOnScreenMessage(
'success', $this->
lng->txt(
'settings_saved'),
true);
378 $this->
ctrl->redirect($this,
'settings');
384 if (!$this->
upload->hasBeenProcessed()) {
388 foreach ($this->
upload->getResults() as $single_file_upload) {
389 if ($single_file_upload->isOK()) {
391 $this->
upload->moveFilesTo(
395 $this->
settings->setLoginElementImage($single_file_upload->getName());
398 }
catch (\
ILIAS\Filesystem\Exception\IllegalStateException
$e) {
399 $this->
logger->warning(
'Upload failed with message: ' . $e->getMessage());
409 $this->review->getGlobalRoles(),
416 if ($a_with_select_option) {
417 $select[0] = $this->
lng->txt(
'links_select_one');
419 foreach ($global_roles as $role_id) {
448 $this->
toolbar->setFormAction($this->
ctrl->getFormAction($this));
449 $this->
toolbar->addFormButton($this->
lng->txt(
'auth_oidc_discover_scopes'),
'discoverScopesFromServer');
452 $form = $this->initScopesForm();
453 $this->tpl->setContent($this->
renderer->render($form));
456 private function initScopesForm():
Form
464 $form = $this->
ui->input()->container()->form()->standard(
465 $this->
ctrl->getFormAction($this,
'saveScopes'),
475 $type = $this->
settings->getValidateScopes();
483 $found_scopes = $this->
settings->getSupportedScopesFromUrl(
$url);
484 if ($found_scopes ===
true) {
485 $this->
mainTemplate->setOnScreenMessage(
'success', $this->
lng->txt(
'auth_oidc_discover_scopes_info'));
498 $disabled_input = $this->
ui
501 ->text($this->
lng->txt(
'auth_oidc_settings_default_scopes'),
'')
504 ->withDedicatedName(
'default_scope')
505 ->withDisabled(
true);
507 $scopeValues = $this->
settings->getAdditionalScopes();
509 $tag_input = $this->
ui
513 $this->
lng->txt(
'auth_oidc_settings_additional_scopes'),
515 )->withValue($scopeValues)
516 ->withDedicatedName(
'custom_scope')
517 ->withByline($this->
lng->txt(
'auth_oidc_settings_additional_scopes_info'));
518 $group1 = $this->
ui->input()->field()->group(
520 $this->
lng->txt(
'auth_oidc_settings_validate_scope_default')
522 $group2 = $this->
ui->input()->field()->group(
524 $this->
lng->txt(
'auth_oidc_settings_discovery_url') => $this->ui
528 $this->lng->txt(
'auth_oidc_settings_discovery_url')
530 ->withAdditionalTransformation($this->trimIfStringTrafo())
532 $this->settings->getCustomDiscoveryUrl() ??
''
535 $this->lng->txt(
'auth_oidc_settings_validate_scope_custom')
537 $group3 = $this->
ui->input()->field()->group(
539 $this->
lng->txt(
'auth_oidc_settings_validate_scope_none')
541 $url_validation = $this->
ui->input()->field()->switchableGroup(
547 $this->
lng->txt(
'auth_oidc_settings_validate_scopes')
548 )->withDedicatedName(
'validate_scopes')->withValue($this->
settings->getValidateScopes());
549 $group = $this->
ui->input()->field()->group(
550 [$disabled_input, $tag_input, $url_validation]
552 $ui_container[] = $group;
554 return $ui_container;
566 $form = $this->initScopesForm();
567 if ($this->request->getMethod() ===
'POST') {
568 $request_form = $form->withRequest($this->request);
569 $result = $request_form->getData();
570 if ($result ===
null) {
571 $this->
mainTemplate->setOnScreenMessage(
'failure', $this->
lng->txt(
'err_check_input'));
576 foreach ($form->getInputs() as $group => $groups) {
577 foreach ($groups->getInputs() as $key => $input) {
578 $dedicated_name = $input->getDedicatedName();
579 $result_data = $result[$group][$key];
580 if ($dedicated_name ===
'validate_scopes') {
581 $type = (
int) $result_data[0];
582 $url = array_pop($result_data[1]);
583 } elseif ($dedicated_name ===
'custom_scope') {
584 $custom_scopes = $result_data;
596 $this->
settings->setAdditionalScopes((array) $custom_scopes);
597 $this->
settings->setValidateScopes((
int) $type);
602 $this->
mainTemplate->setOnScreenMessage(
'success', $this->
lng->txt(
'settings_saved'),
true);
603 $this->
ctrl->redirect($this,
'scopes');
606 if ($this->failed_validation_messages !==
'') {
607 $this->failed_validation_messages = $this->
lng->txt(
611 $this->failed_validation_messages = $this->
lng->txt(
'err_check_input');
614 $this->
mainTemplate->setOnScreenMessage(
'failure', $this->failed_validation_messages,
true);
615 $this->
ctrl->redirect($this,
'scopes');
629 $discoveryURL =
$url;
632 $discoveryURL =
null;
636 $validation_result = $discoveryURL !==
null ? $this->
settings->validateScopes(
640 if (!empty($validation_result)) {
642 $this->failed_validation_messages =
644 $this->
lng->txt(
'auth_oidc_settings_invalid_scopes'),
645 implode(
',', $validation_result[1])
648 $this->failed_validation_messages = sprintf(
649 $this->
lng->txt(
'auth_oidc_settings_discovery_error'),
650 $validation_result[1]
663 $this->failed_validation_messages =
$e->getMessage();
676 $form = $this->initUserMappingForm();
677 if ($this->request->getMethod() ===
'POST' &&
678 $this->request->getQueryParams()[
'opic'] ===
'opic_user_data_mapping') {
679 $request_form = $form->withRequest($this->request);
680 $result = $request_form->getData();
681 if ($result ===
null) {
682 $this->
mainTemplate->setOnScreenMessage(
'failure', $this->
lng->txt(
'err_check_input'));
687 foreach ($this->
settings->getProfileMappingFields() as $field => $lng_key) {
691 foreach ($this->user_defined_fields as $field) {
692 $field = self::UDF_STRING . $field->getIdentifier();
699 $this->
mainTemplate->setOnScreenMessage(
'success', $this->
lng->txt(
'settings_saved'),
true);
700 $this->
ctrl->redirect($this, self::STAB_PROFILE);
705 $form = $this->initUserMappingForm();
706 $request_form = $form->withRequest($this->request);
707 $result = $request_form->getData();
708 foreach ($form->getInputs() as $group => $groups) {
709 foreach ($groups->getInputs() as $key => $input) {
710 $dedicated_name = $input->getDedicatedName();
711 $result_data = $result[$group][$key];
713 if ($dedicated_name === $field . self::VALUE_STRING) {
714 $this->
settings->setProfileMappingFieldValue(
718 } elseif ($dedicated_name === $field . self::UPDATE_STRING) {
719 $this->
settings->setProfileMappingFieldUpdate(
746 $form->setTitle($this->
lng->txt(
'auth_oidc_role_mapping_table'));
747 $form->setFormAction($this->
ctrl->getFormAction($this, self::STAB_ROLES));
752 'role_map_' . $role_id
754 $role_map->setInfo($this->
lng->txt(
'auth_oidc_role_info'));
755 $role_map->setValue($this->
settings->getRoleMappingValueForId((
int) $role_id));
756 $form->addItem($role_map);
760 'role_map_update_' . $role_id
762 $update->setOptionTitle($this->
lng->txt(
'auth_oidc_update_role_info'));
763 $update->setValue(
'1');
764 $update->setChecked(!$this->
settings->getRoleMappingUpdateForId((
int) $role_id));
765 $form->addItem($update);
769 $form->addCommandButton(
'saveRoles', $this->
lng->txt(
'save'));
780 if ($form->checkInput()) {
786 $role_settings[(
int) $role_id][
'update'] = !$form->getInput(
'role_map_update_' . $role_id);
787 $role_settings[(
int) $role_id][
'value'] =
'';
789 $input_role = trim($form->getInput(
'role_map_' . $role_id));
790 if ($input_role ===
'') {
794 $role_params = explode(
'::', $input_role);
797 if (count($role_params) !== 2) {
798 if ($form->getItemByPostVar(
'role_map_' . $role_id)) {
799 $form->getItemByPostVar(
'role_map_' . $role_id)->setAlert($this->
lng->txt(
'msg_wrong_format'));
804 $role_settings[(
int) $role_id][
'value'] = $input_role;
808 $form->setValuesByPost();
809 $this->
mainTemplate->setOnScreenMessage(
'failure', $this->
lng->txt(
'err_check_input'));
814 $this->
settings->setRoleMappings($role_settings);
816 $this->
mainTemplate->setOnScreenMessage(
'success', $this->
lng->txt(
'settings_saved'),
true);
817 $this->
ctrl->redirect($this,
'roles');
820 $form->setValuesByPost();
822 $this->
mainTemplate->setOnScreenMessage(
'failure', $this->
lng->txt(
'err_check_input'));
829 $this->
tabs->addSubTab(
831 $this->
lng->txt(
'auth_oidc_' . self::STAB_SETTINGS),
832 $this->ctrl->getLinkTarget($this, self::STAB_SETTINGS)
837 $this->
tabs->addSubTab(
839 $this->
lng->txt(
'auth_oidc_' . self::STAB_SCOPES),
840 $this->ctrl->getLinkTarget($this, self::STAB_SCOPES)
843 $this->
tabs->addSubTab(
845 $this->
lng->txt(
'auth_oidc_' . self::STAB_PROFILE),
846 $this->ctrl->getLinkTarget($this, self::STAB_PROFILE)
848 $this->
tabs->addSubTab(
850 $this->
lng->txt(
'auth_oidc_' . self::STAB_ROLES),
851 $this->ctrl->getLinkTarget($this, self::STAB_ROLES)
855 $this->
tabs->activateSubTab($active_tab);
864 if ((
int) $this->mapping_template === self::VIEW_TAB_EFFECTIVE_MAPPING) {
874 if ($this->mapping_template === self::VIEW_TAB_EFFECTIVE_MAPPING) {
876 $this->
factory->link()->standard(
877 $this->lng->txt(
'auth_oidc_here'),
878 'https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims'
879 )->withOpenInNewViewport(
true)
884 $this->
factory->link()->standard(
885 $this->lng->txt(
'auth_oidc_here'),
886 $this->ctrl->getLinkTarget($this, self::STAB_SCOPES)
889 $tab_name = $this->
lng->txt(
'auth_oidc_configured_scopes');
890 $message = sprintf($this->
lng->txt(
'auth_odic_scope_info'),
$url, $tab_name);
898 $mapping = $this->attribute_mapping_template->getMappingRulesByAdditionalScopes(
899 $this->
settings->getAdditionalScopes()
902 if (count($mapping) > 0) {
903 $this->
settings->clearProfileMaps();
906 foreach ($mapping as $field => $item) {
907 $this->
settings->setProfileMappingFieldValue(
916 private function initUserMappingForm():
Form
921 foreach ($this->
settings->getProfileMappingFields() as $mapping =>
$lang) {
925 foreach ($this->user_defined_fields as $field) {
929 $this->
ctrl->setParameter(
932 'opic_user_data_mapping'
941 $this->
ctrl->getFormAction($this,
'saveProfileMapping'),
955 $value = $this->
settings->getProfileMappingFieldValue(self::UDF_STRING . $definition->getIdentifier());
956 $update = $this->
settings->getProfileMappingFieldUpdate(self::UDF_STRING . $definition->getIdentifier());
958 $text_input = $this->
ui
961 ->text($definition->getLabel(),
'')
964 ->withDedicatedName(self::UDF_STRING . $definition->getIdentifier() . self::VALUE_STRING);
965 $checkbox_input = $this->
ui
967 ->field()->checkbox(
'', $this->
lng->txt(
'auth_oidc_update_field_info'))
970 self::UDF_STRING . $definition->getIdentifier() . self::UPDATE_STRING
972 $group = $this->
ui->input()->field()->group(
973 [$text_input, $checkbox_input]
975 $ui_container[] = $group;
977 return $ui_container;
986 $value = $this->
settings->getProfileMappingFieldValue($mapping);
987 $update = $this->
settings->getProfileMappingFieldUpdate($mapping);
989 $text_input = $this->
ui
995 ->withDedicatedName($mapping . self::VALUE_STRING);
996 $checkbox_input = $this->
ui
999 ->checkbox(
'', $this->
lng->txt(
'auth_oidc_update_field_info'))
1000 ->withValue($update)
1001 ->withDedicatedName($mapping . self::UPDATE_STRING);
1002 $group = $this->
ui->input()->field()->group(
1008 $ui_container[] = $group;
1010 return $ui_container;
1015 if ($this->user_defined_fields ===
null) {
1016 $this->user_defined_fields = $this->
profile->getAllUserDefinedFields();
1022 $form = $this->initUserMappingForm();
1027 $target = $this->
http->request()->getRequestTarget();
1030 $this->refinery->kindlyTo()->int()
1036 $this->
lng->txt(
'auth_oidc_saved_values') =>
"$target&" . self::POST_VALUE .
'=' .
self::SAVED_VALUES,
1042 $aria_label =
'change_the_currently_displayed_mode';
1043 $active_label = $this->
lng->txt(
'auth_oidc_saved_values');
1044 if ($active !== self::EFFECTIVE_ATTRIBUTE_MAPPING_TAB) {
1047 $view_control = $this->
factory->viewControl()->mode($actions, $aria_label)->withActive($active_label);
1049 $this->tpl->setContent($this->
renderer->render([$view_control, $form]));
1056 $this->tpl->setOnScreenMessage(
1057 $this->tpl::MESSAGE_TYPE_FAILURE,
1058 $this->
lng->txt(
'permission_denied'),
1061 $this->
ctrl->redirect($this,
'settings');
1067 return $this->
refinery->custom()->transformation(
static function (array $values): array {
1074 return $this->
refinery->custom()->transformation(
static function ($value) {
1075 if (is_string($value)) {
1076 $value = trim($value);
Builds a Color from either hex- or rgb values.
static stripSlashesRecursive($a_data, bool $a_strip_html=true, string $a_allow="")
Class ilCtrl provides processing control methods.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Error Handling & global info handling.
Component logger with individual log levels by component id.
static _lookupTitle(int $obj_id)
final const OPEN_ID_CONFIGURED_SCOPES
buildScopeSelection(array $ui_container)
updateProfileMappingFieldValue(string $field)
readonly Profile $profile
ServerRequestInterface $request
saniziteArrayElementsTrafo()
roles(?ilPropertyFormGUI $form=null)
readonly ilLogger $logger
ilOpenIdAttributeMappingTemplate $attribute_mapping_template
array $user_defined_fields
checkAccessBool(string $a_permission)
redirectToSettingsScreenIfNoURLIsConfigured()
const EFFECTIVE_ATTRIBUTE_MAPPING_TAB
readonly FileUpload $upload
readonly ilGlobalTemplateInterface $mainTemplate
readonly ilOpenIdConnectSettings $settings
const VIEW_TAB_EFFECTIVE_MAPPING
setSubTabs(string $active_tab)
settings(?ilPropertyFormGUI $form=null)
prepareRoleSelection(bool $a_with_select_option=true)
readonly ilAccessHandler $access
checkAccess(string $a_permission)
buildUserMappingInputFormUDF($definition, array $ui_container)
string $failed_validation_messages
saveImageFromHttpRequest()
const URL_VALIDATION_PROVIDER_STRING
ilGlobalTemplateInterface $tpl
discoverScopesFromServer()
readonly ilErrorHandling $error
buildUserMappingInputForUserData(string $lang, string $mapping, array $ui_container)
validateDiscoveryUrl(int $type, ?string $url, array $scopes)
readonly ilRbacReview $review
ILIAS Refinery Factory $refinery
__construct(int $a_ref_id)
const LOGIN_ELEMENT_TYPE_IMG
const VALIDATION_ISSUE_INVALID_SCOPE
const URL_VALIDATION_PROVIDER
const URL_VALIDATION_CUSTOM
const LOGOUT_SCOPE_GLOBAL
const URL_VALIDATION_NONE
const LOGIN_ELEMENT_TYPE_TXT
This class represents an option in a radio group.
class ilRbacReview Contains Review functions of core Rbac.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a text property in a property form.
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,...
This is how the factory for UI elements looks.
An entity that renders components to a string output.
Interface ilAccessHandler This interface combines all available interfaces which can be called via gl...
static http()
Fetches the global http state from ILIAS.
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.