From 7cbba1ec8a0de90e02632fe06beebb2e672a07a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20Schr=C3=B6der=2C=20M=2E=20A=2E?= <schroeder@data-quest.de> Date: Thu, 19 Dec 2024 13:38:22 +0000 Subject: [PATCH] =?UTF-8?q?Resolve=20"Accountmanagement=20f=C3=BCr=20verkn?= =?UTF-8?q?=C3=BCpfte=20ILIAS-Accounts=20in=20Stud.IP"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #4263 Merge request studip/studip!3368 --- app/controllers/admin/ilias_interface.php | 2 + app/controllers/admin/user.php | 12 ++++ app/controllers/my_ilias_accounts.php | 64 ++++++++++++++++++ .../admin/ilias_interface/edit_content.php | 4 ++ app/views/admin/user/edit.php | 37 ++++++++++- .../administrate_account.php | 65 +++++++++++++++++++ lib/ilias_interface/ConnectedIlias.php | 17 +++-- lib/ilias_interface/IliasUser.php | 3 +- 8 files changed, 197 insertions(+), 7 deletions(-) create mode 100644 app/views/my_ilias_accounts/administrate_account.php diff --git a/app/controllers/admin/ilias_interface.php b/app/controllers/admin/ilias_interface.php index d0e59ea7775..750e33d9118 100644 --- a/app/controllers/admin/ilias_interface.php +++ b/app/controllers/admin/ilias_interface.php @@ -129,6 +129,7 @@ class Admin_IliasInterfaceController extends AuthenticatedController 'url' => _('https://<URL zur ILIAS-Installation>'), 'client' => '', 'ldap_enable' => '', + 'reconnect_accounts' => false, 'no_account_updates' => false, 'admin' => 'ilias_soap_admin', 'admin_pw' => '', @@ -351,6 +352,7 @@ class Admin_IliasInterfaceController extends AuthenticatedController $this->ilias_configs[$index]['course_veranstaltungsnummer'] = Request::get('ilias_course_veranstaltungsnummer'); } $this->ilias_configs[$index]['delete_ilias_users'] = Request::get('ilias_delete_ilias_users'); + $this->ilias_configs[$index]['reconnect_accounts'] = Request::bool('ilias_reconnect_accounts', false); $this->ilias_configs[$index]['delete_ilias_courses'] = Request::get('ilias_delete_ilias_courses'); $this->ilias_configs[$index]['category_create_on_add_module'] = Request::get('ilias_category_create_on_add_module'); $this->ilias_configs[$index]['category_to_desktop'] = Request::get('ilias_category_to_desktop'); diff --git a/app/controllers/admin/user.php b/app/controllers/admin/user.php index 4af6b42470b..9a610598935 100644 --- a/app/controllers/admin/user.php +++ b/app/controllers/admin/user.php @@ -415,6 +415,18 @@ class Admin_UserController extends AuthenticatedController $this->user_roles = $this->user->getRoles(); + // get ilias account data + if ($GLOBALS['perm']->have_perm('root') && Config::get()->ILIAS_INTERFACE_ENABLE) { + $this->ilias_list = []; + foreach (Config::get()->ILIAS_INTERFACE_SETTINGS as $ilias_index => $ilias_config) { + if ($ilias_config['is_active']) { + $this->ilias_list[$ilias_index] = new ConnectedIlias($ilias_index); + $this->ilias_list[$ilias_index]->soap_client->clearCache(); + $this->ilias_user[$ilias_index] = new IliasUser($ilias_index, $ilias_config['version'], $user_id); + } + } + } + // Änderungen speichern if (Request::submitted('edit')) { CSRFProtection::verifyUnsafeRequest(); diff --git a/app/controllers/my_ilias_accounts.php b/app/controllers/my_ilias_accounts.php index b82ec7d88ec..84060acf9b5 100644 --- a/app/controllers/my_ilias_accounts.php +++ b/app/controllers/my_ilias_accounts.php @@ -161,6 +161,70 @@ class MyIliasAccountsController extends AuthenticatedController $this->redirect($this->url_for('my_ilias_accounts/index')); } + /** + * Administrate account for ILIAS installation + * @param $user_id studip user id + * @param $index Index of ILIAS installation + * @param $mode action type + */ + public function administrate_account_action($user_id, $index) + { + if (!$GLOBALS['perm']->have_perm('root')) { + throw new AccessDeniedException(); + } + + $ilias_configs = Config::get()->ILIAS_INTERFACE_SETTINGS; + if ($ilias_configs[$index]['is_active']) { + $this->ilias = new ConnectedIlias($index); + $this->ilias_index = $index; + $this->ilias_login = ''; + $this->matched_user = false; + $this->external_account_login = ''; + $this->external_account_id = false; + $this->user_exists = false; + $this->user = new IliasUser($index, $ilias_configs[$index]['version'], $user_id); + + if (Request::submitted('lookup_account')) { + $this->ilias_login = trim(Request::option('ilias_login')); + $this->matched_user = $this->ilias->soap_client->lookupUser($this->ilias_login); + if (empty($this->matched_user)) { + PageLayout::postError(sprintf(_('Es wurde kein Account mit dem Loginnamen "%s" gefunden.'), htmlReady($this->ilias_login))); + } else { + PageLayout::postInfo(sprintf(_('Account "%s" wurde gefunden.'), htmlReady($this->ilias_login))); + } + } elseif (Request::submitted('connect_account')) { + $new_user = $this->ilias->soap_client->getUser(Request::option('ilias_user_id')); + if ($new_user['usr_id'] && $new_user['login']) { + $this->user->id = $new_user['usr_id']; + $this->user->login = $new_user['login']; + $this->user->setConnection(IliasUser::USER_TYPE_ORIGINAL); + PageLayout::postSuccess(_('Account zugeordnet.')); + } + } elseif (Request::submitted('disconnect_account')) { + if ($this->user->unsetConnection(true)) { + PageLayout::postSuccess(_('Account-Zuordnung entfernt.')); + } + } elseif (Request::submitted('new_account')) { + $this->ilias->user = new IliasUser($index, $ilias_configs[$index]['version'], $user_id); + $this->ilias->soap_client->setCachingStatus(false); + $this->ilias->soap_client->clearCache(); + $this->ilias->newUser(); + PageLayout::postSuccess(_('Account angelegt.')); + } + + // check if connection is valid / available + if ($this->user->isConnected()) { + $existing_user = $this->ilias->soap_client->getUser($this->user->id); + if ($existing_user && $existing_user['usr_id'] === $this->user->id) { + $this->user_exists = true; + } + } else { + $this->external_account_login = $ilias_configs[$index]['user_prefix'] . $this->user->studip_login; + $this->external_account_id = $this->ilias->soap_client->lookupUser($this->external_account_login); + } + } + } + /** * Redirect to ILIAS installation * @param $index Index of ILIAS installation diff --git a/app/views/admin/ilias_interface/edit_content.php b/app/views/admin/ilias_interface/edit_content.php index d0eb47e21e0..77c76eb9fb9 100644 --- a/app/views/admin/ilias_interface/edit_content.php +++ b/app/views/admin/ilias_interface/edit_content.php @@ -38,6 +38,10 @@ <input type="checkbox" name="ilias_delete_ilias_users" value="1" <?= $ilias_config['delete_ilias_users'] ? 'checked' : '' ?>> <span><?= _('Beim Löschen von Stud.IP-Accounts ILIAS-Accounts ebenfalls löschen (alle zugehörigen Objekte werden gelöscht!)') ?></span> </label> + <label> + <input type="checkbox" name="ilias_reconnect_accounts" value="1" <?= $ilias_config['reconnect_accounts'] ? 'checked' : '' ?>> + <span><?= _('Externe User-Accounts automatisch verbinden, wenn sie den passenden Loginnamen haben') ?></span> + </label> <label> <span><?= _('Prefix für automatisch angelegte Usernamen') ?></span> <? if ($ilias_config['is_active']) : ?> diff --git a/app/views/admin/user/edit.php b/app/views/admin/user/edit.php index 47596a99496..3313e6ab608 100644 --- a/app/views/admin/user/edit.php +++ b/app/views/admin/user/edit.php @@ -232,8 +232,6 @@ use Studip\Button, Studip\LinkButton; <? endif ?> </fieldset> - - <fieldset> <legend> <?= _('Registrierungsdaten') ?> @@ -368,6 +366,41 @@ use Studip\Button, Studip\LinkButton; </section> </fieldset> + <? if ($GLOBALS['perm']->have_perm('root') && Config::get()->ILIAS_INTERFACE_ENABLE) : ?> + <? foreach ($ilias_list as $ilias_index => $ilias) : ?> + <fieldset> + <legend> + <?= htmlReady(sprintf(_('Account in %s'), htmlReady($ilias->getName()))) ?> + </legend> + + <? if ($ilias_user[$ilias_index]->isConnected()) : ?> + <label> + <?= _('Loginname des verknüpften Accounts:') ?> + <?= htmlReady($ilias_user[$ilias_index]->getUsername()) ?> + </label> + <label> + <?= LinkButton::create( + _('Verknüpfung bearbeiten'), + $controller->url_for('my_ilias_accounts/administrate_account/' . $ilias_user[$ilias_index]->studip_id . '/' . $ilias_index . '/edit'), + ['data-dialog' => 'reload-on-close'] + ) ?> + </label> + <? else : ?> + <label> + <?= _('Kein Account verknüpft') ?> + </label> + <label> + <?= LinkButton::create( + _('Verknüpfung erstellen'), + $controller->url_for('my_ilias_accounts/administrate_account/' . $ilias_user[$ilias_index]->studip_id . '/' . $ilias_index . '/edit'), + ['data-dialog' => 'reload-on-close'] + ) ?> + </label> + <? endif ?> + </fieldset> + <? endforeach ?> + <? endif ?> + <? if (in_array($user->perms, ['autor', 'tutor', 'dozent'])): ?> <fieldset> <legend> diff --git a/app/views/my_ilias_accounts/administrate_account.php b/app/views/my_ilias_accounts/administrate_account.php new file mode 100644 index 00000000000..6b86fd8d168 --- /dev/null +++ b/app/views/my_ilias_accounts/administrate_account.php @@ -0,0 +1,65 @@ +<form class="default" action="<?= $controller->link_for('my_ilias_accounts/administrate_account/' . $user->studip_id . '/' . $ilias_index) ?>" method="post" data-dialog="reload-on-close"> + <?= CSRFProtection::tokenTag() ?> + <fieldset> + <legend> + <?= _('Bestehenden Account zuordnen') ?> + </legend> + <? if (!$matched_user) : ?> + <label> + <span><?= _('Loginname') ?></span> + <input type="text" name="ilias_login" size="50" maxlength="50" value="<?= htmlReady($ilias_login) ?>"> + <?= Studip\Button::createAccept(_('Account Suchen'), 'lookup_account') ?> + </label> + <? else : ?> + <label> + <span><?= htmlReady(sprintf(_('ILIAS Account %s (ID %s)'), $ilias_login, $matched_user)) ?></span> + </label> + <input type="hidden" name="ilias_user_id" value="<?= htmlReady($matched_user) ?>"> + <?= Studip\Button::createAccept(_('Account zuordnen'), 'connect_account') ?> + <? endif ?> + </fieldset> + <? if ($user->isConnected()) : ?> + <fieldset> + <legend> + <?= _('Verknüpfter Account') ?> + </legend> + <table class="default nohover"> + <tr> + <td><?= _('Loginname des verknüpften Accounts:') ?></td> + <td> + <?= htmlReady($user->getUsername()) ?> + <? if (!$user_exists): ?> + - <?= _('Der verknüpfte Account wurde im angebundenen ILIAS-System nicht gefunden!') ?> + <? endif; ?> + </td> + </tr> + <tr> + <td><?= _('Eigene Kategorie:') ?></td> + <td><?= !empty($user->getCategory()) ? _('ID') . ' ' . htmlReady($user->getCategory()) : _('nicht vorhanden') ?></td> + </tr> + <tr> + <td><?= _('Account-Typ:') ?></td> + <td><?= $user->getUserType() == IliasUser::USER_TYPE_ORIGINAL ? _('Lokaler ILIAS-Account') : _('Automatisch erstellter Account') ?></td> + </tr> + </table> + <?= Studip\Button::createCancel(_('Verknüpfung aufheben'), 'disconnect_account') ?> + </fieldset> + <? else : ?> + <fieldset> + <legend> + <?= _('Kein Account verknüpft') ?> + </legend> + <? if ($external_account_id) : ?> + <label> + <?= sprintf(_('Es existiert bereits ein ILIAS-Account mit dem Loginnamen %s.'), htmlReady($external_account_login)) ?> + <input type="hidden" name="ilias_user_id" value="<?= htmlReady($external_account_id) ?>"> + <?= Studip\Button::createAccept(_('Mit externem Account verknüpfen'), 'connect_account') ?> + </label> + <? else : ?> + <label> + <?= Studip\Button::createAccept(_('Neuen Account anlegen'), 'new_account') ?> + </label> + <? endif ?> + </fieldset> + <? endif ?> +</form> \ No newline at end of file diff --git a/lib/ilias_interface/ConnectedIlias.php b/lib/ilias_interface/ConnectedIlias.php index 94c6ad81413..e90f75b6fde 100644 --- a/lib/ilias_interface/ConnectedIlias.php +++ b/lib/ilias_interface/ConnectedIlias.php @@ -336,8 +336,17 @@ class ConnectedIlias ($this->user->auth_plugin == $this->ilias_config['ldap_enable'])) { $this->user->id = $user_exists; $this->user->login = $user_data["login"]; - $this->user->setConnection($this->user->getUserType(), true); - PageLayout::postSuccess(sprintf(_("Verbindung mit Nutzer ID %s wiederhergestellt."), $this->user->id)); + $this->user->setConnection($this->user->getUserType()); + PageLayout::postSuccess(sprintf( + _('Verbindung mit Account ID %s wiederhergestellt.'), + htmlReady($this->user->id) + )); + return true; + } elseif ($user_exists && $this->ilias_config['reconnect_accounts']) { + $this->user->id = $user_exists; + $this->user->login = $user_data["login"]; + $this->user->setConnection($this->user->getUserType()); + PageLayout::postSuccess(sprintf(_('Verbindung mit Account ID %s wiederhergestellt.'), htmlReady($this->user->id))); return true; } elseif ($user_exists) { $this->error[] = sprintf(_('Externer Account konnte nicht angelegt werden. Es existiert bereits ein User mit dem Login %s in %s'), $user_data["login"], $this->ilias_config['name']); @@ -361,7 +370,7 @@ class ConnectedIlias } // set role according to Stud.IP perm - if (User::findCurrent()->perms === 'root') { + if (User::find($this->user->studip_id)->perms === 'root') { $role_id = 2; } else { $role_id = 4; @@ -519,7 +528,7 @@ class ConnectedIlias // data for user category in ILIAS $object_data["title"] = sprintf(_("Eigene Daten von %s (%s)."), $this->user->getName(), $this->user->getId()); - $object_data["description"] = sprintf(_("Hier befinden sich die persönlichen Lernmodule des Benutzers %s."), $this->user->getName()); + $object_data['description'] = sprintf(_('Hier befinden sich die persönlichen Lernmodule von %s.'), $this->user->getName()); $object_data["type"] = "cat"; $object_data["owner"] = $this->user->getId(); diff --git a/lib/ilias_interface/IliasUser.php b/lib/ilias_interface/IliasUser.php index c9233df4330..fbd15cec893 100644 --- a/lib/ilias_interface/IliasUser.php +++ b/lib/ilias_interface/IliasUser.php @@ -502,7 +502,7 @@ class IliasUser function unsetConnection($ignore_usertype = false) { if (!$ignore_usertype && ($this->getUserType() != self::USER_TYPE_ORIGINAL)) { - return; + return false; } $query = "DELETE FROM auth_extern WHERE studip_user_id = ? AND external_user_system_type = ? AND external_user_type = ?"; @@ -515,6 +515,7 @@ class IliasUser $this->is_connected = false; $this->readData(); + return true; } /** -- GitLab