Version 17 (modified by 5 years ago) ( diff ) | ,
---|
Access Control & Permissions
Table of Contents
There are a number of different security policies available to allow either a simple system or else provide advanced functionality:
- S3AAA - Sahana's Access Control system
The default security policy has most data available to Read by anonymous users & Edit/Delete by registered users.
Registered Users are added to Roles.
- The 1st registered user gets the 'Administrator' role (id 1) by default
- All registered users get the 'Authenticated' role (id 2) by default
Control access to a Module
If all you need to do is to limit access to the controllers within 1 module, then this can be done whilst staying in the simple security policy.
You can configure options in the modules configuration in modules/templates/<template>/config.py
or models/000_config.py
:
- Add an
access = "|x|",
line to the relevant module section.- 'x' is the ID of the role that should be allowed access to the module
- This both hides the menu item & blocks access to the whole /module/ hierarchy.
Control access to Functions & Tables
You need to go up to security level 4, or above, in your modules/templates/<template>/config.py
or models/000_config.py
:
settings.security.policy = 3 # Apply Controller ACLs
or:
settings.security.policy = 4 # Apply both Controller and Function ACLs
You then need to populate specific access permissions in the s3_permission
table in the database.
- If there are no permissions defined for any user for a resource, then access is unrestricted.
- If a permission is defined for any user then all other users have no access at all unless explicitly granted (Users with the Administrator role are exempt - they always have access).
- These permissions would normally be set via PrePopulate but there is a powerful API available to add/modify roles via CLI scripts & it is also possible to do it by directly modifying the database.
In order for these checks to be done, then you need to set that module as restricted=True
in your modules/templates/<template>/config.py
or models/000_config.py
:
Control access to Tables
If you want to control access to the data in a table, no matter by which controller it is accessed, then you need to go up to security level 5, or above, in your modules/templates/<template>/config.py
or models/000_config.py
:
settings.security.policy = 5 # Apply Controller, Function and Table ACLs
Note: Controllers which don't use the S3 framework can bypass this security, so you should not develop such custom controllers where you need to keep the data secure.
Control access to Records
Records can have a Realm - the Realm Entity can be an individual Person, a Group, an Organisation (including Branches, Teams & Facilities), or other Person Entity (PE).
You can see the Person Entity Model here:
This allows control of access by Realm - so staff of 1 Organisation can see their records of a certain type yet not those for another Organisation in the same database.
You need to go up to security level 6, or above, in your modules/templates/<template>/config.py
or models/000_config.py
:
settings.security.policy = 6: Apply Controller, Function, Table ACLs and Entity Realm
NB This also requires an ACL to a role other than Anonymous, Authenticated or Admin. Resources are never realm-restricted for these 3 roles.
This functionality can be extended to support Hierarchy so that data restricted to a single organisation can be made available to all branches of that Organisation (however data owned by the Branch is by default only visible to members of the Branch):
settings.security.policy = 7: Apply Controller, Function, Table ACLs and Entity Realm + Hierarchy
Note that if an entity is specified on the ACL, then that is NOT hierarchical...only the Entity on the auth_membership record is.
This functionality can be extended yet further by allowing organisations to share their private data with selected individuals, teams, facilities and organisations that they wish to (this is done by delegating the access role to that other entity, as they can now decide which of their people get the access):
settings.security.policy = 8: Apply Controller, Function, Table ACLs, Entity Realm + Hierarchy and Delegations
Record Approval
When Record Approval is enabled, this limits access to records until they are approved, in addition to all the other options.
There are 2 additional permissions to grant to roles: Review (read unapproved) & Approve
Creating Roles and ACLs
See also: How Permission Rules Are Applied
Roles and ACLs are normally created during Prepopulate.
e.g.
- https://github.com/flavour/eden/blob/master/modules/templates/IFRC/auth_roles.csv
- Explanation of these roles: https://docs.google.com/document/d/1Jg8NfFAASOeRBALNSXLkA9bg1AcPHRXhr1V3CeA0TFA/edit
If you need to add ACLs after pre-pop (e.g. on a live production server):
- Have an auth_roles.csv with just the title row & the ACLs which you wish to add, e.g.:
uid,role,controller,function,uacl inv_super,Warehouse Super Editor,inv,req_match,READ
- Have a tasks.cfg with just the line to import the roles:
echo "*,import_role,auth_roles.csv" > /tmp/tasks.cfg
- Copy both of these files to a folder on the server (e.g. /tmp)
- Open a web2py shell:
w2p
- To clear all existing permissions (if you are doing a full replacement rather than just adding a new one):
s3db.s3_permission.truncate() db.commit()
- To import roles:
auth.override = True s3db.load_all_models() bi = s3base.S3BulkImporter() s3.import_role = bi.import_role protected = auth.PROTECTED auth.PROTECTED = [] request.env.request_method = "GET" path = os.path.join("/","tmp") bi.perform_tasks(path) db.commit() auth.PROTECTED = protected