Usage¶
Description part¶
The description part is called ACL within the library.
The following implementations are built-in:
- IdACL:
- the ACL applies to records identified by their internal Invenio UUIDs
- DefaultACL:
- the ACL applies to all records in a given schema(s)
- ElasticsearchACL:
- the ACL applies to all records in the given schema(s) that match the given ES query
- PropertyValueACL:
- simpler implementation of ElasticsearchACL. The ACL applies to all records in the given schema(s) whose named property/set of properties has a given value
Actors¶
Actor defines who has access to a set of resources identified by mapping above. The following implementations are built-in:
- UserActor:
- a set of users (direct enumeration) that have access
- RoleActor:
- a set of user roles that have access
- SystemRoleActor:
- an actor that matches anonymous users, authenticated users or everyone
Actors can also take data from the indexed document. For example, if the document contains a property “creator_id”, one can use RecordUserActor(…, path=’/creator_id’) to write an ACL matching the creator (whoever it is).
The following record actors are built-in:
- RecordUserActor:
- a set of users enumerated in a property in the indexed record
- RecordRoleActor:
- a set of user roles enumerated in a property in the indexed record
Again, these are extensible, so for example if the record metadata contains property faculty, one can write a custom PRBACRoleActor(role=’administrator’, parameter=’faculty’, path=’/faculty’) to assign rights to the correct faculty administrator defined in a local PRBAC (parametrized role-based access control) system - would match all users with prbac role “administrator[faculty=<value of faculty property in the document>]”
Admin interface¶
The ACLs and actors can be set in the admin interface (albeit not comfortably - we expect that the ACLs are created by your custom code/ui to restrict users to create only ACLs of certain type).
At first create an ACL Actor, in this example a Role ACL (make sure you have the role defined in User Management / Role tab).
In the second step map the actor to operation and records, for example property-value based:
Within Python code¶
Creating/Updating/Deleting ACLs
The ACL and Actors are normal sqlalchemy models, use them as usual. For example:
acl = DefaultACL(name='record default', schemas=[RECORD_SCHEMA],
operation='get',
originator=current_user)
user = User.query.filter(email='...').one()
actor = UserActor(name='VIP users', originator=test_users.u1,
users=[user])
db.session.add(acl)
db.session.add(actor)
To (re)apply the ACL to existing records do not forget to call:
from invenio_explicit_acls.proxies import current_explicit_acls
acl = ....
current_explicit_acls.reindex_acl(acl, delayed=False)
for cases when ACL is created / modified and:
from invenio_explicit_acls.proxies import current_explicit_acls
acl = .... # (a removed acl)
current_explicit_acls.reindex_acl_removed(acl, delayed=False)
when ACL has been removed.
Searching with current_user
To search records within a request for the current_user just replace RecordsSearch class with ACLRecordsSearch. For example:
index, doc_type = schema_to_index(RECORD_SCHEMA)
data = ACLRecordsSearch(index=index, doc_type=doc_type).execute().hits
For more info see https://invenio-search.readthedocs.io.
Searching on behalf of another user
Sometimes we need to search on behalf of another user or the current_user is not set (when working outside the request context, such as in celery task). The ACLs need to get:
- the user
- set of system roles, such as any_user, authenticated_user from invenio_access.permissions
from invenio_access.permissions import authenticated_user
tested_user = ...
data = ACLRecordsSearch(
index=index, doc_type=doc_type,
user=tested_user,
context = {
system_roles=[authenticated_user]
}
).execute().hits
Always provide system_roles. If not provided, SystemRoleActor will take them from g.identity which is probably not what you want in this context !