Esempio n. 1
0
def test_get_matching_users(app, db, es, test_users):
    with db.session.begin_nested():
        actor = UserActor(name='test',
                          originator=test_users.u1,
                          users=[test_users.u2])
        db.session.add(actor)
    assert [test_users.u2.id] == list(actor.get_matching_users())
Esempio n. 2
0
def test_get_elasticsearch_representation(app, db, es, test_users):
    with db.session.begin_nested():
        actor = UserActor(name='test',
                          originator=test_users.u1,
                          users=[test_users.u2])
        db.session.add(actor)
    assert [test_users.u2.id] == actor.get_elasticsearch_representation()
Esempio n. 3
0
def test_get_es_schema(app, db, es, test_users):
    with db.session.begin_nested():
        actor = UserActor(name='test',
                          originator=test_users.u1,
                          users=[test_users.u2])
        db.session.add(actor)

    assert {'type': 'integer'} == actor.get_elasticsearch_schema(ES_VERSION[0])
Esempio n. 4
0
def test_get_elasticsearch_query(app, db, es, test_users):
    with db.session.begin_nested():
        actor = UserActor(name='test',
                          originator=test_users.u1,
                          users=[test_users.u2])
        db.session.add(actor)
    assert Term(_invenio_explicit_acls__user=test_users.u3.id) == \
           actor.get_elasticsearch_query(test_users.u3, {'system_roles': [authenticated_user]})

    assert actor.get_elasticsearch_query(AnonymousUser(),
                                         {'system_roles': [any_user]}) is None
def test_get_record_no_acls_anonymous(app, db, es, es_acl_prepare, test_users):

    with db.session.begin_nested():
        # create an empty ACL in order to get the _invenio_explicit_acls filled
        acl = DefaultACL(name='test',
                         schemas=[RECORD_SCHEMA],
                         priority=0,
                         operation='get',
                         originator=test_users.u1)
        db.session.add(acl)
        actor = UserActor(name='test',
                          acl=acl,
                          users=[],
                          originator=test_users.u1)
        db.session.add(actor)

    pid, record = create_record({}, clz=SchemaEnforcingRecord)
    RecordIndexer().index(record)

    # make sure it is flushed
    current_search_client.indices.flush()

    # try to get it ...
    with app.test_client() as client:
        res = client.get(record_url(pid))
        assert res.status_code == 401  # unauthorized

    # get it directly from ES
    res = get_from_es(pid)['_source']
    assert res['control_number'] == pid.pid_value
    assert res['$schema'] == 'https://localhost/schemas/' + RECORD_SCHEMA
    assert '_invenio_explicit_acls' in res
Esempio n. 6
0
def test_rest_delete_record(app, db, es, es_acl_prepare, test_users):
    with app.test_client() as client:
        with db.session.begin_nested():
            acl = DefaultACL(name='default',
                             schemas=[RECORD_SCHEMA],
                             priority=0,
                             originator=test_users.u1,
                             operation='update')
            actor = UserActor(name='u1',
                              users=[test_users.u1],
                              acl=acl,
                              originator=test_users.u1)

            db.session.add(acl)
            db.session.add(actor)

        pid, record = create_record({'keywords': ['blah']},
                                    clz=SchemaEnforcingRecord)
        RecordIndexer().index(record)
        current_search_client.indices.refresh()
        current_search_client.indices.flush()

        login(client, test_users.u2)
        response = client.delete(record_url(pid))
        assert response.status_code == 403

        login(client, test_users.u1)
        response = client.delete(record_url(pid))
        assert response.status_code == 204

        with pytest.raises(NoResultFound):
            Record.get_record(pid.object_uuid)
Esempio n. 7
0
def test_str(app, db, test_users):
    with db.session.begin_nested():
        actor = UserActor(name='test',
                          originator=test_users.u1,
                          users=[test_users.u2])
        db.session.add(actor)
    assert 'UserActor[test]' == str(actor)
