diff --git a/SQL/0000-00-01-Permission.sql b/SQL/0000-00-01-Permission.sql index 4a11304ca89..a3a9b5a09fb 100644 --- a/SQL/0000-00-01-Permission.sql +++ b/SQL/0000-00-01-Permission.sql @@ -9,6 +9,10 @@ DROP TABLE IF EXISTS `permissions_category`; DROP TABLE IF EXISTS `user_perm_rel`; +DROP TABLE IF EXISTS `role`; +DROP TABLE IF EXISTS `role_permission_rel`; +DROP TABLE IF EXISTS `user_role_rel`; + SET FOREIGN_KEY_CHECKS=1; -- -- Table structure for table `permissions_category` @@ -22,7 +26,7 @@ CREATE TABLE `permissions_category` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -INSERT INTO `permissions_category` VALUES +INSERT INTO `permissions_category` VALUES (1,'Roles'), (2,'Permission'); @@ -113,9 +117,9 @@ INSERT INTO `permissions` VALUES INSERT INTO `user_perm_rel` (userID, permID) - SELECT u.ID, p.permID - FROM users u JOIN permissions p - WHERE u.userid = 'admin' + SELECT u.ID, p.permID + FROM users u JOIN permissions p + WHERE u.userid = 'admin' ORDER BY p.permID; -- permissions for each notification module @@ -131,3 +135,28 @@ CREATE TABLE `notification_modules_perm_rel` ( -- populate notification perm table INSERT INTO notification_modules_perm_rel SELECT nm.id, p.permID FROM notification_modules nm JOIN permissions p WHERE nm.module_name='media' AND (p.code='media_write' OR p.code='media_read'); INSERT INTO notification_modules_perm_rel SELECT nm.id, p.permID FROM notification_modules nm JOIN permissions p WHERE nm.module_name='document_repository' AND (p.code='document_repository_view' OR p.code='document_repository_delete'); + + +CREATE TABLE `role` ( + `RoleID` INTEGER unsigned NOT NULL AUTO_INCREMENT, + `Name` varchar(255), + `Label` varchar(255), + PRIMARY KEY (`RoleID`), + UNIQUE KEY `UK_Name` (`Name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `role_permission_rel` ( + `RoleID` INTEGER unsigned NOT NULL, + `PermissionID` INTEGER unsigned NOT NULL, + PRIMARY KEY (`RoleID`,`PermissionID`), + CONSTRAINT `FK_role_permission_rel_RoleID` FOREIGN KEY (`RoleID`) REFERENCES `role` (`RoleID`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `FK_role_permission_rel_PermissionID` FOREIGN KEY (`PermissionID`) REFERENCES `permissions` (`permID`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `user_role_rel` ( + `UserID` INTEGER unsigned NOT NULL, + `RoleID` INTEGER unsigned NOT NULL, + PRIMARY KEY (`UserID`,`RoleID`), + CONSTRAINT `FK_user_role_rel_userID` FOREIGN KEY (`UserID`) REFERENCES `users` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `FK_user_role_rel_RoleID` FOREIGN KEY (`RoleID`) REFERENCES `role` (`RoleID`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/SQL/Archive/2018-03-10-permission_roles.sql b/SQL/Archive/2018-03-10-permission_roles.sql new file mode 100644 index 00000000000..f88a6ebfe50 --- /dev/null +++ b/SQL/Archive/2018-03-10-permission_roles.sql @@ -0,0 +1,23 @@ +CREATE TABLE `role` ( + `RoleID` INTEGER unsigned NOT NULL AUTO_INCREMENT, + `Name` varchar(255), + `Label` varchar(255), + PRIMARY KEY (`RoleID`), + UNIQUE KEY `UK_Name` (`Name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `role_permission_rel` ( + `RoleID` INTEGER unsigned NOT NULL, + `PermissionID` INTEGER unsigned NOT NULL, + PRIMARY KEY (`RoleID`,`PermissionID`), + CONSTRAINT `FK_role_permission_rel_RoleID` FOREIGN KEY (`RoleID`) REFERENCES `role` (`RoleID`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `FK_role_permission_rel_PermissionID` FOREIGN KEY (`PermissionID`) REFERENCES `permissions` (`permID`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `user_role_rel` ( + `UserID` INTEGER unsigned NOT NULL, + `RoleID` INTEGER unsigned NOT NULL, + PRIMARY KEY (`UserID`,`RoleID`), + CONSTRAINT `FK_user_role_rel_userID` FOREIGN KEY (`UserID`) REFERENCES `users` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `FK_user_role_rel_RoleID` FOREIGN KEY (`RoleID`) REFERENCES `role` (`RoleID`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/php/libraries/Permission.class.inc b/php/libraries/Permission.class.inc new file mode 100644 index 00000000000..dc850bfb86b --- /dev/null +++ b/php/libraries/Permission.class.inc @@ -0,0 +1,215 @@ + + * @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 + * @link https://www.github.com/aces/Loris/ + */ + +/** + * The Loris Permission class + * + * @category Main + * @package Loris + * @author Rida Abou-Haidar + * @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 + * @link https://www.github.com/aces/Loris/ + */ +class Permission +{ + /** + * Stores Database being used + * + * @var $DB Database + * @access private + */ + var $DB; + + /** + * Permission constructor. + * + * @param Database $Database database + */ + function __construct($Database) + { + $this->DB = $Database; + } + + + /** + * Gets the list of permissions in the database. + * + * @return array Associative array in the form $permissionID=>$permissionName + */ + function getPermissions() + { + $permissions = $this->DB->pselectColWithIndexKey( + "SELECT permID, code + FROM permissions", + array(), + "permID" + ); + + return $permissions; + } + + /** + * Gets the list of permission labels in the database. + * + * @return array Associative array in the form $permissionID=>$permissionLabel + */ + function getPermissionLabels() + { + $permissions = $this->DB->pselectColWithIndexKey( + "SELECT permID, description + FROM permissions", + array(), + "permID" + ); + + return $permissions; + } + + /** + * Checks if the string is a permission within the database + * + * @param string $permissionName the permission to be checked + * + * @return boolean + */ + function isPermission($permissionName) + { + $permissions = $this->getPermissions(); + if (in_array($permissionName, $permissions, true)) { + return true; + } + return false; + } + + /** + * Gets the ID of a permission given its name + * + * @param string $permissionName the permission name for which the ID is needed + * + * @throws LorisException if permission does not exist + * + * @return int + */ + function getPermissionIDFromName($permissionName) + { + if (!$this->isPermission($permissionName)) { + throw new LorisException( + "Could not retrieve the permission ID for + permission '$permissionName'" + ); + } + + $permissionID = $this->DB->pselectOne( + "SELECT permID + FROM permissions + WHERE code=:PN", + array("PN" => $permissionName) + ); + return $permissionID; + } + + /** + * Gets the NAME of a permission given its ID + * + * @param int $permissionID the permission ID for which the name is needed + * + * @throws LorisException if permission ID does not exist + * + * @return string + */ + function getPermissionNameFromID($permissionID) + { + $permissionName = $this->DB->pselectOne( + "SELECT code + FROM permissions + WHERE permID=:PID", + array("PID" => $permissionID) + ); + + if (empty($permissionName)) { + throw new LorisException( + "Could not retrieve the permission name for + permission ID '$permissionID'" + ); + } + return $permissionName; + } + + /** + * Gets the roles associated to a permission + * + * @param int $permissionID the permission + * + * @return array non-associative with values being the permission IDs + */ + function getPermissionRoleIDs($permissionID) + { + $roles = $this->DB->pselectCol( + "SELECT RoleID + FROM role_permission_rel + WHERE PermissionID=:PID", + array("PID" => $permissionID) + ); + + return $roles; + } + + /** + * Returns all the users with the permission + * + * @param int $permissionID the permission + * + * @return array Associative array ($userID=>$RealName) that have the permission + */ + function getPermissionUsers($permissionID) + { + $usersWithPermission = $this->DB->pselectColWithIndexKey( + "SELECT upr.userID, u.Real_name + FROM user_perm_rel upr + JOIN users u ON u.ID=upr.userID + WHERE upr.permId=:PID", + array("PID" => $permissionID), + "userID" + ); + return $usersWithPermission; + } + + /** + * Gets all the users' permissions based on their roles + * + * @param array $roleIDs role set associated with a user + * + * @return array associative array ($permissionID=>$permissionName) of + * permissions associated with the given permission set + */ + function getPermissionsFromRoles($roleIDs) + { + $roleObject = new \Role($this->DB); + $permissions = $this->getPermissions(); + + $userPermissions = array(); + + foreach ($roleIDs as $roleID) { + $rolePermissions = $roleObject->getRolePermissionIDs($roleID); + foreach ($rolePermissions as $permissionID) { + //if permissions overlap between roles, this will + //just overwrite data with the same data + $userPermissions[$permissionID] = $permissions[$permissionID]; + } + } + + return $userPermissions; + } + + +} \ No newline at end of file diff --git a/php/libraries/Role.class.inc b/php/libraries/Role.class.inc new file mode 100644 index 00000000000..8751006d2cc --- /dev/null +++ b/php/libraries/Role.class.inc @@ -0,0 +1,203 @@ + + * @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 + * @link https://www.github.com/aces/Loris/ + */ + +/** + * The Loris Role class + * + * @category Main + * @package Loris + * @author Rida Abou-Haidar + * @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 + * @link https://www.github.com/aces/Loris/ + */ +class Role +{ + /** + * Stores Database being used + * + * @var $DB Database + * @access private + */ + var $DB; + + /** + * Role constructor. + * + * @param Database $Database database + */ + function __construct($Database) + { + $this->DB = $Database; + } + + /** + * Gets the list of roles in the database. + * + * @return array Associative array in the form $roleID=>$roleName + */ + function getRoles() + { + + $roles = $this->DB->pselectColWithIndexKey( + "SELECT RoleID, Name + FROM role", + array(), + "RoleID" + ); + + return $roles; + } + + /** + * Gets the list of role labelss in the database. + * + * @return array Associative array in the form $roleID=>$roleLabel + */ + function getRoleLabels() + { + + $roles = $this->DB->pselectColWithIndexKey( + "SELECT RoleID, Label + FROM role", + array(), + "RoleID" + ); + + return $roles; + } + + /** + * Checks if the string is a role within the database + * + * @param string $roleName the role name to be checked + * + * @return boolean + */ + function isRole($roleName) + { + $roles = $this->getRoles(); + + if (in_array($roleName, $roles, true)) { + return true; + } + return false; + } + + /** + * Gets the ID of a role given its name + * + * @param string $roleName the role name for which the ID is needed + * + * @throws LorisException if role does not exist + * + * @return int + */ + function getRoleIDFromName($roleName) + { + if (!$this->isRole($roleName)) { + throw new LorisException( + "Could not retrieve the role ID for role '$roleName'" + ); + } + + $roleID = $this->DB->pselectOne( + "SELECT RoleID + FROM role + WHERE Name=:RN", + array("RN" => $roleName) + ); + + return $roleID; + } + + /** + * Gets the permissions associated to a role + * + * @param int $roleID the role + * + * @return array non-associative with values being the permission IDs + */ + function getRolePermissionIDs($roleID) + { + $permissions = $this->DB->pselectCol( + "SELECT PermissionID + FROM role_permission_rel + WHERE RoleID=:RID", + array("RID" => $roleID) + ); + + return $permissions; + } + + /** + * Returns all the users with the role + * + * @param int $roleID the role + * + * @return array Associative array ($userID=>$RealName) that have the role + */ + function getRoleUsers($roleID) + { + $usersWithRole = $this->DB->pselectColWithIndexKey( + "SELECT urr.UserID, u.Real_name + FROM user_role_rel urr + JOIN users u ON u.ID=urr.UserID + WHERE urr.RoleID=:RID", + array("RID" => $roleID), + "UserID" + ); + return $usersWithRole; + } + + /** + * Checks if a given role contains a given permission + * + * @param int $roleID the ID of the role + * @param int $permissionID the ID of the permission + * + * @return boolean + */ + function hasPermission($roleID, $permissionID) + { + $rolePermissionIDs = $this->getRolePermissionIDs($roleID); + + if (in_array($permissionID, $rolePermissionIDs, true)) { + return true; + } + return false; + } + + /** + * Gets all the users' roles based on their permissions + * + * @param array $permissionIDs Permission set + * + * @return array associative array ($roleID=>$roleName) of roles associated + * with the given permission set + */ + function getRolesFromPermissions($permissionIDs) + { + $roles = $this->getRoles(); + $userRoles = array(); + + foreach ($roles as $roleID=>$roleName) { + $rolePermissionIDs = $this->getRolePermissionIDs($roleID); + if (!array_diff($rolePermissionIDs, $permissionIDs)) { + $userRoles[$roleID] = $roleName; + } + } + + return $userRoles; + } + +} \ No newline at end of file diff --git a/tools/role_permission_configurator.php b/tools/role_permission_configurator.php new file mode 100644 index 00000000000..bda0d3354ae --- /dev/null +++ b/tools/role_permission_configurator.php @@ -0,0 +1,516 @@ + + * @license Loris license + * @link https://www.github.com/aces/Loris + */ + +require_once __DIR__ . "/../vendor/autoload.php"; +require_once __DIR__ . "/generic_includes.php"; + +$roleObject = new \Role($DB); +$permissionObject = new \Permission($DB); +$userObject = new \User(); + +$roles = $roleObject->getRoles(); +$permissions = $permissionObject->getPermissions(); + +//################################################################################## +// +// PARSING ARGUMENTS +// +//################################################################################## +// User did not provide any args +if (count($argv) === 1) { + syntaxIncorrect(); + exit(1); +} + +if (count($argv) === 2 && isset($argv[1])) { + switch ($argv[1]) { + case "roles": + // User asking for the list of roles + if (!empty($roles)) { + echo "The roles in the database are:\n\n"; + prettyPrint($roles); + } + else { + echo "There are currently no roles in the database.\n"; + } + exit(2); + case "permissions": + // User asking for the list of permissions + + echo "The permissions in the database are:\n\n"; + prettyPrint($permissions); + exit(3); + case "rebuildRoles": + // User asking to reassign roles based on the user permissions + rebuildRoles(); + exit(4); + case "rebuildPermissions": + // User asking to reassign permissions based on the user roles + rebuildPermissions(); + exit(5); + + default: + if (!$roleObject->isRole($argv[1])) { + // Arg syntax not correct + echo "\nThis option is unavailable !\n\n"; + syntaxIncorrect(); + exit(1); + } else { + $role = $argv[1]; + // User asking for the permissions associated with a role + echo "The permissions for the $role role are:\n\n"; + prettyPrint( + $permissionObject->getPermissionsFromRoles( + array($roleObject->getRoleIDFromName($role)) + ) + ); + exit(7); + } + } +} + +if ((count($argv) === 4 || (count($argv) === 5) && $argv[4] === 'updateExisting')) { + $role = $argv[1]; + $permission = $argv[3]; + $update = (isset($argv[4]) && $argv[4] === 'updateExisting') ? true : false; + switch ($argv[2]) { + case "add": + // User looking to add a permission to a role + if ($permissionObject->isPermission($permission) + && $roleObject->isRole($role) + ) { + addPermission($role, $permission, $update); + exit(8); + } + else { + echo "$permission or $role is not a valid option.\n"; + exit(9); + } + case "remove": + // User looking to remove a permission from a role + if ($permissionObject->isPermission($permission) + && $roleObject->isRole($role) + ) { + removePermission($role, $permission, $update); + exit(11); + } else { + echo "$permission or $role is not a valid option.\n"; + exit(12); + } + default: + // Arg syntax not correct + echo "\nThis option is unavailable !\n\n"; + syntaxIncorrect(); + exit(1); + } +} + +syntaxIncorrect(); +exit(1); + +//################################################################################## +// +// MAIN FUNCTIONS +// +//################################################################################## + +/** + * Prints a message to users with the argument instructions + * + * @return void + */ +function syntaxIncorrect() +{ + echo "You have not used the correct argument syntax for this script. + +To see the roles in the database: php role_permission_configurator.php roles +To see the permissions in the database: php role_permission_configurator.php permissions +To see the permissions for a role: php role_permission_configurator.php \$role +To add a permission to the role: php role_permission_configurator.php \$role add \$perm [updateExisting] +-> The updateExisting option adds the permission to + users currently in the specified role +To remove a permission from the role: php role_permission_configurator.php \$role remove \$perm [updateExisting] +-> The updateExisting option removes the permission + from users currently in the specified role +To rebuild the roles for every user based on their permissions: php role_permission_configurator.php rebuildRoles +To rebuild permissions for every user based on their role: php role_permission_configurator.php rebuildPermissions\n"; +} + +/** + * Rebuilds roles based on user permissions. Deletes all roles then checks + * every user's permissions to give them the appropriate roles. + * + * @return void + */ +function rebuildRoles() +{ + global $roleObject; + $DB = \Database::singleton(); + + echo "Rebuilding roles based on user permissions\n"; + echo "Note: This command removes all roles associated with users and\t + rebuilds them depending on their permissions\n\n"; + // Iterate over each user, update their roles based on their permissions + foreach (getUsers() as $userID=>$userName) { + + // delete existing roles + $DB->delete( + 'user_role_rel', + array('UserID' => $userID) + ); + // get their permission set + $userPermissionIDs = getUserPermissionIDs($userID); + + // recalculate their roles + $newRoles = $roleObject->getRolesFromPermissions($userPermissionIDs); + + if (!empty($newRoles)) { + echo "Updating roles for $userName\n"; + // update their roles in the database + foreach ($newRoles as $roleID => $roleName) { + echo "\tAdding $roleName\n"; + $DB->insert( + 'user_role_rel', + array( + 'UserID' => $userID, + 'RoleID' => $roleID, + ) + ); + } + echo "\n"; + } + } +} + +/** + * Rebuilds permissions based on user roles. Tops up permissions associated with + * each user by looking at which roles the user is associated with. This function + * does NOT delete any permissions as some permissions are given + * independently from roles + * + * @return void + */ +function rebuildPermissions() +{ + global $permissionObject; + $DB = \Database::singleton(); + + echo "Updating permissions based on user roles\n"; + echo "Note: This command does not remove any existing user permissions,\t + it simply adds to them.\n\n"; + // Iterate over each user, update their roles based on their permissions + foreach (getUsers() as $userID=>$userName) { + //Avoid deleting current permissions since + //some permissions might not be associated with roles + + // get user roles + $roleIDs = getUserRoleIDs($userID); + + // recalculate their roles + $newPermissions = $permissionObject->getPermissionsFromRoles($roleIDs); + + //unset existing permissions to avoid insert query + foreach ($newPermissions as $permissionID=>$permissionName) { + if (userHasPermission($userID, $permissionID)) { + unset($newPermissions[$permissionID]); + } + } + + if (!empty($newPermissions)) { + echo "Updating permissions for $userName\n"; + foreach ($newPermissions as $permissionID=>$permissionName) { + if (!userHasPermission($userID, $permissionID)) { + echo "\tAdding $permissionName\n"; + $DB->insert( + 'user_perm_rel', + array( + 'userID' => $userID, + 'permID' => $permissionID, + ) + ); + } + } + echo "\n"; + } + } +} + +/** + * Adds a permission to a role. Updates users with that role to either obtain + * the new permission or loose the role depending on the $update parameter + * + * @param string $role the name of the role + * @param string $permission the name of the permission + * @param bool $update if true, adds permission to users with current role. + * if false, removes the role from the user + * + * @return void + */ +function addPermission($role, $permission, $update) +{ + global $permissionObject; + global $roleObject; + $DB = \Database::singleton(); + + echo "Adding the $permission permission to the $role role...\n\n"; + + $roleID = $roleObject->getRoleIDFromName($role); + $permissionID = $permissionObject->getPermissionID($permission); + + // Check is it has that permission already + if ($roleObject->hasPermission($roleID, $permissionID)) { + echo "The $role role already has the $permission permission." . + "No changes to be made.\n"; + exit(); + } + + // Insert the permission into permission role rel table + $DB->insert( + 'role_permission_rel', + array( + 'RoleID' => $roleID, + 'PermissionID' => $permissionID, + ) + ); + + echo "\n$permission was added to the $role category.\n\n"; + + // Update the permissions for the user with the role + echo "Updating the users with the $role role...\n\n"; + + //Check if users who already have this role need to be given that permission + if ($update) { + //If YES, rebuild the permissions to add the + //new permission to all users currently with this role + rebuildPermissions(); + } else { + //If NO, rebuild the roles to remove the role from users who + //do not already have the permission + rebuildRoles(); + } +} + +/** + * Removes a permission from a role. Updates users with that role to either lose + * the permission that was removed or keep it. In either case, some users might + * gain the affected role given that the minimum required permissions + * have been reduced + * + * @param string $role the name of the role + * @param string $permission the name of the permission + * @param bool $update if true, removes permission from users with this role. + * if false, leaves permission for users with this role + * + * @return void + */ +function removePermission($role, $permission, $update) +{ + global $permissionObject; + global $roleObject; + $DB = \Database::singleton(); + + echo "Removing the $permission permission from the $role role...\n\n"; + + $roleID = $roleObject->getRoleIDFromName($role); + $permissionID = $permissionObject->getPermissionID($permission); + + // Check is it has that permission already + if (!$roleObject->hasPermission($roleID, $permissionID)) { + echo "The $role role does not contain the $permission permission." . + " No changes to be made.\n"; + exit(); + } + + // Delete the role from the role permission rel table + $DB->delete( + 'role_permission_rel', + array( + 'RoleID' => $roleID, + 'PermissionID' => $permissionID, + ) + ); + + echo "\n$permission was removed from the $role category.\n"; + + // Update the users with that role + echo "Updating the users with the $role role...\n\n"; + + // Check if users who already have this role need to be + // stripped from that permission + if ($update) { + //If YES, manually remove permission from users in the database + $userIDsWithRole = $roleObject->getRoleUsers($roleID); + foreach ($userIDsWithRole as $userID=>$userName) { + //redundant check to avoid database exception + if (userHasPermission($userID, $permissionID)) { + $DB->delete( + 'user_perm_rel', + array( + 'userID' => $userID, + 'permID' => $permissionID, + ) + ); + echo "User $userName lost the $permission permission.\n"; + } + } + + } else { + // If NO, nothing to do here because we will need to + // rebuild the rows in either case below + } + + // rebuild the roles in case users now meet all the + // remaining necessary permissions with which the role is associated + rebuildRoles(); +} + +//################################################################################## +// +// HELPER FUNCTIONS +// +//################################################################################## + +//TODO: Most of these functions should be moved into a +//Model class for user + +/** + * PrettyPrint + * + * Prints an array without the array keys + * + * @param array $array the array to be printed + * + * @return void + */ +function prettyPrint($array) +{ + foreach ($array as $child) { + echo "$child\n"; + } +} +/** + * Gets all the users in the database + * + * @return array Associative array ($userID=>$Real_name) + */ +function getUsers() +{ + $DB = \Database::singleton(); + + $users = $DB->pselectColWithIndexKey( + "SELECT ID, Real_name + FROM users", + array(), + "ID" + ); + + return $users; +} + +/** + * Gets the permission IDs associated to a user + * + * @param int $userID the user ID + * + * @return array non-associative array of IDs + */ +function getUserPermissionIDs($userID) +{ + $DB = \Database::singleton(); + + $userPermissions = $DB->pselectCol( + "SELECT permID + FROM user_perm_rel + WHERE userID=:UID", + array('UID' => $userID) + ); + + return $userPermissions; +} + +/** + * Gets the role IDs associated to a user + * + * @param int $userID the UserID + * + * @return array non-associative array of IDs + */ +function getUserRoleIDs($userID) +{ + $DB = \Database::singleton(); + + $userRoles = $DB->pselectCol( + "SELECT RoleID + FROM user_role_rel + WHERE UserID=:UID", + array('UID' => $userID) + ); + + return $userRoles; +} + +/** + * Checks if a given user has a given role + * + * @param int $userID the user ID + * @param int $roleID the role ID + * + * @return boolean + */ +function userHasRole($userID, $roleID) +{ + $DB = \Database::singleton(); + + $result = $DB->pselectOne( + "SELECT RoleID + FROM user_role_rel + WHERE UserID=:UID AND RoleID=:RID", + array( + 'UID' => $userID, + 'RID' => $roleID, + ) + ); + + if (empty($result)) { + return false; + } + return true; +} + +/** + * Checks if a given user has a given permission + * + * @param int $userID the user ID + * @param int $permissionID the permission ID + * + * @return boolean + */ +function userhasPermission($userID, $permissionID) +{ + $DB = \Database::singleton(); + + $result = $DB->pselectOne( + "SELECT userID + FROM user_perm_rel upr + WHERE userID=:UID AND permID=:PID", + array( + 'UID' => $userID, + 'PID' => $permissionID, + ) + ); + + if (empty($result)) { + return false; + } + return true; +} \ No newline at end of file