Closed xLink closed 11 years ago
Class Permissions ->assignPermissions[ $user_id = array/id, $module, $permissions = array() ] ->getAvailablePermissionsTypes ->getUserPermissions[ $user_id, $module ] ->hasView[ $user_id, $module ] ->hasRead[ $user_id, $module ] ->hasSpecial[ $user_id, $module, $name ] <- name for all module specific perms
I would suggest something like the following (needs refined):
CREATE TABLE `users` (
`users_id` int unsigned not null auto_increment,
`users_name` varchar(16) not null,
/* Password, salt etc... */
PRIMARY KEY (users_id),
);
CREATE TABLE `permissions` (
`permissions_id` int unsigned not null auto_increment,
`permissions_key` varchar(16) not null 'Valid php identifier eg Site.Login.Allow',
`permissions_name` varchar(16) not null 'Human readable name eg Allow site login',
PRIMARY KEY (permissions_id),
UNIQUE KEY (permissions_key),
);
CREATE TABLE `roles` (
`roles_id` int unsigned not null auto_increment,
`roles_name` varchar(16) not null,
PRIMARY KEY (roles_id),
UNIQUE KEY (roles_name),
);
CREATE TABLE `roles_permissions` (
`roles_id` int unsigned not null 'Foreign key',
`permissions_id` int unsigned not null 'Foreign key',
PRIMARY KEY (roles_id, permissions_id),
INDEX `fk_roles_permissions$roles_id_idx` (roles_id ASC),
INDEX `fk_roles_permissions$permissions_id_idx` (permissions_id ASC),
CONSTRAINT `fk_roles_permissions$roles_id` FOREIGN KEY (roles_id) REFERENCES roles (roles_id) ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT `fk_roles_permissions$permissions_id` FOREIGN KEY (permissions_id) REFERENCES permissions (permissions_id) ON UPDATE NO ACTION ON DELETE NO ACTION,
) COMMENT 'Relate roles to permissions';
CREATE TABLE `roles_users` (
`roles_id` int unsigned not null 'Foreign key',
`users_id` int unsigned not null 'Foreign key',
PRIMARY KEY (roles_id, users_id),
INDEX `fk_roles_users$roles_id_idx` (roles_id ASC),
INDEX `fk_roles_users$users_id_idx` (users_id ASC),
CONSTRAINT `fk_roles_users$roles_id` FOREIGN KEY (roles_id) REFERENCES roles (roles_id) ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT `fk_roles_users$users_id` FOREIGN KEY (users_id) REFERENCES users (users_id) ON UPDATE NO ACTION ON DELETE NO ACTION,
) COMMENT 'Relate roles to users';
I have chosen to represent these as interfaces for brevity, more functions will need added for querying by name/id and adding/removing roles/permissions etc.
interface IPermission {
public $permission_id;
public $permission_key;
public $permission_name;
public getRoles(); //Get a list of roles with this permission
public getUsers(); //Get a list of users with this permission
}
interface IRole {
public $role_id;
public $role_name;
public getUsers(); //Get a list of users with this role
public getPermissions(); //Get a list of permissions for this role
public hasPermission($idOrKey); // Determine if this role has the given permission id/key
}
interface IUser {
public $user_id;
public $user_name;
public getRoles(); //Get a list of roles for this user
public getPermissions(); //Get a merged list of permissions for all roles this user has
public hasPermission($idOrKey); // Determine if this user has the given permission id/key
}
You would have a convention for the naming scheme for permission keys, something like ModuleName.Method eg: Blog.Post Blog.Delete Blog.Add
Or you could create a Modules and Modules_Users, Modules_Permissions table set and implement in a similar way to the users/permissions above.
Access control then becomes a case of something like this:
/* ... Authenticate the user... */
/* ... Populate the $currentUser IUser interface object...*/
if ($currentUser->isLoggedIn() && $currentUser->hasPermission('Blog.Post')) {
//Allow the user to post on the blog
}
Iccle, You raise some good points, but It'd be great if we could set permissions based on other criteria, such as the id the item (eg, set perms on the individual blog post).
That's how granular it should be.
That can be done fairly easily with the system hes got in place, with a few alterations.
The permissions table is going to be setup a bit like the Config table, so it can be a serialized array of perms, which the 'value' can either be a module or a url (for example) which then can be associated with the user perms/role
Going on from Iccle's post, Was thinking something like this, SO granular, that it can be set on a user or on a group.
Permissions Key | Permissions Name |
---|---|
USER.VIEW | View a user |
USER.LIST | View a list of users |
USER.VIEW_DETAILED | View a user in depth [Info they don't show to the public] |
USER.EDIT | Edit a user |
USER.DELETE | Delete a user |
USER.BAN | Ban a user site |
USER.KICK | Kick a user from the site |
USER.SWITCH | Login as this user |
BLOG.VIEW | View a Blog Post |
BLOG.LIST | View a list of blogs |
BLOG.POST | Post a Blog |
BLOG.DELETE | Delete A Blog |
ADMIN.LOGIN | View the admin UI |
ADMIN.SWITCH_USERS | Login to session pretending to be that user |
ADMIN.SHUTDOWN | Shutdown the site |
ADMIN.LOCK | Lock the site |
ADMIN.UPDATE | Update the CMS |
MODULES.INSTALL | Install a Module |
MODULES.UNINSTALL | Uninstall a Module |
MODULES.ENABLE | Enable a Module |
MODULES.DISABLE | Disable a Module |
MODULES.UPDATE | Update a Module |
THEMES.INSTALL | Install a Theme |
THEMES.UNINSTALL | Uninstall a Theme |
THEMES.ENABLE | Enable a Theme |
THEMES.DISABLE | Disable a Theme |
THEMES.UPDATE | Update a Theme |
Permissions ID (Int, 11) | Content ID (Int, 11) | Group_Id (int,11) |
---|---|---|
1 | 14 | 43 |
1 | 12 | |
323 |
the idea being you can set permissions on individual content, or just general areas, Meaning that permissions can be set generally or user specific.
having a think about it now, i think iccles approach isnt far of the bat, to apply the permissions to a user you should throw the user in a personal group, and apply the permissions to that, atleast in then your ensuring that the permissions can be overridden properly.
as for the rest of it, it sounds good tbh, keys should be referenced & uniqued with the group id, ie group 2 cant have 2x BLOG.READ flags set.
also this method allows modules to have their own setup of permissions, and integrated nicely into the CMS as a whole, which is always handy
Sounds good to be honest.
Permissions Class is Done, Needs a bit of testing still but valid for use now. https://github.com/cybershade/CSCMS/commit/fe4ada031f257358eadffec8758b3bf6220623f5
Im thinking we need a Permission Class, if nothing else it should implement functionality to apply permissions based on the page. Something like the forum should be able to take the permissions & implement them to its needs, but something as simple as an article module should be able to make use of a default permission system.
View = Can see the content on the site Read = Can read the content Post = Gives posting abilities, for the most part this will probably be down to the comments sys Reply = Gives replying abilities Edit = Editorial Access to the content Del = Removing Abilties Move = Moving the content, new alias on the system, to a new parent page etc Special = Any special access, probably used for Mod = Moderator Abilities