Permissioning - users and roles
Submitted by rainer on Tue, 05/20/2008 - 11:39
This is about what permission we want to implement in opentimesheet.
My first proposal:
- Group controllers can run all reports for projects in that group
- Group managers can create, approve and close projects in that group
- Group admins can add users to groups
- Group workers are not existent
A role in a supergroup inherits to all groups within this supergroup.

Subscribe comments
Comments
I'm indecisive what to define first: The permissions that the users may have or the way we store the permission.
Are the three groups enough? Should we have a 1:n mapping group->users for each of the rights or should we have a more complex solution? Something like:
Table "user_rights" (columns: user, group, permission):
- userA, <group>, controller.reports.report1
- userA, <group>, controller.reports.report2
- userA, <group>, controller.reports.report4
- userB, <group>, controller.reports.report3
- userC, <group>, controller.reports
User X wants to run report 3. Report 3 validates the authorization of User X for "userX, <group>, controller.reports.report3". User A does not have this right, User B does have it. User C also has the permission to run this report since he has the right to run *all* reports.
Again, this is a very granular solution but it does not require the user to go to the extremes. Some OTS-users will simply grant their managers two rights: "bigBoss, <group>, controller" and "bigBoss, <group>, manager".
To make the permission test as easy as possible in the report code, there should be a permission manager that provides a call like: PM.hasPermission(userCredential, requestedRight). We will need this anyways to handle the login-session for the API. Perhaps we should talk about sessions, credentials, and other ugly things in a separate thread.
BTW: I suggest that every API-call except login requires a user credential (or session-ID) as first parameter.
Hmmmm,
I know this may sound a bit boring, but why not use a tried-and-tested approach such as "Profiles"/"Roles" as used by many databases such as Oracle, etc? It's basically the same and the advantage is that people know the terms and are experienced with the concept (at least those who have worked with DBs) ?
Cause I am business driven, I'd prefer to start with concept development and later think about the implementation. But I agree that we should have credentials in each API call and I agree that there should be a kind of "permissioning manager" - means tier - to decide about permissions.
I would not differ reporting permissions.
I am not sure, if I got goran right but imho we have roles here: "manager", "controller", "worker", "admin". And we have permissions like "execute report", "enter time", "create user" ...
And to bridge over to daniel: I see permissions not flexible for the first release. Say we have roles a, b, c and we have permissions x, y, z. We can hardcode or better store in a "kind-of-static" table the assignments: a:x+y, b:z, c:x+z.
Then let the users simply have roles in groups. And on actions check the credentials against the users role.
So far, so unclear :-)
Hi,
well what I tried to say was this: I had the impression(!) that Daniel had the intention to desgin&implement a complete rights management (concept) instead of using something that is already there (i.e. the Oracle roles). My thought was to use something (i.e. some infrastructure/package) that is already there and wrap it with a nice interface so we can quickly go to implementing the timesheet functionality instead of fiddling with the infrastructure...
Hope I was a bit clearer this time.. shouldn't write blog posts that late;)
We cannot use database users and database roles for this. Several reasons... i.e. there are no roles in MySQL, won't have thousands of users in my DB system... But anyway, we can have a simple concept :-)
Yes, I had (and have) the intention to implement the complete rights management. I, too, would like to have a simple concept.
The concept outlined above isn't as complex as it might seem. For the user it is easy if she only configures the users to have the roles "manager", "controller" and so on. For the coders it means that they have to use one token ("controller.reports.report1") per task. When you write a report, you will have to know that you need the "controller" permission anyways, you will also know that you are writing a "report" and since there has to be a user readable name of the report, there is no problem to find a unique report name.
Matching the requested right against the user's rights isn't a hard job, too. I don't expect this to be the hard part of the authentication/authorization system.
Oh and one more reason not to use DB-permissions: It would be great to have a stable interface inside the OTS-code between "kernel" and "database" at some point. In OTS x.0 (x > 1) it might be useful to add support for other database engines than MySQL. Users searching for a simple time sheet application might not want to maintain a MySQL installation. For this audience, a PLSQL (or even XML) based backend might be great. ("Set up OTS and you are done. MySQL loved - but not needed.")
Back to the basics of OTS - we will not incorporate any business logic here (what a sophisticated reporting would be).
The only reporting-like functionality we should provide is an API call like giveTimes(user-credentials, group, timerange, includeSubgroups ... ) - to be defined.
Then leave the task of summation, rendering and whatever to the surrounding (using) legacy system. Again my strong believe in restrictions: We must not do more then the minimum in OTS kernel.
The permission check in the above scenario should be something like: Is the executor of giveTimes() a "controller" of "group" or a "controller" a superior group of "group".
KISS - principle is vital for success.