xLink / CybershadeCMS

[Abandoned][Broke] Repo for CybershadeCMS
1 stars 0 forks source link

Permission Class #12

Closed xLink closed 11 years ago

xLink commented 11 years ago

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

MantisSTS commented 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

iccle commented 11 years ago

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
  }
NoelDavies commented 11 years ago

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.

MantisSTS commented 11 years ago

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

NoelDavies commented 11 years ago

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.

xLink commented 11 years ago

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

MantisSTS commented 11 years ago

Sounds good to be honest.

xLink commented 11 years ago

Permissions Class is Done, Needs a bit of testing still but valid for use now. https://github.com/cybershade/CSCMS/commit/fe4ada031f257358eadffec8758b3bf6220623f5