Esempio n. 8
0
def test_cli_full_reindex(app, db, es, capsys, es_acl_prepare, test_users):
    pid, record = create_record(
        {
            '$schema': RECORD_SCHEMA,
            'keywords': ['blah']
        },
        clz=SchemaEnforcingRecord)
    RecordIndexer().index(record)
    current_search_client.indices.flush()
    with db.session.begin_nested():
        acl = ElasticsearchACL(name='test',
                               schemas=[RECORD_SCHEMA],
                               priority=0,
                               operation='get',
                               originator=test_users.u1,
                               record_selector={'term': {
                                   'keywords': 'blah'
                               }})
        db.session.add(acl)
        u = UserActor(name='test',
                      acl=acl,
                      originator=test_users.u1,
                      users=[test_users.u1])
        db.session.add(u)

    # now the record is not indexed and ACL is not in the helper index, check it ...
    retrieved = RecordsSearch(
        index=schema_to_index(RECORD_SCHEMA)[0]).get_record(
            record.id).execute().hits[0].to_dict()
    assert '_invenio_explicit_acls' not in retrieved

    # just a precaution test
    assert current_explicit_acls.enabled_schemas == {RECORD_SCHEMA}

    # and run the reindex - should reindex one record
    from invenio_explicit_acls.cli import full_reindex_impl
    full_reindex_impl(verbose=True, records=True, in_bulk=False)

    captured = capsys.readouterr()
    assert captured.out.strip() == """
Reindexing ACLs
Updating ACL representation for "test" (%s) on schemas ['records/record-v1.0.0.json']
Getting records for schema records/record-v1.0.0.json
   ... collected 1 records
Adding 1 records to indexing queue""".strip() % (acl.id)

    current_search_client.indices.flush()

    retrieved = RecordsSearch(
        index=schema_to_index(RECORD_SCHEMA)[0]).get_record(
            record.id).execute().hits[0].to_dict()
    assert clear_timestamp(retrieved['_invenio_explicit_acls']) == [{
        'id':
        str(acl.id),
        'operation':
        'get',
        'timestamp':
        'cleared',
        'user': [1]
    }]
Esempio n. 9
0
def test_aclserializer(app, db, es, es_acl_prepare, test_users):
    with db.session.begin_nested():
        acl1 = DefaultACL(name='default',
                          schemas=[RECORD_SCHEMA],
                          priority=0,
                          originator=test_users.u1,
                          operation='get')
        actor1 = UserActor(name='auth',
                           users=[test_users.u1],
                           acl=acl1,
                           originator=test_users.u1)

        db.session.add(acl1)
        db.session.add(actor1)

    pid, rec = create_record({'title': 'blah'}, clz=SchemaEnforcingRecord)
    RecordIndexer().index(rec)
    current_search_client.indices.flush()

    assert current_jsonschemas.url_to_path(
        rec['$schema']) in current_explicit_acls.enabled_schemas
    assert list(DefaultACL.get_record_acls(rec)) != []

    index, doc_type = schema_to_index(RECORD_SCHEMA)
    data = current_search_client.get(index=index,
                                     doc_type=doc_type,
                                     id=str(pid.object_uuid))['_source']
    assert '_invenio_explicit_acls' in data
    assert len(data['_invenio_explicit_acls']) == 1

    with app.test_request_context():
        login_user(test_users.u1)
        set_identity(test_users.u1)

        acljson_serializer = ACLJSONSerializer(RecordSchemaV1,
                                               acl_rest_endpoint='recid',
                                               replace_refs=True)
        serialized = json.loads(acljson_serializer.serialize(pid, rec))
        assert serialized['invenio_explicit_acls'] == ["get"]

    with app.test_client() as client:
        login(client, test_users.u1)
        search_results = client.get(url_for('invenio_records_rest.recid_list'))
        search_results = get_json(search_results)
        hits = search_results['hits']['hits']
        assert len(hits) == 1
        assert hits[0]['invenio_explicit_acls'] == ["get"]
