def get_record_permissions(recid=None): if not recid: return False action_edit_record = RecordUpdateActionNeed(str(recid)) action_read_record = RecordReadActionNeed(str(recid)) action_index_record = RecordIndexActionNeed(str(recid)) permissions = dict() permissions['u_edit'] = ActionUsers.query_by_action( action_edit_record).all() permissions['u_read'] = ActionUsers.query_by_action( action_read_record).all() permissions['u_index'] = ActionUsers.query_by_action( action_index_record).all() permissions['r_edit'] = ActionRoles.query_by_action( action_edit_record).all() permissions['r_read'] = ActionRoles.query_by_action( action_read_record).all() permissions['r_index'] = ActionRoles.query_by_action( action_index_record).all() result = permissions['u_edit'] + permissions['u_read'] + permissions['u_index'] + \ permissions['r_edit'] + permissions['r_read'] + permissions['r_index'] return result
def test_invenio_access_permission_cache_redis(app): """Caching the user using redis.""" cache = RedisCache() InvenioAccess(app, cache=cache) with app.test_request_context(): user_can_all = User(email='*****@*****.**') user_can_open = User(email='*****@*****.**') db.session.add(user_can_all) db.session.add(user_can_open) db.session.add(ActionUsers(action='open', user=user_can_all)) db.session.flush() identity_open = FakeIdentity(UserNeed(user_can_open.id)) permission_open = DynamicPermission(ActionNeed('open')) assert not permission_open.allows(identity_open) assert current_access.get_action_cache('open') == (set( [Need(method='id', value=1)]), set([])) db.session.add(ActionUsers(action='open', user=user_can_open)) db.session.flush() permission_open = DynamicPermission(ActionNeed('open')) assert permission_open.allows(identity_open) assert current_access.get_action_cache('open') == (set( [Need(method='id', value=1), Need(method='id', value=2)]), set([]))
def oauth2(app, db): """Creates authentication tokens for test. Add these attributes in the app object and return app: - user: a fake user that have authorization to archive_read and write - token: api token for user """ from invenio_access.models import ActionUsers from invenio_oauth2server.models import Token from invenio_archivematica.permissions import archive_read, archive_write datastore = app.extensions['security'].datastore app.user = datastore.create_user(email='*****@*****.**', password='******', active=True) db.session.commit() db.session.add(ActionUsers.allow(archive_read, user=app.user)) db.session.add(ActionUsers.allow(archive_write, user=app.user)) app.token = Token.create_personal('test-', app.user.id, scopes=['archive:actions'], is_internal=True).access_token db.session.commit() return app
def users(app): # Create test users encrypted_password = encrypt_password('123456') user = User( email='*****@*****.**', password=encrypted_password, active=True ) user_partially_allowed = User( email='*****@*****.**', password=encrypted_password, active=True, ) user_allowed = User( email='*****@*****.**', password=encrypted_password, active=True, ) db.session.add_all( [user, user_partially_allowed, user_allowed] ) db.session.commit() # Create actions for the allowed user restricted_collection_action = ActionUsers( action='view-restricted-collection', argument='Restricted Collection', user_id=user_allowed.id ) another_restricted_collection_action = ActionUsers( action='view-restricted-collection', argument='Another Restricted Collection', user_id=user_allowed.id ) # Create actions for the partially allowed user partial_restricted_collection_action = ActionUsers( action='view-restricted-collection', argument='Restricted Collection', user_id=user_partially_allowed.id ) db.session.add_all( [ restricted_collection_action, another_restricted_collection_action, partial_restricted_collection_action ] ) db.session.commit() yield SessionActivity.query.delete() ActionUsers.query.filter_by(action='view-restricted-collection').delete() User.query.filter_by(email='*****@*****.**').delete() User.query.filter_by(email='*****@*****.**').delete() User.query.filter_by(email='*****@*****.**').delete() db.session.commit()
def test_permission_factory(app, db, action, permission_factory): """Test revisions.""" InvenioAccess(app) rec_uuid = uuid.uuid4() with db.session.begin_nested(): user_all = User(email='*****@*****.**') user_one = User(email='*****@*****.**') user_none = User(email='*****@*****.**') db.session.add(user_all) db.session.add(user_one) db.session.add(user_none) db.session.add(ActionUsers(action=action, user=user_all, argument=None)) db.session.add( ActionUsers(action=action, user=user_one, argument=str(rec_uuid))) record = Record.create({'title': 'permission test'}, id_=rec_uuid) # Create a record and assign permissions. permission = permission_factory(record) # Assert which permissions has access. assert permission.allows(FakeIdentity(UserNeed(user_all.id))) assert permission.allows(FakeIdentity(UserNeed(user_one.id))) assert not permission.allows(FakeIdentity(UserNeed(user_none.id)))
def test_dynamic_permission_needs_cache_invalidation(app): """Testing DynamicPermission refreshes needs. This is important when protecting a view with @permission.require(http_exception=403) If cache does not get invalidated, the needs will only be refreshed when the Python process restarts. """ cache = SimpleCache() InvenioAccess(app, cache=cache) with app.test_request_context(): user_can_all = User(email='*****@*****.**') user_can_open = User(email='*****@*****.**') db.session.add(user_can_all) db.session.add(user_can_open) db.session.add(ActionUsers(action='open', user=user_can_all)) db.session.flush() permission_open = DynamicPermission(ActionNeed('open')) assert permission_open.needs == set([Need(method='id', value=1)]) db.session.add(ActionUsers(action='open', user=user_can_open)) db.session.flush() assert permission_open.needs == set( [Need(method='id', value=1), Need(method='id', value=2)] )
def _add_experiment_permissions(cls, data, id_): """Add read permissions to everybody assigned to experiment.""" exp_need = exp_need_factory(data['_experiment']) # give read access to members of collaboration for au in ActionUsers.query_by_action(exp_need).all(): try: ActionUsers.query_by_action( RECORD_ACTION_NEEDS(id_)['record-read']).filter_by( user=au.user).one() except NoResultFound: db.session.add( ActionUsers.allow(RECORD_ACTION_NEEDS(id_)['record-read'], user=au.user)) data['_access']['record-read']['users'].append(au.user.id) for ar in ActionRoles.query_by_action(exp_need).all(): try: ActionRoles.query_by_action( RECORD_ACTION_NEEDS(id_)['record-read']).filter_by( role=ar.role).one() except NoResultFound: db.session.add( ActionRoles.allow(RECORD_ACTION_NEEDS(id_)['record-read'], role=ar.role)) data['_access']['record-read']['roles'].append(ar.role.id)
def test_invenio_access_permission_for_users(app): """User can access to an action allowed/denied to the user""" InvenioAccess(app) with app.test_request_context(): db.session.begin(nested=True) user_can_all = User(email='*****@*****.**') user_can_read = User(email='*****@*****.**') user_can_open = User(email='*****@*****.**') db.session.add(user_can_all) db.session.add(user_can_read) db.session.add(user_can_open) db.session.add(ActionUsers(action='open', user=user_can_all)) db.session.add(ActionUsers(action='open', user=user_can_open)) db.session.add(ActionUsers(action='read', user=user_can_all)) db.session.add(ActionUsers(action='read', user=user_can_read)) db.session.commit() permission_open = DynamicPermission(ActionNeed('open')) permission_read = DynamicPermission(ActionNeed('read')) identity_all = FakeIdentity(UserNeed(user_can_all.id)) identity_read = FakeIdentity(UserNeed(user_can_read.id)) identity_open = FakeIdentity(UserNeed(user_can_open.id)) assert permission_open.allows(identity_all) assert permission_read.allows(identity_all) assert permission_open.allows(identity_open) assert not permission_read.allows(identity_open) assert not permission_open.allows(identity_read) assert permission_read.allows(identity_read)
def _add_experiment_permissions(cls, data, id_): """Add read permissions to everybody assigned to experiment.""" exp_need = exp_need_factory(data['_experiment']) # give read access to members of collaboration for au in ActionUsers.query_by_action(exp_need).all(): try: ActionUsers.query_by_action( RECORD_ACTION_NEEDS(id_)['record-read'] ).filter_by(user=au.user).one() except NoResultFound: db.session.add( ActionUsers.allow( RECORD_ACTION_NEEDS(id_)['record-read'], user=au.user ) ) data['_access']['record-read']['users'].append(au.user.id) for ar in ActionRoles.query_by_action(exp_need).all(): try: ActionRoles.query_by_action( RECORD_ACTION_NEEDS(id_)['record-read'] ).filter_by(role=ar.role).one() except NoResultFound: db.session.add( ActionRoles.allow( RECORD_ACTION_NEEDS(id_)['record-read'], role=ar.role ) ) data['_access']['record-read']['roles'].append(ar.role.id)
def test_invenio_access_permission_cache(app): """Caching the user using memory caching.""" cache = SimpleCache() InvenioAccess(app, cache=cache) with app.test_request_context(): user_can_all = User(email='*****@*****.**') user_can_open = User(email='*****@*****.**') user_can_open_1 = User(email='*****@*****.**') db.session.add(user_can_all) db.session.add(user_can_open) db.session.add(user_can_open_1) db.session.add(ActionUsers(action='open', user=user_can_all)) db.session.flush() permission_open = DynamicPermission(ActionNeed('open')) identity_open = FakeIdentity(UserNeed(user_can_open.id)) assert not permission_open.allows(identity_open) assert current_access.get_action_cache('open') == ( set([Need(method='id', value=1)]), set([]) ) db.session.add(ActionUsers(action='open', user=user_can_open)) db.session.flush() permission_open = DynamicPermission(ActionNeed('open')) assert permission_open.allows(identity_open) assert current_access.get_action_cache('open') == ( set([Need(method='id', value=1), Need(method='id', value=2)]), set([]) ) db.session.add(ActionUsers(action='open', argument=1, user=user_can_open_1)) db.session.flush() identity_open_1 = FakeIdentity(UserNeed(user_can_open_1.id)) permission_open_1 = DynamicPermission( ParameterizedActionNeed('open', '1')) assert not permission_open.allows(identity_open_1) assert permission_open_1.allows(identity_open_1) assert current_access.get_action_cache('open::1') == ( set([Need(method='id', value=1), Need(method='id', value=2), Need(method='id', value=3)]), set([]) ) assert current_access.get_action_cache('open') == ( set([Need(method='id', value=1), Need(method='id', value=2)]), set([]) )
def permissions(db, bucket): """Permission for users.""" users = { None: None, } for user in [ 'auth', 'location', 'bucket', 'objects', 'objects-read-version']: users[user] = create_test_user( email='{0}@invenio-software.org'.format(user), password='******', active=True ) location_perms = [ location_update_all, bucket_read_all, bucket_read_versions_all, bucket_update_all, bucket_listmultiparts_all, object_read_all, object_read_version_all, object_delete_all, object_delete_version_all, multipart_read_all, multipart_delete_all, ] bucket_perms = [ bucket_read_all, object_read_all, bucket_update_all, object_delete_all, multipart_read_all, ] objects_perms = [ object_read_all, ] for perm in location_perms: db.session.add(ActionUsers( action=perm.value, user=users['location'])) for perm in bucket_perms: db.session.add(ActionUsers( action=perm.value, argument=str(bucket.id), user=users['bucket'])) for perm in objects_perms: db.session.add(ActionUsers( action=perm.value, argument=str(bucket.id), user=users['objects'])) db.session.commit() yield users
def create_record(collection): """Basic test view.""" collection = Collection.query.filter( Collection.name == collection).first_or_404() schema = urljoin(current_app.config.get('JSONSCHEMAS_HOST'), url_for('records.jsonschema', collection=collection.name)) data, pid, recid = construct_record(collection, json.loads(request.get_data()), current_user.id, schema) try: record = Record.create(data, id_=recid) except ValidationError as error: print("============================") print(error.message) print("============================") db.session.rollback() resp = jsonify(**{'message': error.message}) resp.status_code = 400 return resp # Invenio-Indexer is delegating the document inferring to # Invenio-Search which is analysing the string splitting by `/` and # using `.json` to be sure that it cans understand the mapping. record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower()) indexer = RecordIndexer() indexer.index(record) # Creating permission needs for the record action_edit_record = RecordUpdateActionNeed(str(recid)) action_read_record = RecordReadActionNeed(str(recid)) action_index_record = RecordIndexActionNeed(str(recid)) # Giving index, read, write permissions to user/creator db.session.add(ActionUsers.allow(action_edit_record, user=current_user)) db.session.add(ActionUsers.allow(action_read_record, user=current_user)) db.session.add(ActionUsers.allow(action_index_record, user=current_user)) db.session.commit() resp = jsonify(**{'pid': pid}) resp.status_code = 200 return resp
def users(app, db): """Create users.""" def dump_user(user): """User object to dict.""" return { 'email': user.email, 'id': user.id, 'password': password } password = '******' with db.session.begin_nested(): datastore = app.extensions['security'].datastore # create users hashed_password = hash_password(password) user1 = datastore.create_user(email='*****@*****.**', password=hashed_password, active=True) user2 = datastore.create_user(email='*****@*****.**', password=hashed_password, active=True) # Give role to admin db.session.add(ActionUsers(action='admin-access', user=user1)) db.session.commit() return { 'user1': dump_user(user1), 'user2': dump_user(user2) }
def _add_deposit_permissions(cls, data, id_): """Inherit permissions after deposit.""" data['_access'] = { DEPOSIT_TO_RECORD_ACTION_MAP[action]: permission for action, permission in data['_access'].items() } for action, permission in data['_access'].items(): for role in permission['roles']: role = Role.query.filter_by(id=role).one() try: ActionRoles.query.filter_by(action=action, argument=str(id_), role_id=role.id).one() except NoResultFound: db.session.add( ActionRoles.allow(RECORD_ACTION_NEEDS(id_)[action], role=role)) for user in permission['users']: user = User.query.filter_by(id=user).one() try: ActionUsers.query.filter_by(action=action, argument=str(id_), user_id=user.id).one() except NoResultFound: db.session.add( ActionUsers.allow(RECORD_ACTION_NEEDS(id_)[action], user=user))
def test_file_permissions(app, db, record_with_files_creation, user, access_right, expected): """Test file permissions.""" pid, record, record_url = record_with_files_creation # Create test users admin = User(email='*****@*****.**', password='******') owner = User(email='*****@*****.**', password='******') auth = User(email='*****@*****.**', password='******') db.session.add_all([admin, owner, auth]) db.session.add(ActionUsers.allow(ActionNeed('admin-access'), user=admin)) db.session.commit() # Create test record record['access_right'] = access_right record['owners'] = [owner.id] record.commit() db.session.commit() file_url = url_for( 'invenio_records_ui.recid_files', pid_value=pid.pid_value, filename='Test.pdf', ) with app.test_client() as client: if user: # Login as user with client.session_transaction() as sess: sess['user_id'] = User.query.filter_by( email='{}@zenodo.org'.format(user)).one().id sess['_fresh'] = True res = client.get(file_url) assert res.status_code == expected
def users(app): """Create user fixtures.""" hashed_password = hash_password('123456') user = User(email='*****@*****.**', password=hashed_password, active=True) user_allowed = User(email='*****@*****.**', password=hashed_password, active=True) db.session.add_all([user, user_allowed]) db.session.commit() author_admin = ActionUsers(action='admin-holdingpen-authors', user_id=user_allowed.id) db.session.add(author_admin) db.session.commit() yield ActionUsers.query.filter_by(action='admin-holdingpen-authors').delete() User.query.filter_by(email='*****@*****.**').delete() User.query.filter_by(email='*****@*****.**').delete() db.session.commit()
def grant_vocabulary_editor_permission(cls, user_id, vocabulary_id) -> Dict[str, bool]: done = False msg = '' try: vocabulary = Vocabulary.query.filter_by( identifier=vocabulary_id).first() user = User.query.filter_by(id=user_id).first() if not vocabulary: msg = 'Vocabulary not found' elif not user: msg = 'User not found' else: db.session.add( ActionUsers.allow(ObjectVocabularyEditor(vocabulary.id), user=user)) db.session.commit() msg = 'Vocabulary Editor Permission granted over {0}'.format( vocabulary.name) done = True except Exception as e: msg = str(e) # print(str(e)) return msg, done
def users(app, db): """Create users.""" users = { 'cms_user': create_user_with_role('*****@*****.**', '*****@*****.**'), 'cms_user2': create_user_with_role('*****@*****.**', '*****@*****.**'), 'alice_user': create_user_with_role('*****@*****.**', '*****@*****.**'), 'alice_user2': create_user_with_role('*****@*****.**', '*****@*****.**'), 'atlas_user': create_user_with_role('*****@*****.**', '*****@*****.**'), 'atlas_user2': create_user_with_role('*****@*****.**', '*****@*****.**'), 'lhcb_user': create_user_with_role('*****@*****.**', '*****@*****.**'), 'lhcb_user2': create_user_with_role('*****@*****.**', '*****@*****.**'), 'superuser': create_user_with_role('*****@*****.**', '*****@*****.**'), } db.session.add(ActionUsers.allow(superuser_access, user=users['superuser'])) db.session.commit() return users
def team_management(community): """Team management for communities. :param community_id: ID of the community to manage. """ Action = namedtuple("Action", ["title", "name", "existing"]) actions = [] permissions = _get_permissions() for action in permissions: # 12 = len("communities-") a = Action(action[12:].replace("-", " ").capitalize(), action, ActionUsers.query_by_action( _get_needs(action, community.id)).all()) actions.append(a) ctx = mycommunities_ctx() ctx.update({ "community": community, "actions": actions }) return render_template( current_app.config['COMMUNITIES_TEAM_TEMPLATE'], **ctx )
def users(): """Create users needed in this test module.""" curator = User( email='*****@*****.**', password=hash_password('curator'), active=True, ) scientist = User( email='*****@*****.**', password=hash_password('scientist'), active=True, ) db.session.add_all([curator, scientist]) db.session.commit() curator_action = ActionUsers( action='editor_manage_tickets', argument=None, user_id=curator.id, ) db.session.add(curator_action) db.session.commit() yield ActionUsers.query.filter_by(action='editor_manage_tickets').delete() User.query.filter_by(email='*****@*****.**').delete() User.query.filter_by(email='*****@*****.**').delete() db.session.commit()
def give_admin_access_for_user(self, user): """Give admin access for users.""" assert self.id db.session.add(ActionUsers.allow(SchemaAdminAction(self.id), user=user)) db.session.flush()
def create_user(self, email, entry): """Load a single user.""" # when the user's password is set in the configuration, then # this overrides everything else password = current_app.config.get("RDM_RECORDS_USER_FIXTURE_PASSWORDS", {}).get(email) if not password: # for auto-generated passwords use letters, digits, # and some punctuation marks alphabet = string.ascii_letters + string.digits + "+,-_." gen_passwd = "".join(secrets.choice(alphabet) for i in range(20)) password = entry.get("password") or gen_passwd user_data = { "email": email, "active": entry.get("active", False), "password": hash_password(password), } user = current_datastore.create_user(**user_data) for role in entry.get("roles", []): current_datastore.add_role_to_user(user, role) for action in entry.get("allow", []): action = current_access.actions[action] db.session.add(ActionUsers.allow(action, user_id=user.id)) db.session.commit()
def _make_user(role_name, organisation='org', organisation_is_shared=True, access=None): name = role_name if organisation: make_organisation(organisation, is_shared=organisation_is_shared) name = organisation + name email = '{name}@rero.ch'.format(name=name) datastore = app.extensions['security'].datastore user = datastore.find_user(email=email) if user: record = UserRecord.get_user_by_email(email) return record user = datastore.create_user(email=email, password=hash_password('123456'), active=True) datastore.commit() role = datastore.find_role(role_name) if not role: role = Role(name=role_name) role.users.append(user) db.session.add(role) if access: db.session.add(ActionUsers.allow(ActionNeed(access), user=user)) db.session.commit() data = { 'pid': name, 'email': email, 'first_name': name[0].upper() + name[1:], 'last_name': 'Doe', 'role': role_name } if organisation: data['organisation'] = { '$ref': 'https://sonar.ch/api/organisations/{organisation}'.format( organisation=organisation) } record = UserRecord.create(data, dbcommit=True) record.reindex() db.session.commit() return record
def delete_permission(self, allow, community_id=None): with db.session.begin_nested(): user = accounts.datastore.get_user(self.user_id) # only add the access rights if the access control is enabled db.session.add( ActionUsers(action=communities_delete_all.value, argument=str(community_id), user=user, exclude=not allow))
def create_user_with_access(session, username, action): user = _datastore.find_user(email=username) if not user: user = create_test_user(email=username, password='******') session.add(ActionUsers.allow(ActionNeed(action), user=user)) return user
def admin_user(users, roles): """Give admin rights to a user.""" user = users["user1"] role = roles["admin"] current_datastore.add_role_to_user(user, role) action = current_access.actions["superuser-access"] db.session.add(ActionUsers.allow(action, user_id=user.id)) return user
def _add_experiment_permissions(self, experiment, permissions): """Add read permissions to everybody assigned to experiment.""" exp_need = exp_need_factory(experiment) # give read access to members of collaboration with db.session.begin_nested(): for au in ActionUsers.query_by_action(exp_need).all(): self._add_user_permissions(au.user, permissions, db.session) for ar in ActionRoles.query_by_action(exp_need).all(): self._add_egroup_permissions(ar.role, permissions, db.session)
def add_record(metadata, collection, schema, force): """Add record.""" collection = Collection.query.filter( Collection.name == collection).first() if collection is None: return data, pid, recid = construct_record( collection, metadata, 1, {} if force else schema) try: record = Record.create(data, id_=recid) # Invenio-Indexer is delegating the document inferring to # Invenio-Search which is analysing the string splitting by `/` and # using `.json` to be sure that it cans understand the mapping. record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower()) indexer = RecordIndexer() indexer.index(record) # Creating permission needs for the record action_edit_record = RecordUpdateActionNeed(str(recid)) action_read_record = RecordReadActionNeed(str(recid)) action_index_record = RecordIndexActionNeed(str(recid)) # Giving index, read, write permissions to user/creator db.session.add(ActionUsers.allow(action_edit_record)) db.session.add(ActionUsers.allow(action_read_record)) db.session.add(ActionUsers.allow(action_index_record)) db.session.commit() print("DONE!!!") except ValidationError as error: print("============================") pprint(error.message) pprint(error.path) print("============================") db.session.rollback()
def _add_user_permissions(self, user, permissions, session): """Adds permissions for user for this deposit.""" for permission in permissions: session.add( ActionUsers.allow(DEPOSIT_ACTIONS_NEEDS(self.id)[permission], user=user)) session.flush() self['_access'][permission]['users'].append(user.id)
def test_file_permissions(app, db, test_object, # fixtures user, access_right, expected): """Test file permissions.""" # Create test users admin = User(email='*****@*****.**', password='******') owner = User(email='*****@*****.**', password='******') auth = User(email='*****@*****.**', password='******') db.session.add_all([admin, owner, auth]) db.session.add( ActionUsers.allow(ActionNeed('admin-access'), user=admin) ) # Create test record rec_uuid = uuid.uuid4() PersistentIdentifier.create( 'recid', '1', object_type='rec', object_uuid=rec_uuid, status=PIDStatus.REGISTERED ) Record.create({ 'recid': 1, 'owners': [2], 'access_right': access_right, '_files': [ { 'key': test_object.key, 'bucket': str(test_object.bucket_id), 'checksum': 'invalid' }, ] }, id_=rec_uuid) db.session.add( RecordsBuckets(record_id=rec_uuid, bucket_id=test_object.bucket_id) ) file_url = url_for( 'invenio_records_ui.recid_files', pid_value='1', filename=test_object.key ) db.session.commit() with app.test_client() as client: if user: # Login as user with client.session_transaction() as sess: sess['user_id'] = User.query.filter_by( email='{}@zenodo.org'.format(user)).one().id sess['_fresh'] = True res = client.get(file_url) assert res.status_code == expected
def add_record(metadata, collection, schema, force): """Add record.""" collection = Collection.query.filter(Collection.name == collection).first() if collection is None: return data, pid, recid = construct_record(collection, metadata, 1, {} if force else schema) try: record = Record.create(data, id_=recid) # Invenio-Indexer is delegating the document inferring to # Invenio-Search which is analysing the string splitting by `/` and # using `.json` to be sure that it cans understand the mapping. record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower()) indexer = RecordIndexer() indexer.index(record) # Creating permission needs for the record action_edit_record = RecordUpdateActionNeed(str(recid)) action_read_record = RecordReadActionNeed(str(recid)) action_index_record = RecordIndexActionNeed(str(recid)) # Giving index, read, write permissions to user/creator db.session.add(ActionUsers.allow(action_edit_record)) db.session.add(ActionUsers.allow(action_read_record)) db.session.add(ActionUsers.allow(action_index_record)) db.session.commit() print("DONE!!!") except ValidationError as error: print("============================") pprint(error.message) pprint(error.path) print("============================") db.session.rollback()
def users(app, db): """Create users.""" user1 = create_test_user(email='*****@*****.**', password='******') user2 = create_test_user(email='*****@*****.**', password='******') user_admin = create_test_user(email='*****@*****.**', password='******') with db.session.begin_nested(): # set admin permissions db.session.add(ActionUsers(action=action_admin_access.value, user=user_admin)) db.session.add(ActionUsers(action=deposit_admin_access.value, user=user_admin)) db.session.commit() return [ {'email': user1.email, 'id': user1.id}, {'email': user2.email, 'id': user2.id}, {'email': user_admin.email, 'id': user_admin.id} ]
def update_permission(self, allow, community_id=None): with db.session.begin_nested(): user = accounts.datastore.get_user(self.user_id) # only add the access rights if the access control is enabled if not app.extensions[ 'b2share-communities'].rest_access_control_disabled: db.session.add( ActionUsers(action=communities_update_all.value, argument=str(community_id), user=user, exclude=not allow))
def test_monitoring_check_es_db_counts(app, client, contribution_person_data, system_librarian_martigny): """Test monitoring check_es_db_counts.""" res = client.get(url_for('api_monitoring.check_es_db_counts', delay=0)) assert res.status_code == 200 assert get_json(res) == {'data': {'status': 'green'}} pers = Contribution.create(data=contribution_person_data, delete_pid=False, dbcommit=True, reindex=False) flush_index(ContributionsSearch.Meta.index) res = client.get(url_for('api_monitoring.check_es_db_counts', delay=0)) assert res.status_code == 200 assert get_json(res) == { 'data': { 'status': 'red' }, 'errors': [{ 'code': 'DB_ES_COUNTER_MISSMATCH', 'details': 'There are 1 items from cont missing in ES.', 'id': 'DB_ES_COUNTER_MISSMATCH', 'links': { 'about': 'http://localhost/monitoring/check_es_db_counts', 'cont': 'http://localhost/monitoring/missing_pids/cont' }, 'title': "DB items counts don't match ES items count." }] } # this view is only accessible by monitoring res = client.get(url_for('api_monitoring.missing_pids', doc_type='cont')) assert res.status_code == 401 login_user_via_session(client, system_librarian_martigny.user) res = client.get(url_for('api_monitoring.missing_pids', doc_type='cont')) assert res.status_code == 403 # give user superuser admin rights db.session.add( ActionUsers.allow(superuser_access, user=system_librarian_martigny.user)) db.session.commit() res = client.get( url_for('api_monitoring.missing_pids', doc_type='cont', delay=0)) assert res.status_code == 200 assert get_json(res) == { 'data': { 'DB': [], 'ES': ['http://localhost/contributions/cont_pers'], 'ES duplicate': [] } }
def create_user_with_access(username, action): user = _datastore.find_user(email=username) if not user: user = create_test_user(email=username, password='******') db_.session.add(ActionUsers.allow( ActionNeed(action), user=user)) db_.session.commit() return user
def _make_user(role_name, organisation='org'): make_organisation(organisation) name = role_name if organisation: name = organisation + name email = '{name}@rero.ch'.format(name=name) datastore = app.extensions['security'].datastore user = datastore.find_user(email=email) if user: record = UserRecord.get_user_by_email(email) return record user = datastore.create_user(email=email, password=hash_password('123456'), active=True) datastore.commit() role = datastore.find_role(role_name) if not role: role = Role(name=role_name) role.users.append(user) db.session.add(role) db.session.add( ActionUsers.allow(ActionNeed( '{role}-access'.format(role=role_name)), user=user)) db.session.commit() record = UserRecord.create( { 'pid': name, 'email': email, 'full_name': name, 'roles': [role_name], 'organisation': { '$ref': 'https://sonar.ch/api/organisations/{organisation}'.format( organisation=organisation) } }, dbcommit=True) record.reindex() db.session.commit() return record
def change_record_privacy(pid_value=None): resolver = Resolver( pid_type='recid', object_type='rec', getter=Record.get_record) pid, record = resolver.resolve(pid_value) permission_update_record = update_permission_factory(record) if not permission_update_record.can(): abort(403) index_instance = ActionUsers.query.filter( ActionUsers.action == "records-index", ActionUsers.argument == str(record.id), ActionUsers.user_id.is_(None)).first() read_instance = ActionUsers.query.filter( ActionUsers.action == "records-read", ActionUsers.argument == str(record.id), ActionUsers.user_id.is_(None)).first() with db.session.begin_nested(): if index_instance: db.session.delete(index_instance) db.session.delete(read_instance) else: action_read_record = RecordReadActionNeed(str(record.id)) action_index_record = RecordIndexActionNeed(str(record.id)) db.session.add(ActionUsers.allow(action_read_record)) db.session.add(ActionUsers.allow(action_index_record)) db.session.commit() resp = jsonify() resp.status_code = 200 return resp
def _add_user_permissions(self, user, permissions, session): """Adds permissions for user for this deposit.""" for permission in permissions: session.add( ActionUsers.allow( DEPOSIT_ACTIONS_NEEDS(self.id)[permission], user=user ) ) session.flush() self['_access'][permission]['users'].append(user.id)
def create_user(name, roles=None, permissions=None, admin_communities=None, member_communities=None): """Create a user. Args: name (str): user's name. roles (list): roles assigned to this new user. Returns: (UserInfo) created user's information. """ users_password = '******' accounts = current_app.extensions['invenio-accounts'] security = current_app.extensions['security'] email = '{}@example.org'.format(name) with db.session.begin_nested(): user = accounts.datastore.create_user( email=email, password=hash_password(users_password), active=True, ) db.session.add(user) if roles is not None: for role in roles: security.datastore.add_role_to_user(user, role) if permissions is not None: for permission in permissions: # permissions of the form [('action name', 'argument'), (...)] if len(permission) == 2: permission = ParameterizedActionNeed(permission[0], permission[1]) db.session.add(ActionUsers.allow(permission, user=user)) return UserInfo(email=email, password=users_password, id=user.id)
def set_user_permissions(user, permissions, id, session, access): _permissions = (p for p in permissions if p.get( "action", "") in DEPOSIT_ACTIONS) for permission in _permissions: if (permission.get("op", "") == "add"): try: session.add(ActionUsers.allow( DEPOSIT_ACTIONS_NEEDS(id).get( permission.get("action", ""), ""), user=user )) except: return access.get(permission["action"], {}).get( 'user', []).append(user.id) elif (permission.get("op", "") == "remove"): try: au = ActionUsers.query.filter( ActionUsers.action == permission.get("action", ""), ActionUsers.argument == str(id), ActionUsers.user_id == user.id).first() if au: session.delete(au) except: return access.get(permission["action"], {}).get( 'user', []).remove(user.id) return access
def test_file_permissions(app, db, record_with_files_creation, user, access_right, expected): """Test file permissions.""" pid, record, record_url = record_with_files_creation # Create test users admin = User(email='*****@*****.**', password='******') owner = User(email='*****@*****.**', password='******') auth = User(email='*****@*****.**', password='******') db.session.add_all([admin, owner, auth]) db.session.add( ActionUsers.allow(ActionNeed('admin-access'), user=admin) ) db.session.commit() # Create test record record['access_right'] = access_right record['owners'] = [owner.id] record.commit() db.session.commit() file_url = url_for( 'invenio_records_ui.recid_files', pid_value=pid.pid_value, filename='Test.pdf', ) with app.test_client() as client: if user: # Login as user with client.session_transaction() as sess: sess['user_id'] = User.query.filter_by( email='{}@zenodo.org'.format(user)).one().id sess['_fresh'] = True res = client.get(file_url) assert res.status_code == expected
def _add_deposit_permissions(cls, data, id_): """Inherit permissions after deposit.""" data['_access'] = { DEPOSIT_TO_RECORD_ACTION_MAP[action]: permission for action, permission in data['_access'].items() } for action, permission in data['_access'].items(): for role in permission['roles']: role = Role.query.filter_by(id=role).one() db.session.add( ActionRoles.allow( RECORD_ACTION_NEEDS(id_)[action], role=role ) ) for user in permission['users']: user = User.query.filter_by(id=user).one() db.session.add( ActionUsers.allow( RECORD_ACTION_NEEDS(id_)[action], user=user ) )
def add_record(metadata, collection, schema, force, files=[]): """Add record.""" collection = Collection.query.filter( Collection.name == collection).first() if collection is None: return data, pid, recid = construct_record( collection, metadata, 1, {} if force else schema) d = current_app.config['DATADIR'] buckets = [] data['_files'] = [] for file in files: bucket = Bucket.create(default_location=Location.get_default()) buckets.append(bucket) with open(pkg_resources.resource_filename( 'cap.modules.fixtures', os.path.join('data', 'files', file) ), 'rb') as fp: obj = ObjectVersion.create(bucket, file, stream=fp) data['_files'].append({ 'bucket': str(obj.bucket_id), 'key': obj.key, 'size': obj.file.size, 'checksum': str(obj.file.checksum), 'version_id': str(obj.version_id), }) try: record = Record.create(data, id_=recid) for bucket in buckets: rb = RecordsBuckets(record_id=record.id, bucket_id=bucket.id) db.session.add(rb) # Invenio-Indexer is delegating the document inferring to # Invenio-Search which is analysing the string splitting by `/` and # using `.json` to be sure that it cans understand the mapping. record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower()) indexer = RecordIndexer() indexer.index(record) # Creating permission needs for the record action_edit_record = RecordUpdateActionNeed(str(recid)) action_read_record = RecordReadActionNeed(str(recid)) action_index_record = RecordIndexActionNeed(str(recid)) # Giving index, read, write permissions to user/creator db.session.add(ActionUsers.allow(action_edit_record)) db.session.add(ActionUsers.allow(action_read_record)) db.session.add(ActionUsers.allow(action_index_record)) db.session.commit() print("DONE!!!") except ValidationError as error: print("============================") pprint(error.message) pprint(error.path) print("============================") db.session.rollback()
def update_record_permissions(pid_value=None): resolver = Resolver( pid_type='recid', object_type='rec', getter=Record.get_record) pid, record = resolver.resolve(pid_value) emails = [] roles = [] userrole_list = request.get_json().keys() if not (current_app.config.get('EMAIL_REGEX', None)): resp = jsonify(**{message: "ERROR in email regex ;)"}) resp.status_code = 400 return resp email_regex = re.compile(current_app.config.get('EMAIL_REGEX'), ) for userrole in userrole_list: if email_regex.match(userrole): emails.append(userrole) else: #: [TOBEFIXED] Needs to check if E-Group exists try: role = Role.query.filter(Role.name == userrole).first() if not role: tmp_role = _datastore.create_role(name=userrole) roles.append(userrole) except: print("Something happened when trying to create '"+userrole+"' role") # Role.add(tmp_role) users = User.query.filter(User.email.in_(emails)).all() roles = Role.query.filter(Role.name.in_(roles)).all() action_edit_record = RecordUpdateActionNeed(str(record.id)) action_read_record = RecordReadActionNeed(str(record.id)) action_index_record = RecordIndexActionNeed(str(record.id)) with db.session.begin_nested(): for user in users: for action in request.get_json().get(user.email, None): if (action.get("action", None) == "records-read" and action.get("op", None) == "add"): db.session.add(ActionUsers.allow(action_read_record, user=user)) elif (action.get("action", None) == "records-index" and action.get("op", None) == "add"): db.session.add(ActionUsers.allow(action_index_record, user=user)) elif (action.get("action", None) == "records-update" and action.get("op", None) == "add"): db.session.add(ActionUsers.allow(action_edit_record, user=user)) elif (action.get("action", None) == "records-read" and action.get("op", None) == "remove"): au = ActionUsers.query.filter(ActionUsers.action == "records-read", ActionUsers.argument == str(record.id), ActionUsers.user_id == user.id).first() if (au): db.session.delete(au) elif (action.get("action", None) == "records-index" and action.get("op", None) == "remove"): au = ActionUsers.query.filter(ActionUsers.action == "records-index", ActionUsers.argument == str(record.id), ActionUsers.user_id == user.id).first() if (au): db.session.delete(au) elif (action.get("action", None) == "records-update" and action.get("op", None) == "remove"): au = ActionUsers.query.filter(ActionUsers.action == "records-update", ActionUsers.argument == str(record.id), ActionUsers.user_id == user.id).first() if (au): db.session.delete(au) # db.session.begin(nested=True) for role in roles: for action in request.get_json().get(role.name, None): if (action.get("action", None) == "records-read" and action.get("op", None) == "add"): db.session.add(ActionRoles.allow(action_read_record, role=role)) elif (action.get("action", None) == "records-index" and action.get("op", None) == "add"): db.session.add(ActionRoles.allow(action_index_record, role=role)) elif (action.get("action", None) == "records-update" and action.get("op", None) == "add"): db.session.add(ActionRoles.allow(action_edit_record, role=role)) elif (action.get("action", None) == "records-read" and action.get("op", None) == "remove"): au = ActionRoles.query.filter(ActionRoles.action == "records-read", ActionRoles.argument == str(record.id), ActionRoles.role_id == role.id).first() if (au): db.session.delete(au) elif (action.get("action", None) == "records-index" and action.get("op", None) == "remove"): au = ActionRoles.query.filter(ActionRoles.action == "records-index", ActionRoles.argument == str(record.id), ActionRoles.role_id == role.id).first() if (au): db.session.delete(au) elif (action.get("action", None) == "records-update" and action.get("op", None) == "remove"): au = ActionRoles.query.filter(ActionRoles.action == "records-update", ActionRoles.argument == str(record.id), ActionRoles.role_id == role.id).first() if (au): db.session.delete(au) db.session.commit() resp = jsonify() resp.status_code = 200 return resp
def delete_record_read_permissions(recid=None, user=None): action_read_record = RecordReadActionNeed(str(recid)) db.session.delete(ActionUsers.allow(action_read_record, user=user))
def add_record_edit_permissions(recid=None, user=None): action_edit_record = RecordUpdateActionNeed(str(recid)) db.session.add(ActionUsers.allow(action_edit_record, user=user))
def add_record_index_permissions(recid=None, user=None): action_index_record = RecordIndexActionNeed(str(recid)) db.session.add(ActionUsers.allow(action_index_record, user=user))