diff --git a/components/ILIAS/AccessControl/classes/Setup/class.ilAccessCustomRBACOperationAddedObjective.php b/components/ILIAS/AccessControl/classes/Setup/class.ilAccessCustomRBACOperationAddedObjective.php index d08b92d6631e..6249a1b48aca 100755 --- a/components/ILIAS/AccessControl/classes/Setup/class.ilAccessCustomRBACOperationAddedObjective.php +++ b/components/ILIAS/AccessControl/classes/Setup/class.ilAccessCustomRBACOperationAddedObjective.php @@ -25,6 +25,8 @@ class ilAccessCustomRBACOperationAddedObjective implements Setup\Objective { + private const NO_DIC_FOUND = 'There is no $DIC.'; + protected string $id; protected string $title; protected string $class; @@ -125,7 +127,7 @@ public function achieve(Environment $environment): Environment $db->insert("rbac_ta", $values); } - $GLOBALS["DIC"] = $dic; + $this->resetDIC($dic); return $environment; } @@ -159,8 +161,7 @@ public function isApplicable(Environment $environment): bool } } - $GLOBALS["DIC"] = $dic; - + $this->resetDIC($dic); return count($this->types) && in_array($this->class, ['create', 'object', 'general']); } @@ -172,17 +173,26 @@ protected function initEnvironment(Setup\Environment $environment) // subcomponents of the various readers to run. This is a memento to the // fact, that dependency injection is something we want. Currently, every // component could just service locate the whole world via the global $DIC. - $DIC = []; - if (isset($GLOBALS["DIC"])) { - $DIC = $GLOBALS["DIC"]; + $DIC = self::NO_DIC_FOUND; + if (array_key_exists('DIC', $GLOBALS)) { + $DIC = $GLOBALS['DIC']; } - $GLOBALS["DIC"] = new DI\Container(); - $GLOBALS["DIC"]["ilDB"] = $db; + $GLOBALS['DIC'] = new DI\Container(); + $GLOBALS['DIC']['ilDB'] = $db; - if (!defined("ILIAS_ABSOLUTE_PATH")) { - define("ILIAS_ABSOLUTE_PATH", dirname(__FILE__, 6)); + if (!defined('ILIAS_ABSOLUTE_PATH')) { + define('ILIAS_ABSOLUTE_PATH', dirname(__FILE__, 6)); } return $DIC; } + + protected function resetDIC($dic): void + { + if ($dic !== self::NO_DIC_FOUND) { + $GLOBALS['DIC'] = $dic; + return; + } + unset($GLOBALS['DIC']); + } } diff --git a/components/ILIAS/AccessControl/classes/class.ilObjRole.php b/components/ILIAS/AccessControl/classes/class.ilObjRole.php index 34f1a985ec71..00f3f07d670a 100755 --- a/components/ILIAS/AccessControl/classes/class.ilObjRole.php +++ b/components/ILIAS/AccessControl/classes/class.ilObjRole.php @@ -530,9 +530,9 @@ public function __getPermissionDefinitions(): array return [$rbac_objects, $rbac_operations]; } - public static function isAutoGenerated(int $a_role_id): bool + public function isAutoGenerated(): bool { - return substr(ilObject::_lookupTitle($a_role_id), 0, 3) == 'il_'; + return substr($this->title, 0, 3) == 'il_'; } /** diff --git a/components/ILIAS/AccessControl/classes/class.ilObjRoleFolderGUI.php b/components/ILIAS/AccessControl/classes/class.ilObjRoleFolderGUI.php index 0a5afc49c723..ae4c4529845a 100755 --- a/components/ILIAS/AccessControl/classes/class.ilObjRoleFolderGUI.php +++ b/components/ILIAS/AccessControl/classes/class.ilObjRoleFolderGUI.php @@ -123,6 +123,11 @@ protected function initRolesFromPOST(): array return []; } + public function returnObject(): void + { + $this->viewObject(); + } + public function viewObject(): void { $this->tabs_gui->activateTab('view'); @@ -136,7 +141,7 @@ public function viewObject(): void $this->toolbar->addComponent( $this->ui_factory->link()->standard( $this->lng->txt('rolf_create_role'), - $this->ctrl->getLinkTarget($this, 'create') + $this->ctrl->getLinkTargetByClass(ilObjRoleGUI::class, 'create') ) ); } @@ -145,7 +150,7 @@ public function viewObject(): void $this->toolbar->addComponent( $this->ui_factory->link()->standard( $this->lng->txt('rolf_create_rolt'), - $this->ctrl->getLinkTarget($this, 'create') + $this->ctrl->getLinkTargetByClass(ilObjRoleTemplateGUI::class, 'create') ) ); $this->ctrl->clearParameters($this); @@ -752,7 +757,7 @@ protected function initSettingsForm(): ilPropertyFormGUI $admin->setValue((string) 1); $form->addItem($admin); - $check = new ilCheckboxInputGui($this->lng->txt('rbac_log'), 'rbac_log'); + $check = new ilCheckboxInputGUI($this->lng->txt('rbac_log'), 'rbac_log'); $check->setInfo($this->lng->txt('rbac_log_info')); $check->setChecked($privacy->enabledRbacLog()); $form->addItem($check); diff --git a/components/ILIAS/AccessControl/classes/class.ilObjRoleGUI.php b/components/ILIAS/AccessControl/classes/class.ilObjRoleGUI.php index 0454015ba8a6..91ac2f12d722 100755 --- a/components/ILIAS/AccessControl/classes/class.ilObjRoleGUI.php +++ b/components/ILIAS/AccessControl/classes/class.ilObjRoleGUI.php @@ -22,6 +22,8 @@ use ILIAS\Refinery\Factory; use ILIAS\UI\Factory as UIFactory; use ILIAS\UI\Renderer; +use ILIAS\UI\Component\Modal\Interruptive as InterruptiveModal; +use ILIAS\UI\Component\Input\Container\Form\Standard as StandardForm; /** * Class ilObjRoleGUI @@ -33,17 +35,18 @@ */ class ilObjRoleGUI extends ilObjectGUI { - protected const MODE_GLOBAL_UPDATE = 1; - protected const MODE_GLOBAL_CREATE = 2; - protected const MODE_LOCAL_UPDATE = 3; - protected const MODE_LOCAL_CREATE = 4; + private const FORM_KEY_TITLE = 'title'; + private const FORM_KEY_DESCRIPTION = 'description'; + private const FORM_KEY_ILIAS_ID = 'ilias_id'; + private const FORM_KEY_ON_REGISTRATION_FORM = 'on_registration_form'; + private const FORM_KEY_ALLOW_LOCAL_USER_ASSIGNMENT = 'allow_local_user_assignment'; + private const FORM_KEY_PROTECT = 'protect'; protected int $obj_ref_id = 0; protected int $obj_obj_id = 0; protected string $obj_obj_type = ''; protected string $container_type = ''; protected int $role_id = 0; - protected ilRbacAdmin $rbacadmin; protected ilHelpGUI $help; private ilLogger $logger; private GlobalHttpState $http; @@ -60,7 +63,6 @@ public function __construct( /** @var ILIAS\DI\Container $DIC */ global $DIC; - $this->rbacadmin = $DIC['rbacadmin']; $this->help = $DIC['ilHelp']; $this->logger = $DIC->logger()->ac(); @@ -231,126 +233,91 @@ protected function showDefaultPermissionSettings(): bool || $this->obj_definition->isAdministrationObject($this->getContainerType()); } - protected function initFormRoleProperties(int $a_mode): ilPropertyFormGUI + protected function getRoleForm(bool $is_role_creation_form = false): StandardForm { - $form = new ilPropertyFormGUI(); - if ($this->creation_mode) { - $this->ctrl->setParameter($this, "new_type", 'role'); + $this->ctrl->setParameter($this, 'new_type', 'role'); } - $form->setFormAction($this->ctrl->getFormAction($this)); - switch ($a_mode) { - case self::MODE_GLOBAL_CREATE: - $form->setTitle($this->lng->txt('role_new')); - $form->addCommandButton('save', $this->lng->txt('role_new')); - break; + $ff = $this->ui_factory->input()->field(); - case self::MODE_GLOBAL_UPDATE: - $form->setTitle($this->lng->txt('role_edit')); - $form->addCommandButton('update', $this->lng->txt('save')); - break; + $title_validation_constraint = $this->refinery->custom()->constraint( + fn(string $v): bool => preg_match('/^il_.*$/', $v) ? false : true, + $this->lng->txt('msg_role_reserved_prefix') + ); - case self::MODE_LOCAL_CREATE: - case self::MODE_LOCAL_UPDATE: - } - // Fix cancel - $form->addCommandButton('cancel', $this->lng->txt('cancel')); + $role_is_autogenerated = false; - $title = new ilTextInputGUI($this->lng->txt('title'), 'title'); - if (ilObjRole::isAutoGenerated($this->object->getId())) { - $title->setDisabled(true); - } else { - //#17111 No validation for disabled fields - $title->setValidationRegexp('/^(?!il_).*$/'); - $title->setValidationFailureMessage($this->lng->txt('msg_role_reserved_prefix')); + if (!$is_role_creation_form) { + $role_is_autogenerated = $this->object->isAutoGenerated(); } - $title->setSize(40); - $title->setMaxLength(70); - $title->setRequired(true); - $form->addItem($title); + $inputs = [ + self::FORM_KEY_TITLE => $ff->text($this->lng->txt('title')) + ->withMaxLength(70) + ->withRequired(true) + ->withAdditionalTransformation($title_validation_constraint) + ->withValue($is_role_creation_form ? '' : $this->object->getTitle()) + ->withDisabled($role_is_autogenerated), + self::FORM_KEY_DESCRIPTION => $ff->textarea($this->lng->txt('description')) + ->withMaxLimit(4000) + ->withValue($is_role_creation_form ? '' : $this->object->getDescription()) + ->withDisabled($role_is_autogenerated), - $desc = new ilTextAreaInputGUI($this->lng->txt('description'), 'desc'); - if (ilObjRole::isAutoGenerated($this->object->getId())) { - $desc->setDisabled(true); - } - $desc->setCols(40); - $desc->setRows(3); - $form->addItem($desc); + ]; - if ($a_mode != self::MODE_LOCAL_CREATE && $a_mode != self::MODE_GLOBAL_CREATE) { - $ilias_id = new ilNonEditableValueGUI($this->lng->txt("ilias_id"), "ilias_id"); - $form->addItem($ilias_id); + if (!$is_role_creation_form) { + $inputs[self::FORM_KEY_ILIAS_ID] = $ff->text($this->lng->txt('ilias_id')) + ->withDisabled(true) + ->withValue('il_' . IL_INST_ID . '_' + . $this->object->getType() . '_' . $this->object->getId()); } - if ($this->obj_ref_id == ROLE_FOLDER_ID) { - $reg = new ilCheckboxInputGUI($this->lng->txt('allow_register'), 'reg'); - $reg->setValue("1"); - #$reg->setInfo($this->lng->txt('rbac_new_acc_reg_info')); - $form->addItem($reg); - - $la = new ilCheckboxInputGUI($this->lng->txt('allow_assign_users'), 'la'); - $la->setValue("1"); - #$la->setInfo($this->lng->txt('rbac_local_admin_info')); - $form->addItem($la); - } - - $pro = new ilCheckboxInputGUI($this->lng->txt('role_protect_permissions'), 'pro'); - $pro->setValue("1"); - #$pro->setInfo($this->lng->txt('role_protext_permission_info')); - $form->addItem($pro); - return $form; - } - - /** - * Store form input in role object - * @param object $role - */ - protected function loadRoleProperties(ilObjRole $role, ilPropertyFormGUI $form): void - { - //Don't set if fields are disabled to prevent html manipulation. - if (!$form->getItemByPostVar('title')->getDisabled()) { - $role->setTitle((string) $form->getInput('title')); - } - if (!$form->getItemByPostVar('desc')->getDisabled()) { - $role->setDescription((string) $form->getInput('desc')); + if ($this->obj_ref_id === ROLE_FOLDER_ID) { + $inputs[self::FORM_KEY_ON_REGISTRATION_FORM] = $ff->checkbox($this->lng->txt('allow_register')) + ->withValue($is_role_creation_form ? false : $this->object->getAllowRegister()); + $inputs[self::FORM_KEY_ALLOW_LOCAL_USER_ASSIGNMENT] = $ff->checkbox($this->lng->txt('allow_assign_users')) + ->withValue($is_role_creation_form ? false : $this->object->getAssignUsersStatus()); } - $role->setAllowRegister((bool) $form->getInput('reg')); - $role->toggleAssignUsersStatus((bool) $form->getInput('la')); - } - /** - * Read role properties and write them to form - */ - protected function readRoleProperties(ilObject $role, ilPropertyFormGUI $form): void - { - global $DIC; - - $rbacreview = $DIC['rbacreview']; - - $data['title'] = $role->getPresentationTitle(); - $data['desc'] = $role->getDescription(); - $data['ilias_id'] = 'il_' . IL_INST_ID . '_' . ilObject::_lookupType($role->getId()) . '_' . $role->getId(); - $data['reg'] = $role->getAllowRegister(); - $data['la'] = $role->getAssignUsersStatus(); - $data['pro'] = $rbacreview->isProtected($this->obj_ref_id, $role->getId()); + $inputs[self::FORM_KEY_PROTECT] = $ff->checkbox($this->lng->txt('role_protect_permissions')) + ->withValue( + $is_role_creation_form + ? false + : $this->rbac_review->isProtected($this->obj_ref_id, $this->object->getId()) + ); - $form->setValuesByArray($data); + return $this->ui_factory->input()->container()->form()->standard( + $this->ctrl->getFormActionByClass( + self::class, + $is_role_creation_form ? 'save' : 'update' + ), + $inputs + )->withSubmitLabel( + $is_role_creation_form ? $this->lng->txt('role_new') : $this->lng->txt('save') + ); } - /** - * Only called from administration -> role folder ? - * Otherwise this check access is wrong - */ public function createObject(): void { if (!$this->rbac_system->checkAccess('create_role', $this->obj_ref_id)) { $this->tpl->setOnScreenMessage('failure', $this->lng->txt('permission_denied'), true); $this->ctrl->redirectByClass(ilRepositoryGUI::class); } - $form = $this->initFormRoleProperties(self::MODE_GLOBAL_CREATE); - $this->tpl->setContent($form->getHTML()); + + $this->tabs_gui->setBackTarget( + $this->lng->txt('cancel'), + $this->ctrl->getParentReturnByClass(self::class) + ); + + $this->tpl->setContent( + $this->ui_renderer->render( + $this->ui_factory->panel()->standard( + $this->lng->txt('role_new'), + $this->getRoleForm(true) + ) + ) + ); } public function editObject(): void @@ -361,21 +328,7 @@ public function editObject(): void } $this->tabs_gui->activateTab('edit_properties'); - // Show copy role button - if ($this->object->getId() != SYSTEM_ROLE_ID) { - $this->toolbar->setFormAction($this->ctrl->getFormAction($this)); - if ($this->rbac_review->isDeleteable($this->object->getId(), $this->obj_ref_id)) { - $this->toolbar->addComponent( - $this->ui_factory->link()->standard( - $this->lng->txt('rbac_delete_role'), - $this->ctrl->getLinkTarget($this, 'confirmDeleteRole') - ) - ); - } - } - $form = $this->initFormRoleProperties(self::MODE_GLOBAL_UPDATE); - $this->readRoleProperties($this->object, $form); - $this->tpl->setContent($form->getHTML()); + $this->buildEditPage(); } /** @@ -384,25 +337,39 @@ public function editObject(): void */ public function saveObject(): void { - $form = $this->initFormRoleProperties(self::MODE_GLOBAL_CREATE); - if ($form->checkInput()) { - $role = new ilObjRole(); - $this->loadRoleProperties($role, $form); - $role->create(); - $this->rbacadmin->assignRoleToFolder($role->getId(), $this->obj_ref_id, 'y'); - $this->rbacadmin->setProtected( - $this->obj_ref_id, - $role->getId(), - $form->getInput('pro') ? 'y' : 'n' + $form = $this->getRoleForm(true)->withRequest($this->request); + $data = $form->getData(); + if ($data === null) { + $this->tabs_gui->setBackTarget( + $this->lng->txt('cancel'), + $this->ctrl->getParentReturnByClass(self::class) ); - $this->tpl->setOnScreenMessage('success', $this->lng->txt("role_added"), true); - $this->ctrl->setParameter($this, 'obj_id', $role->getId()); - $this->ctrl->redirect($this, 'perm'); + $this->tpl->setContent( + $this->ui_renderer->render( + $this->ui_factory->panel()->standard( + $this->lng->txt('role_new'), + $form + ) + ) + ); + return; } - $this->tpl->setOnScreenMessage('failure', $this->lng->txt('err_check_input')); - $form->setValuesByPost(); - $this->tpl->setContent($form->getHTML()); + $role = new ilObjRole(); + $role->setTitle($data[self::FORM_KEY_TITLE]); + $role->setDescription($data[self::FORM_KEY_DESCRIPTION]); + $role->setAllowRegister($data[self::FORM_KEY_ON_REGISTRATION_FORM]); + $role->toggleAssignUsersStatus($data[self::FORM_KEY_ALLOW_LOCAL_USER_ASSIGNMENT]); + $role->create(); + $this->rbac_admin->assignRoleToFolder($role->getId(), $this->obj_ref_id, 'y'); + $this->rbac_admin->setProtected( + $this->obj_ref_id, + $role->getId(), + $data[self::FORM_KEY_PROTECT] ? 'y' : 'n' + ); + $this->tpl->setOnScreenMessage('success', $this->lng->txt('role_added'), true); + $this->ctrl->setParameter($this, 'obj_id', $role->getId()); + $this->ctrl->redirect($this, 'perm'); } /** @@ -411,22 +378,57 @@ public function saveObject(): void */ public function updateObject(): void { - $form = $this->initFormRoleProperties(self::MODE_GLOBAL_UPDATE); - if ($form->checkInput()) { - $this->loadRoleProperties($this->object, $form); - $this->object->update(); - $this->rbacadmin->setProtected( - $this->obj_ref_id, - $this->object->getId(), - $form->getInput('pro') ? 'y' : 'n' - ); - $this->tpl->setOnScreenMessage('success', $this->lng->txt("saved_successfully"), true); - $this->ctrl->redirect($this, 'edit'); + $form = $this->getRoleForm()->withRequest($this->request); + $data = $form->getData(); + if ($data === null) { + $this->buildEditPage($form); + return; } - $this->tpl->setOnScreenMessage('failure', $this->lng->txt('err_check_input')); - $form->setValuesByPost(); - $this->tpl->setContent($form->getHTML()); + if (isset($data['title'])) { + $this->object->setTitle($data[self::FORM_KEY_TITLE]); + } + if (isset($data['description'])) { + $this->object->setDescription($data[self::FORM_KEY_DESCRIPTION]); + } + $this->object->setAllowRegister($data[self::FORM_KEY_ON_REGISTRATION_FORM]); + $this->object->toggleAssignUsersStatus($data[self::FORM_KEY_ALLOW_LOCAL_USER_ASSIGNMENT]); + $this->object->update(); + $this->rbac_admin->setProtected( + $this->obj_ref_id, + $this->object->getId(), + $data[self::FORM_KEY_PROTECT] ? 'y' : 'n' + ); + + $this->tpl->setOnScreenMessage('success', $this->lng->txt('saved_successfully'), true); + $this->ctrl->redirect($this, 'edit'); + } + + private function buildEditPage(StandardForm $form = null): void + { + $page_content = []; + if ($this->object->getId() != SYSTEM_ROLE_ID) { + $this->toolbar->setFormAction($this->ctrl->getFormAction($this)); + if ($this->rbac_review->isDeleteable($this->object->getId(), $this->obj_ref_id)) { + $modal = $this->buildConfirmationModal(); + $this->toolbar->addComponent( + $this->ui_factory->button()->standard( + $this->lng->txt('rbac_delete_role'), + $modal->getShowSignal() + ) + ); + $page_content[] = $modal; + } + } + + $page_content[] = $this->ui_factory->panel()->standard( + $this->lng->txt('role_edit'), + $form ?? $this->getRoleForm() + ); + + $this->tpl->setContent( + $this->ui_renderer->render($page_content) + ); } protected function permObject(bool $a_show_admin_permissions = false): void @@ -435,19 +437,25 @@ protected function permObject(bool $a_show_admin_permissions = false): void $this->setSubTabs('default_perm_settings'); + if (!$this->checkAccess('write', 'edit_permission')) { + $this->tpl->setOnScreenMessage('failure', $this->lng->txt('msg_no_perm_write'), true); + $this->ctrl->redirectByClass(ilRepositoryGUI::class); + } + if ($a_show_admin_permissions) { $this->tabs_gui->setSubTabActive('rbac_admin_permissions'); } else { $this->tabs_gui->setSubTabActive('rbac_repository_permissions'); } - if (!$this->checkAccess('write', 'edit_permission')) { - $this->tpl->setOnScreenMessage('failure', $this->lng->txt('msg_no_perm_write'), true); - $this->ctrl->redirectByClass(ilRepositoryGUI::class); - } + $this->tpl->addBlockFile( + 'ADM_CONTENT', + 'adm_content', + 'tpl.rbac_template_permissions.html', + 'components/ILIAS/AccessControl' + ); - // Show copy role button - if ($this->object->getId() != SYSTEM_ROLE_ID) { + if ($this->object->getId() !== SYSTEM_ROLE_ID) { $this->toolbar->setFormAction($this->ctrl->getFormAction($this)); $this->toolbar->addComponent( $this->ui_factory->link()->standard( @@ -456,22 +464,17 @@ protected function permObject(bool $a_show_admin_permissions = false): void ) ); if ($this->rbac_review->isDeleteable($this->object->getId(), $this->obj_ref_id)) { + $modal = $this->buildConfirmationModal(); $this->toolbar->addComponent( - $this->ui_factory->link()->standard( + $this->ui_factory->button()->standard( $this->lng->txt('rbac_delete_role'), - $this->ctrl->getLinkTarget($this, 'confirmDeleteRole') + $modal->getShowSignal() ) ); + $this->tpl->setVariable('DELETION_MODAL', $this->ui_renderer->render($modal)); } } - $this->tpl->addBlockFile( - 'ADM_CONTENT', - 'adm_content', - 'tpl.rbac_template_permissions.html', - 'components/ILIAS/AccessControl' - ); - $this->tpl->setVariable('PERM_ACTION', $this->ctrl->getFormAction($this)); $acc = new ilAccordionGUI(); @@ -523,18 +526,11 @@ protected function permObject(bool $a_show_admin_permissions = false): void $this->tpl->setVariable('OPTIONS_TABLE', $options->getHTML()); } - /** - * Show administration permissions - */ protected function adminPermObject(): void { $this->permObject(true); } - /** - * Save admin permissions - * @return - */ protected function adminPermSaveObject(): void { $this->permSaveObject(true); @@ -653,13 +649,13 @@ public function permSaveObject(bool $a_show_admin_permissions = false): void foreach (array_keys($subs) as $subtype) { // Delete per object type - $this->rbacadmin->deleteRolePermission($this->object->getId(), $this->obj_ref_id, $subtype); + $this->rbac_admin->deleteRolePermission($this->object->getId(), $this->obj_ref_id, $subtype); } $template_permissions = $this->retrieveTemplatePermissionsFromPost(); foreach ($template_permissions as $key => $ops_array) { // sets new template permissions - $this->rbacadmin->setRolePermission($this->object->getId(), $key, $ops_array, $this->obj_ref_id); + $this->rbac_admin->setRolePermission($this->object->getId(), $key, $ops_array, $this->obj_ref_id); } if ($rbac_log_active) { @@ -682,7 +678,7 @@ public function permSaveObject(bool $a_show_admin_permissions = false): void if ( $this->obj_ref_id == ROLE_FOLDER_ID || $this->rbac_review->isAssignable($this->object->getId(), $this->obj_ref_id)) { - $this->rbacadmin->setProtected($this->obj_ref_id, $this->object->getId(), ilUtil::tf2yn($protected)); + $this->rbac_admin->setProtected($this->obj_ref_id, $this->object->getId(), ilUtil::tf2yn($protected)); } $recursive = false; if ($this->http->wrapper()->post()->has('recursive')) { @@ -776,9 +772,9 @@ public function adoptPermSaveObject(): void if ($this->object->getId() == $source) { $this->tpl->setOnScreenMessage('failure', $this->lng->txt("msg_perm_adopted_from_itself"), true); } else { - $this->rbacadmin->deleteRolePermission($this->object->getId(), $this->obj_ref_id); + $this->rbac_admin->deleteRolePermission($this->object->getId(), $this->obj_ref_id); $parentRoles = $this->rbac_review->getParentRoleIds($this->obj_ref_id, true); - $this->rbacadmin->copyRoleTemplatePermissions( + $this->rbac_admin->copyRoleTemplatePermissions( $source, $parentRoles[$source]["parent"], $this->obj_ref_id, @@ -836,7 +832,7 @@ public function addUserObject(array $a_user_ids): void $this->tpl->setOnScreenMessage('failure', $this->lng->txt('msg_anonymous_cannot_be_assigned'), true); return; } - $this->rbacadmin->assignUser($this->object->getId(), $user_id, false); + $this->rbac_admin->assignUser($this->object->getId(), $user_id, false); } // update object data entry (to update last modification date) @@ -903,7 +899,7 @@ public function deassignUserObject(): void // ... else perform deassignment foreach ($selected_users as $user) { if (!isset($last_role[$user])) { - $this->rbacadmin->deassignUser($this->object->getId(), $user); + $this->rbac_admin->deassignUser($this->object->getId(), $user); } } @@ -925,10 +921,6 @@ public function deassignUserObject(): void */ public function userassignmentObject(): void { - global $DIC; - - $ilUser = $DIC['ilUser']; - if (!$this->checkAccess('edit_userassignment', 'edit_permission')) { $this->tpl->setOnScreenMessage( $this->lng->txt("msg_no_perm_assign_user_to_role"), @@ -944,7 +936,7 @@ public function userassignmentObject(): void // protected admin role if ($this->object->getId() != SYSTEM_ROLE_ID - || ($this->rbac_review->isAssigned($ilUser->getId(), SYSTEM_ROLE_ID) + || ($this->rbac_review->isAssigned($this->user->getId(), SYSTEM_ROLE_ID) || !ilSecuritySettings::_getInstance()->isAdminRoleProtected())) { // add member ilRepositorySearchGUI::fillAutoCompleteToolbar( @@ -978,7 +970,7 @@ public function userassignmentObject(): void $role_assignment_editable = true; if ( $this->object->getId() == SYSTEM_ROLE_ID && - !ilSecuritySettings::_getInstance()->checkAdminRoleAccessible($ilUser->getId())) { + !ilSecuritySettings::_getInstance()->checkAdminRoleAccessible($this->user->getId())) { $role_assignment_editable = false; } $ut = new ilAssignedUsersTableGUI( @@ -993,19 +985,6 @@ public function userassignmentObject(): void $this->tpl->setVariable('TABLE_UA', $ut->getHTML()); } - /** - * cancelObject is called when an operation is canceled, method links back - * @access public - */ - public function cancelObject(): void - { - if ($this->requested_new_type != 'role') { - $this->ctrl->redirect($this, 'userassignment'); - } else { - $this->ctrl->redirectByClass("ilobjrolefoldergui", "view"); - } - } - /** * @inheritdoc */ @@ -1019,7 +998,7 @@ protected function addAdminLocatorItems(bool $do_not_add_object = false): void $this->ctrl->getLinkTargetByClass("ilobjrolefoldergui", 'view') ); - if ($this->getRoleId() > 0) { + if ($this->object instanceof ilObjRole) { $this->locator->addItem( ilObjRole::_getTranslation($this->object->getTitle()), $this->ctrl->getLinkTarget($this, 'perm') @@ -1047,7 +1026,7 @@ protected function getTabs(): void // not so nice (workaround for using tabs in repository) $this->tabs_gui->clearTargets(); - $this->help->setScreenIdComponent("role"); + $this->help->setScreenIdComponent('role'); $this->tabs_gui->setBackTarget( $this->lng->txt('btn_back'), (string) $this->ctrl->getParentReturn($this) @@ -1062,8 +1041,8 @@ protected function getTabs(): void } if ($this->checkAccess('write', 'edit_permission') && $this->showDefaultPermissionSettings()) { $this->tabs_gui->addTarget( - "default_perm_settings", - $this->ctrl->getLinkTarget($this, "perm"), + 'default_perm_settings', + $this->ctrl->getLinkTarget($this, 'perm'), [], get_class($this) ); @@ -1074,9 +1053,9 @@ protected function getTabs(): void 'edit_permission' ) && $activate_role_edit && $this->object->getId() != ANONYMOUS_ROLE_ID) { $this->tabs_gui->addTarget( - "user_assignment", - $this->ctrl->getLinkTarget($this, "userassignment"), - ["deassignUser", "userassignment", "assignUser", "searchUserForm", "search"], + 'user_assignment', + $this->ctrl->getLinkTarget($this, 'userassignment'), + ['deassignUser', 'userassignment', 'assignUser', 'searchUserForm', 'search'], get_class($this) ); } @@ -1085,10 +1064,10 @@ protected function getTabs(): void 'write', 'edit_permission' ) && $activate_role_edit && $this->object->getId() != ANONYMOUS_ROLE_ID) { - $this->lng->loadLanguageModule("rep"); + $this->lng->loadLanguageModule('rep'); $this->tabs_gui->addTarget( - "rep_recommended_content", - $this->ctrl->getLinkTargetByClass("ilrecommendedcontentroleconfiggui", "") + 'rep_recommended_content', + $this->ctrl->getLinkTargetByClass('ilrecommendedcontentroleconfiggui', '') ); } if ($this->checkAccess('write', 'edit_permission')) { @@ -1333,4 +1312,22 @@ protected function ensureRoleAccessForContext(): bool } return true; } + + private function buildConfirmationModal(): InterruptiveModal + { + $message = $this->lng->txt('rbac_role_delete_qst'); + if ($this->rbac_review->isAssigned($this->user->getId(), $this->object->getId())) { + $message .= ('
' . $this->lng->txt('rbac_role_delete_self')); + } + return $this->ui_factory->modal()->interruptive( + $this->lng->txt('confirm'), + $message, + $this->ctrl->getFormActionByClass(self::class, 'performDeleteRole') + )->withAffectedItems([ + $this->ui_factory->modal()->interruptiveItem()->standard( + (string) $this->object->getId(), + $this->object->getTitle() + ) + ]); + } } diff --git a/components/ILIAS/AccessControl/classes/class.ilObjRoleTemplateGUI.php b/components/ILIAS/AccessControl/classes/class.ilObjRoleTemplateGUI.php index 92f8f74065f6..cafc92c798fc 100755 --- a/components/ILIAS/AccessControl/classes/class.ilObjRoleTemplateGUI.php +++ b/components/ILIAS/AccessControl/classes/class.ilObjRoleTemplateGUI.php @@ -1,7 +1,5 @@ creation_mode) { - $this->ctrl->setParameter($this, "new_type", 'rolt'); + $this->ctrl->setParameter($this, 'new_type', 'rolt'); } - $form->setFormAction($this->ctrl->getFormAction($this)); - - if ($a_mode == self::FORM_MODE_CREATE) { - $form->setTitle($this->lng->txt('rolt_new')); - $form->addCommandButton('save', $this->lng->txt('rolt_new')); - } else { - $form->setTitle($this->lng->txt('rolt_edit')); - $form->addCommandButton('update', $this->lng->txt('save')); - } - $form->addCommandButton('cancel', $this->lng->txt('cancel')); - - $title = new ilTextInputGUI($this->lng->txt('title'), 'title'); - if ($a_mode != self::FORM_MODE_CREATE) { - if ($this->object->isInternalTemplate()) { - $title->setDisabled(true); - } - $title->setValue(ilObjRole::_getTranslation($this->object->getTitle())); - } - $title->setSize(40); - $title->setMaxLength(70); - $title->setRequired(true); - $form->addItem($title); + $ff = $this->ui_factory->input()->field(); - $desc = new ilTextAreaInputGUI($this->lng->txt('description'), 'desc'); + $title_validation_constraint = $this->refinery->custom()->constraint( + fn(string $v): bool => preg_match('/^il_.*$/', $v) ? false : true, + $this->lng->txt('msg_role_reserved_prefix') + ); - if ($a_mode != self::FORM_MODE_CREATE) { - $desc->setValue($this->object->getDescription()); - } - $desc->setCols(40); - $desc->setRows(3); - $form->addItem($desc); - - if ($a_mode != self::FORM_MODE_CREATE) { - $ilias_id = new ilNonEditableValueGUI($this->lng->txt("ilias_id"), "ilias_id"); - $ilias_id->setValue('il_' . IL_INST_ID . '_' . ilObject::_lookupType($this->object->getId()) . '_' . $this->object->getId()); - $form->addItem($ilias_id); + $inputs = [ + self::FORM_KEY_TITLE => $ff->text($this->lng->txt('title')) + ->withMaxLength(70) + ->withRequired(true) + ->withAdditionalTransformation($title_validation_constraint) + ->withValue( + $is_role_creation_form ? '' + : ilObjRole::_getTranslation($this->object->getTitle()) + )->withDisabled($is_role_creation_form ? false : $this->object->isInternalTemplate()), + self::FORM_KEY_DESCRIPTION => $ff->textarea($this->lng->txt('description')) + ->withMaxLimit(4000) + ->withValue($is_role_creation_form ? '' : $this->object->getDescription()) + ]; + + if (!$is_role_creation_form) { + $inputs[self::FORM_KEY_ILIAS_ID] = $ff->text($this->lng->txt('ilias_id')) + ->withDisabled(true) + ->withValue('il_' . IL_INST_ID . '_' + . $this->object->getType() . '_' . $this->object->getId()); } - $pro = new ilCheckboxInputGUI($this->lng->txt('role_protect_permissions'), 'protected'); - $pro->setChecked($GLOBALS['DIC']['rbacreview']->isProtected( - $this->rolf_ref_id, - $this->object->getId() - )); - $pro->setValue((string) 1); - $form->addItem($pro); + $inputs[self::FORM_KEY_PROTECT] = $ff->checkbox($this->lng->txt('role_protect_permissions')) + ->withValue( + $is_role_creation_form + ? false + : $this->rbac_review->isProtected($this->rolf_ref_id, $this->object->getId()) + ); - return $form; + return $this->ui_factory->input()->container()->form()->standard( + $this->ctrl->getFormActionByClass( + self::class, + $is_role_creation_form ? 'save' : 'update' + ), + $inputs + )->withSubmitLabel( + $is_role_creation_form ? $this->lng->txt('rolt_new') : $this->lng->txt('save') + ); } - public function createObject(ilPropertyFormGUI $form = null): void + public function createObject(): void { - if (!$this->rbac_system->checkAccess("create_rolt", $this->rolf_ref_id)) { - $this->error->raiseError($this->lng->txt("permission_denied"), $this->error->MESSAGE); - } - if ($form === null) { - $form = $this->initFormRoleTemplate(self::FORM_MODE_CREATE); + if (!$this->rbac_system->checkAccess('create_rolt', $this->rolf_ref_id)) { + $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE); } - $this->tpl->setContent($form->getHTML()); + + $this->tabs_gui->setBackTarget( + $this->lng->txt('cancel'), + $this->ctrl->getParentReturnByClass(self::class) + ); + + $this->tpl->setContent( + $this->ui_renderer->render( + $this->ui_factory->panel()->standard( + $this->lng->txt('rolt_new'), + $this->getRoleTemplateForm(true) + ) + ) + ); } /** @@ -153,64 +161,89 @@ public function editObject(ilPropertyFormGUI $form = null): void $this->error->raiseError($this->lng->txt("msg_no_perm_write"), $this->error->MESSAGE); } - if ($form === null) { - $form = $this->initFormRoleTemplate(self::FORM_MODE_EDIT); - } - $this->tpl->setContent($form->getHTML()); + $this->tpl->setContent( + $this->ui_renderer->render( + $this->ui_factory->panel()->standard( + $this->lng->txt('rolt_edit'), + $this->getRoleTemplateForm() + ) + ) + ); } - public function updateObject(): void + public function saveObject(): void { - // check write access - if (!$this->rbac_system->checkAccess("write", $this->rolf_ref_id)) { - $this->error->raiseError($this->lng->txt("msg_no_perm_modify_rolt"), $this->error->WARNING); + if (!$this->rbac_system->checkAccess("create_rolt", $this->rolf_ref_id)) { + $this->ilias->raiseError($this->lng->txt("msg_no_perm_create_rolt"), $this->ilias->error_obj->WARNING); } - $form = $this->initFormRoleTemplate(self::FORM_MODE_EDIT); - if ($form->checkInput()) { - if (!$this->object->isInternalTemplate()) { - $this->object->setTitle($form->getInput('title')); - } - $this->object->setDescription($form->getInput('desc')); - $this->rbac_admin->setProtected( - $this->rolf_ref_id, - $this->object->getId(), - $form->getInput('protected') ? 'y' : 'n' + $form = $this->getRoleTemplateForm(true)->withRequest($this->request); + $data = $form->getData(); + if ($data === null) { + $this->tabs_gui->setBackTarget( + $this->lng->txt('cancel'), + $this->ctrl->getParentReturnByClass(self::class) ); - $this->object->update(); - $this->tpl->setOnScreenMessage('success', $this->lng->txt("saved_successfully"), true); - $this->ctrl->returnToParent($this); + + $this->tpl->setContent( + $this->ui_renderer->render( + $this->ui_factory->panel()->standard( + $this->lng->txt('rolt_new'), + $form + ) + ) + ); + return; } - $form->setValuesByPost(); - $this->editObject($form); + $role_template = new ilObjRoleTemplate(); + $role_template->setTitle($data[self::FORM_KEY_TITLE]); + $role_template->setDescription($data[self::FORM_KEY_DESCRIPTION]); + $role_template->create(); + $this->rbac_admin->assignRoleToFolder($role_template->getId(), $this->rolf_ref_id, 'n'); + $this->rbac_admin->setProtected( + $this->rolf_ref_id, + $role_template->getId(), + $data[self::FORM_KEY_PROTECT] ? 'y' : 'n' + ); + $this->tpl->setOnScreenMessage('success', $this->lng->txt("rolt_added"), true); + $this->ctrl->setParameter($this, 'obj_id', $role_template->getId()); + $this->ctrl->redirect($this, 'perm'); } - public function saveObject(): void + public function updateObject(): void { - if (!$this->rbac_system->checkAccess("create_rolt", $this->rolf_ref_id)) { - $this->ilias->raiseError($this->lng->txt("msg_no_perm_create_rolt"), $this->ilias->error_obj->WARNING); + if (!$this->rbac_system->checkAccess('write', $this->rolf_ref_id)) { + $this->error->raiseError($this->lng->txt('msg_no_perm_modify_rolt'), $this->error->WARNING); } - $form = $this->initFormRoleTemplate(); - if ($form->checkInput()) { - $roltObj = new ilObjRoleTemplate(); - $roltObj->setTitle($form->getInput('title')); - $roltObj->setDescription($form->getInput('desc')); - $roltObj->create(); - $this->rbac_admin->assignRoleToFolder($roltObj->getId(), $this->rolf_ref_id, 'n'); - $this->rbac_admin->setProtected( - $this->rolf_ref_id, - $roltObj->getId(), - $form->getInput('protected') ? 'y' : 'n' + + $form = $this->getRoleTemplateForm()->withRequest($this->request); + $data = $form->getData(); + if ($data === null) { + $this->tpl->setContent( + $this->ui_renderer->render( + $this->ui_factory->panel()->standard( + $this->lng->txt('rolt_edit'), + $form + ) + ) ); + return; + } - $this->tpl->setOnScreenMessage('success', $this->lng->txt("rolt_added"), true); - // redirect to permission screen - $this->ctrl->setParameter($this, 'obj_id', $roltObj->getId()); - $this->ctrl->redirect($this, 'perm'); + if (!$this->object->isInternalTemplate()) { + $this->object->setTitle($data[self::FORM_KEY_TITLE]); } - $form->setValuesByPost(); - $this->createObject($form); + + $this->object->setDescription($data[self::FORM_KEY_DESCRIPTION]); + $this->object->update(); + $this->rbac_admin->setProtected( + $this->rolf_ref_id, + $this->object->getId(), + $data[self::FORM_KEY_PROTECT] ? 'y' : 'n' + ); + $this->tpl->setOnScreenMessage('success', $this->lng->txt("saved_successfully"), true); + $this->ctrl->returnToParent($this); } protected function permObject(): void @@ -293,10 +326,8 @@ function ($array) { $custom_transformer ); } - // delete all existing template entries - //$rbacadmin->deleteRolePermission($this->object->getId(), $this->ref_id); - $subs = ilObjRole::getSubObjects('root', false); + $subs = ilObjRole::getSubObjects('root', false); foreach (array_keys($subs) as $subtype) { // Delete per object type $this->rbac_admin->deleteRolePermission($this->object->getId(), $this->ref_id, $subtype); @@ -374,11 +405,6 @@ protected function getTabs(): void } } - public function cancelObject(): void - { - $this->ctrl->redirectByClass("ilobjrolefoldergui", "view"); - } - /** * @inheritdoc */ diff --git a/components/ILIAS/AccessControl/classes/class.ilPermission2GUI.php b/components/ILIAS/AccessControl/classes/class.ilPermission2GUI.php deleted file mode 100755 index 83508a7575ed..000000000000 --- a/components/ILIAS/AccessControl/classes/class.ilPermission2GUI.php +++ /dev/null @@ -1,215 +0,0 @@ - - * @ingroup ServicesAccessControl - */ -class ilPermission2GUI -{ - private const TAB_POSITION_PERMISSION_SETTINGS = "position_permission_settings"; - - protected object $gui_obj; - protected ilErrorHandling $ilErr; - protected ilCtrl $ctrl; - protected ilLanguage $lng; - protected ilObjectDefinition $objDefinition; - protected ilGlobalTemplateInterface $tpl; - protected ilRbacSystem $rbacsystem; - protected ilRbacReview $rbacreview; - protected ilRbacAdmin $rbacadmin; - protected ilObjectDataCache $objectDataCache; - protected ilTabsGUI $tabs; - protected GlobalHttpState $http; - protected Factory $refinery; - - private array $roles = []; - private int $num_roles = 0; - - public function __construct(object $a_gui_obj) - { - global $DIC; - - $this->objDefinition = $DIC['objDefinition']; - $this->objectDataCache = $DIC['ilObjDataCache']; - $this->tpl = $DIC->ui()->mainTemplate(); - $this->lng = $DIC->language(); - $this->lng->loadLanguageModule("rbac"); - $this->ctrl = $DIC->ctrl(); - $this->rbacsystem = $DIC->rbac()->system(); - $this->rbacreview = $DIC->rbac()->review(); - $this->rbacadmin = $DIC->rbac()->admin(); - $this->tabs = $DIC->tabs(); - $this->ilErr = $DIC['ilErr']; - $this->http = $DIC->http(); - $this->refinery = $DIC->refinery(); - - $this->gui_obj = $a_gui_obj; - $this->tabs->activateTab('perm_settings'); - } - - // show owner sub tab - public function owner(): void - { - $this->__initSubTabs("owner"); - - $form = new ilPropertyFormGUI(); - $form->setFormAction($this->ctrl->getFormAction($this, "owner")); - $form->setTitle($this->lng->txt("info_owner_of_object")); - - $login = new ilTextInputGUI($this->lng->txt("login"), "owner"); - $login->setDataSource($this->ctrl->getLinkTargetByClass([get_class($this), - 'ilRepositorySearchGUI' - ], 'doUserAutoComplete', '', true)); - $login->setRequired(true); - $login->setSize(50); - $login->setInfo($this->lng->txt("chown_warning")); - $login->setValue(ilObjUser::_lookupLogin($this->gui_obj->getObject()->getOwner())); - $form->addItem($login); - $form->addCommandButton("changeOwner", $this->lng->txt("change_owner")); - $this->tpl->setContent($form->getHTML()); - } - - public function changeOwner(): void - { - $owner = ''; - if ($this->http->wrapper()->post()->has('owner')) { - $owner = $this->http->wrapper()->post()->retrieve( - 'owner', - $this->refinery->kindlyTo()->string() - ); - } - if (!$user_id = ilObjUser::_lookupId($owner)) { - $this->tpl->setOnScreenMessage('failure', $this->lng->txt('user_not_known')); - $this->owner(); - return; - } - - // no need to change? - if ($user_id != $this->gui_obj->getObject()->getOwner()) { - $this->gui_obj->getObject()->setOwner($user_id); - $this->gui_obj->getObject()->updateOwner(); - $this->objectDataCache->deleteCachedEntry($this->gui_obj->getObject()->getId()); - - if (ilRbacLog::isActive()) { - ilRbacLog::add(ilRbacLog::CHANGE_OWNER, $this->gui_obj->getObject()->getRefId(), [$user_id]); - } - } - - $this->tpl->setOnScreenMessage('success', $this->lng->txt('owner_updated'), true); - - if (!$this->rbacsystem->checkAccess("edit_permission", $this->gui_obj->getObject()->getRefId())) { - $this->ctrl->redirect($this->gui_obj); - return; - } - $this->ctrl->redirect($this, 'owner'); - } - - // init sub tabs - public function __initSubTabs(string $a_cmd): void - { - $perm = $a_cmd === 'perm'; - $perm_positions = $a_cmd === ilPermissionGUI::CMD_PERM_POSITIONS; - $info = $a_cmd === 'perminfo'; - $owner = $a_cmd === 'owner'; - $log = $a_cmd === 'log'; - - $this->tabs->addSubTabTarget( - "permission_settings", - $this->ctrl->getLinkTarget($this, "perm"), - "", - "", - "", - $perm - ); - - if (ilOrgUnitGlobalSettings::getInstance()->isPositionAccessActiveForObject($this->gui_obj->getObject()->getId())) { - $this->tabs->addSubTabTarget( - self::TAB_POSITION_PERMISSION_SETTINGS, - $this->ctrl->getLinkTarget($this, ilPermissionGUI::CMD_PERM_POSITIONS), - "", - "", - "", - $perm_positions - ); - } - - $this->tabs->addSubTabTarget( - "info_status_info", - $this->ctrl->getLinkTargetByClass([get_class($this), "ilobjectpermissionstatusgui"], "perminfo"), - "", - "", - "", - $info - ); - $this->tabs->addSubTabTarget( - "owner", - $this->ctrl->getLinkTarget($this, "owner"), - "", - "", - "", - $owner - ); - - if (ilRbacLog::isActive()) { - $this->tabs->addSubTabTarget( - "rbac_log", - $this->ctrl->getLinkTarget($this, "log"), - "", - "", - "", - $log - ); - } - } - - public function log(): void - { - if (!ilRbacLog::isActive()) { - $this->ctrl->redirect($this, "perm"); - } - - $this->__initSubTabs("log"); - - $table = new ilRbacLogTableGUI($this, "log", $this->gui_obj->getObject()->getRefId()); - $this->tpl->setContent($table->getHTML()); - } - - public function applyLogFilter(): void - { - $table = new ilRbacLogTableGUI($this, "log", $this->gui_obj->getObject()->getRefId()); - $table->resetOffset(); - $table->writeFilterToSession(); - $this->log(); - } - - public function resetLogFilter(): void - { - $table = new ilRbacLogTableGUI($this, "log", $this->gui_obj->getObject()->getRefId()); - $table->resetOffset(); - $table->resetFilter(); - $this->log(); - } -} diff --git a/components/ILIAS/AccessControl/classes/class.ilPermissionGUI.php b/components/ILIAS/AccessControl/classes/class.ilPermissionGUI.php index 224c51707f79..b883bf430150 100755 --- a/components/ILIAS/AccessControl/classes/class.ilPermissionGUI.php +++ b/components/ILIAS/AccessControl/classes/class.ilPermissionGUI.php @@ -13,47 +13,91 @@ * https://www.ilias.de * https://github.com/ILIAS-eLearning * - ******************************************************************** - */ + *********************************************************************/ + declare(strict_types=1); +use ILIAS\AccessControl\Log\Table; + +use ILIAS\HTTP\GlobalHttpState; +use ILIAS\Refinery\Factory; use ILIAS\UI\Factory as UIFactory; -use ILIAS\HTTP\Wrapper\WrapperFactory; +use ILIAS\UI\Renderer as UIRenderer; +use ILIAS\Data\Factory as DataFactory; /** - * New PermissionGUI (extends from old ilPermission2GUI) - * RBAC related output - * * @author Stefan Meyer * @author Sascha Hofmann * @version $Id$ * @ilCtrl_Calls ilPermissionGUI: ilObjRoleGUI, ilRepositorySearchGUI, ilObjectPermissionStatusGUI * @ingroup ServicesAccessControl */ -class ilPermissionGUI extends ilPermission2GUI +class ilPermissionGUI { - protected const CMD_PERM_POSITIONS = 'permPositions'; public const CMD_SAVE_POSITIONS_PERMISSIONS = 'savePositionsPermissions'; - - protected object $current_obj; - - protected ilRecommendedContentManager $recommended_content_manager; - protected ilToolbarGUI $toolbar; - protected UIFactory $ui_factory; - protected ILIAS\HTTP\Wrapper\WrapperFactory $wrapper; - protected ilOrgUnitPositionDBRepository $positionRepo; - protected ilOrgUnitPermissionDBRepository $permissionRepo; - protected ilOrgUnitOperationDBRepository $operationRepo; - - public function __construct(object $a_gui_obj) + private const CMD_PERM_POSITIONS = 'permPositions'; + private const TAB_POSITION_PERMISSION_SETTINGS = "position_permission_settings"; + + private ilObjectGUI $current_obj; + + private ilRecommendedContentManager $recommended_content_manager; + private ilOrgUnitPositionDBRepository $positionRepo; + private ilOrgUnitPermissionDBRepository $permissionRepo; + private ilOrgUnitOperationDBRepository $operationRepo; + + private ilObjectGUI $gui_obj; + private ilErrorHandling $ilErr; + private ilCtrl $ctrl; + private ilLanguage $lng; + private ilObjectDefinition $object_definition; + private ilGlobalTemplateInterface $tpl; + private ilUIService $ui_service; + private ilRbacSystem $rbacsystem; + private ilRbacReview $rbacreview; + private ilRbacAdmin $rbacadmin; + private ilObjectDataCache $objectDataCache; + private ilTabsGUI $tabs; + private GlobalHttpState $http; + private Factory $refinery; + private ilToolbarGUI $toolbar; + private UIFactory $ui_factory; + private UIRenderer $ui_renderer; + private DataFactory $data_factory; + private ilDBInterface $db; + private ilObjUser $user; + private ilTree $tree; + + public function __construct(ilObjectGUI $a_gui_obj) { + /** @var ILIAS\DI\Container $DIC */ global $DIC; - $this->wrapper = $DIC->http()->wrapper(); + $this->object_definition = $DIC['objDefinition']; + $this->ui_service = $DIC->uiService(); + $this->objectDataCache = $DIC['ilObjDataCache']; + $this->tpl = $DIC['tpl']; + $this->lng = $DIC['lng']; + $this->ctrl = $DIC['ilCtrl']; + $this->rbacsystem = $DIC['rbacsystem']; + $this->rbacreview = $DIC['rbacreview']; + $this->rbacadmin = $DIC['rbacadmin']; + $this->tabs = $DIC['ilTabs']; + $this->ilErr = $DIC['ilErr']; + $this->http = $DIC['http']; + $this->refinery = $DIC['refinery']; $this->toolbar = $DIC['ilToolbar']; $this->ui_factory = $DIC['ui.factory']; - parent::__construct($a_gui_obj); + $this->ui_renderer = $DIC['ui.renderer']; + $this->db = $DIC['ilDB']; + $this->user = $DIC['ilUser']; + $this->tree = $DIC['tree']; + + $this->data_factory = new DataFactory(); $this->recommended_content_manager = new ilRecommendedContentManager(); + + $this->lng->loadLanguageModule('rbac'); + $this->gui_obj = $a_gui_obj; + $this->tabs->activateTab('perm_settings'); } private function getPositionRepo(): ilOrgUnitPositionDBRepository @@ -147,7 +191,7 @@ public function getCurrentObject(): object /** * Called after toolbar action applyTemplateSwitch */ - protected function confirmTemplateSwitch(): void + public function confirmTemplateSwitch(): void { $this->ctrl->setReturn($this, 'perm'); // @todo: removed deprecated ilCtrl methods, this needs inspection by a maintainer. @@ -167,7 +211,7 @@ public function perm(ilTable2GUI $table = null): void $this->toolbar->addSeparator(); } - if ($this->objDefinition->hasLocalRoles($this->getCurrentObject()->getType()) && !$this->isAdministrationObject() + if ($this->object_definition->hasLocalRoles($this->getCurrentObject()->getType()) && !$this->isAdministrationObject() ) { $this->toolbar->setFormAction($this->ctrl->getFormAction($this)); @@ -195,12 +239,12 @@ public function perm(ilTable2GUI $table = null): void $this->tpl->setContent($table->getHTML()); } - protected function isAdminRoleFolder(): bool + private function isAdminRoleFolder(): bool { return $this->getCurrentObject()->getRefId() == ROLE_FOLDER_ID; } - protected function isAdministrationObject(): bool + private function isAdministrationObject(): bool { return $this->getCurrentObject()->getType() == 'adm'; } @@ -208,12 +252,12 @@ protected function isAdministrationObject(): bool /** * Check if node is subobject of administration folder */ - protected function isInAdministration(): bool + private function isInAdministration(): bool { - return (bool) $GLOBALS['DIC']['tree']->isGrandChild(SYSTEM_FOLDER_ID, $this->getCurrentObject()->getRefId()); + return $this->tree->isGrandChild(SYSTEM_FOLDER_ID, $this->getCurrentObject()->getRefId()); } - protected function applyFilter(): void + public function applyFilter(): void { $table = new ilObjectRolePermissionTableGUI($this, 'perm', $this->getCurrentObject()->getRefId()); $table->resetOffset(); @@ -221,7 +265,7 @@ protected function applyFilter(): void $this->perm($table); } - protected function resetFilter(): void + public function resetFilter(): void { $table = new ilObjectRolePermissionTableGUI($this, 'perm', $this->getCurrentObject()->getRefId()); $table->resetOffset(); @@ -283,16 +327,10 @@ public function applyRoleFilter(array $a_roles, int $a_filter_id): array protected function savePermissions(): void { - global $DIC; - - $rbacreview = $DIC['rbacreview']; - $objDefinition = $DIC['objDefinition']; - $rbacadmin = $DIC['rbacadmin']; - $table = new ilObjectRolePermissionTableGUI($this, 'perm', $this->getCurrentObject()->getRefId()); $roles = $this->applyRoleFilter( - $rbacreview->getParentRoleIds($this->getCurrentObject()->getRefId()), + $this->rbacreview->getParentRoleIds($this->getCurrentObject()->getRefId()), (int) $table->getFilterItemByPostVar('role')->getValue() ); @@ -300,19 +338,19 @@ protected function savePermissions(): void $log_old = ilRbacLog::gatherFaPa($this->getCurrentObject()->getRefId(), array_keys((array) $roles)); # all possible create permissions - $possible_ops_ids = $rbacreview->getOperationsByTypeAndClass( + $possible_ops_ids = $this->rbacreview->getOperationsByTypeAndClass( $this->getCurrentObject()->getType(), 'create' ); # createable (activated) create permissions - $create_types = $objDefinition->getCreatableSubObjects( + $create_types = $this->object_definition->getCreatableSubObjects( $this->getCurrentObject()->getType() ); $createable_ops_ids = ilRbacReview::lookupCreateOperationIds(array_keys((array) $create_types)); - $post_perm = $this->wrapper->post()->has('perm') - ? $this->wrapper->post()->retrieve( + $post_perm = $this->http->wrapper()->post()->has('perm') + ? $this->http->wrapper()->post()->retrieve( 'perm', $this->refinery->kindlyTo()->dictOf( $this->refinery->kindlyTo()->dictOf( @@ -328,7 +366,7 @@ protected function savePermissions(): void } $new_ops = array_keys((array) ($post_perm[$role] ?? [])); - $old_ops = $rbacreview->getRoleOperationsOnObject( + $old_ops = $this->rbacreview->getRoleOperationsOnObject( $role, $this->getCurrentObject()->getRefId() ); @@ -343,12 +381,12 @@ protected function savePermissions(): void } } - $rbacadmin->revokePermission( + $this->rbacadmin->revokePermission( $this->getCurrentObject()->getRefId(), $role ); - $rbacadmin->grantPermission( + $this->rbacadmin->grantPermission( $role, array_unique($new_ops), $this->getCurrentObject()->getRefId() @@ -356,8 +394,8 @@ protected function savePermissions(): void } if (ilPermissionGUI::hasContainerCommands($this->getCurrentObject()->getType())) { - $inherit_post = $this->wrapper->post()->has('inherit') - ? $this->wrapper->post()->retrieve( + $inherit_post = $this->http->wrapper()->post()->has('inherit') + ? $this->http->wrapper()->post()->retrieve( 'inherit', $this->refinery->kindlyTo()->dictOf( $this->refinery->kindlyTo()->bool() @@ -380,7 +418,7 @@ protected function savePermissions(): void if ( $parent_id === $this->getCurrentObject()->getRefId() && !isset($inherit_post[$obj_id]) - && !$rbacreview->isBlockedAtPosition($obj_id, $this->getCurrentObject()->getRefId()) + && !$this->rbacreview->isBlockedAtPosition($obj_id, $this->getCurrentObject()->getRefId()) ) { ilLoggerFactory::getLogger('ac')->debug('Stop local policy for: ' . $role['obj_id']); $role_obj = ilObjectFactory::getInstanceByObjId($obj_id); @@ -394,35 +432,35 @@ protected function savePermissions(): void && isset($inherit_post[$obj_id]) ) { ilLoggerFactory::getLogger('ac')->debug('Create local policy'); - $rbacadmin->copyRoleTemplatePermissions( + $this->rbacadmin->copyRoleTemplatePermissions( $obj_id, $parent_id, $this->getCurrentObject()->getRefId(), $obj_id ); ilLoggerFactory::getLogger('ac')->debug('Assign role to folder'); - $rbacadmin->assignRoleToFolder($obj_id, $this->getCurrentObject()->getRefId(), 'n'); + $this->rbacadmin->assignRoleToFolder($obj_id, $this->getCurrentObject()->getRefId(), 'n'); } } } // Protect permissions if (ilPermissionGUI::hasContainerCommands($this->getCurrentObject()->getType())) { - $protected_post = $this->wrapper->post()->has('protect') - ? $this->wrapper->post()->retrieve( + $protected_post = $this->http->wrapper()->post()->has('protect') + ? $this->http->wrapper()->post()->retrieve( 'protect', $this->refinery->kindlyTo()->dictOf($this->refinery->kindlyTo()->int()) ) : []; foreach ($roles as $role) { $obj_id = (int) $role['obj_id']; - if ($rbacreview->isAssignable($obj_id, $this->getCurrentObject()->getRefId())) { + if ($this->rbacreview->isAssignable($obj_id, $this->getCurrentObject()->getRefId())) { if (isset($protected_post[$obj_id]) && - !$rbacreview->isProtected($this->getCurrentObject()->getRefId(), $obj_id)) { - $rbacadmin->setProtected($this->getCurrentObject()->getRefId(), $obj_id, 'y'); + !$this->rbacreview->isProtected($this->getCurrentObject()->getRefId(), $obj_id)) { + $this->rbacadmin->setProtected($this->getCurrentObject()->getRefId(), $obj_id, 'y'); } elseif (!isset($protected_post[$obj_id]) && - $rbacreview->isProtected($this->getCurrentObject()->getRefId(), $obj_id)) { - $rbacadmin->setProtected($this->getCurrentObject()->getRefId(), $obj_id, 'n'); + $this->rbacreview->isProtected($this->getCurrentObject()->getRefId(), $obj_id)) { + $this->rbacadmin->setProtected($this->getCurrentObject()->getRefId(), $obj_id, 'n'); } } } @@ -440,10 +478,9 @@ protected function savePermissions(): void } $this->tpl->setOnScreenMessage('success', $this->lng->txt('settings_saved'), true); $this->ctrl->redirect($this, 'perm'); - #$this->perm(); } - protected function showConfirmBlockRole(array $a_blocked_info): void + private function showConfirmBlockRole(array $a_blocked_info): void { $info = ''; if ($a_blocked_info['new_blocked']) { @@ -481,18 +518,18 @@ protected function showConfirmBlockRole(array $a_blocked_info): void $this->tpl->setContent($confirm->getHTML()); } - protected function modifyBlockRoles(): void + private function modifyBlockRoles(): void { $this->blockRoles( - $this->wrapper->post()->has('new_block') - ? $this->wrapper->post()->retrieve( + $this->http->wrapper()->post()->has('new_block') + ? $this->http->wrapper()->post()->retrieve( 'new_block', $this->refinery->kindlyTo()->dictOf($this->refinery->kindlyTo()->int()) ) : [] ); - $this->unblockRoles($this->wrapper->post()->has('new_unblock') - ? $this->wrapper->post()->retrieve( + $this->unblockRoles($this->http->wrapper()->post()->has('new_unblock') + ? $this->http->wrapper()->post()->retrieve( 'new_unblock', $this->refinery->kindlyTo()->dictOf($this->refinery->kindlyTo()->int()) ) @@ -502,10 +539,7 @@ protected function modifyBlockRoles(): void $this->ctrl->redirect($this, 'perm'); } - /** - * - */ - protected function unblockRoles($roles): void + private function unblockRoles(array $roles): void { foreach ($roles as $role) { // delete local policy @@ -529,7 +563,7 @@ protected function unblockRoles($roles): void } } - protected function blockRoles($roles): void + private function blockRoles(array $roles): void { foreach ($roles as $role) { // Set assign to 'y' only if it is a local role @@ -564,7 +598,7 @@ public static function hasContainerCommands(string $a_type): bool return $objDefinition->isContainer($a_type) && $a_type != 'root' && $a_type != 'adm' && $a_type != 'rolf'; } - protected function displayImportRoleForm(ilPropertyFormGUI $form = null): void + private function displayImportRoleForm(ilPropertyFormGUI $form = null): void { $this->tabs->clearTargets(); @@ -574,7 +608,7 @@ protected function displayImportRoleForm(ilPropertyFormGUI $form = null): void $this->tpl->setContent($form->getHTML()); } - protected function doImportRole(): void + private function doImportRole(): void { $form = $this->initImportForm(); if ($form->checkInput()) { @@ -609,10 +643,7 @@ protected function doImportRole(): void $this->displayImportRoleForm($form); } - /** - * init import form - */ - protected function initImportForm(): ilPropertyFormGUI + private function initImportForm(): ilPropertyFormGUI { $form = new ilPropertyFormGUI(); $form->setFormAction($this->ctrl->getFormAction($this)); @@ -628,7 +659,7 @@ protected function initImportForm(): ilPropertyFormGUI return $form; } - protected function initRoleForm(): ilPropertyFormGUI + private function initRoleForm(): ilPropertyFormGUI { $form = new ilPropertyFormGUI(); $form->setFormAction($this->ctrl->getFormAction($this)); @@ -698,18 +729,15 @@ protected function initRoleForm(): ilPropertyFormGUI } // Local policy only for containers - if ($this->objDefinition->isContainer($this->getCurrentObject()->getType())) { - $check = new ilCheckboxInputGui($this->lng->txt("rbac_role_rights_copy_change_existing"), 'existing'); + if ($this->object_definition->isContainer($this->getCurrentObject()->getType())) { + $check = new ilCheckboxInputGUI($this->lng->txt("rbac_role_rights_copy_change_existing"), 'existing'); $check->setInfo($this->lng->txt('rbac_change_existing_objects_desc_new_role')); $form->addItem($check); } return $form; } - /** - * Show add role form - */ - protected function displayAddRoleForm(): void + public function displayAddRoleForm(): void { $this->tabs->clearTargets(); $form = $this->initRoleForm(); @@ -722,7 +750,7 @@ protected function displayAddRoleForm(): void * is displayed in the permission settings dialogue for an object * TODO: change this bahaviour */ - protected function addRole(): void + public function addRole(): void { $form = $this->initRoleForm(); if ($form->checkInput()) { @@ -787,23 +815,19 @@ protected function addRole(): void } } - protected function getModifiedBlockedSettings(): array + private function getModifiedBlockedSettings(): array { - global $DIC; - - $rbacreview = $DIC['rbacreview']; - $blocked_info['new_blocked'] = []; $blocked_info['new_unblocked'] = []; $blocked_info['num'] = 0; - $visible_block = $this->wrapper->post()->has('visible_block') - ? $this->wrapper->post()->retrieve( + $visible_block = $this->http->wrapper()->post()->has('visible_block') + ? $this->http->wrapper()->post()->retrieve( 'visible_block', $this->refinery->kindlyTo()->dictOf($this->refinery->kindlyTo()->int()) ) : []; - $block_post = $this->wrapper->post()->has('block') - ? $this->wrapper->post()->retrieve( + $block_post = $this->http->wrapper()->post()->has('block') + ? $this->http->wrapper()->post()->retrieve( 'block', $this->refinery->kindlyTo()->dictOf($this->refinery->kindlyTo()->int()) ) @@ -811,7 +835,7 @@ protected function getModifiedBlockedSettings(): array foreach ($visible_block as $role => $one) { - $blocked = $rbacreview->isBlockedAtPosition($role, $this->getCurrentObject()->getRefId()); + $blocked = $this->rbacreview->isBlockedAtPosition($role, $this->getCurrentObject()->getRefId()); if (isset($block_post[$role]) && !$blocked) { $blocked_info['new_blocked'][] = $role; $blocked_info['num']++; @@ -824,11 +848,7 @@ protected function getModifiedBlockedSettings(): array return $blocked_info; } - // - // OrgUnit Position Permissions - // - - protected function permPositions(): void + public function permPositions(): void { $perm = self::CMD_PERM_POSITIONS; $this->__initSubTabs($perm); @@ -839,7 +859,7 @@ protected function permPositions(): void $this->tpl->setContent($table->getHTML()); } - protected function savePositionsPermissions(): void + public function savePositionsPermissions(): void { $this->__initSubTabs(self::CMD_PERM_POSITIONS); @@ -847,8 +867,8 @@ protected function savePositionsPermissions(): void $ref_id = $this->getCurrentObject()->getRefId(); // handle local sets - $local_post = $this->wrapper->post()->has('local') - ? $this->wrapper->post()->retrieve( + $local_post = $this->http->wrapper()->post()->has('local') + ? $this->http->wrapper()->post()->retrieve( 'local', $this->refinery->kindlyTo()->dictOf($this->refinery->kindlyTo()->int()) ) @@ -862,8 +882,8 @@ protected function savePositionsPermissions(): void } } - $position_perm_post = $this->wrapper->post()->has('position_perm') - ? $this->wrapper->post()->retrieve( + $position_perm_post = $this->http->wrapper()->post()->has('position_perm') + ? $this->http->wrapper()->post()->retrieve( 'position_perm', $this->refinery->kindlyTo()->dictOf( $this->refinery->kindlyTo()->dictOf( @@ -892,4 +912,143 @@ protected function savePositionsPermissions(): void $this->tpl->setOnScreenMessage('success', $this->lng->txt('settings_saved'), true); $this->ctrl->redirect($this, self::CMD_PERM_POSITIONS); } + + public function owner(): void + { + $this->__initSubTabs('owner'); + + $form = new ilPropertyFormGUI(); + $form->setFormAction($this->ctrl->getFormAction($this, "owner")); + $form->setTitle($this->lng->txt("info_owner_of_object")); + + $login = new ilTextInputGUI($this->lng->txt("login"), "owner"); + $login->setDataSource($this->ctrl->getLinkTargetByClass([get_class($this), + 'ilRepositorySearchGUI' + ], 'doUserAutoComplete', '', true)); + $login->setRequired(true); + $login->setSize(50); + $login->setInfo($this->lng->txt("chown_warning")); + $login->setValue(ilObjUser::_lookupLogin($this->gui_obj->getObject()->getOwner())); + $form->addItem($login); + $form->addCommandButton("changeOwner", $this->lng->txt("change_owner")); + $this->tpl->setContent($form->getHTML()); + } + + public function changeOwner(): void + { + $owner = ''; + if ($this->http->wrapper()->post()->has('owner')) { + $owner = $this->http->wrapper()->post()->retrieve( + 'owner', + $this->refinery->kindlyTo()->string() + ); + } + if (!$user_id = ilObjUser::_lookupId($owner)) { + $this->tpl->setOnScreenMessage('failure', $this->lng->txt('user_not_known')); + $this->owner(); + return; + } + + // no need to change? + if ($user_id != $this->gui_obj->getObject()->getOwner()) { + $this->gui_obj->getObject()->setOwner($user_id); + $this->gui_obj->getObject()->updateOwner(); + $this->objectDataCache->deleteCachedEntry($this->gui_obj->getObject()->getId()); + + if (ilRbacLog::isActive()) { + ilRbacLog::add(ilRbacLog::CHANGE_OWNER, $this->gui_obj->getObject()->getRefId(), [$user_id]); + } + } + + $this->tpl->setOnScreenMessage('success', $this->lng->txt('owner_updated'), true); + + if (!$this->rbacsystem->checkAccess("edit_permission", $this->gui_obj->getObject()->getRefId())) { + $this->ctrl->redirect($this->gui_obj); + return; + } + $this->ctrl->redirect($this, 'owner'); + } + + private function __initSubTabs(string $a_cmd): void + { + $perm = $a_cmd === 'perm'; + $perm_positions = $a_cmd === ilPermissionGUI::CMD_PERM_POSITIONS; + $info = $a_cmd === 'perminfo'; + $owner = $a_cmd === 'owner'; + $log = $a_cmd === 'log'; + + $this->tabs->addSubTabTarget( + "permission_settings", + $this->ctrl->getLinkTarget($this, "perm"), + "", + "", + "", + $perm + ); + + if (ilOrgUnitGlobalSettings::getInstance()->isPositionAccessActiveForObject($this->gui_obj->getObject()->getId())) { + $this->tabs->addSubTabTarget( + self::TAB_POSITION_PERMISSION_SETTINGS, + $this->ctrl->getLinkTarget($this, ilPermissionGUI::CMD_PERM_POSITIONS), + "", + "", + "", + $perm_positions + ); + } + + $this->tabs->addSubTabTarget( + "info_status_info", + $this->ctrl->getLinkTargetByClass([get_class($this), "ilobjectpermissionstatusgui"], "perminfo"), + "", + "", + "", + $info + ); + $this->tabs->addSubTabTarget( + "owner", + $this->ctrl->getLinkTarget($this, "owner"), + "", + "", + "", + $owner + ); + + if (ilRbacLog::isActive()) { + $this->tabs->addSubTabTarget( + "rbac_log", + $this->ctrl->getLinkTarget($this, 'log'), + "", + "", + "", + $log + ); + } + } + + public function log(): void + { + if (!ilRbacLog::isActive()) { + $this->ctrl->redirect($this, 'perm'); + } + + $this->__initSubTabs('log'); + + $table = new Table( + new ilRbacLog($this->db), + $this->ui_factory, + $this->data_factory, + $this->lng, + $this->ctrl, + $this->ui_service, + $this->object_definition, + $this->http->request(), + $this->rbacreview, + $this->user, + $this->gui_obj + ); + $this->tpl->setContent($this->ui_renderer->render( + $table->getTableAndFilter() + )); + } } diff --git a/components/ILIAS/AccessControl/classes/class.ilRbacLog.php b/components/ILIAS/AccessControl/classes/class.ilRbacLog.php index 9e072521adf2..4614973a837e 100755 --- a/components/ILIAS/AccessControl/classes/class.ilRbacLog.php +++ b/components/ILIAS/AccessControl/classes/class.ilRbacLog.php @@ -1,6 +1,5 @@ db->setLimit($range->getLength(), $range->getStart()); + $set = $this->db->query( + 'SELECT * FROM ' . self::LOG_TABLE_NAME + . ' WHERE ref_id = ' . $this->db->quote($ref_id, ilDBConstants::T_INTEGER) + . $this->getWhereForFilter($filter) + . $order->join( + ' ORDER BY ', + static fn(string $ret, string $key, string $value): string => + $ret === ' ORDER BY ' ? "{$ret} {$key} {$value}" : "{$ret}, {$key} {$value} " + ) + ); + $result = []; + while ($row = $this->db->fetchAssoc($set)) { + $row['data'] = unserialize($row['data'], [false]); + $result[] = $row; + } + return $result; + } + + public function getLogItemsCount( + int $ref_id, + array $filter + ): int { + $result = $this->db->fetchObject( + $this->db->query( + 'SELECT COUNT(*) as cnt FROM ' . self::LOG_TABLE_NAME . ' WHERE ref_id = ' + . $this->db->quote( + $ref_id, + ilDBConstants::T_INTEGER + ) . $this->getWhereForFilter($filter) + ) + ); + return $result->cnt; + } + + private function getWhereForFilter(?array $filter): string + { + if ($filter === null) { + return ''; + } + + $where = []; + if (isset($filter['action'])) { + $where[] = ' ' . $this->db->in( + 'action', + $filter['action'], + false, + ilDBConstants::T_INTEGER + ); + } + if (isset($filter['from'])) { + $where[] = ' created >= ' . $this->db->quote( + $filter['from'], + ilDBConstants::T_INTEGER + ); + } + if (isset($filter['to'])) { + $where[] = ' created <= ' . $this->db->quote( + $filter['to'], + ilDBConstants::T_INTEGER + ); + } + + if (count($where) > 0) { + $where = array_merge([' AND '], [implode(' AND ', $where)]); + } + return implode('', $where); + } + public static function isActive(): bool { return ilPrivacySettings::getInstance()->enabledRbacLog(); } - public static function gatherFaPa(int $a_ref_id, array $a_role_ids, bool $a_add_action = false): array + public static function gatherFaPa(int $ref_id, array $role_ids, bool $add_action = false): array { global $DIC; @@ -50,55 +135,55 @@ public static function gatherFaPa(int $a_ref_id, array $a_role_ids, bool $a_add_ // if result is used as input to diffFaPa() we need "raw" data // roles - foreach ($a_role_ids as $role_id) { + foreach ($role_ids as $role_id) { if ($role_id != SYSTEM_ROLE_ID) { - if ($a_add_action) { - $result["ops"][$role_id]["add"] = $rbacreview->getRoleOperationsOnObject($role_id, $a_ref_id); + if ($add_action) { + $result["ops"][$role_id]["add"] = $rbacreview->getRoleOperationsOnObject($role_id, $ref_id); } else { - $result["ops"][$role_id] = $rbacreview->getRoleOperationsOnObject($role_id, $a_ref_id); + $result["ops"][$role_id] = $rbacreview->getRoleOperationsOnObject($role_id, $ref_id); } } } // inheritance - if ($a_ref_id && $a_ref_id != ROLE_FOLDER_ID) { - if ($a_add_action) { - $result["inht"]["add"] = $rbacreview->getRolesOfRoleFolder($a_ref_id); + if ($ref_id && $ref_id != ROLE_FOLDER_ID) { + if ($add_action) { + $result["inht"]["add"] = $rbacreview->getRolesOfRoleFolder($ref_id); } else { - $result["inht"] = $rbacreview->getRolesOfRoleFolder($a_ref_id); + $result["inht"] = $rbacreview->getRolesOfRoleFolder($ref_id); } } return $result; } - public static function diffFaPa(array $a_old, array $a_new): array + public static function diffFaPa(array $old, array $new): array { $result = []; // roles - foreach ((array) $a_old["ops"] as $role_id => $ops) { - $diff = array_diff($ops, $a_new["ops"][$role_id]); + foreach ((array) $old["ops"] as $role_id => $ops) { + $diff = array_diff($ops, $new["ops"][$role_id]); if ($diff !== []) { $result["ops"][$role_id]["rmv"] = array_values($diff); } - $diff = array_diff($a_new["ops"][$role_id], $ops); + $diff = array_diff($new["ops"][$role_id], $ops); if ($diff !== []) { $result["ops"][$role_id]["add"] = array_values($diff); } } - if (isset($a_old["inht"]) || isset($a_new["inht"])) { - if (isset($a_old["inht"]) && !isset($a_new["inht"])) { - $result["inht"]["rmv"] = $a_old["inht"]; - } elseif (!isset($a_old["inht"]) && isset($a_new["inht"])) { - $result["inht"]["add"] = $a_new["inht"]; + if (isset($old["inht"]) || isset($new["inht"])) { + if (isset($old["inht"]) && !isset($new["inht"])) { + $result["inht"]["rmv"] = $old["inht"]; + } elseif (!isset($old["inht"]) && isset($new["inht"])) { + $result["inht"]["add"] = $new["inht"]; } else { - $diff = array_diff($a_old["inht"], $a_new["inht"]); + $diff = array_diff($old["inht"], $new["inht"]); if ($diff !== []) { $result["inht"]["rmv"] = array_values($diff); } - $diff = array_diff($a_new["inht"], $a_old["inht"]); + $diff = array_diff($new["inht"], $old["inht"]); if ($diff !== []) { $result["inht"]["add"] = array_values($diff); } @@ -107,29 +192,29 @@ public static function diffFaPa(array $a_old, array $a_new): array return $result; } - public static function gatherTemplate(int $a_role_ref_id, int $a_role_id): array + public static function gatherTemplate(int $role_ref_id, int $role_id): array { global $DIC; $rbacreview = $DIC->rbac()->review(); - return $rbacreview->getAllOperationsOfRole($a_role_id, $a_role_ref_id); + return $rbacreview->getAllOperationsOfRole($role_id, $role_ref_id); } - public static function diffTemplate(array $a_old, array $a_new): array + public static function diffTemplate(array $old, array $new): array { $result = []; - $types = array_unique(array_merge(array_keys($a_old), array_keys($a_new))); + $types = array_unique(array_merge(array_keys($old), array_keys($new))); foreach ($types as $type) { - if (!isset($a_old[$type])) { - $result[$type]["add"] = $a_new[$type]; - } elseif (!isset($a_new[$type])) { - $result[$type]["rmv"] = $a_old[$type]; + if (!isset($old[$type])) { + $result[$type]["add"] = $new[$type]; + } elseif (!isset($new[$type])) { + $result[$type]["rmv"] = $old[$type]; } else { - $diff = array_diff($a_old[$type], $a_new[$type]); + $diff = array_diff($old[$type], $new[$type]); if ($diff !== []) { $result[$type]["rmv"] = array_values($diff); } - $diff = array_diff($a_new[$type], $a_old[$type]); + $diff = array_diff($new[$type], $old[$type]); if ($diff !== []) { $result[$type]["add"] = array_values($diff); } @@ -138,33 +223,33 @@ public static function diffTemplate(array $a_old, array $a_new): array return $result; } - public static function add(int $a_action, int $a_ref_id, array $a_diff, bool $a_source_ref_id = false): bool + public static function add(int $action, int $ref_id, array $diff, bool $source_ref_id = false): bool { global $DIC; $ilUser = $DIC->user(); $ilDB = $DIC->database(); - if (self::isValidAction($a_action) && count($a_diff)) { - if ($a_source_ref_id) { - $a_diff["src"] = $a_source_ref_id; + if (self::isValidAction($action) && count($diff)) { + if ($source_ref_id) { + $diff["src"] = $source_ref_id; } - $id = $ilDB->nextId('rbac_log'); + $id = $ilDB->nextId(self::LOG_TABLE_NAME); - $ilDB->query("INSERT INTO rbac_log (log_id, user_id, created, ref_id, action, data)" . + $ilDB->query('INSERT INTO ' . self::LOG_TABLE_NAME . ' (log_id, user_id, created, ref_id, action, data)' . " VALUES (" . $ilDB->quote($id, "integer") . "," . $ilDB->quote($ilUser->getId(), "integer") . "," . $ilDB->quote(time(), "integer") . - "," . $ilDB->quote($a_ref_id, "integer") . "," . $ilDB->quote($a_action, "integer") . - "," . $ilDB->quote(serialize($a_diff), "text") . ")"); + "," . $ilDB->quote($ref_id, "integer") . "," . $ilDB->quote($action, "integer") . + "," . $ilDB->quote(serialize($diff), "text") . ")"); return true; } return false; } - protected static function isValidAction(int $a_action): bool + protected static function isValidAction(int $action): bool { if (in_array( - $a_action, + $action, [ self::EDIT_PERMISSIONS, self::MOVE_OBJECT, @@ -181,58 +266,12 @@ protected static function isValidAction(int $a_action): bool return false; } - public static function getLogItems(int $a_ref_id, int $a_limit, int $a_offset, array $a_filter = null): array - { - global $DIC; - - $ilDB = $DIC->database(); - $rbacreview = $DIC->rbac()->review(); - - $where = []; - if ($a_filter) { - if ($a_filter["action"]) { - $where[] = "action = " . $ilDB->quote($a_filter["action"], "integer"); - } - if ($a_filter["date"]["from"]) { - $from = $a_filter["date"]["from"]->get(IL_CAL_UNIX); - $from = strtotime("00:00:00", $from); - $where[] = "created >= " . $ilDB->quote($from, "integer"); - } - if ($a_filter["date"]["to"]) { - $to = $a_filter["date"]["to"]->get(IL_CAL_UNIX); - $to = strtotime("23:59:59", $to); - $where[] = "created <= " . $ilDB->quote($to, "integer"); - } - - if (count($where) > 0) { - $where = array_merge([' AND '], [implode(' AND ', $where)]); - } - } - - $set = $ilDB->query("SELECT COUNT(*) FROM rbac_log WHERE ref_id = " . $ilDB->quote( - $a_ref_id, - "integer" - ) . implode('', $where)); - $res = $ilDB->fetchAssoc($set); - $count = array_pop($res); - - $ilDB->setLimit($a_limit, $a_offset); - $set = $ilDB->query("SELECT * FROM rbac_log WHERE ref_id = " . $ilDB->quote($a_ref_id, "integer") . - implode('', $where) . " ORDER BY created DESC"); - $result = []; - while ($row = $ilDB->fetchAssoc($set)) { - $row["data"] = unserialize($row["data"]); - $result[] = $row; - } - return ["cnt" => $count, "set" => $result]; - } - - public static function delete(int $a_ref_id): void + public static function delete(int $ref_id): void { global $DIC; $ilDB = $DIC->database(); - $ilDB->query("DELETE FROM rbac_log WHERE ref_id = " . $ilDB->quote($a_ref_id, "integer")); + $ilDB->query('DELETE FROM ' . self::LOG_TABLE_NAME . ' WHERE ref_id = ' . $ilDB->quote($ref_id, 'integer')); self::garbageCollection(); } @@ -245,7 +284,7 @@ public static function garbageCollection(): void $settings = ilPrivacySettings::getInstance(); $max = $settings->getRbacLogAge(); - $ilDB->query("DELETE FROM rbac_log WHERE created < " . $ilDB->quote( + $ilDB->query('DELETE FROM ' . self::LOG_TABLE_NAME . ' WHERE created < ' . $ilDB->quote( strtotime("-" . $max . "months"), "integer" )); diff --git a/components/ILIAS/AccessControl/classes/class.ilRbacLogTableGUI.php b/components/ILIAS/AccessControl/classes/class.ilRbacLogTableGUI.php deleted file mode 100755 index bb49238040a7..000000000000 --- a/components/ILIAS/AccessControl/classes/class.ilRbacLogTableGUI.php +++ /dev/null @@ -1,270 +0,0 @@ - - * @ilCtrl_Calls ilRbacLogTableGUI: - * @ingroup ServicesAccessControl - */ -class ilRbacLogTableGUI extends ilTable2GUI -{ - protected array $operations = []; - protected array $filter = []; - protected array $action_map = []; - private int $ref_id; - - public function __construct(object $a_parent_obj, string $a_parent_cmd, int $a_ref_id) - { - global $DIC; - - $this->setId('rbaclog'); - $this->ref_id = $a_ref_id; - - parent::__construct($a_parent_obj, $a_parent_cmd); - $this->setTitle($this->lng->txt('rbac_log')); - $this->setLimit(5); - - $this->addColumn($this->lng->txt('date'), '', '15%'); - $this->addColumn($this->lng->txt('name'), '', '10%'); - $this->addColumn($this->lng->txt('login'), '', '10%'); - $this->addColumn($this->lng->txt('action'), '', '15%'); - $this->addColumn($this->lng->txt('rbac_changes'), '', '50%'); - - $this->setExternalSegmentation(true); - $this->setEnableHeader(true); - $this->setFormAction($this->ctrl->getFormAction($a_parent_obj, $a_parent_cmd)); - $this->setRowTemplate('tpl.rbac_log_row.html', 'components/ILIAS/AccessControl'); - $this->setFilterCommand('applyLogFilter'); - $this->setResetCommand('resetLogFilter'); - - $this->action_map = [ilRbacLog::EDIT_PERMISSIONS => $this->lng->txt('rbac_log_edit_permissions'), - ilRbacLog::MOVE_OBJECT => $this->lng->txt('rbac_log_move_object'), - ilRbacLog::LINK_OBJECT => $this->lng->txt('rbac_log_link_object'), - ilRbacLog::COPY_OBJECT => $this->lng->txt('rbac_log_copy_object'), - ilRbacLog::CREATE_OBJECT => $this->lng->txt('rbac_log_create_object'), - ilRbacLog::EDIT_TEMPLATE => $this->lng->txt('rbac_log_edit_template'), - ilRbacLog::EDIT_TEMPLATE_EXISTING => $this->lng->txt('rbac_log_edit_template_existing'), - ilRbacLog::CHANGE_OWNER => $this->lng->txt('rbac_log_change_owner') - ]; - - $this->initFilter(); - $this->getItems($this->ref_id, $this->filter); - } - - public function initFilter(): void - { - $item = $this->addFilterItemByMetaType('action', ilTable2GUI::FILTER_SELECT); - $item->setOptions(['' => $this->lng->txt('all')] + $this->action_map); - $this->filter['action'] = $item->getValue(); - - $item = $this->addFilterItemByMetaType('date', ilTable2GUI::FILTER_DATE_RANGE); - $this->filter['date'] = $item->getDate(); - } - - protected function getItems(int $a_ref_id, array $a_current_filter = null): void - { - global $DIC; - - $rbacreview = $DIC['rbacreview']; - - $this->determineOffsetAndOrder(); - - foreach ($rbacreview->getOperations() as $op) { - $this->operations[$op['ops_id']] = $op['operation']; - } - - // special case: role folder should display root folder entries - if ($a_ref_id == ROLE_FOLDER_ID) { - $a_ref_id = ROOT_FOLDER_ID; - } - - $data = ilRbacLog::getLogItems($a_ref_id, $this->getLimit(), $this->getOffset(), $a_current_filter); - - $this->setData($data['set']); - $this->setMaxCount((int) $data['cnt']); - } - - protected function fillRow(array $a_set): void - { - $this->tpl->setVariable('DATE', ilDatePresentation::formatDate(new ilDateTime($a_set['created'] ?? 0, IL_CAL_UNIX))); - $name = ilObjUser::_lookupName((int) ($a_set['user_id']) ?? 0); - $this->tpl->setVariable('LASTNAME', $name['lastname'] ?? ''); - $this->tpl->setVariable('FIRSTNAME', $name['firstname'] ?? ''); - $this->tpl->setVariable('LOGIN', $name['login'] ?? ''); - $this->tpl->setVariable('ACTION', $this->action_map[$a_set['action']] ?? ''); - - if ($a_set['action'] == ilRbacLog::CHANGE_OWNER) { - $user = ilObjUser::_lookupFullname($a_set['data'][0] ?? 0); - $changes = [['action' => $this->lng->txt('rbac_log_changed_owner'), 'operation' => $user]]; - } elseif ($a_set['action'] == ilRbacLog::EDIT_TEMPLATE) { - $changes = $this->parseChangesTemplate($a_set['data'] ?? []); - } else { - $changes = $this->parseChangesFaPa($a_set['data'] ?? []); - } - - $this->tpl->setCurrentBlock('changes'); - foreach ($changes as $change) { - $this->tpl->setVariable('CHANGE_ACTION', $change['action'] ?? ''); - $this->tpl->setVariable('CHANGE_OPERATION', $change['operation'] ?? ''); - $this->tpl->parseCurrentBlock(); - } - } - - protected function parseChangesFaPa(array $raw): array - { - $result = []; - - $type = ilObject::_lookupType($this->ref_id, true); - - if (isset($raw['src']) && is_numeric($raw['src'])) { - $obj_id = ilObject::_lookupObjectId($raw['src']); - if ($obj_id) { - $result[] = [ - 'action' => $this->lng->txt('rbac_log_source_object'), - 'operation' => '' . ilObject::_lookupTitle($obj_id) . '' - ]; - } - - // added only - foreach ($raw['ops'] as $role_id => $ops) { - foreach ($ops as $op) { - $result[] = [ - 'action' => sprintf( - $this->lng->txt('rbac_log_operation_add'), - ilObjRole::_getTranslation(ilObject::_lookupTitle((int) $role_id)) - ), - 'operation' => $this->getOPCaption($type, $op) - ]; - } - } - } elseif (isset($raw['ops'])) { - foreach ($raw['ops'] as $role_id => $actions) { - foreach ($actions as $action => $ops) { - foreach ((array) $ops as $op) { - $result[] = [ - 'action' => sprintf( - $this->lng->txt('rbac_log_operation_' . $action), - ilObjRole::_getTranslation(ilObject::_lookupTitle((int) $role_id)) - ), - 'operation' => $this->getOPCaption($type, $op) - ]; - } - } - } - } - - if (isset($raw['inht'])) { - foreach ($raw['inht'] as $action => $role_ids) { - foreach ((array) $role_ids as $role_id) { - $result[] = [ - 'action' => sprintf( - $this->lng->txt('rbac_log_inheritance_' . $action), - ilObjRole::_getTranslation(ilObject::_lookupTitle((int) $role_id)) - ) - ]; - } - } - } - - return $result; - } - - protected function parseChangesTemplate(array $raw): array - { - $result = []; - foreach ($raw as $type => $actions) { - foreach ($actions as $action => $ops) { - foreach ($ops as $op) { - $result[] = ['action' => sprintf( - $this->lng->txt('rbac_log_operation_' . $action), - $this->lng->txt('obj_' . $type) - ), - 'operation' => $this->getOPCaption($type, $op) - ]; - } - } - } - return $result; - } - - /** - * @param array|int|string $a_op - */ - protected function getOPCaption(string $a_type, $a_op): string - { - // #11717 - if (is_array($a_op)) { - $res = []; - foreach ($a_op as $op) { - $res[] = $this->getOPCaption($a_type, $op); - } - return implode(', ', $res); - } - - if (is_numeric($a_op) && isset($this->operations[$a_op])) { - $op_id = $this->operations[$a_op]; - if (substr($op_id, 0, 7) != 'create_') { - $perm = $this->getTranslationFromPlugin($a_type, $op_id); - - if ($this->notTranslated($perm, $op_id)) { - if ($this->lng->exists($a_type . '_' . $op_id . '_short')) { - $perm = $this->lng->txt($a_type . '_' . $op_id . '_short'); - } else { - $perm = $this->lng->txt($op_id); - } - } - - return $perm; - } else { - $type = substr($op_id, 7, strlen($op_id)); - $perm = $this->getTranslationFromPlugin($type, $op_id); - - if ($this->notTranslated($perm, $op_id)) { - $perm = $this->lng->txt('rbac_' . $op_id); - } - - return $perm; - } - } - return ''; - } - - /** - * Check the type for plugin and get the translation for op_id - */ - protected function getTranslationFromPlugin(string $type, string $op_id): ?string - { - global $objDefinition; - - if ($objDefinition->isPlugin($type)) { - return ilObjectPlugin::lookupTxtById($type, $op_id); - } - return null; - } - - /** - * Check the op is translated correctly - */ - protected function notTranslated(?string $perm, string $op_id): bool - { - return is_null($perm) || (strpos($perm, $op_id) !== false); - } -} diff --git a/components/ILIAS/AccessControl/classes/class.ilRoleXmlExport.php b/components/ILIAS/AccessControl/classes/class.ilRoleXmlExport.php index bc98c0a64df2..a708f097db70 100755 --- a/components/ILIAS/AccessControl/classes/class.ilRoleXmlExport.php +++ b/components/ILIAS/AccessControl/classes/class.ilRoleXmlExport.php @@ -120,7 +120,9 @@ private function writeRole(int $a_role_id, int $a_rolf): void $this->xmlStartTag('operations'); foreach ($this->rbacreview->getAllOperationsOfRole($a_role_id, $a_rolf) as $obj_group => $operations) { foreach ($operations as $ops_id) { - $this->xmlElement('operation', ['group' => $obj_group], trim($this->operations[$ops_id])); + if (isset($this->operations[$ops_id])) { + $this->xmlElement('operation', ['group' => $obj_group], trim($this->operations[$ops_id])); + } } } $this->xmlEndTag('operations'); diff --git a/components/ILIAS/AccessControl/src/Log/Table.php b/components/ILIAS/AccessControl/src/Log/Table.php new file mode 100644 index 000000000000..3ada3b10bd29 --- /dev/null +++ b/components/ILIAS/AccessControl/src/Log/Table.php @@ -0,0 +1,354 @@ + + */ + private ?array $filter_data; + + private array $action_map = []; + private array $operations = []; + + public function __construct( + private readonly \ilRbacLog $rbac_log, + private readonly UIFactory $ui_factory, + private readonly DataFactory $data_factory, + private readonly \ilLanguage $lng, + private readonly \ilCtrl $ctrl, + private readonly \ilUIService $ui_service, + private readonly \ilObjectDefinition $object_definition, + private readonly RequestInterface $request, + \ilRbacReview $rbac_review, + private readonly \ilObjUser $current_user, + private readonly \ilObjectGUI $gui_object + ) { + $this->action_map = [ + \ilRbacLog::EDIT_PERMISSIONS => $this->lng->txt('rbac_log_edit_permissions'), + \ilRbacLog::MOVE_OBJECT => $this->lng->txt('rbac_log_move_object'), + \ilRbacLog::LINK_OBJECT => $this->lng->txt('rbac_log_link_object'), + \ilRbacLog::COPY_OBJECT => $this->lng->txt('rbac_log_copy_object'), + \ilRbacLog::CREATE_OBJECT => $this->lng->txt('rbac_log_create_object'), + \ilRbacLog::EDIT_TEMPLATE => $this->lng->txt('rbac_log_edit_template'), + \ilRbacLog::EDIT_TEMPLATE_EXISTING => $this->lng->txt('rbac_log_edit_template_existing'), + \ilRbacLog::CHANGE_OWNER => $this->lng->txt('rbac_log_change_owner') + ]; + + foreach ($rbac_review->getOperations() as $op) { + $this->operations[$op['ops_id']] = $op['operation']; + } + } + + public function getTableAndFilter(): array + { + return [ + $this->getFilter(), + $this->getTable() + ]; + } + + private function getTable(): DataTable + { + $cf = $this->ui_factory->table()->column(); + + return $this->ui_factory->table()->data( + $this->lng->txt('rbac_log'), + [ + self::COLUMN_DATE => $cf->date( + $this->lng->txt('date'), + $this->buildUserDateTimeFormat() + ), + self::COLUMN_NAME => $cf->text($this->lng->txt('name')), + self::COLUMN_LOGIN => $cf->text($this->lng->txt('login')), + self::COLUMN_ACTION => $cf->text($this->lng->txt('action')), + self::COLUMN_CHANGES => $cf->text($this->lng->txt('rbac_changes')) + ->withIsSortable(false) + ], + $this + )->withRequest($this->request); + } + + private function getFilter(): Filter + { + $ff = $this->ui_factory->input()->field(); + + $inputs = [ + self::FILTER_FIELD_ACTION => $ff->multiSelect( + $this->lng->txt('action'), + $this->action_map + ), + self::FILTER_FIELD_PERIOD => $ff->duration($this->lng->txt('date')) + ]; + + $active = array_fill(0, count($inputs), true); + + $filter = $this->ui_service->filter()->standard( + self::FILTER_ID, + $this->ctrl->getFormActionByClass([get_class($this->gui_object), \ilPermissionGUI::class], 'log'), + $inputs, + $active, + true, + true + ); + $this->filter_data = $this->applyFilterValuesTrafos($this->ui_service->filter()->getData($filter)); + return $filter; + } + + public function getRows( + DataRowBuilder $row_builder, + array $visible_column_ids, + Range $range, + Order $order, + ?array $filter_data, + ?array $additional_parameters + ): \Generator { + $log_data = $this->rbac_log->getLogItems( + $this->getRefId(), + $range, + $order, + $this->filter_data + ); + + foreach ($log_data as $entry) { + $user_data = \ilObjUser::_lookupName($entry['user_id']); + yield $row_builder->buildDataRow( + (string) $entry['log_id'], + [ + self::COLUMN_DATE => (new \DateTimeImmutable('@' . $entry['created'])) + ->setTimezone(new \DateTimeZone($this->current_user->getTimeZone())), + self::COLUMN_NAME => "{$user_data['lastname']}, {$user_data['firstname']}", + self::COLUMN_LOGIN => $user_data['login'], + self::COLUMN_ACTION => $this->action_map[$entry['action']] ?? '', + self::COLUMN_CHANGES => $this->buildChangeColumn($entry['action'], $entry['data'] ?? []) + ] + ); + } + } + + public function getTotalRowCount( + ?array $filter_data, + ?array $additional_parameters + ): ?int { + return $this->rbac_log->getLogItemsCount($this->getRefId(), $filter_data); + } + + private function getRefId(): int + { + // special case: role folder should display root folder entries + if ($this->gui_object->getRefId() === ROLE_FOLDER_ID) { + return ROOT_FOLDER_ID; + } + return $this->gui_object->getRefId(); + } + + private function buildUserDateTimeFormat(): DateFormat + { + $user_format = $this->current_user->getDateFormat(); + if ($this->current_user->getTimeFormat() == \ilCalendarSettings::TIME_FORMAT_24) { + return $this->data_factory->dateFormat()->withTime24($user_format); + } + return $this->data_factory->dateFormat()->withTime12($user_format); + } + + private function applyFilterValuesTrafos(array $filter_values): array + { + $transformed_values = [ + 'action' => $filter_values['action'] + ]; + if (isset($filter_values['period'][0])) { + $transformed_values['from'] = (new \DateTimeImmutable( + $filter_values['period'][0], + new \DateTimeZone($this->current_user->getTimeZone()) + ))->getTimestamp(); + } + if (isset($filter_values['period'][1])) { + $transformed_values['to'] = (new \DateTimeImmutable( + $filter_values['period'][1] . '23:59:59', + new \DateTimeZone($this->current_user->getTimeZone()) + ))->getTimestamp(); + } + return $transformed_values; + } + + private function buildChangeColumn(int $action, array $data): string + { + if ($action === \ilRbacLog::CHANGE_OWNER) { + $user_name = \ilObjUser::_lookupFullname($data[0] ?? 0); + return "{$this->lng->txt('rbac_log_changed_owner')}: {$user_name}"; + } + + if ($action === \ilRbacLog::EDIT_TEMPLATE) { + return $this->parseChangesTemplate($data); + } + + return $this->parseChangesFaPa($data); + } + + private function parseChangesFaPa(array $raw): string + { + $result = []; + + if (isset($raw['src']) && is_int($raw['src'])) { + $obj_id = \ilObject::_lookupObjectId($raw['src']); + if ($obj_id) { + $result[] = "{$this->lng->txt('rbac_log_source_object')}: " + . '' + . \ilObject::_lookupTitle($obj_id) . ''; + } + + // added only + foreach ($raw['ops'] as $role_id => $ops) { + foreach ($ops as $op) { + $result[] = sprintf( + $this->lng->txt('rbac_log_operation_add'), + \ilObjRole::_getTranslation(\ilObject::_lookupTitle((int) $role_id)) + ) . ': ' . $this->getOPCaption($this->gui_object->getObject()->getType(), $op); + } + } + } elseif (isset($raw['ops'])) { + foreach ($raw['ops'] as $role_id => $actions) { + foreach ($actions as $action => $ops) { + foreach ((array) $ops as $op) { + $result[] = sprintf( + $this->lng->txt('rbac_log_operation_' . $action), + \ilObjRole::_getTranslation(\ilObject::_lookupTitle((int) $role_id)) + ) . ': ' . $this->getOPCaption($this->gui_object->getObject()->getType(), $op); + } + } + } + } + + if (isset($raw['inht'])) { + foreach ($raw['inht'] as $action => $role_ids) { + foreach ((array) $role_ids as $role_id) { + $result[] = sprintf( + $this->lng->txt('rbac_log_inheritance_' . $action), + \ilObjRole::_getTranslation(\ilObject::_lookupTitle((int) $role_id)) + ); + } + } + } + + return implode('
', $result); + } + + private function parseChangesTemplate(array $raw): string + { + $result = []; + foreach ($raw as $type => $actions) { + foreach ($actions as $action => $ops) { + foreach ($ops as $op) { + $result[] = sprintf( + $this->lng->txt('rbac_log_operation_' . $action), + $this->lng->txt('obj_' . $type) + ) . ': ' . $this->getOPCaption($type, $op); + } + } + } + return implode('
', $result); + } + + private function getOPCaption(string $type, array|int|string $op): string + { + if (is_array($op)) { + return array_reduce( + $op, + fn(string $c, array|int|string $v) => $c === '' + ? $this->getOPCaption($type, $v) + : $c . ',' . $this->getOPCaption($type, $v), + '' + ); + } + + if (!isset($this->operations[$op])) { + return ''; + } + + $op_id = $this->operations[$op]; + if (substr($op_id, 0, 7) !== 'create_') { + return $this->getNonCreateTranslation($type, $op_id); + } + + return $this->getCreateTranslation($type, $op_id); + } + + private function getNonCreateTranslation(string $type, string $op_id): string + { + $perm = $this->getTranslationFromPlugin($type, $op_id); + if ($this->isTranslated($perm, $op_id)) { + return $perm; + } + + if ($this->lng->exists($type . '_' . $op_id . '_short')) { + return $this->lng->txt($type . '_' . $op_id . '_short'); + } + + return $this->lng->txt($op_id); + } + + private function getCreateTranslation(string $type, string $op_id): string + { + $obj_type = substr($op_id, 7, strlen($op_id)); + $perm = $this->getTranslationFromPlugin($obj_type, $op_id); + + if ($this->isTranslated($perm, $op_id)) { + return $perm; + } + + return $this->lng->txt('rbac_' . $op_id); + } + + private function getTranslationFromPlugin(string $type, string $op_id): ?string + { + if ($this->object_definition->isPlugin($type)) { + return \ilObjectPlugin::lookupTxtById($type, $op_id); + } + return null; + } + + private function isTranslated(?string $perm, string $op_id): bool + { + return $perm !== null && strpos($perm, $op_id) === false; + } +} diff --git a/components/ILIAS/AccessControl/templates/default/tpl.rbac_template_permissions.html b/components/ILIAS/AccessControl/templates/default/tpl.rbac_template_permissions.html index 0177731c2f0a..485526f70918 100755 --- a/components/ILIAS/AccessControl/templates/default/tpl.rbac_template_permissions.html +++ b/components/ILIAS/AccessControl/templates/default/tpl.rbac_template_permissions.html @@ -3,3 +3,4 @@
{OPTIONS_TABLE} +{DELETION_MODAL} diff --git a/components/ILIAS/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php b/components/ILIAS/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php index fac51fe93b0c..ef041be8317d 100755 --- a/components/ILIAS/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php +++ b/components/ILIAS/Authentication/classes/Frontend/class.ilAuthFrontendCLI.php @@ -1,7 +1,5 @@ - * - */ +declare(strict_types=1); + class ilAuthFrontendCLI extends ilAuthFrontend implements ilAuthFrontendInterface { + /** + * This overwrites ilAuthFrontend::checkIp used in ilAuthFrontend::authenticate + * since CLI does not set $_SERVER['REMOTE_ADDR']! + */ + protected function checkIp(ilObjUser $user): bool + { + return true; + } } diff --git a/components/ILIAS/Authentication/classes/LoginPage/LoginPageLanguagesOverviewTable.php b/components/ILIAS/Authentication/classes/LoginPage/LoginPageLanguagesOverviewTable.php index 7a5fa365a503..065a654c4763 100644 --- a/components/ILIAS/Authentication/classes/LoginPage/LoginPageLanguagesOverviewTable.php +++ b/components/ILIAS/Authentication/classes/LoginPage/LoginPageLanguagesOverviewTable.php @@ -26,7 +26,7 @@ use Psr\Http\Message\ServerRequestInterface; use ilAuthLoginPageEditorSettings; use ilLanguage; -use ilCtrl; +use ilCtrlInterface; class LoginPageLanguagesOverviewTable implements UI\Component\Table\DataRetrieval { @@ -42,7 +42,7 @@ class LoginPageLanguagesOverviewTable implements UI\Component\Table\DataRetrieva private ?array $records = null; public function __construct( - private readonly ilCtrl $ctrl, + private readonly ilCtrlInterface $ctrl, private readonly ilLanguage $lng, \ILIAS\HTTP\Services $http, private readonly \ILIAS\UI\Factory $ui_factory, diff --git a/components/ILIAS/Authentication/classes/Setup/AbandonLoadDependantSessionDatabaseUpdateObjective.php b/components/ILIAS/Authentication/classes/Setup/AbandonLoadDependantSessionDatabaseUpdateObjective.php new file mode 100644 index 000000000000..68bee1e819df --- /dev/null +++ b/components/ILIAS/Authentication/classes/Setup/AbandonLoadDependantSessionDatabaseUpdateObjective.php @@ -0,0 +1,70 @@ +db = $db; + } + + public function step_1(): void + { + $this->db->manipulate( + 'DELETE FROM settings WHERE ' . $this->db->in( + 'keyword', + [ + 'session_handling_type', + 'session_max_count', + 'session_min_idle', + 'session_max_idle', + 'session_max_idle_after_first_request' + ] + ) + ); + + if ($this->db->tableExists('usr_session_log')) { + $this->db->dropTable('usr_session_log', false); + } + + if ($this->db->tableColumnExists('usr_session_stats', 'max_sessions')) { + $this->db->dropTableColumn('usr_session_stats', 'max_sessions'); + } + + if ($this->db->tableColumnExists('usr_session_stats', 'closed_limit')) { + $this->db->dropTableColumn('usr_session_stats', 'closed_limit'); + } + + if ($this->db->tableColumnExists('usr_session_stats', 'closed_idle')) { + $this->db->dropTableColumn('usr_session_stats', 'closed_idle'); + } + + if ($this->db->tableColumnExists('usr_session_stats', 'closed_idle_first')) { + $this->db->dropTableColumn('usr_session_stats', 'closed_idle_first'); + } + } +} diff --git a/components/ILIAS/Authentication/classes/class.ilAuthLoginPageEditorGUI.php b/components/ILIAS/Authentication/classes/class.ilAuthLoginPageEditorGUI.php index 8330af9fb40d..3015d6954d04 100755 --- a/components/ILIAS/Authentication/classes/class.ilAuthLoginPageEditorGUI.php +++ b/components/ILIAS/Authentication/classes/class.ilAuthLoginPageEditorGUI.php @@ -24,7 +24,7 @@ */ class ilAuthLoginPageEditorGUI { - private ilCtrl $ctrl; + private ilCtrlInterface $ctrl; private ilLanguage $lng; private ilGlobalTemplateInterface $tpl; private ilTabsGUI $tabs; @@ -32,10 +32,7 @@ class ilAuthLoginPageEditorGUI private \ILIAS\Refinery\Factory $refinery; private \ILIAS\UI\Factory $ui_factory; private \ILIAS\UI\Renderer $ui_renderer; - private \ILIAS\Style\Content\Object\ObjectFacade $content_style_domain; - - //variables from requests private ?string $redirect_source = null; private ?int $key = null; diff --git a/components/ILIAS/Authentication/classes/class.ilAuthLoginPageEditorSettings.php b/components/ILIAS/Authentication/classes/class.ilAuthLoginPageEditorSettings.php index e57e8049da6f..bb95c76c1190 100755 --- a/components/ILIAS/Authentication/classes/class.ilAuthLoginPageEditorSettings.php +++ b/components/ILIAS/Authentication/classes/class.ilAuthLoginPageEditorSettings.php @@ -18,50 +18,37 @@ declare(strict_types=1); -/** - * Storage of editor settings - * - * @author Stefan Meyer - */ class ilAuthLoginPageEditorSettings { public const MODE__UNDEFINED = 0; public const MODE_IPE = 2; - private array $languages = []; + private static ?self $instance = null; - private static ?ilAuthLoginPageEditorSettings $instance = null; + /** + * @var array + */ + private array $languages = []; private ilSetting $storage; - - private int $mode = 0; - + private int $mode = self::MODE__UNDEFINED; private ilLanguage $lng; - public function __construct() + private function __construct() { global $DIC; - $this->lng = $DIC->language(); + $this->lng = $DIC->language(); $this->storage = new ilSetting('login_editor'); + $this->read(); } - /** - * Get singelton instance - * @return ilAuthLoginPageEditorSettings - */ - public static function getInstance(): ilAuthLoginPageEditorSettings + public static function getInstance(): self { - if (self::$instance) { - return self::$instance; - } - return self::$instance = new ilAuthLoginPageEditorSettings(); + return self::$instance ?? (self::$instance = new self()); } - /** - * @return ilSetting - */ - protected function getStorage(): ilSetting + private function getStorage(): ilSetting { return $this->storage; } @@ -76,41 +63,29 @@ public function getMode(): int return $this->mode; } - /** - * Get ilias editor language - * @param string $a_langkey - * @return string - */ public function getIliasEditorLanguage(string $a_langkey): string { if ($this->isIliasEditorEnabled($a_langkey)) { return $a_langkey; } + if ($this->isIliasEditorEnabled($this->lng->getDefaultLanguage())) { return $this->lng->getDefaultLanguage(); } + return ''; } - /** - * Enable editor for language - */ public function enableIliasEditor(string $a_langkey, bool $a_status): void { $this->languages[$a_langkey] = $a_status; } - /** - * Check if ilias editor is enabled for a language - */ public function isIliasEditorEnabled(string $a_langkey): bool { return $this->languages[$a_langkey] ?? false; } - /** - * Update settings - */ public function update(): void { $this->getStorage()->set('mode', (string) $this->getMode()); @@ -120,17 +95,13 @@ public function update(): void } } - /** - * Read settings - */ public function read(): void { $this->setMode((int) $this->getStorage()->get('mode', (string) self::MODE_IPE)); - // Language settings $this->languages = []; foreach ($this->lng->getInstalledLanguages() as $lngkey) { - $this->enableIliasEditor($lngkey, (bool) $this->getStorage()->get($lngkey, "")); + $this->enableIliasEditor($lngkey, (bool) $this->getStorage()->get($lngkey, '')); } } } diff --git a/components/ILIAS/Authentication/classes/class.ilSession.php b/components/ILIAS/Authentication/classes/class.ilSession.php index ac280f7b422d..44af1fde53d1 100755 --- a/components/ILIAS/Authentication/classes/class.ilSession.php +++ b/components/ILIAS/Authentication/classes/class.ilSession.php @@ -25,24 +25,6 @@ */ class ilSession { - /** - * - * Constant for fixed dession handling - * - * @var integer - * - */ - public const SESSION_HANDLING_FIXED = 0; - - /** - * - * Constant for load dependend session handling - * - * @var integer - * - */ - public const SESSION_HANDLING_LOAD_DEPENDENT = 1; - /** * Constant for reason of session destroy * @@ -50,9 +32,6 @@ class ilSession */ public const SESSION_CLOSE_USER = 1; // manual logout public const SESSION_CLOSE_EXPIRE = 2; // has expired - public const SESSION_CLOSE_FIRST = 3; // kicked by session control (first abidencer) - public const SESSION_CLOSE_IDLE = 4; // kickey by session control (ilde time) - public const SESSION_CLOSE_LIMIT = 5; // kicked by session control (limit reached) public const SESSION_CLOSE_LOGIN = 6; // anonymous => login public const SESSION_CLOSE_PUBLIC = 7; // => anonymous public const SESSION_CLOSE_TIME = 8; // account time limit reached @@ -376,73 +355,31 @@ public static function _duplicate(string $a_session_id): string } /** - * * Returns the expiration timestamp in seconds - * - * @param boolean If passed, the value for fixed session is returned - * @return integer The expiration timestamp in seconds - * @static - * */ - public static function getExpireValue(bool $fixedMode = false): int + public static function getExpireValue(): int { - global $DIC; - - if ($fixedMode) { - // fixed session - return time() + self::getIdleValue($fixedMode); - } - - /** @var ilSetting $ilSetting */ - $ilSetting = $DIC['ilSetting']; - if ($ilSetting->get('session_handling_type', (string) self::SESSION_HANDLING_FIXED) === (string) self::SESSION_HANDLING_FIXED) { - return time() + self::getIdleValue($fixedMode); - } - - if ($ilSetting->get('session_handling_type', (string) self::SESSION_HANDLING_FIXED) === (string) self::SESSION_HANDLING_LOAD_DEPENDENT) { - // load dependent session settings - $max_idle = (int) ($ilSetting->get('session_max_idle') ?? ilSessionControl::DEFAULT_MAX_IDLE); - return time() + $max_idle * 60; - } - return time() + ilSessionControl::DEFAULT_MAX_IDLE * 60; + return time() + self::getIdleValue(); } /** - * * Returns the idle time in seconds - * - * @param boolean If passed, the value for fixed session is returned - * @return integer The idle time in seconds */ - public static function getIdleValue(bool $fixedMode = false): int + public static function getIdleValue(): int { global $DIC; - $ilSetting = $DIC['ilSetting']; $ilClientIniFile = $DIC['ilClientIniFile']; - if ($fixedMode || $ilSetting->get('session_handling_type', (string) self::SESSION_HANDLING_FIXED) === (string) self::SESSION_HANDLING_FIXED) { - // fixed session - return (int) $ilClientIniFile->readVariable('session', 'expire'); - } - - if ($ilSetting->get('session_handling_type', (string) self::SESSION_HANDLING_FIXED) === (string) self::SESSION_HANDLING_LOAD_DEPENDENT) { - // load dependent session settings - return ((int) $ilSetting->get('session_max_idle', (string) (ilSessionControl::DEFAULT_MAX_IDLE))) * 60; - } - return ilSessionControl::DEFAULT_MAX_IDLE * 60; + return (int) $ilClientIniFile->readVariable('session', 'expire'); } /** - * * Returns the session expiration value - * - * @return integer The expiration value in seconds - * */ public static function getSessionExpireValue(): int { - return self::getIdleValue(true); + return self::getIdleValue(); } /** diff --git a/components/ILIAS/Authentication/classes/class.ilSessionControl.php b/components/ILIAS/Authentication/classes/class.ilSessionControl.php index 4610d869bc27..812a88850c7b 100755 --- a/components/ILIAS/Authentication/classes/class.ilSessionControl.php +++ b/components/ILIAS/Authentication/classes/class.ilSessionControl.php @@ -27,10 +27,7 @@ class ilSessionControl * default value for settings that have not * been defined in setup or administration yet */ - public const DEFAULT_MAX_COUNT = 0; public const DEFAULT_MIN_IDLE = 15; - public const DEFAULT_MAX_IDLE = 30; - public const DEFAULT_MAX_IDLE_AFTER_FIRST_REQUEST = 1; public const DEFAULT_ALLOW_CLIENT_MAINTENANCE = 1; /** @@ -39,12 +36,7 @@ class ilSessionControl * @var array $setting_fields */ private static array $setting_fields = array( - 'session_max_count', - 'session_min_idle', - 'session_max_idle', - 'session_max_idle_after_first_request', 'session_allow_client_maintenance', - 'session_handling_type' ); /** @@ -117,17 +109,7 @@ public static function handleLoginEvent(string $a_login, ilAuthSession $auth_ses ilSession::set(self::SESSION_TYPE_KEY, $type); self::debug(__METHOD__ . " --> update sessions type to (" . $type . ")"); - // do not handle login event in fixed duration mode - if ((int) $ilSetting->get('session_handling_type', (string) ilSession::SESSION_HANDLING_FIXED) !== ilSession::SESSION_HANDLING_LOAD_DEPENDENT) { - return true; - } - - if (in_array($type, self::$session_types_controlled, true)) { - //TODO rework this, as it did return value of a void method call - self::checkCurrentSessionIsAllowed($auth_session, $user_id); - return true; - } - return false; + return true; } /** @@ -135,100 +117,6 @@ public static function handleLoginEvent(string $a_login, ilAuthSession $auth_ses */ public static function handleLogoutEvent(): void { - global $DIC; - - $ilSetting = $DIC['ilSetting']; - - // do not handle logout event in fixed duration mode - if ((int) $ilSetting->get('session_handling_type', '0') !== 1) { - return; - } - - ilSession::set('SessionType', self::SESSION_TYPE_UNKNOWN); - self::debug(__METHOD__ . " --> reset sessions type to (" . ilSession::get('SessionType') . ")"); - - // session_destroy() is called in auth, so raw data will be updated - - self::removeSessionCookie(); - } - - /** - * checks wether the current session exhaust the limit of sessions - * when limit is reached it deletes "firstRequestAbidencer" and checks again - * when limit is still reached it deletes "oneMinIdleSession" and checks again - * when limit is still reached the current session will be logged out - */ - private static function checkCurrentSessionIsAllowed(ilAuthSession $auth, int $a_user_id): void - { - global $DIC; - - $ilSetting = $DIC['ilSetting']; - - $max_sessions = (int) $ilSetting->get('session_max_count', (string) self::DEFAULT_MAX_COUNT); - - if ($max_sessions > 0) { - // get total number of sessions - $num_sessions = self::getExistingSessionCount(self::$session_types_controlled); - - self::debug(__METHOD__ . "--> total existing sessions (" . $num_sessions . ")"); - - if (($num_sessions + 1) > $max_sessions) { - self::debug(__METHOD__ . ' --> limit for session pool reached, but try kicking some first request abidencer'); - - self::kickFirstRequestAbidencer(self::$session_types_controlled); - - // get total number of sessions again - $num_sessions = self::getExistingSessionCount(self::$session_types_controlled); - - if (($num_sessions + 1) > $max_sessions) { - self::debug(__METHOD__ . ' --> limit for session pool still reached so try kick one min idle session'); - - self::kickOneMinIdleSession(self::$session_types_controlled); - - // get total number of sessions again - $num_sessions = self::getExistingSessionCount(self::$session_types_controlled); - - if (($num_sessions + 1) > $max_sessions) { - self::debug(__METHOD__ . ' --> limit for session pool still reached so logout session (' . session_id() . ') and trigger event'); - - ilSession::setClosingContext(ilSession::SESSION_CLOSE_LIMIT); - - // as the session is opened and closed in one request, there - // is no proper session yet and we have to do this ourselves - ilSessionStatistics::createRawEntry( - session_id(), - ilSession::get(self::SESSION_TYPE_KEY), - time(), - $a_user_id - ); - - $auth->logout(); - - // Trigger reachedSessionPoolLimit Event - $ilAppEventHandler = $DIC['ilAppEventHandler']; - $ilAppEventHandler->raise( - 'components/ILIAS/Authentication', - 'reachedSessionPoolLimit', - array() - ); - - // auth won't do this, we need to close session properly - // already done in new implementation - // session_destroy(); - - ilUtil::redirect('login.php?reached_session_limit=true'); - } else { - self::debug(__METHOD__ . ' --> limit of session pool not reached anymore after kicking one min idle session'); - } - } else { - self::debug(__METHOD__ . ' --> limit of session pool not reached anymore after kicking some first request abidencer'); - } - } else { - self::debug(__METHOD__ . ' --> limit for session pool not reached yet'); - } - } else { - self::debug(__METHOD__ . ' --> limit for session pool not set so check is bypassed'); - } } /** @@ -250,79 +138,6 @@ public static function getExistingSessionCount(array $a_types): int return (int) $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)->num_sessions; } - /** - * if sessions exist that relates to given session types - * and idled longer than min idle parameter, this method - * deletes one of these sessions - */ - private static function kickOneMinIdleSession(array $a_types): void - { - global $DIC; - - $ilDB = $DIC['ilDB']; - $ilSetting = $DIC['ilSetting']; - - $ts = time(); - $min_idle = (int) $ilSetting->get('session_min_idle', (string) self::DEFAULT_MIN_IDLE) * 60; - $max_idle = (int) $ilSetting->get('session_max_idle', (string) self::DEFAULT_MAX_IDLE) * 60; - - $query = "SELECT session_id,expires FROM usr_session WHERE expires >= %s " . - "AND (expires - %s) < (%s - %s) " . - "AND " . $ilDB->in('type', $a_types, false, 'integer') . " ORDER BY expires"; - - $res = $ilDB->queryF( - $query, - array('integer', 'integer', 'integer', 'integer'), - array($ts, $ts, $max_idle, $min_idle) - ); - - if ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) { - ilSession::_destroy($row->session_id, ilSession::SESSION_CLOSE_IDLE, $row->expires); - - self::debug(__METHOD__ . ' --> successfully deleted one min idle session'); - - return; - } - self::debug(__METHOD__ . ' --> no min idle session available for deletion'); - } - - /** - * kicks sessions of users that abidence after login - * so people could not login and go for coffe break ;-) - */ - private static function kickFirstRequestAbidencer(array $a_types): void - { - global $DIC; - - $ilDB = $DIC['ilDB']; - $ilSetting = $DIC['ilSetting']; - - $max_idle_after_first_request = (int) $ilSetting->get('session_max_idle_after_first_request') * 60; - - if ((int) $max_idle_after_first_request === 0) { - return; - } - - $query = "SELECT session_id,expires FROM usr_session WHERE " . - "(ctime - createtime) < %s " . - "AND (%s - createtime) > %s " . - "AND " . $ilDB->in('type', $a_types, false, 'integer'); - - $res = $ilDB->queryF( - $query, - array('integer', 'integer', 'integer'), - array($max_idle_after_first_request, time(), $max_idle_after_first_request) - ); - - $session_ids = array(); - while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) { - $session_ids[$row->session_id] = $row->expires; - } - ilSession::_destroy($session_ids, ilSession::SESSION_CLOSE_FIRST, true); - - self::debug(__METHOD__ . ' --> Finished kicking first request abidencer'); - } - /** * checks if session exists for given id * and if it is still valid diff --git a/components/ILIAS/Authentication/classes/class.ilSessionReminder.php b/components/ILIAS/Authentication/classes/class.ilSessionReminder.php index 1283ef693f7a..3718995491c9 100755 --- a/components/ILIAS/Authentication/classes/class.ilSessionReminder.php +++ b/components/ILIAS/Authentication/classes/class.ilSessionReminder.php @@ -60,16 +60,7 @@ public static function isGloballyActivated(): bool $ilSetting = $DIC['ilSetting']; - $isSessionReminderEnabled = (bool) $ilSetting->get('session_reminder_enabled', null); - $sessionHandlingMode = (int) $ilSetting->get( - 'session_handling_type', - (string) ilSession::SESSION_HANDLING_FIXED - ); - - return ( - $isSessionReminderEnabled && - $sessionHandlingMode === ilSession::SESSION_HANDLING_FIXED - ); + return (bool) $ilSetting->get('session_reminder_enabled'); } public function __construct(ilObjUser $user, ClockInterface $clock) @@ -89,7 +80,7 @@ private function init(): void )) * 60 ); - $this->setExpirationTime(ilSession::getIdleValue(true) + $this->clock->now()->getTimestamp()); + $this->setExpirationTime(ilSession::getIdleValue() + $this->clock->now()->getTimestamp()); $this->setCurrentTime($this->clock->now()->getTimestamp()); $this->calculateSecondsUntilExpiration(); diff --git a/components/ILIAS/Authentication/classes/class.ilSessionStatistics.php b/components/ILIAS/Authentication/classes/class.ilSessionStatistics.php index c1cd92316973..9e03b6e78084 100755 --- a/components/ILIAS/Authentication/classes/class.ilSessionStatistics.php +++ b/components/ILIAS/Authentication/classes/class.ilSessionStatistics.php @@ -281,9 +281,6 @@ public static function aggregateRawHelper(int $a_begin, int $a_end): void // "relevant" closing types $separate_closed = array(ilSession::SESSION_CLOSE_USER, ilSession::SESSION_CLOSE_EXPIRE, - ilSession::SESSION_CLOSE_IDLE, - ilSession::SESSION_CLOSE_FIRST, - ilSession::SESSION_CLOSE_LIMIT, ilSession::SESSION_CLOSE_LOGIN); // gather/process data (build event timeline) @@ -368,11 +365,6 @@ public static function aggregateRawHelper(int $a_begin, int $a_end): void } unset($events); - - // do we (really) need a log here? - // $max_sessions = (int)$ilSetting->get("session_max_count", ilSessionControl::DEFAULT_MAX_COUNT); - $max_sessions = self::getLimitForSlot($a_begin); - // save aggregated data $fields = array( "active_min" => array("integer", $active_min), @@ -382,12 +374,8 @@ public static function aggregateRawHelper(int $a_begin, int $a_end): void "opened" => array("integer", $opened_counter), "closed_manual" => array("integer", (int) ($closed_counter[ilSession::SESSION_CLOSE_USER] ?? 0)), "closed_expire" => array("integer", (int) ($closed_counter[ilSession::SESSION_CLOSE_EXPIRE] ?? 0)), - "closed_idle" => array("integer", (int) ($closed_counter[ilSession::SESSION_CLOSE_IDLE] ?? 0)), - "closed_idle_first" => array("integer", (int) ($closed_counter[ilSession::SESSION_CLOSE_FIRST] ?? 0)), - "closed_limit" => array("integer", (int) ($closed_counter[ilSession::SESSION_CLOSE_LIMIT] ?? 0)), "closed_login" => array("integer", (int) ($closed_counter[ilSession::SESSION_CLOSE_LOGIN] ?? 0)), "closed_misc" => array("integer", (int) ($closed_counter[0] ?? 0)), - "max_sessions" => array("integer", $max_sessions) ); $ilDB->update( "usr_session_stats", @@ -415,51 +403,6 @@ protected static function deleteAggregatedRaw($a_now): void " WHERE start_time <= " . $ilDB->quote($cut, "integer")); } - /** - * Get latest slot during which sessions were maxed out - */ - public static function getLastMaxedOut(): int - { - global $DIC; - - $ilDB = $DIC['ilDB']; - - $sql = "SELECT max(slot_end) latest FROM usr_session_stats" . - " WHERE active_max >= max_sessions" . - " AND max_sessions > " . $ilDB->quote(0, "integer"); - $res = $ilDB->query($sql); - $row = $ilDB->fetchAssoc($res); - if ($row["latest"]) { - return (int) $row["latest"]; - } - return 0; - } - - /** - * Get maxed out duration in given timeframe - * - * @return ?int seconds - */ - public static function getMaxedOutDuration(int $a_from, int $a_to): ?int - { - global $DIC; - - $ilDB = $DIC['ilDB']; - - $sql = "SELECT SUM(slot_end-slot_begin) dur FROM usr_session_stats" . - " WHERE active_max >= max_sessions" . - " AND max_sessions > " . $ilDB->quote(0, "integer") . - " AND slot_end > " . $ilDB->quote($a_from, "integer") . - " AND slot_begin < " . $ilDB->quote($a_to, "integer"); - $res = $ilDB->query($sql); - $row = $ilDB->fetchAssoc($res); - if ($row["dur"]) { - return (int) $row["dur"]; - } - //TODO check if return null as timestamp causes issues - return null; - } - /** * Get session counters by type (opened, closed) */ @@ -470,8 +413,7 @@ public static function getNumberOfSessionsByType(int $a_from, int $a_to): array $ilDB = $DIC['ilDB']; $sql = "SELECT SUM(opened) opened, SUM(closed_manual) closed_manual," . - " SUM(closed_expire) closed_expire, SUM(closed_idle) closed_idle," . - " SUM(closed_idle_first) closed_idle_first, SUM(closed_limit) closed_limit," . + " SUM(closed_expire) closed_expire," . " SUM(closed_login) closed_login, SUM(closed_misc) closed_misc" . " FROM usr_session_stats" . " WHERE slot_end > " . $ilDB->quote($a_from, "integer") . @@ -490,8 +432,7 @@ public static function getActiveSessions(int $a_from, int $a_to): array /** @var ilDBInterface $ilDB */ $ilDB = $DIC['ilDB']; - $sql = "SELECT slot_begin, slot_end, active_min, active_max, active_avg," . - " max_sessions" . + $sql = "SELECT slot_begin, slot_end, active_min, active_max, active_avg" . " FROM usr_session_stats" . " WHERE slot_end > " . $ilDB->quote($a_from, "integer") . " AND slot_begin < " . $ilDB->quote($a_to, "integer") . @@ -526,52 +467,4 @@ public static function getLastAggregation(): ?int //TODO check if return null as timestamp causes issues return null; } - - /** - * Get max session setting for given timestamp - * - */ - public static function getLimitForSlot(int $a_timestamp): int - { - global $DIC; - - $ilDB = $DIC['ilDB']; - $ilSetting = $DIC['ilSetting']; - - $ilDB->setLimit(1); - $sql = "SELECT maxval FROM usr_session_log" . - " WHERE tstamp <= " . $ilDB->quote($a_timestamp, "integer") . - " ORDER BY tstamp DESC"; - $res = $ilDB->query($sql); - $val = $ilDB->fetchAssoc($res); - if (isset($val["maxval"]) && $val["maxval"]) { - return (int) $val["maxval"]; - } - - return (int) $ilSetting->get("session_max_count", (string) ilSessionControl::DEFAULT_MAX_COUNT); - } - - /** - * Log max session setting - */ - public static function updateLimitLog(int $a_new_value): void - { - global $DIC; - - $ilDB = $DIC['ilDB']; - $ilSetting = $DIC['ilSetting']; - $ilUser = $DIC['ilUser']; - - $new_value = $a_new_value; - $old_value = (int) $ilSetting->get("session_max_count", (string) ilSessionControl::DEFAULT_MAX_COUNT); - - if ($new_value !== $old_value) { - $fields = array( - "tstamp" => array("timestamp", time()), - "maxval" => array("integer", $new_value), - "user_id" => array("integer", $ilUser->getId()) - ); - $ilDB->insert("usr_session_log", $fields); - } - } } diff --git a/components/ILIAS/Authentication/classes/class.ilSessionStatisticsGUI.php b/components/ILIAS/Authentication/classes/class.ilSessionStatisticsGUI.php index f1b6e2f0de9c..9b294b71f033 100755 --- a/components/ILIAS/Authentication/classes/class.ilSessionStatisticsGUI.php +++ b/components/ILIAS/Authentication/classes/class.ilSessionStatisticsGUI.php @@ -469,15 +469,6 @@ protected function renderCurrentBasics(): string $active = ilSessionControl::getExistingSessionCount(ilSessionControl::$session_types_controlled); - $control_active = ((int) $this->settings->get('session_handling_type', "0") === 1); - if ($control_active) { - $control_max_sessions = (int) $this->settings->get('session_max_count', (string) ilSessionControl::DEFAULT_MAX_COUNT); - $control_min_idle = (int) $this->settings->get('session_min_idle', (string) ilSessionControl::DEFAULT_MIN_IDLE); - $control_max_idle = (int) $this->settings->get('session_max_idle', (string) ilSessionControl::DEFAULT_MAX_IDLE); - $control_max_idle_first = (int) $this->settings->get('session_max_idle_after_first_request', (string) ilSessionControl::DEFAULT_MAX_IDLE_AFTER_FIRST_REQUEST); - } - - $last_maxed_out = new ilDateTime(ilSessionStatistics::getLastMaxedOut(), IL_CAL_UNIX); $last_aggr = new ilDateTime(ilSessionStatistics::getLastAggregation(), IL_CAL_UNIX); @@ -491,32 +482,6 @@ protected function renderCurrentBasics(): string $left->setVariable("CAPTION_LAST_AGGR", $this->lng->txt("trac_last_aggregation")); $left->setVariable("VALUE_LAST_AGGR", ilDatePresentation::formatDate($last_aggr)); - $left->setVariable("CAPTION_LAST_MAX", $this->lng->txt("trac_last_maxed_out_sessions")); - $left->setVariable("VALUE_LAST_MAX", ilDatePresentation::formatDate($last_maxed_out)); - - $left->setVariable("CAPTION_SESSION_CONTROL", $this->lng->txt("sess_load_dependent_session_handling")); - if (!$control_active) { - $left->setVariable("VALUE_SESSION_CONTROL", $this->lng->txt("no")); - } else { - $left->setVariable("VALUE_SESSION_CONTROL", $this->lng->txt("yes")); - - $left->setCurrentBlock("control_details"); - - $left->setVariable("CAPTION_SESSION_CONTROL_LIMIT", $this->lng->txt("session_max_count")); - $left->setVariable("VALUE_SESSION_CONTROL_LIMIT", $control_max_sessions); - - $left->setVariable("CAPTION_SESSION_CONTROL_IDLE_MIN", $this->lng->txt("session_min_idle")); - $left->setVariable("VALUE_SESSION_CONTROL_IDLE_MIN", $control_min_idle); - - $left->setVariable("CAPTION_SESSION_CONTROL_IDLE_MAX", $this->lng->txt("session_max_idle")); - $left->setVariable("VALUE_SESSION_CONTROL_IDLE_MAX", $control_max_idle); - - $left->setVariable("CAPTION_SESSION_CONTROL_IDLE_FIRST", $this->lng->txt("session_max_idle_after_first_request")); - $left->setVariable("VALUE_SESSION_CONTROL_IDLE_FIRST", $control_max_idle_first); - - $left->parseCurrentBlock(); - } - // sync button if ($this->access->checkAccess("write", "", $this->ref_id)) { $left->setVariable("URL_SYNC", $this->ilCtrl->getFormAction($this, "adminSync")); @@ -531,11 +496,9 @@ protected function buildData(int $a_time_from, int $a_time_to, string $a_title): { // basic data - time related - $maxed_out_duration = round(ilSessionStatistics::getMaxedOutDuration($a_time_from, $a_time_to) / 60); $counters = ilSessionStatistics::getNumberOfSessionsByType($a_time_from, $a_time_to); $opened = (int) $counters["opened"]; - $closed_limit = (int) $counters["closed_limit"]; - unset($counters["opened"], $counters["closed_limit"]); + unset($counters["opened"]); // build center column @@ -549,8 +512,6 @@ protected function buildData(int $a_time_from, int $a_time_to, string $a_title): new ilDateTime($a_time_to, IL_CAL_UNIX) ) . ")"; - $data["maxed_out_time"] = array($this->lng->txt("trac_maxed_out_time"), $maxed_out_duration); - $data["maxed_out_counter"] = array($this->lng->txt("trac_maxed_out_counter"), $closed_limit); $data["opened"] = array($this->lng->txt("trac_sessions_opened"), $opened); $data["closed"] = array($this->lng->txt("trac_sessions_closed"), array_sum($counters)); foreach ($counters as $type => $counter) { @@ -629,12 +590,6 @@ protected function getChart(array $a_data, string $a_title, int $a_scale = self: $colors[] = $colors_map[$measure]; } - if ($a_scale === self::SCALE_DAY || $a_scale === self::SCALE_WEEK) { - $max_line = $chart->getDataInstance(ilChartGrid::DATA_LINES); - $max_line->setLabel($this->lng->txt("session_max_count")); - $colors[] = "#cc0000"; - } - $chart->setColors($colors); $chart_data = $this->adaptDataToScale($a_scale, $a_data); @@ -689,18 +644,11 @@ protected function getChart(array $a_data, string $a_title, int $a_scale = self: $value = (int) $item["active_" . $measure]; $act_line[$measure]->addPoint($date, $value); } - - if (isset($max_line)) { - $max_line->addPoint($date, (int) $item["max_sessions"]); - } } foreach ($act_line as $line) { $chart->addData($line); } - if (isset($max_line)) { - $chart->addData($max_line); - } $chart->setTicks($labels, null, true); diff --git a/components/ILIAS/Authentication/service.xml b/components/ILIAS/Authentication/service.xml index c757feaed5f3..bb5723582b3e 100755 --- a/components/ILIAS/Authentication/service.xml +++ b/components/ILIAS/Authentication/service.xml @@ -14,7 +14,6 @@ - diff --git a/components/ILIAS/Authentication/templates/default/tpl.session_statistics_center.html b/components/ILIAS/Authentication/templates/default/tpl.session_statistics_center.html index d57c192851be..44d0c3c96caf 100755 --- a/components/ILIAS/Authentication/templates/default/tpl.session_statistics_center.html +++ b/components/ILIAS/Authentication/templates/default/tpl.session_statistics_center.html @@ -12,6 +12,4 @@

{TIMEFRAME}

  • {CAPTION_CLOSED_DETAILS}: {VALUE_CLOSED_DETAILS}
  • -

    {CAPTION_MAXED_OUT_COUNTER}: {VALUE_MAXED_OUT_COUNTER}

    -

    {CAPTION_MAXED_OUT_TIME}: {VALUE_MAXED_OUT_TIME}

    \ No newline at end of file diff --git a/components/ILIAS/Authentication/templates/default/tpl.session_statistics_left.html b/components/ILIAS/Authentication/templates/default/tpl.session_statistics_left.html index 4e16aaf17ac3..b2719a5475c3 100755 --- a/components/ILIAS/Authentication/templates/default/tpl.session_statistics_left.html +++ b/components/ILIAS/Authentication/templates/default/tpl.session_statistics_left.html @@ -2,16 +2,6 @@

    {CAPTION_CURRENT}: {VALUE_CURRENT}

    {CAPTION_LAST_AGGR}: {VALUE_LAST_AGGR}

    -

    {CAPTION_LAST_MAX}: {VALUE_LAST_MAX}

    -

    {CAPTION_SESSION_CONTROL}: {VALUE_SESSION_CONTROL}

    - -
      -
    • {CAPTION_SESSION_CONTROL_LIMIT}: {VALUE_SESSION_CONTROL_LIMIT}
    • -
    • {CAPTION_SESSION_CONTROL_IDLE_MIN}: {VALUE_SESSION_CONTROL_IDLE_MIN}
    • -
    • {CAPTION_SESSION_CONTROL_IDLE_MAX}: {VALUE_SESSION_CONTROL_IDLE_MAX}
    • -
    • {CAPTION_SESSION_CONTROL_IDLE_FIRST}: {VALUE_SESSION_CONTROL_IDLE_FIRST}
    • -
    -