Esempio n. 10
0
def test_create_record_no_acls_authenticated(app, db, es, es_acl_prepare,
                                             test_users):
    with app.test_client() as client:

        with db.session.begin_nested():
            # create an empty ACL in order to get the _invenio_explicit_acls filled
            acl = DefaultACL(name='test',
                             schemas=[RECORD_SCHEMA],
                             priority=0,
                             operation='get',
                             originator=test_users.u1)
            db.session.add(acl)
            actor = UserActor(name='test',
                              acl=acl,
                              users=[],
                              originator=test_users.u1)
            db.session.add(actor)

        login(client, test_users.u1)
        response = client.post(records_url(),
                               data=json.dumps({
                                   'title': 'blah',
                                   'contributors': []
                               }),
                               content_type='application/json')
        # print("Response", response.get_data(as_text=True))
        assert response.status_code == 201

        created_record_metadata = get_json(response)['metadata']

        # check that ACLs are not leaking
        assert 'invenio_explicit_acls' not in created_record_metadata

        pid = PersistentIdentifier.get(
            'recid', created_record_metadata['control_number'])
        res = get_from_es(pid)['_source']

        assert res['control_number'] == pid.pid_value
        assert res['$schema'] == 'https://localhost/schemas/' + RECORD_SCHEMA
        assert '_invenio_explicit_acls' in res

        # still can not get it
        res = client.get(record_url(pid))
        assert res.status_code == 403  # Forbidden
Esempio n. 11
0
def test_user_matches(app, db, es, test_users):
    with db.session.begin_nested():
        actor = UserActor(name='test',
                          originator=test_users.u1,
                          users=[test_users.u2])
        db.session.add(actor)
    assert not actor.user_matches(test_users.u1,
                                  {'system_roles': [authenticated_user]})
    assert actor.user_matches(test_users.u2,
                              {'system_roles': [authenticated_user]})
    assert not actor.user_matches(test_users.u3,
                                  {'system_roles': [authenticated_user]})
    assert not actor.user_matches(AnonymousUser(),
                                  {'system_roles': [any_user]})
Esempio n. 12
0
def test_aclrecordsearch_returnall(app, db, es, es_acl_prepare, test_users):
    with db.session.begin_nested():
        acl1 = ElasticsearchACL(name='test', schemas=[RECORD_SCHEMA],
                                priority=0, operation='get', originator=test_users.u1,
                                record_selector={'term': {
                                    'keywords': 'test'
                                }})
        actor1 = SystemRoleActor(name='auth', system_role='any_user', acl=acl1, originator=test_users.u1)
        db.session.add(acl1)
        db.session.add(actor1)

    current_explicit_acls.reindex_acl(acl1, delayed=False)

    with app.test_client() as client:
        login(client, test_users.u1)
        response = client.post(records_url(),
                               data=json.dumps({'title': 'blah', 'contributors': [], 'keywords': ['blah']}),
                               content_type='application/json')
        assert response.status_code == 201
        rest_metadata = get_json(response)['metadata']
        assert 'control_number' in rest_metadata

    # make sure indices are flushed
    current_search_client.indices.refresh()
    current_search_client.indices.flush()

    index, doc_type = schema_to_index(RECORD_SCHEMA)

    record_uuid = PersistentIdentifier.get('recid', rest_metadata['control_number']).object_uuid
    with app.test_request_context():
        login_user(test_users.u1)
        set_identity(test_users.u1)
        assert current_user == test_users.u1

        # acl1 does not apply to the resource so the search must return no data
        assert not len(
            ACLRecordsSearch(index=index, doc_type=doc_type, operation='get').get_record(record_uuid).execute())

        # when acl_return_all is specified, return all matching records regardless of ACL
        with_all = ACLRecordsSearch(index=index, doc_type=doc_type).acl_return_all().get_record(
            record_uuid).execute().hits
        assert len(with_all) == 1
        assert with_all[0]['_invenio_explicit_acls'] == []

    # add another acl, this one maps to the record
    with db.session.begin_nested():
        acl2 = ElasticsearchACL(name='test', schemas=[RECORD_SCHEMA],
                                priority=0, operation='get', originator=test_users.u1,
                                record_selector={'term': {
                                    'keywords': 'blah'
                                }})
        actor2 = UserActor(name='u2', users=[test_users.u2], acl=acl2, originator=test_users.u1)
        db.session.add(acl2)
        db.session.add(actor2)

    current_explicit_acls.reindex_acl(acl2, delayed=False)

    # make sure indices are flushed
    current_search_client.indices.refresh()
    current_search_client.indices.flush()

    # for the same user acl_return_all() must return the record and effective acls
    with app.test_request_context():
        login_user(test_users.u1)
        set_identity(test_users.u1)

        # when acl_return_all is specified, return all matching records regardless of ACL
        with_all = ACLRecordsSearch(index=index, doc_type=doc_type).acl_return_all().get_record(
            record_uuid).execute().hits
        assert len(with_all) == 1
        assert clear_timestamp(with_all[0].to_dict()['_invenio_explicit_acls']) == [
            {
                'operation': 'get',
                'id': acl2.id,
                'timestamp': 'cleared',
                'user': [2]
            }
        ]

    # for user2 plain ACLRecordsSearch must return the record and effective acls
    with app.test_request_context():
        login_user(test_users.u2)
        set_identity(test_users.u2)
        # when acl_return_all is specified, return all matching records regardless of ACL
        with_all = ACLRecordsSearch(index=index, doc_type=doc_type).get_record(record_uuid).execute().hits
        assert len(with_all) == 1
        assert clear_timestamp(with_all[0].to_dict()['_invenio_explicit_acls']) == [
            {
                'operation': 'get',
                'id': acl2.id,
                'timestamp': 'cleared',
                'user': [2]
            }
        ]
