From af51e82596020e533bfd6df00e172d71f0d31e51 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Willms <tleilax+studip@gmail.com> Date: Mon, 13 Mar 2023 21:34:17 +0000 Subject: [PATCH] extend RolePersistence, fixes #2054 Closes #2054 Merge request studip/studip!1334 --- lib/plugins/db/RolePersistence.class.php | 109 ++++++++++++++++++++++- 1 file changed, 106 insertions(+), 3 deletions(-) diff --git a/lib/plugins/db/RolePersistence.class.php b/lib/plugins/db/RolePersistence.class.php index 25925951b3a..3514ca6c6d3 100644 --- a/lib/plugins/db/RolePersistence.class.php +++ b/lib/plugins/db/RolePersistence.class.php @@ -22,7 +22,7 @@ class RolePersistence /** * Returns all available roles. * - * @return array Roles + * @return Role[]|array{system: Role[], other: Role[]} */ public static function getAllRoles(bool $grouped = false): array { @@ -111,7 +111,7 @@ class RolePersistence * * @param Role $role */ - public static function deleteRole($role) + public static function deleteRole($role): bool { $id = $role->getRoleid(); $name = $role->getRolename(); @@ -121,7 +121,7 @@ class RolePersistence $statement->execute([$id]); $statement->setFetchMode(PDO::FETCH_COLUMN, 0); - DBManager::get()->execute( + $result = DBManager::get()->execute( "DELETE `roles`, `roles_user`, `roles_plugins`, `roles_studipperms` FROM `roles` LEFT JOIN `roles_user` USING (`roleid`) @@ -131,6 +131,10 @@ class RolePersistence [$id] ); + if ($result === 0) { + return false; + } + // sweep roles cache self::expireRolesCache(); self::expireUserCache(); @@ -140,6 +144,27 @@ class RolePersistence } NotificationCenter::postNotification('RoleDidDelete', $id, $name); + + return true; + } + + /** + * Delete role by name if not a permanent role. System roles cannot be + * deleted. + * + * @param string $role_name + * + * @return bool + */ + public static function deleteRoleByName(string $role_name): bool + { + foreach (self::getAllRoles() as $role) { + if ($role->getRolename() === $role_name) { + return self::deleteRole($role); + } + } + + return false; } /** @@ -174,6 +199,44 @@ class RolePersistence ); } + /** + * Assigns a role to a stud.ip permission. System roles cannot be assigned + * to permissions. + * + * @param string $perm + * @param Role $role + * + * @return bool + * @throws Exception + */ + public static function assignRoleToPerm(string $perm, Role $role): bool + { + if ($role->getSystemtype()) { + throw new Exception('Cannot assign system roles to permissions.'); + } + + if (!in_array($perm, ['user', 'autor', 'tutor', 'dozent', 'admin', 'root'])) { + throw new Exception("Invalid permission {$perm}"); + } + + $query = "INSERT INTO `roles_studipperms` (`roleid`, `permname`) + VALUES (?, ?)"; + $result = DBManager::get()->execute($query, [$role->getRoleid(), $perm]); + + if ($result === 0) { + return false; + } + + User::findEachByPerms( + function (User $user) { + self::expireUserCache($user->id); + }, + $perm + ); + + return true; + } + /** * Gets all assigned roles from the database for a user * @@ -307,6 +370,46 @@ class RolePersistence ); } + /** + * Removes a role from a stud.ip permission. System roles cannot be removed + * from permissions. + * + * @param string $perm + * @param Role $role + * + * @return bool + * @throws Exception + */ + public static function deleteRoleAssignmentFromPerm(string $perm, Role $role): bool + { + if ($role->getSystemtype()) { + throw new Exception('Cannot remove system role assignment from permissions.'); + } + + if (!in_array($perm, ['user', 'autor', 'tutor', 'dozent', 'admin', 'root'])) { + throw new Exception("Invalid permission {$perm}"); + } + + $query = "DELETE FROM `roles_studipperms` + WHERE `roleid` = ? + AND `permname` = ?"; + $result = DBManager::get()->execute($query, [$role->getRoleid(), $perm]); + + if ($result === 0) { + return false; + } + + User::findEachByPerms( + function (User $user) { + self::expireUserCache($user->id); + }, + $perm + ); + + return true; + } + + /** * Get's all Role-Assignments for a certain user. * If no user is set, all role assignments are returned. -- GitLab