[[TOC]] = !OrgAuth = !OrgAuth are security policies based on policy 5 (table-level permissions) which allow each of the organizations using the same instance of Sahana Eden to control who can access their respective data and with which permissions. == Realms == === Person Entities === A '''person entity''' is a type of records describing business entities which involve one or more individual persons. This can be, e.g., organisations, offices, teams, and of course persons. Person entity types implement the pr_pentity super-entity: {{{#!python table = define_table(tablename, super_link("pe_id", "pr_pentity"), ... s3db.configure(tablename, super_entity="pr_pentity", ... }}} To retrieve the person entity ID (pe_id) of any instance record, you can use: {{{#!python pe_id = s3db.pr_get_pe_id(tablename, record_id) }}} === Organisation Units === In an organizational structure, a person entity can be a sub-unit ('''organization unit''', OU) of another person entity. E.g. an office can be a sub-unit of an organisation, or a person a sub-unit of a team. - see also: [wiki:BluePrintPersonEntityModel BluePrint PersonEntityModel] - Epydocs for the PR Hierarchy API are here: [http://pub.nursix.org/eden/pr] Functions to introspect and manipulate the OU Hierarchy are in particular: - pr_add_affiliation - pr_remove_affiliation - pr_update_affiliations - pr_get_ancestors - pr_get_descendants === Realms === The '''realm''' of a person entity is the set of all records controlled ("owned") by this entity (="their data"). The realm which a particular record belongs to is encoded as person entity ID (pe_id) in the {{{realm_entity}}} field in this record. The "realm_entity" field - if present in the table - gets automatically populated in CRUD and Imports (during create), using the auth.s3_set_record_owner method. Where the realm entity can be determined from the record itself, you may wish it to be updated along with changes in the record. In this case, you can set the '''update_realm''' setting for the table to {{{True}}}: {{{#!python s3db.configure(tablename, update_realm=True) }}} Realm entity updates will propagate to all components listed under the '''realm_components''' setting: {{{#!python s3db.configure(tablename, update_realm=True, realm_components=["abc", "xyz"]) }}} The entity whose realm a record will belong to will be calculate according to the following (in order of decreasing priority): ==== 1. 'Global 'auth.realm_entity''' function: ==== It is possible to set a global method for the realm_entity hook in the config.py of the respective template: {{{#!python settings.auth.realm_entity = function }}} The global function must accept {{{(table, row)}}} as parameters, and return the pe_id (Person Entity ID) of the realm entity. If the function returns {{{0}}}, then set_record_owner will fall back to the table-specific realm_entity setting. ==== 2. Table '''realm_entity''' function: ==== {{{#!python s3db.configure(tablename, realm_entity = function_or_lambda) }}} The table function must accept {{{(table, row)}}} as parameters, and return the pe_id (Person Entity ID) of the realm entity. '''NOTE:''' As the global realm_entity function overrides any table-specific setting (this is deliberate), to retain a table specific setting, you must repeat it in the global realm_entity function. If the realm_entity hook returns {{{0}}}, then set_record_owner will fall back to the standard cascade (see below). ==== 4. {{{pe_id}}} field in record ==== This does not apply for pr_person records: individual users should not have their own realm as there is no per-user functionality to control their realm. ==== 5. {{{organisation_id}}} field in record ==== ==== 6. {{{site_id}}} field in record ==== ==== 7. {{{group_id}}} field in record ==== ==== 8. None ==== If none of the above apply, then the record will not belong to any realm. Where that is the case, the user's realms don't need to match the record's realm, whilst all other access restrictions still apply - i.e. the record is ''not'' "public", but rather "shared" across all realms. === Role Restrictions === In all !OrgAuth policies (6, 7 and 8), a role assignment for a user (and thus all the permissions the user receives out of this role) can be restricted to a particular realm: [[Image(orgauth1.png)]] - to remove role assignments, tick the respective checkboxes under "Roles Currently Assigned" and then click "Remove. - to assign another role, choose the role from the drop-down list under "Assign Another Role", choose the realm for the assignment from the ''"For Entity"'' drop-down and then click "Add". '''NOTE:''' The ANONYMOUS, AUTHENTICATED and ADMIN roles cannot be restricted to a realm, but always apply site-wide. The realm for each role assignment can be chosen from the ''"For Entity"'' list. This list is grouped by entity type (try scrolling down to see them all) and ordered alphabetically: [[Image(orgauth2.png)]] In this list there is also an entry for '''All Entities''' which means that this role assignment is ''not'' restricted to a realm, but applies ''site-wide'' (=for all records regardless of their respective realm entity). The entry '''Default Realm''' means all entities the user is (or will be) an organisation unit of at the time of the request authorization. '''NOTE:''' The "Default Realm" setting can be dangerous and may be inappropriate for most multi-tenancy settings, because the user would automatically receive this role for any entity they will ever join in future - without that entity being anyhow in control of this. However, in certain deployments, this dynamic realm may still be convenient practice. To check which realms a role of the current user applies for, you can access: {{{#!python realms = current.auth.user.realms[role] }}} This can either be a list of the PE IDs (=this role applies for all records where ''realm_entity'' belongs to this list) or None (=this role applies site-wide). === Realm Hierarchy === In policies 7 and 8, realms follow the OU '''hierarchy'''. That is, the realm of an entity includes all the realms of all organization units (OU) of this entity. === Access Delegation === !OrgAuth policy 8 additionally allows the '''delegation''' of access rights for a realm to other entities (rather than to particular users), thus facilitating controlled data sharing at the organization level. == Restriction Level == ||'''Policy'''||'''Role assignments are restricted to'''|| ||6||the realm of a person entity|| ||7||the realm of a person entity including the realms of any of its organisation units|| ||8||the realm of a person entity including the realms of any of its organisation units + delegated realms|| == Delegations of Permissions == A person entity can allow another entity to access records within their realm with the permissions of a certain user role. This is called "delegation". All users which are affiliated with the other entity (or any of its organisation units) can then exercise the permissions of the delegated role on the realm of the delegating entity provided they would have the same permissions for the realm of the other entity. Example: - if OrgA allows OrgB to access their realm with the "HR Editor" role, then all users affiliated with OrgB are permitted to edit human resource records of OrgA ''if'' they are permitted to edit human resource records for OrgB. '''NOTE:''' Delegations are not personal. If a user is no longer affiliated with the receiving entity, they can not receive permissions out of the delegations to this entity anymore - and vice versa. For personal delegations, it is better to use a direct role assignment for the realm of the delegating entity.