hicsail/anchor

Assign customized roles(scopes) with different permission levels to users

Opened this issue · 0 comments

Context

Scopes in hapi allow you to apply access restriction on individual routes. It’s a two step procedure where you need to 1-define a scope property on a route and 2-another scope property within the authenticated user credentials. Both scope properties are evaluated against each other.
To determine if a request is allowed to access the resource, hapi evaluates the required scope defined within config.auth.scope against the scope property defined within request.auth.credentials.

The purpose of this task is to refactor how we have done the second step mentioned above and provide the developers using anchor with an easy way to update the set of valid user scope/role strings based on the context in which anchor is being used without having to modify multiple parts of the code.

Current behavior

Right now the set of possible permission strings are hard coded(root, admin, researcher, clinician, analyst) and there is no clean way to update them.
So when the user with the highest privilege(currently root) wants to assign roles to other users through the UI shown below, root options for giving permission to other users is limited to the options hard coded in the UI code. (for example,these role names are valid in clinical applications while a lot of times we are using anchor in a context where some of these roles are not meaningful and/or we need to add new meaningful roles depending on the context of application)
The idea is to add a key to anchor general config file config.js containing permission name strings and their corresponding access levels.

user-roles

Expected behavior

We should be able to update the roles property in config.js and then the options for updating user roles on the UI above, should get updated automatically and api routes for promoting and demoting a user should be parameterized for the available roles in config.js So we only have one PUT api route for promoting a user to a specific role (role string passed as the request parameter) and one DELETE api route for demoting a user.

Steps

  • 1- Add a key with appropriate name (role) to config object in config.js file. Value for each key should be another object with at least a name property(string) and an accessLevel property(integer). (Later in an enhancement step, Updating/Creating role object inside 'config.js' should be integrated into our first time setup process).
    (For the first version you can start with the current available roles, [root, admin, researcher, clinician. analyst] with corresponding [5,4,3,2,1] access levels.

  • 2- Modify /roles web route in server/web/routes/users.js, so that inside route handler you get the roles object from config file and pass it to users/roles template when replying with the view.

  • 3- Update the roles table in server/web/templates/users/roles.handlebars, so that the role table is being created using the template variable(role object) passed to it. (In step 2, we have already passed role object from config.jsto our template, so inside our template we have access to it). You also need to update the java script code in server/web/public/scripts/users/roles.js to get rid of hard codded permission level but still have to toggle functionality for promote and demoting a user. promote and demote functions need to be updated as well.

  • 4- Right now for promoting or demoting a user, we have 2 separate api routes in server/api/users.js (one with method DELETE and another with method PUT) for each permission string meaning that with the current permission strings ['root', 'admin' ,'researcher', 'clinician', 'analyst'] in total we 10 api routes for updating a user roles and the role string is being hard coded in the route path.
    For example for promoting a user to be a researcher we have the /api/users/researcher/{id} PUT route and for demoting a user from being a researcher we have '/users/researcher/{id}' DELETE route even though the code inside these routes is very similar. The goal is to merge all PUT routes into one single '/api/users/{role}/{id}' route where we pass the role string as a request parameter and merge all DELETE routes into one single '/api/users/{role}/{id}' with role being the role string passed to our route as a request parameter.
    you need to add a pre step to this route for validating the role request parameter. The role request parameter is valid only if it exists in the role object in config.js file.

  • 5- Update tests. Since we are updating api functionality for promoting and demoting, we also need to update the tests for these api in test/server/api/users.js file. we have also updated /roles web route, so we need to update the test for it as well.