![]() |
Access Control List(s)?
Hey!
I'm wondering how to best achieve this thing that I want for my CMS. First of all, I want to be able to via the code decide what pages that can be viewed by what user based on usergroup and userstatus. An example is that some pages I want everyone to be able to see. Some pages I want only logged in members to see. And some pages I want logged in members with the usergroup of premium member(and higher) to see. Secondly, I want to be able to decide what features that can be USED by what user based on usergroup. An example is that .. say I have a feature called image statistic that shows the latest users who viewed another user's image in his gallery. I maybe only want admins to be able to use this feature. And thirdly, I want the users to decide the permissions they want to use on their profile/gallery aswell. And example is.. Say I've activated the feature image statistic for members(and higher). Then they will have access to that part of the control panel in their usercp. But I want to allow them to set who can view that "widget" on their profile/gallery. Some of the users might only want themselves to be able to see it. Some might want their friends to be able to see it. Some might want logged in users to see it. And some might want to allow this widget to be seen on their profile/gallery by guests(not logged in) - obviously only possible if the page is allowed to be viewed by guests. Obviously, I want the users to be able to set who can view their gallery/profile aswell. So basically, it's 4 lines of access controls. 1. I want to define what pages can be viewed by what user based on usergroup and userstatus. 2. I want to define what widgets can be used by what user based on usergroup. 3. I want users to be able to define what members can view their profile/gallery. 4. I want users to be able to define what widgets they want to use from a list of available widgets they are ALLOWED to use(read #2). Okay, long post that leads to nothing.. or does it? I'm wondering how I can create this the best way that provides easy to use functions that runs the checks matching the criterias above. |
ACL lists can be quite simple to use for a basis such as this,
Here is a breakdown of how it works All pages, widgets, features etc etc .. that you want to limit access would be considered resources Each usergroup would be considered as roles It would then be written in a manner such as Code:
if (role A) can access (resource B)php Code:
To use this you would do the following Have a 3 mysql tables that contain the following, assuming you already have the usergroup table you would need the following two resources ---------------------------------------- resourceId name resourcesAllow ---------------------------------------- resourceId roleId Map the role that are allowed to view each resource Example for roles roles ------------------------------------------ roleId name For the first call to the ACL you would do the following php Code:
There after it would only be php Code:
This is a very basic ACL .... Adding a removing resources, permissions would be quite simple through the administration and users could even create their own :) Hope this get u on a good start |
Thanks! I think I have a basic idea of a structure I want to use for this that will accomplish this quite easially.
The difficult part is the part to allow users to add their own permissions.. Perhaps something like this as a syntax. php Code:
That's for adding pages, features and roles. Will probably fetch all the roles, features and pages from the database and iterate through the result and add them automatically. We set the user by passing in the user object of the user so we can access the current users' usergroup for instance. php Code:
To see if the user viewing the page is allowed to view usercp. If they can, it checks if the user logged in can use the image statistic feature(where they will be able to set their own permissions for who can see the image statistic on their gallery). php Code:
Again, checks if the user viewing the page has access to view the page gallery. Then they check if they can see the feature image statistic in the current gallery(so we pass through the gallery id so we can check the permissions the gallery owner has set). Does that look OK? |
Here's the classes. Do you see any potential problems with this setup, please tell me! And if you know how to fix it, please say that too xD
PermissionList.php php Code:
PermissionUser.php php Code:
usage.php php Code:
This way I can: 1. Manage access on pages based on usergroups 2. Manage access to certain features that the users can activate in the gallery 3. Manage access to view certain features in the gallery based on the permissions set by the owner of the gallery(of course they can only set permissions on those features that the user is allowed to activate; read #2). I haven't tested it, because.. I don't have a user class to test it with yet, nor a database for this.. nor a website to actually test the different permissions. I just want to know if you see any problems in this solution, if it can be done better and if you think this is a good solution. Edit: Already spot a problem with this. I want the users to be able to have the option of allowing only users on their friendslist access a feature.. how would I do that? I can't really add that into a seperate ROLE.. |
at PermissionList.php,
PHP Code:
|
Quote:
|
1 Attachment(s)
Why separate the resources into three types and have three separate methods for each one as they are doing the same thing?
Here are the files to a more advanced ACL System It has the ability to do the following
|
Quote:
What if I have a feature called "blog", that would go into the resource "blog". Then also, I have a page called "blog", that would also be a resource "blog" - but wait, that won't work.. It already exists! And lastly, how do I store the permissions set by the owner of the blog into the "blog"(as used in $perm->canSee() function which checks if the viewing user can see the "blog" in this case, based on the permission set by the owner)? I can't store it as a resource.. because there are already 2 other "blog" resources.. That is, in my opinion, a flawed system. But maybe I've misunderstood how to use this.. Quote:
|
Quote:
But you would only need to setup the resources in a different named manner. For your blog example feature_blog page_blog Each blog "owner would have say" 23_blog - 23 being their userId Which then permissions can be set, it may seem a bit more complicated but it would be fairly the same as a naming convention that can be easily modified to suit your needs rather than having multiple methods that perform the same logic, which once your code starts scaling could lead to future bugs. A few more examples would be "23_blog_post_415_comment_edit" -> Resource:: UserId -> 23 Blog PostId -> 415 Comment editing "page_aboutme_view" -> Resource:: About me page viewing "widget_25_15_view" -> Resource:: WidgetId->25 UserId -> 15 Viewing |
Quote:
My only concern about that is.. won't there be like.. TONS of entries in that database table that has the resources?? And won't it be quite resource-demanding to search through the table if it contains tens of thousands of permission sets? |
No it would not be of any issue you can index the resource titles, I have dealt with database tables with a over a million entries and have not seen a noticeable performance hit due to queries as long you have the database properly indexed it
|
Aha, that sounds great.
One more thing though. I looked through the ACL system you zipped. First of all, it is far too advanced for me. But I got an idea from that system, that I want for my system. That is allowedUsers and disallowedUsers. Basically my tables would look something like this: Code:
Usergroups:My "usergroups" table would basically be like your "roles". My "perm_allowedGroups" would basically be like your "roleId" in your "resourcesAllow" table. As you see, I added allowedUsers and disallowedUsers. "allowedUsers" is so I can grant access to a specific user to a specific resource even if they are in a usergroup that originally DOESN'T have access to that resource. "disallowedUsers" is so I can remove access from a specific user to a specific resource even if they are in a usergroup that originally HAVE access to that resource. All that is good. But how would I do that in the PHP(in the ACL class) ?? |
To check for users that are in specific allow deny situations, you can quite easily use an array of users allowed / users denied for each role so a perm array might look something like
Code:
rray(4) {And you would do that logic at the same time you perform the group checking, just make sure that the user check are performed last to ensure the inheritance of permissions is correct |
Yea, the inheritance of permissions is the hard part..
How would I store an array in the database btw?? You can't really store an array as it is, can you? I was thinking of storing it as a string like "54, 32, 12" and then use split(', ') on the result when I fetch the string from database.. Can that be done any better? |
Nevermind. I just learned about serialize and unserialize.
Here's the function I did for isAllowed. php Code:
That way I can check 1. If the usergroup exists in AllowedGroups - allow but if the userid exists in DisallowedUsers - deny 2. If the usergroup does not exist in AllowedGroups - deny but if the userid exists in AllowedUsers - allow I think.. My only question now is.. how would I let my users set a permission that only users on their friendlist is allowed to see something?? |
You should check the deny for users individually outside both checking for user allow and group allow access as the deny permission is more strict it should override an allow for specific users, other than that it looks good
To set it to where users only on the friend list can view the resource when loading the page simply append the friend list ID's to the allowed users array |
Quote:
How would I reorganize my if-statements to do it your way then? *too tired* Quote:
But when I check the allowed users array, how would I know that the ID is a friendlist or a userid ?? By the way, thanks for all the help! I'm learning tons every day about this thanks to you :-) |
You would simply take the if statement for the deny check and drop it below the if statement for the group and user allow check puesdo code would be
Code:
if usergroup in allowlist:Code:
FriendsList TableQuote:
|
Quote:
Code:
if usergroup in allowedgroups_list OR userid in allowedusers_listQuote:
Like: friendlist- userid, friendid The problem I have though, is.. you remember this? Code:
["Allowed Users"]=>Like.. Your example about "23_blog_post_415_comment_edit" What if I want that user with id 23 to be allowed to have the option to allow the users on his friendlist to be able to edit the comments on his blogpost with id 415? My tables looks like this Code:
Usergroups:I'm TRYING to explain, but I'm not sure I'm explaining very good.. do you understand what I mean? |
You wouldn't have to worry about storing the friendlist ID, you would could set an option to allow a user to set a blog post comment editing for users on his friendslist.
Then once you parse out the friendlist add the userId from the friendlist table to the allowedUsers array So it would be something like Code:
Fetch user friendlist |
| All times are GMT. The time now is 01:45 AM. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0