Page 1 of 2
Advanced Permission Management
Posted: Mon Aug 30, 2004 1:53 am
by livetronix
I am trying to setup an intranet management system with some very pain in the *** permission levels.
You can have 3 users: (more to come alter)
- Admin
- Employee
- Secretary
Each user should get access to certian areas and see certian links while the other should not.
Also users can be part of multiple groups. A user could be an Admin and an Employee. They're are also different companies
Company 1
-> Seattle Branch
-> Sacramento Branch
Company 2
-> New York
-> Dallas
There would be a super admin of all the companies that can add employees any permission, than there would be Seattle Branch Admin, etc.
I need a system that is very flexible and can be expanded upon easily without a whole rewrite.
It needs to work two ways:
1. On menu pages, don't show this link if user doesn't have permission.
2. Give permission denied if they try to access certian pages.
I know it's probably not going to be too friendly on the database but it is a requirement for this project.
Posted: Mon Aug 30, 2004 2:32 am
by feyd
sounds like a simple many-to-many relationship set up to me.
http://www.oreilly.com/catalog/javadtab ... r/ch02.pdf
you'll probably need a function to slap together all the permissions for any given location..
Posted: Mon Aug 30, 2004 8:26 pm
by Christopher
You probably don't need that complicated a system. I would suggest just having two fields in each user record: company and access. Company can contain a 1,2,3... so you can select data and display for only the user's company. The access field can be as simple as a comma delimited string: Admin,Employee,Secretary. Then for access control you can do something like this:
// assuming you have authenticated the user and stored info in session
$access = explode(',', $_SESSION['user']['access']);
$groups = array_intersect ($access, array('Admin', 'Employee'));
if ($groups) {
// access allowed
} else {
// access denied
}
Posted: Tue Aug 31, 2004 12:57 am
by livetronix
Arborint,
Thats a start, but here are a couple problems I feel I will face...
1. For Modular Purposes, I want to define the groups dynamically.
2. Somehow the Super Admin should be able to redefine permissions for specific users.
3. If a user is a member of multiple companies they could have multiple permissions.
I had a meeting with the people tonight, we kind of decided that they should pick there role on a menu. Since different roles have different admins. So at least we can limit them to one role and one company at a time - that should simplify the process.
IE: Groups: The user is a member of Admin, Secretary in Company 1 and Reviewer and Processor in Company 2.
Right now they are acting as a Sec in Company 1.
I don't know if that makes sense to anyone, I am kind of confused as it is.
Posted: Tue Aug 31, 2004 1:57 am
by livetronix
Code: Select all
User
UserID
Email
FirstName
LastName
Group
GroupID
GroupName
PermissionGroup
PermissionGroupID
PageID
GroupID
Level (Y, N, L) Yes, No, Limited
PermissionUser – overrides the group permissions
UserPermissionID
UserID
PageID
CompanyID
Level (Y, N, L) Yes, No, Limited
Page
PageID
Fuseaction
Session
SessionID
UserID
Hash
StartTimeStamp
LastTimeStamp
Company
CompanyID
CompanyName
CompanyUser
CompanyUserID
CompanyID
UserID
This is how I think the database could work. It should work the way I've concepulized things, is it the most productive way? Database heavey?
Posted: Tue Aug 31, 2004 7:33 am
by McGruff
I haven't used
phpgacl but it might be worth a look.
Posted: Tue Aug 31, 2004 9:15 am
by livetronix
McGruff wrote:I haven't used
phpgacl but it might be worth a look.
I looked at PHPGacl, the tutorial they have doesn't make any sense to me, it doesn't show how to use their confusing Admin Panel. Anyone used it before?
Posted: Wed Sep 01, 2004 4:35 am
by Christopher
1. For Modular Purposes, I want to define the groups dynamically.
Not sure what you mean here. I assume that the groups are just names that are specific to each implementation. In this case Admin/User, in another Teacher/Student. Or you could have a separate table where 1=Admin, 2=User and look up the descriptions.
2. Somehow the Super Admin should be able to redefine permissions for specific users.
Since the groups and companies are fields in each user's database record, the admin can updated them as needed. The example assumed that the groups had been previously loaded into a session var when the user signed-in. The example has array_intersect ($access, array('Admin', 'Employee')) where $access contains the groups from the user's record and array('Admin', 'Employee') are what are allowed to view this page.
3. If a user is a member of multiple companies they could have multiple permissions.
IE: Groups: The user is a member of Admin, Secretary in Company 1 and Reviewer and Processor in Company 2.
Right now they are acting as a Sec in Company 1.
The simplest would be to have a different account for each company. You could also make the format of the permissions with company and role info like "1:Admin,2:Admin,2:Secretary" but then they would have to select which role the were in. Multiple accounts for these people might be simpler. [/i][/quote]
Posted: Wed Sep 01, 2004 6:37 am
by McGruff
Posted: Wed Sep 01, 2004 9:08 pm
by Christopher
I have found that Java Best Practices are often PHP Worst Practices. Things like phpgacl are good examples of Java inspired overkill. It may be good for some massive system, but I got it working and never used it because it was too big, slow and complicated. The theories might be great.
Posted: Wed Sep 01, 2004 9:31 pm
by McGruff
You might be right about phpgacl - as I said I haven't used it.
Sorry I was a bit terse. However, db normalisation is important, whichever lanugage you're coding in. Storing all that data in one field is not a flexible solution, I think.
Posted: Thu Sep 02, 2004 2:00 am
by Christopher
Actually I think I was the one who was a bit terse, sorry.
I think my take on this is that it is not a database problem at all. I doubt the site would be doing any SELECTs on the "access" field. Maybe on an admin page somewhere, but certainly not a high traffic page.
The data in the "access" field is loaded once when the user is authenticated. Then I'm assuming that it is saved in the session (or a cookie). After that the access control code in a page uses the data in the session to check if the user has access to the page. You don't want to go to the database on each page for access control in PHP. In Java with data persistance or caching it is a whole different thing.
This is a case of the Perl coder in me beating up the Java coder in me (they fight a lot) and I lapse into string splitting, arrays and regexp. I have used similar (optimized) code on sites with >25k users so I know its fast and works. Also building the access fields is simply imploding the value of a multi-select form var. I doubt I would even head down the "1:Admin,2:Admin,2:Secretary" road, but it does only gets parsed once at authentication. Access control is still just an array check (e.g. array_intersect($access[$company], array('Admin', 'Employee')).
Finally I like the explicit, self documenting quality of code like:
if ($access->allow(array('Admin', 'Secretary')) {
or
$controller->allowAccess(array('Admin', 'Secretary'));
Posted: Thu Sep 02, 2004 3:45 am
by livetronix
I was going to program it as a multi query select to see if they have access.
Code: Select all
SELECT Level FROM UserPermission WHERE UserID = $UserID AND PageID = $PageID AND CompanyID = $CompanyID
if ($Level == Yes) {
// they have permission
} else {
// Load Groups User is IN
/* code here */
// Check permission
SELECT Level FROM GroupPermission WHERE GroupID = $GroupID AND PageID = $PageID
if ($Level == Yes) { // on any group since we take highest permission
// they have permission
} else {
// Permission Denied
}
}
Thats like an extra 3-4 queries per page, nothing huge. This site will be a log in only system and we will be making money from the logged in users so it doesn't have to be fast as lightening, but I don't want to build a system that chugs and is not scalable.
How would you do the authentication part looking at my database structure (posted above).
Posted: Thu Sep 02, 2004 4:18 pm
by McGruff
What about this (<--> denotes a many-to-many relationship and an intermediate join table, not shown):
user <--> user_groups <--> page_groups <--> pages
User_groups could be Seattle admin, Charleston employees, etc. Unless you need to find permissions based on level or company alone (which you don't, if I understand you right), that might be an acceptable denormalisation.
The super-admin is simply a user group with one member. Possibly there is no need for a parallel system of permissions allocated at the user and group levels.
The page_groups table (ie defined sections or areas of the site) might make managing permissions easier in the same way as the user groups table: ie you can assign groups of pages to user groups rather than one page at a time. Or it might not really be necessary.
A single INNER JOIN query gets all the user's permissions.
Posted: Thu Sep 02, 2004 6:11 pm
by livetronix
Only problem is permission levels should be, first group based and than user based.
IE: You can put a user in certian groups, but you have the ability to overwrite certian permission by specific user.
Plus for each individual company a member is involved in they should get a different permission basis. IE: SuperAdmin of one company but regular user of another company.
This is getting very confusing...