Changes between Initial Version and Version 1 of doc/developer/UserRolesArchitecture

11/06/06 10:37:06 (15 years ago)

First draft, new roles and permission architecture


  • doc/developer/UserRolesArchitecture

    v1 v1  
     2Original author: Benoit Grégoire, last modified: [[Timestamp]] 
     3= New user permission architecture, General model = 
     5== Stakeholders (Role and permission types) == 
     7Each role and permissions (rights) are relevent to one of the following object type or static object: 
     8 * Node 
     9 * Network 
     10 * Server 
     11 * Content 
     12These define the stakeholder types. 
     14Note:  The right to access a specific Content type will be a network right.  This way, we can define a "Beginer editor" and "Advanced editor" roles 
     16== Permissions == 
     17Permissions are defined in the code, all in a big PHP lookup table to allow easy translations. 
     18$PERMISSIONS['PERMISSION_ID'] = array(_("permission description"), STAKEHOLDER_TYPE); 
     20These roles id's must also be listed in a database table for relationships.  The database table will be generated by a synchronization script to keep it in sync.  An elegant way to run it is probably to put unside te catch block of an exception when there is a mismatch, easing the maintenance burden (only code needs to be modified when a permission type is added or deleted) 
     22En example of permission would be NODE_PERM_EDIT_METADATA.  Being a Node stakeholder type, the user who get's this permission gets to be allowed to edit the metadata of the specific node that this permission applies to. 
     24== Roles == 
     25Roles are administrator-definable group of permissions of the same type as the role (Node, Network, etc.).  For example, if we define the "Tech support" Node role, we can assign various Node permissions to this role, but only node permissions. 
     27If we then assign some user "Tech support" role for a specific node, that user is a "Tech support" stakeholder for that node. 
     29=== User types (system roles) === 
     30Wile administrators can define new roles, there is a need for a few SYSTEM defined roles that are always present.   
     31 * Anyone (annonymous)  
     32  * maybe just special-case an ID, like SPLASH_ONLY_USER? 
     33  * Exists for server, network, node, etc. 
     34 * Logged-in user 
     35 * Validated users 
     36 * Users in validation 
     38User validity levels (Allowed, Validation, etc.) map to system roles 
     40== Data model == 
     41The different stakeholder tables list user-role pairs 
     42Node (ex: curator) 
     43Network (ex: login multiple times, edit other people content, access to Reusable content library, etc.) 
     47== Groups == 
     48To keep things simple, there is no concept of groups in the classic sense.  Roles allow doing much the same thing, and are simpler. 
     50== Implicit permissions == 
     51To keep things simple, defining implicit permissions (such as making NETWORK_EDIT_ANY_NODE imply NODE_PERM_EDIT_METADATA for each node) will not be supported.  While this is a desireable feature, implementing a simple UI for this is not easy, and since most permissions apply to specific objects, the code to check them would be complex and have low performance. 
     53This means that when using permissions in the code, BOTH will have to be specified as allowed.  The API will be written to make this easy. 
     55Note that once again, properly defined roles do much the same thing.  (For example, a node owner can have a certain number of implicit permissions). 
     57== Sudo support == 
     58It would be extremely usefull to allow an administrator to masquerade as another user for testing pusposes.  Logging out would then get him back as the original user. 
     60= Handling insufficient permission = 
     61In the comon case, missing permissions should be handled through exceptions, Caught in MainUI.  This will solve two annoying problems, while getting rid of just about all current permission error handling code: 
     62        -If the user is not logged in (because of a timeout, or never logged-in), allow him to login. 
     63        -If the user doesnt have the necessary permission(s), inform him (telling which permission is missing) and allow to login as another user. 
     64In both cases, if the user successfully logs-in (with the rights permission), the get and post parameters are regenerated and the original operation is attempted again. 
     66TODO:  Discuss exception handling more in depth: 
     67 * where do we catch them 
     68 * where do we throw them 
     69 * corner cases 
     70 * how doe we define the exceptions (One exception sub-object per type?) 
     72= API = 
     73Security ou User???::hasPermission($permission, $object_id) (object may be a singleton) 
     74/** Allows the user to login if if not logged--in, or re-login if insufficient permission */ 
     76Security::getUsersWithPermission($permission, $target_object); //Return list of users with this permission 
     77Security::getUsersWithRole($role, $object_id); //Return an array of users with the given role.  If objects_id is null, all users with the specific role are returned, along with an array of objects for which they have this role.  Maybe this function won'T actually be implemented, as it's there mostly for reporting and sending notification of hotspots going down. 
     78Security::getPermissions($user);  //returns array of PERMISSION constants for this user. 
     80Security::hasPermission($permission, $target_object, $user);  //user is optionnal, if unspecified, the current user is used.  User can also be null, meaning that there is no user currently logged-in 
     81Security::hasEitherPermissions(array $permission, $target_object, $user); 
     82Security::hasAllPermissions(array $permission, $target_object, $user); 
     84Security::requirePermission($permission, $target_object, $user);  //These function return an exception and ultimately allow the user to login (or login as another user) to repeat hte operation 
     85Security::requireEitherPermissions(array $permission, $target_object, $user); 
     86Security::requireAllPermissions(array $permission, $target_object, $user); 
     88= Data model = 
     89permission_type table 
     90 * permission_id 
     92permission table 
     93 * permission_id REFERENCES permission_type 
     94 * stakeholder_table (Implicitely gives the object type)  
     96roles table 
     97 * role_id 
     98 * role_name (langstring_id ?) 
     101 * role_id REFERENCES roles 
     102 * permission_id REFERENCES role 
     103There is a check constraint that verifies that the role and permission type matches. 
     105One table per stakeholder type 
     107 * object_id 
     108 * user_id 
     109 * role 
     111== Problems to be solved by this == 
     112Example of things this will allow (this is only the list from Max Horvath, there are many more things waiting for this). 
     113 * Allow owners to have more granular permission to edit content (some can edit login, some not, etc.) 
     114 * Restrict user access to a single node (user_can_access_all_nodes, netowork permission) 
     115 * Fon-like: user can login only if his node is online 
     116 * Time limited internet usage 
     118== Why our own rights and permissions framework == 
     119Couldn't find one that allowed tying rights to instances of objects.  Otherwise, [ LiveUser] would have almost done the trick. 
     122TODO:  Discuss where this fits into auto-node creation