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 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 _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 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 _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 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 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 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_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 _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 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_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 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 test_patron_loans_view(app, patron1, testdata, client): """Test check for users update in sync command.""" db.session.add( ActionUsers.allow(retrieve_patron_loans_access_action, user=patron1)) db.session.commit() patron = Patron(patron1.id) PatronIndexer().index(patron) current_search.flush_and_refresh(index="*") login_user_via_session(client, email=patron1.email) resp = client.get(url_for("cds_ils_patron_loans.patron_loans", person_id=1)) assert resp.status_code == 200 expected_books_on_loan = [{ "barcode": "123456789-3", "end_date": "2018-07-28", "library": "Main Library", "location": "Route de Meyrin", "title": "Prairie Fires: The American Dreams of " "Laura Ingalls Wilder", }] expected_loan_requests = [{ "request_start_date": "2018-06-28", "request_end_date": "2018-07-28", "library": "Main Library", "location": "Route de Meyrin", "title": "The Gulf: The Making of An American Sea", }] data = resp.json assert data["books_on_loan"] == expected_books_on_loan assert data["loan_requests"] == expected_loan_requests # test extra_info assert patron.extra_info assert data["person_id"] == patron.extra_info["person_id"] assert data["department"] == patron.extra_info["department"]
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 set_user_permissions(user, permissions, deposit, session, access, force=False): _permissions = (p for p in permissions if p.get( "action", "") in DEPOSIT_ACTIONS) for permission in _permissions: if permission.get("op", "") == "add": if (not force and ActionUsers.query.filter_by( action=permission['action'], user_id=user.id, argument=str(deposit.id) ).all()): return try: session.add(ActionUsers.allow( DEPOSIT_ACTIONS_NEEDS(deposit.id).get( permission.get("action", ""), ""), user=user )) except: return access.get(permission["action"], {}).get( 'user', []).append(user.id) elif permission.get("op", "") == "remove": if (not force and not ActionUsers.query.filter_by( action=permission['action'], user_id=user.id, argument=str(deposit.id) ).all()): return try: au = ActionUsers.query.filter( ActionUsers.action == permission.get("action", ""), ActionUsers.argument == str(deposit.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 create_user(self, email, entry): """Load a single user.""" password = self._get_password(email, entry) 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", []) or []: current_datastore.add_role_to_user(user, role) for action in entry.get("allow", []) or []: action = current_access.actions[action] db.session.add(ActionUsers.allow(action, user_id=user.id)) db.session.commit()
def users(app, db, roles_data, users_data, create_roles): """Create test users.""" ds = app.extensions['invenio-accounts'].datastore result = {} with app.app_context(): with db.session.begin_nested(): for user_key, user_data in iteritems(users_data): user_data['password'] = hash_password(user_data['password']) user = ds.create_user(**user_data) result[user_key] = user roles = Role.query.filter( Role.id.in_(role['id'] for role in create_roles[:5])).all() result['user1'].roles.extend(roles) db.session.add( ActionUsers.allow( superuser_access, user=result['admin'], )) for user in result.values(): scopes = current_oauth2server.scope_choices() db.session.add(user) user.allowed_token = Token.create_personal( name='allowed_token', user_id=user.id, scopes=[s[0] for s in scopes]).access_token user_ref = namedtuple('UserRef', 'id, allowed_token, data') result_user = { name: user_ref( id=user.id, data=users_data[name], allowed_token=user.allowed_token, ) for name, user in six.iteritems(result) } db.session.commit() return result_user
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=encrypt_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 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 create(self, entry): """Load a single user.""" email = entry.pop("email") password = self._get_password(email, entry) user_data = { "email": email, "active": entry.get("active", False), "password": hash_password(password), } try: user = current_datastore.create_user(**user_data) for role in entry.get("roles", []) or []: current_datastore.add_role_to_user(user, role) for action in entry.get("allow", []) or []: action = current_access.actions[action] db.session.add(ActionUsers.allow(action, user_id=user.id)) db.session.commit() except IntegrityError: current_app.logger.info( f"skipping creation of {email}, already existing")
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 grant_notification_viewed_permission(cls, user_id, notification_id, is_flush=True) -> Dict[ str, bool]: done = False msg = '' try: user = User.query.filter_by(id=user_id) if not user: msg = 'User not found' else: db.session.add( ActionUsers.allow(ObjectNotificationEditor(notification_id), user=user) ) if is_flush: db.session.flush() else: db.session.commit() msg = 'Notification marking viewed Permission granted ' done = True except Exception as e: msg = str(e) # print(str(e)) return msg, done
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 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_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 create(cls, data, id_=None, owner=current_user): """Create a new deposit. :param data: metadata, need to contain $schema|$ana_type field :type data: dict :param id_: specify a UUID to use for the new record, instead of automatically generated :type id_: `uuid.UUID` :param owner: owner of a new deposit (will get all permissions) :type owner: `invenio_accounts.models.User` :warn: if user session owner will be automatically current_user :return: newly created deposit :rtype: `CAPDeposit` Process: * fill deposit metadata based on given data * initialize the follow internal fields (underscore prefixed): _experiment: 'experiment_of_given_schema' _deposit: { 'id': pid_value, 'status': 'draft', 'owners': [owner_id], 'created_by': owner_id } _access: { 'deposit-admin': { 'roles': [], 'users': [owner.id] }, 'deposit-update': { 'roles': [], 'users': [owner.id] }, 'deposit-read': { 'roles': [], 'users': [owner.id] } } * validate metadata against given schema (defined by $schema|$ana_type) * create RecordMetadata instance * create bucket for storing deposit files * set owner permissions in the db * index deposit in elasticsearch """ if current_user and current_user.is_authenticated: owner = current_user with db.session.begin_nested(): uuid_ = id_ or uuid.uuid4() data = cls._preprocess_create_data(data, uuid_, owner) # create RecordMetadata instance deposit = Record.create(data, id_=uuid_, validator=NoRequiredValidator) deposit.__class__ = cls # create files bucket bucket = Bucket.create() RecordsBuckets.create(record=deposit.model, bucket=bucket) # give owner permissions to the deposit if owner: for permission in DEPOSIT_ACTIONS: db.session.add( ActionUsers.allow(DEPOSIT_ACTIONS_NEEDS( deposit.id)[permission], user=owner)) db.session.flush() return deposit
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 add_record_index_permissions(recid=None, user=None): action_index_record = RecordIndexActionNeed(str(recid)) db.session.add(ActionUsers.allow(action_index_record, user=user))
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 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