Access Control Design for the VM Module

Contents

Overview

At the time of writing, the access control system used in Sahana is being reworked. It previously used the PHP GACL library, which was a more complicated and use-case specific security framework. Now, however, Sahana's security system simply controls access to database data based on the data's classification level, a user's role, and whether or not that role is designated to create, view, update, or delete that classified information. Some details on this new system are available here: Sahana Data Security and Privacy Design, and low-level details of this system and how to interface with it can be found here: Sahana's New Access Control System.

Compliance with the VM module

Using this system of access control is very simple to do, and for many use cases in the VM module it is sufficient in allowing or denying the appropriate access. However, due to the VM module's nature and since it has its own set of roles and users (volunteers and site managers), Sahana's access control system was not enough for certain use cases. For example, if a volunteer would like to edit his own information, by solely using Sahana's system of data access control, he would not be able to update (or even view) his own information, since it is classified as 'Person Sensitive', and all volunteers are simple 'Registered Users', who do not have access at all to 'Person Sensitive' information. So, to work around these special cases, an additional system of access control had to be designed.

Auxiliary Access Control

The additional access control system used in the VM module is one that consists simply of 'requests', which can be thought of as use cases, and 'constraints', which together form the basic logic necessary to impose additional requirements to access control or to override Sahana's access control system.

Requests

All requests are stored in the vm_access_request database table. There should be an entry in this table for each request that you wish to impose additional constraints on. For each entry, you must store:

  • request_id - An integer to uniquely identify each request.
  • act - The 'act' parameter in the URL for the page being requested.
  • vm_action - The 'vm_action' parameter in the URL for the page being requested.
  • description - A short description for the page being requested to make it easier to modify access to and keep track of all requests. For convention, prefix the description with 'Display' if information is being displayed on the page, or 'process' if the page is processing system information. However, not complying with this naming convention will have no effect on the effectiveness of the access control system.


VM Constraints

All VM-specific constraints (such as ones to override other access control constraints under certain circumstances) are stored in the vm_access_constraint database table. As mentioned above, these constraints consist of either additional requirements to impose on access control for a request, or possible overrides of Sahana's data access control. For each entry, you must store:

  • constraint_id - A string to uniquely identify a constraint. For convention, prefix any new constraints with 'req_' if it is an additional possible requirement to impose, or 'ovr_' if it is a case to override any other access control constraints.
  • description - A short description for the page being requested to make it easier to modify access to and keep track of all constraints.

All of these constraints are checked against the requests made in the AccessController class. So, if a new constraint were to be added to this table, you would have to go into the AccessController and take appropriate action if it is found for a particular request.


Linking VM constraints and requests

To link constraints to requests, use the vm_access_constraint_to_request database table. For each entry, you must store:

  • request_id - The unique integer identifier of a request.
  • constraint_id - The unique string identifier of a constraint to impose on the request.


Data Classification Constraints

All data classification constraints (such as requiring permissions to the necessary database tables) are stored in the vm_access_classification_to_request table. For each entry, you must store:

  • request_id - The unique integer identifier of a request.
  • table_name - The name of the table you are checking permissions on.
  • crud - The types of permissions to request on this table.

Example

Now, to solve the problem before where a volunteer could not edit his own information, we simply look up the row in vm_access_request where 'act' is 'volunteer' and 'vm_action' is 'edit':

request_id act vm_action description
3 volunteer edit Display form for editing an existing volunteer's information


Look up the constraint to add in vm_access_constraint:

constraint_id description
ovr_my_info Full access is granted if it is the logged-in volunteer's own information


And link request_id 3 to constraint_id 'ovr_my_info':

request_id constraint_id
3 ovr_my_info


To make it simpler for administrators of the system to make these changes, a user interface in the 'Admin' module has been created to do so. Go to 'Module Config' -> 'Volunteer Management' -> 'Access Control Modifications'. You will be presented with a form to select a use case to modify access to:

Select an access request use case

Select a use case from the list and click 'Continue'. Now you can edit the access control settings by making your changes and clicking 'Save Changes':

Modify constraints on the access request

Future Development

Below is a description of how to modify access control settings that cannot be modified via the 'Admin' -> 'Module Config' -> 'Volunteer Management' -> 'Access Control Modifications' user interface.

  • Override conventions
    • To have the 'ovr_my_info' constraint work properly, the page to override access to must contain as either a $_POST or $_GET variable a parameter whose name is 'p_uuid' and whose value is the p_uuid of the person who has unconditional access to it.
    • To have the 'ovr_my_proj' constraint work properly, the page to override access to must contain as either a $_POST or $_GET variable a parameter whose name is 'proj_id' and whose value is the project ID for which being a part of will grant unconditional access to it.
    • To have the 'ovr_mgr_proj' constraint work properly, the page to override access to must contain as either a $_POST or $_GET variable a parameter whose name is 'proj_id' and whose value is the project ID for which being a site manager for will grant unconditional access to it.


  • To add a new access request use case, you must:
    • Add it to the vm_access_request table
    • If it requires any extra constraints, link the request to the constraints in the vm_access_constraint_to_request table
    • If it requires access to any database tables, specify them in the vm_access_classification_to_request table


  • To add a new type of special constraint, you must:
    • Add it to the vm_access_constraint table
    • Go to the AccessController::isAuthorized() function and look for the comment that says: //check for possible constraints imposed through the 'extra' array. Follow the pattern to add the logic necessary to check the new constraint.


  • For each implementation of the Controller interface (VolunteerController, ProjectController, etc.), you must add the following code at the beginning of the controlHandler() function:
$ac = new AccessController($getvars);
if(!$ac->isAuthorized())
    return;

An error message will automatically be output if access is denied.