From 8a1140a485b0ac6dfb4718f09a13ba929081c738 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 29 Jul 2017 18:47:32 +0200 Subject: [PATCH] Add private methods to 'Administration' for modifying users' roles --- src/Administration.php | 94 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/src/Administration.php b/src/Administration.php index 17a1cf8..53c81a3 100644 --- a/src/Administration.php +++ b/src/Administration.php @@ -141,4 +141,98 @@ final class Administration extends UserManager { } } + /** + * Modifies the roles for the user where the column with the specified name has the given value + * + * You must never pass untrusted input to the parameter that takes the column name + * + * @param string $columnName the name of the column to filter by + * @param mixed $columnValue the value to look for in the selected column + * @param callable $modification the modification to apply to the existing bitmask of roles + * @return bool whether any user with the given column constraints has been found + * @throws AuthError if an internal problem occurred (do *not* catch) + * + * @see Role + */ + private function modifyRolesForUserByColumnValue($columnName, $columnValue, callable $modification) { + try { + $userData = $this->db->selectRow( + 'SELECT id, roles_mask FROM users WHERE ' . $columnName . ' = ?', + [ $columnValue ] + ); + } + catch (Error $e) { + throw new DatabaseError(); + } + + if ($userData === null) { + return false; + } + + $newRolesBitmask = $modification($userData['roles_mask']); + + try { + $this->db->exec( + 'UPDATE users SET roles_mask = ? WHERE id = ?', + [ + $newRolesBitmask, + (int) $userData['id'] + ] + ); + + return true; + } + catch (Error $e) { + throw new DatabaseError(); + } + } + + /** + * Assigns the specified role to the user where the column with the specified name has the given value + * + * You must never pass untrusted input to the parameter that takes the column name + * + * @param string $columnName the name of the column to filter by + * @param mixed $columnValue the value to look for in the selected column + * @param int $role the role as one of the constants from the {@see Role} class + * @return bool whether any user with the given column constraints has been found + * + * @see Role + */ + private function addRoleForUserByColumnValue($columnName, $columnValue, $role) { + $role = (int) $role; + + return $this->modifyRolesForUserByColumnValue( + $columnName, + $columnValue, + function ($oldRolesBitmask) use ($role) { + return $oldRolesBitmask | $role; + } + ); + } + + /** + * Takes away the specified role from the user where the column with the specified name has the given value + * + * You must never pass untrusted input to the parameter that takes the column name + * + * @param string $columnName the name of the column to filter by + * @param mixed $columnValue the value to look for in the selected column + * @param int $role the role as one of the constants from the {@see Role} class + * @return bool whether any user with the given column constraints has been found + * + * @see Role + */ + private function removeRoleForUserByColumnValue($columnName, $columnValue, $role) { + $role = (int) $role; + + return $this->modifyRolesForUserByColumnValue( + $columnName, + $columnValue, + function ($oldRolesBitmask) use ($role) { + return $oldRolesBitmask & ~$role; + } + ); + } + }