[[TOC]] = !BluePrint for Authorization (alternative version) = == General model == === Authorizable Methods === Authorization is implemented for the following methods: - module access (execute, all controllers of the module) - controller access (execute) - table access (create/read/update/delete and custom method) - record access (create/read/update/delete and custom method) === Basic Policy === Authorization policy is implemented as: - if a method is not restricted, then it is accessible for everyone - if a method is restricted, then permission must be explicitly granted, otherwise it is denied (Allow=>Deny order) === Roles === Permissions are assigned to roles (not to individual users): - roles are stored in '''auth_group''' - '''admin''' role is auth_group 1 (cannot be modified) - membership in the admin role overrides any restrictions everywhere - roles are assigned to users by '''auth_membership''' - this can happen either through admin UI or implicitly (no admin interaction) - it must be possible to log this - additional roles can be created after deployment - this will usually happen implicitly, i.e. not through admin UI - does not require a generic UI solution - roles of the actual user are re-read from the DB and stored in the session once per HTTP request - caching of this re-reading needs a proper method for cache invalidation on update notification - do not implement caching unless it really makes us performance problems There are two pseudo-roles for record access: - author (=the author of the record) - editor (=the last author of the record) == Functions == === Denial of access === {{{ shn_unauthorized(msg="You're not allowed to access this module") }}} - ''shn_unauthorized()'' realizes error notification and redirection as appropriate - non-interactive modes: - raise a HTTP error and a JSON error message - MUST NOT REDIRECT! - interactive modes, one of: - redirect (e.g. to login) and and display an error message on the target page (acceptable) - raise a HTTP error and display an error page, provide redirection options from the error page (more RESTful) - the ''msg'' argument is optional === Module/Controller Access === {{{ if shn_has_role("Facility Admin"): ... }}} - ''shn_has_role()'' refers to the current user - returns always True for sysadmins (auth_group 1) - ''shn_has_role()'' tests can be combined by '''and''', '''or''' and '''not''' === Table/Record Access === - Table auth_table_permissions: tablename, method, role - Table auth_record_permissions: tablename, method, record_id, role {{{shn_permit(table, method, role, id=None)}}} - adds ''role'' to the list of permitted roles for ''method'' on ''table'' (record ''id'' of the table) {{{shn_deny(table, method, role, id=None)}}} - removes ''role'' from the list of permitted roles for ''method'' on ''table'' (record ''id'' of the table) {{{shn_restrict(table, method, role=None, id=None)}}} - sets the list of permitted roles for method on table (record ''id'' of the table) to ''role'' {{{shn_permitted(table, method, id=None)}}} - returns True/False refering to the current user - returns always True for sysadmins (auth_group 1) - record restrictions override table permissions - table restrictions override record permissions {{{ def shn_permitted(table, method, id=None): roles = session.s3.roles # to be continued... }}} === Visibility of options === Extend MenuS3() to check for roles before inserting menu items. Currently: {{{ menu_option = [T("Option"), right=False, URL=url] }}} New: {{{ menu_option = [T("Option"), right=False, restrict=[list_of_roles], URL=url] }}} - hide all sub-items when the main-item is hidden - hide the main item when there are no more sub-items left? - better: instead of hiding, make options "gray" ---- BluePrints