Skip to main content

OArepo Enrollment library for record metadata validation

Project description

oarepo-enrollment-permissions

Work in progress, do not use yet

image image image image image

OArepo Enrollment Permissions library is a bridge between oarepo-enrollment library and invenio records. It provides means to assign user permission to perform actions upon a record (list, update, delete, custom actions).

Installation

pip install oarepo-enrollment-permissions

Usage

  1. In your rest configuration, set search_class class either to oarepo_enrollment_permissions.RecordsSearch or to a class inheriting from oarepo_enrollment_permissions.RecordsSearchMixin.
  2. If your read_permission_factory_imp is not check_elasticsearch, be sure to include the result of oarepo_enrollment_permissions.read_permission_factory in your permission factory - see below for details).
  3. Use oarepo_enrollment_permissions.update_permission_factory as your update permission factory (or call if from your own permission factory - see below for details).
  4. Use oarepo_enrollment_permissions.delete_permission_factory as your delete permission factory (or call if from your own permission factory - see below for details).
  5. Use oarepo_enrollment_permissions.create_permission_factory as your create permission factory (or call if from your own permission factory - see below for details).

Now you are all set, no one has an access until granted.

Granting access

Access is granted via enrollment process. The following enrollment types are available:

Collection

Gives rights to manipulate with a collection. A collection is defined as records with the same values at a given json pointer (specified in configuration or passed to the enroll call).

To grant access to a collection on command-line, call:

invenio oarepo:enroll collection <email> <collection key> actions=read,update,delete,create

If you want to perform the same in REST API, call:

{
    'enrollment_type': "collection",
    'recipient': "someone@example.com",
    'external_key': 'test',
    'operation': 'read'
    // either comma separated or an array
}

Single record

You can grant rights to a single record as well. To do that, invoke:

invenio oarepo:enroll record <email> <record_uuid> actions=read,update,delete

Again, the same can be achieved via API:

{
    'enrollment_type': "record",
    'recipient': "someone@example.com",
    'external_key': '1234-...-1234',
    'operation': 'read'
    // either comma separated or an array
}

Listing and Revoking access

See oarepo-enrollment for help with these.

Customizing search/listing permissions

The provided search class (or mixin) behaves a bit differently than the default invenio RecordsSearch. For anonymous users, the default behaviour is to return empty collection. For authenticated users, enrollments are inspected and are used to filter the records.

This process can be customized via:

from oarepo_enrollment_permissions import RecordsSearch


class MyRecordsSearch(RecordsSearch):
    class Meta:
        # put customizations in here
        pass

Anonymous user

If anonymous user should get access to all/some records, specify default_anonymous_filter property on Meta class.

This property can be either elasticsearch query (Q, Bool) or it might be a function with a signature default_anonymous_filter(search=<RecordsSearch>, **kwargs) -> Union[Q, Bool]. The result of the function is passed to the default elasticsearch filter.

Authenticated user

On Meta class, invenio supports passing default_filter. For convenience reasons this library adds default_filter_factory(search=<RecordsSearch>, **kwargs) -> Union[Q, Bool] that takes precedence if used.

At first the library looks at all successful enrollments of the user whose handler contains get_elasticsearch_filter class method. Then these handlers are called (with the enrollments as parameters) to get filtering query.

There might be a default_filter defined on the search. If it is, the queries from handlers are combined with the default filter depending on the value of default_filter_mode Meta property:

  • or (the default value) - user is granted access if either default_filter or at least one of handler filters match
  • and - user is granted access if default_filter and at least one of handler filters match.

If there is no default_filter used, user is granted access to the record if at least one of handler filters match.

API

Implementing custom permission-enabled enrollment handler

To implement a custom permission-enabled handler, add the following methods:

from oarepo_enrollments import EnrollmentHandler
from invenio_accounts.models import User
from elasticsearch_dsl import Q


class MyCollectionAccess(EnrollmentHandler):
    def enroll(self, user: User, role=None, **kwargs) -> None:
        # no handling required for collections
        pass

    def revoke(self, user: User, role=None, **kwargs) -> None:
        # no handling required for collections
        pass

    def get_elasticsearch_filter(self, search=None, queryset=None, **kwargs):
        collections = []
        for enrollment in queryset:
            collection = enrollment.extra_data.get('collection')
            if collection:
                collections.append(collection)
        if collections:
            return Q('terms', collections=collections)
        return None

    def post_filter_elasticsearch_result(self, search=None, result=None, **kwargs):
        # can be used to hide metadata from results
        pass

Configuration

Collection permissions configuration

To use builtin collection permissions, you have to specify the path or query for filtering collections. There are two ways of doing that - global and per-search.

Global configuration

In your config file, set:

OAREPO_ENROLLMENT_PERMISSIONS_COLLECTION_FILTER = 'collection'

This can be either path in the document that will be placed to Q('terms', <path> = [allowed collections]) or it might be a callable (search=None, collections=None, **) that should return either elasticsearch Q or Bool.

Local configuration

Alternatively, define the path/callable on Meta:

from oarepo_enrollment_permissions import RecordsSearch
from elasticsearch_dsl import Q


class MyRecordsSearch(RecordsSearch):
    class Meta:
        permissions_collection_filter = 'collections'

        # or

        @classmethod
        def permissions_collection_filter(cls, search=None, collections=None, **kwargs):
            return Q('terms', collection__key=collections)

Record permissions configuration

Normally there is no need to override record configuration.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oarepo-enrollment-permissions-1.0.1.tar.gz (12.3 kB view hashes)

Uploaded Source

Built Distribution

oarepo_enrollment_permissions-1.0.1-py2.py3-none-any.whl (18.6 kB view hashes)

Uploaded Python 2 Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page