Esempio n. 13
0
def test_aclrecordsearch_explicit_user(app, db, es, es_acl_prepare, test_users):
    current_explicit_acls.prepare(RECORD_SCHEMA)

    with db.session.begin_nested():
        acl1 = DefaultACL(name='test', schemas=[RECORD_SCHEMA],
                          priority=0, operation='get', originator=test_users.u1)
        actor1 = UserActor(name='auth', acl=acl1, users=[test_users.u1], originator=test_users.u1)
        db.session.add(acl1)
        db.session.add(actor1)

    current_explicit_acls.reindex_acl(acl1, delayed=False)

    record_uuid = uuid.uuid4()
    data = {'title': 'blah', 'contributors': [], 'keywords': ['blah']}
    recid_minter(record_uuid, data)
    rec = SchemaEnforcingRecord.create(data, id_=record_uuid)
    RecordIndexer().index(rec)

    current_search_client.indices.refresh()
    current_search_client.indices.flush()

    rs = ACLRecordsSearch(user=test_users.u1, context={
        'system_roles': ['authenticated_user']
    })
    rec_id = str(rec.id)
    print(json.dumps(rs.query(Ids(values=[rec_id])).query.to_dict(), indent=4))
    assert rs.query(Ids(values=[rec_id])).query.to_dict() == {
        "bool": {
            "minimum_should_match": "100%",
            "filter": [
                {
                    "bool": {
                        "should": [
                            {
                                "nested": {
                                    "path": "_invenio_explicit_acls",
                                    "_name": "invenio_explicit_acls_match_get",
                                    "query": {
                                        "bool": {
                                            "must": [
                                                {
                                                    "term": {
                                                        "_invenio_explicit_acls.operation": "get"
                                                    }
                                                },
                                                {
                                                    "bool": {
                                                        "minimum_should_match": 1,
                                                        "should": [
                                                            {
                                                                "terms": {
                                                                    "_invenio_explicit_acls.role": [
                                                                        1
                                                                    ]
                                                                }
                                                            },
                                                            {
                                                                "term": {
                                                                    "_invenio_explicit_acls.user": 1
                                                                }
                                                            },
                                                            {
                                                                "terms": {
                                                                    "_invenio_explicit_acls.role": [
                                                                        1
                                                                    ]
                                                                }
                                                            },
                                                            {
                                                                "terms": {
                                                                    "_invenio_explicit_acls.system_role": [
                                                                        "authenticated_user"
                                                                    ]
                                                                }
                                                            },
                                                            {
                                                                "term": {
                                                                    "_invenio_explicit_acls.user": 1
                                                                }
                                                            }
                                                        ]
                                                    }
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        ],
                        "minimum_should_match": 1
                    }
                }
            ],
            "must": [
                {
                    "ids": {
                        "values": [
                            rec_id
                        ]
                    }
                }
            ]
        }
    }

    hits = list(ACLRecordsSearch(user=test_users.u1, context={
        'system_roles': [authenticated_user]
    }).get_record(rec.id).execute())

    assert len(hits) == 1
    assert hits[0].meta.id == rec_id
    print(hits)

    hits = list(ACLRecordsSearch(user=test_users.u2, context={
        'system_roles': [authenticated_user]
    }).get_record(rec.id).execute())
    assert hits == []
def test_change_acl_mapping(app, db, es, es_acl_prepare, test_users):
    pid, record = create_record({'$schema': RECORD_SCHEMA, 'keywords': ['blah']}, clz=SchemaEnforcingRecord)
    pid1, record1 = create_record({'$schema': RECORD_SCHEMA, 'keywords': ['test']}, clz=SchemaEnforcingRecord)
    RecordIndexer().index(record)
    RecordIndexer().index(record1)
    current_search_client.indices.flush()

    with db.session.begin_nested():
        acl = ElasticsearchACL(name='test', schemas=[RECORD_SCHEMA],
                               priority=0, operation='get', originator=test_users.u1,
                               record_selector={'term': {
                                   'keywords': 'blah'
                               }})
        actor = UserActor(users=[test_users.u1], acl=acl, originator=test_users.u1)
        db.session.add(acl)
        db.session.add(actor)

    current_explicit_acls.reindex_acl(acl, delayed=False)
    current_search_client.indices.flush()

    index, doc_type = schema_to_index(RECORD_SCHEMA)

    hits = current_search_client.search(
        index=index,
        doc_type=doc_type,
        body={
            'query': {
                'nested': {
                    'path': '_invenio_explicit_acls',
                    'query': {
                        'term': {
                            '_invenio_explicit_acls.id': str(acl.id)
                        }
                    }
                }
            },
            '_source': False
        }
    )['hits']['hits']

    assert len(hits) == 1
    assert hits[0]['_id'] == str(pid.object_uuid)

    with db.session.begin_nested():
        acl.record_selector = {
            'term': {
                'keywords': 'test'
            }
        }
        db.session.add(acl)

    current_explicit_acls.reindex_acl(acl, delayed=False)
    current_search_client.indices.flush()

    hits = current_search_client.search(
        index=index,
        doc_type=doc_type,
        body={
            'query': {
                'nested': {
                    'path': '_invenio_explicit_acls',
                    'query': {
                        'term': {
                            '_invenio_explicit_acls.id': str(acl.id)
                        }
                    }
                }
            },
            '_source': False
        }
    )['hits']['hits']

    assert len(hits) == 1
    assert hits[0]['_id'] == str(pid1.object_uuid)
Esempio n. 15
0
def test_rest_update_record(app, db, es, es_acl_prepare, test_users):
    with app.test_client() as client:
        with db.session.begin_nested():
            acl = DefaultACL(name='default',
                             schemas=[RECORD_SCHEMA],
                             priority=0,
                             originator=test_users.u1,
                             operation='update')
            actor = UserActor(name='u1',
                              users=[test_users.u1],
                              acl=acl,
                              originator=test_users.u1)

            db.session.add(acl)
            db.session.add(actor)

        pid, record = create_record({'keywords': ['blah']},
                                    clz=SchemaEnforcingRecord)
        RecordIndexer().index(record)
        current_search_client.indices.refresh()
        current_search_client.indices.flush()

        login(client, test_users.u1)
        response = client.put(record_url(pid),
                              data=json.dumps({
                                  'keywords': ['test'],
                                  'title': 'blah',
                                  'contributors': []
                              }),
                              content_type='application/json')
        assert response.status_code == 200

        # put valid but relative schema
        response = client.put(record_url(pid),
                              data=json.dumps({
                                  'keywords': ['test'],
                                  'title':
                                  'blah',
                                  'contributors': [],
                                  '$schema':
                                  'records/record-v1.0.0.json'
                              }),
                              content_type='application/json')
        assert response.status_code == 200

        rec1 = Record.get_record(pid.object_uuid)
        assert rec1['keywords'] == ['test']
        assert rec1['$schema'] == 'https://localhost/schemas/' + RECORD_SCHEMA

        login(client, test_users.u2)
        response = client.put(record_url(pid),
                              data=json.dumps({
                                  'keywords': ['test1'],
                                  'title': 'blah',
                                  'contributors': [],
                              }),
                              content_type='application/json')
        assert response.status_code == 403

        rec1 = Record.get_record(pid.object_uuid)
        assert rec1['keywords'] == ['test']  # check value not overwritten

        # try to pu invalid schema
        login(client, test_users.u1)
        response = client.put(record_url(pid),
                              data=json.dumps({
                                  'keywords': ['test-invalid'],
                                  'title':
                                  'blah-invalid',
                                  'contributors': [],
                                  '$schema':
                                  'https://localhost/invalid-schema'
                              }),
                              content_type='application/json')
        assert response.status_code == 400
Esempio n. 16
0
def test_cli_explain(app, db, es, capsys, es_acl_prepare, test_users):
    check_explain(capsys, {'$schema': RECORD_SCHEMA, 'keywords': ['blah']}, """
Possible ACLs
Checking ACLs of type <class 'invenio_explicit_acls.acls.default_acls.DefaultACL'>
Checking ACLs of type <class 'invenio_explicit_acls.acls.elasticsearch_acls.ElasticsearchACL'>
Will run percolate query on index invenio_explicit_acls-acl-v1.0.0-records-record-v1.0.0 and doc_type _doc:
{
"query": {
"bool": {
"must": [
{
"percolate": {
"field": "__acl_record_selector",
"document": {
"$schema": "records/record-v1.0.0.json",
"keywords": [
"blah"
]
}
}
},
{
"term": {
"__acl_record_type": "elasticsearch"
}
}
]
}
}
}
Checking ACLs of type <class 'invenio_explicit_acls.acls.id_acls.IdACL'>
Checking ACLs of type <class 'invenio_explicit_acls.acls.propertyvalue_acls.PropertyValueACL'>
Will run percolate query on index invenio_explicit_acls-acl-v1.0.0-records-record-v1.0.0 and doc_type _doc:
{
"query": {
"bool": {
"must": [
{
"percolate": {
"field": "__acl_record_selector",
"document": {
"$schema": "records/record-v1.0.0.json",
"keywords": [
"blah"
]
}
}
},
{
"term": {
"__acl_record_type": "propertyvalue"
}
}
]
}
}
}
The record is not matched by any ACLs
    """)

    with db.session.begin_nested():
        acl = ElasticsearchACL(name='test', schemas=[RECORD_SCHEMA],
                               priority=0, operation='get', originator=test_users.u1,
                               record_selector={'term': {
                                   'keywords': 'blah'
                               }})
        db.session.add(acl)
        u = UserActor(name='test', acl=acl, originator=test_users.u1, users=[test_users.u1])
        db.session.add(u)
    acl.update()

    current_search_client.indices.refresh()
    current_search_client.indices.flush()

    check_explain(capsys, {}, """Please add $schema to record metadata""")
    check_explain(capsys, {'$schema': RECORD_SCHEMA, 'keywords': ['blah']}, """
Possible ACLs
ElasticsearchACL "test" (%(acl_id)s) on schemas ['records/record-v1.0.0.json']
actors = ['UserActor[test]']
created = 2019-05-10 11:27:26.013084
id = ebb91d27-70fd-4077-b6e1-6aadd7fa0bcd
name = test
operation = get
originator = User <id=1, [email protected]>
originator_id = 1
priority_group = default
record_selector = {'term': {'keywords': 'blah'}}
schemas = ['records/record-v1.0.0.json']
type = elasticsearch
updated = 2019-05-10 11:27:26.013093

Checking ACLs of type <class 'invenio_explicit_acls.acls.default_acls.DefaultACL'>
Checking ACLs of type <class 'invenio_explicit_acls.acls.elasticsearch_acls.ElasticsearchACL'>
   Will run percolate query on index invenio_explicit_acls-acl-v1.0.0-records-record-v1.0.0 and doc_type _doc:
        {
            "query": {
                "bool": {
                    "must": [
                        {
                            "percolate": {
                                "field": "__acl_record_selector",
                                "document": {
                                    "$schema": "records/record-v1.0.0.json",
                                    "keywords": [
                                        "blah"
                                    ]
                                }
                            }
                        },
                        {
                            "term": {
                                "__acl_record_type": "elasticsearch"
                            }
                        }
                    ]
                }
            }
        }
    found match: "test" (%(acl_id)s) on schemas ['records/record-v1.0.0.json'] with priority of 0
         UserActor[test]
Checking ACLs of type <class 'invenio_explicit_acls.acls.id_acls.IdACL'>
Checking ACLs of type <class 'invenio_explicit_acls.acls.propertyvalue_acls.PropertyValueACL'>
   Will run percolate query on index invenio_explicit_acls-acl-v1.0.0-records-record-v1.0.0 and doc_type _doc:
        {
            "query": {
                "bool": {
                    "must": [
                        {
                            "percolate": {
                                "field": "__acl_record_selector",
                                "document": {
                                    "$schema": "records/record-v1.0.0.json",
                                    "keywords": [
                                        "blah"
                                    ]
                                }
                            }
                        },
                        {
                            "term": {
                                "__acl_record_type": "propertyvalue"
                            }
                        }
                    ]
                }
            }
        }

Of these, the following ACLs will be used (have the highest priority):
     "test" (%(acl_id)s) on schemas ['records/record-v1.0.0.json']
         UserActor[test]

The ACLs will get serialized to the following element
{
    "_invenio_explicit_acls": [
        {
            "operation": "get",
            "id": "%(acl_id)s",
            "timestamp": "2019-05-10T10:24:21.812875+00:00",
            "user": [
                1
            ]
        }
    ]
}
""".strip() % {'acl_id': str(acl.id)})

    check_explain(capsys, {'$schema': 'https://localhost/schemas/' + RECORD_SCHEMA, 'keywords': ['blah']}, """
Possible ACLs
ElasticsearchACL "test" (%(acl_id)s) on schemas ['records/record-v1.0.0.json']
actors = ['UserActor[test]']
created = 2019-05-10 11:27:26.013084
id = ebb91d27-70fd-4077-b6e1-6aadd7fa0bcd
name = test
operation = get
originator = User <id=1, [email protected]>
originator_id = 1
priority_group = default
record_selector = {'term': {'keywords': 'blah'}}
schemas = ['records/record-v1.0.0.json']
type = elasticsearch
updated = 2019-05-10 11:27:26.013093

Checking ACLs of type <class 'invenio_explicit_acls.acls.default_acls.DefaultACL'>
Checking ACLs of type <class 'invenio_explicit_acls.acls.elasticsearch_acls.ElasticsearchACL'>
   Will run percolate query on index invenio_explicit_acls-acl-v1.0.0-records-record-v1.0.0 and doc_type _doc:
        {
            "query": {
                "bool": {
                    "must": [
                        {
                            "percolate": {
                                "field": "__acl_record_selector",
                                "document": {
                                    "$schema": "https://localhost/schemas/records/record-v1.0.0.json",
                                    "keywords": [
                                        "blah"
                                    ]
                                }
                            }
                        },
                        {
                            "term": {
                                "__acl_record_type": "elasticsearch"
                            }
                        }
                    ]
                }
            }
        }
    found match: "test" (%(acl_id)s) on schemas ['records/record-v1.0.0.json'] with priority of 0
         UserActor[test]
Checking ACLs of type <class 'invenio_explicit_acls.acls.id_acls.IdACL'>
Checking ACLs of type <class 'invenio_explicit_acls.acls.propertyvalue_acls.PropertyValueACL'>
   Will run percolate query on index invenio_explicit_acls-acl-v1.0.0-records-record-v1.0.0 and doc_type _doc:
        {
            "query": {
                "bool": {
                    "must": [
                        {
                            "percolate": {
                                "field": "__acl_record_selector",
                                "document": {
                                    "$schema": "https://localhost/schemas/records/record-v1.0.0.json",
                                    "keywords": [
                                        "blah"
                                    ]
                                }
                            }
                        },
                        {
                            "term": {
                                "__acl_record_type": "propertyvalue"
                            }
                        }
                    ]
                }
            }
        }

Of these, the following ACLs will be used (have the highest priority):
     "test" (%(acl_id)s) on schemas ['records/record-v1.0.0.json']
         UserActor[test]

The ACLs will get serialized to the following element
{
    "_invenio_explicit_acls": [
        {
            "operation": "get",
            "id": "%(acl_id)s",
            "timestamp": "2019-05-10T10:24:21.812875+00:00",
            "user": [
                1
            ]
        }
    ]
}
""".strip() % {'acl_id': str(acl.id)})

    check_explain(capsys, {'$schema': RECORD_SCHEMA, 'keywords': ['aaa']}, """
Possible ACLs
ElasticsearchACL "test" (%(acl_id)s) on schemas ['records/record-v1.0.0.json']
actors = ['UserActor[test]']
name = test
operation = get
originator = User <id=1, [email protected]>
priority_group = default
record_selector = {'term': {'keywords': 'blah'}}
schemas = ['records/record-v1.0.0.json']
type = elasticsearch
Checking ACLs of type <class 'invenio_explicit_acls.acls.default_acls.DefaultACL'>
Checking ACLs of type <class 'invenio_explicit_acls.acls.elasticsearch_acls.ElasticsearchACL'>
Will run percolate query on index invenio_explicit_acls-acl-v1.0.0-records-record-v1.0.0 and doc_type _doc:
{
"query": {
"bool": {
"must": [
{
"percolate": {
"field": "__acl_record_selector",
"document": {
"$schema": "records/record-v1.0.0.json",
"keywords": [
"aaa"
]
}
}
},
{
"term": {
"__acl_record_type": "elasticsearch"
}
}
]
}
}
}
Checking ACLs of type <class 'invenio_explicit_acls.acls.id_acls.IdACL'>
Checking ACLs of type <class 'invenio_explicit_acls.acls.propertyvalue_acls.PropertyValueACL'>
Will run percolate query on index invenio_explicit_acls-acl-v1.0.0-records-record-v1.0.0 and doc_type _doc:
{
"query": {
"bool": {
"must": [
{
"percolate": {
"field": "__acl_record_selector",
"document": {
"$schema": "records/record-v1.0.0.json",
"keywords": [
"aaa"
]
}
}
},
{
"term": {
"__acl_record_type": "propertyvalue"
}
}
]
}
}
}
The record is not matched by any ACLs

""" % {'acl_id': str(acl.id)})

    with pytest.raises(RuntimeError,
                       match='Explicit ACLs were not prepared for the given schema. Please run invenio explicit-acls prepare http://bla'):
        check_explain(capsys, {'$schema': 'http://blah', 'keywords': ['aaa']}, """""")