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())
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()
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])
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
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)
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)
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] }]
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"]
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
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]})
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] } ]
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)
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
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']}, """""")