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 init_users_and_permissions(): ds = current_app.extensions['invenio-accounts'].datastore with db.session.begin_nested(): superuser_role = ds.create_role( name='superuser', description='admin with no restrictions') cataloger_role = ds.create_role( name='cataloger', description='users with editing capabilities') ds.create_user(email='*****@*****.**', password=encrypt_password("123456"), active=True, roles=[superuser_role]) ds.create_user(email='*****@*****.**', password=encrypt_password("123456"), active=True, roles=[cataloger_role]) db.session.add( ActionRoles(action='superuser-access', role=superuser_role)) db.session.add(ActionRoles(action='admin-access', role=superuser_role)) db.session.add( ActionRoles(action='workflows-ui-admin-access', role=cataloger_role)) db.session.add( ActionRoles(action='admin-holdingpen-authors', role=cataloger_role)) db.session.commit()
def users(app, db): """Create users.""" with db.session.begin_nested(): datastore = app.extensions['security'].datastore user1 = datastore.create_user(email='*****@*****.**', password='******', active=True) user2 = datastore.create_user(email='*****@*****.**', password='******', active=True) admin = datastore.create_user( email='*****@*****.**', password='******', active=True) superadmin = datastore.create_user( email='*****@*****.**', password='******', active=True) # Give a admin role to admin admin_role = Role(name='admin') db.session.add(ActionRoles( action=action_admin_access.value, role=admin_role)) datastore.add_role_to_user(admin, admin_role) # Give a superadmin role to superadmin superadmin_role = Role(name='superadmin') db.session.add(ActionRoles( action=superuser_access.value, role=superadmin_role)) datastore.add_role_to_user(superadmin, superadmin_role) db.session.commit() id_1 = user1.id id_2 = user2.id id_4 = admin.id return [id_1, id_2, id_4]
def users(app, db): """Create admin, manager and users.""" with db.session.begin_nested(): datastore = app.extensions['security'].datastore # create users user = datastore.create_user(email='*****@*****.**', password='******', active=True) # ID 1 manager = datastore.create_user(email='*****@*****.**', password='******', active=True) admin = datastore.create_user( email='*****@*****.**', # ID 2 password='******', active=True) # ID 3 # Give role to admin admin_role = Role(name='admin') db.session.add( ActionRoles(action=superuser_access.value, role=admin_role)) datastore.add_role_to_user(admin, admin_role) # Give role to librarian manager_role = Role(name='manager') db.session.add( ActionRoles(action=create_records_action.value, role=manager_role)) datastore.add_role_to_user(manager, manager_role) db.session.commit() return { 'admin': admin, 'manager': manager, 'user': user, }
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 _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 init_cataloger_permissions(): cataloger = Role.query.filter_by(name=Roles.cataloger.value).one() db.session.add( ActionRoles(action="workflows-ui-admin-access", role=cataloger)) db.session.add( ActionRoles(action="admin-holdingpen-authors", role=cataloger)) db.session.add(ActionRoles(action="update-collection", role=cataloger)) db.session.add(ActionRoles(action="editor-use-api", role=cataloger)) db.session.add(ActionRoles(action="migrator-use-api", role=cataloger))
def init_jlab_permissions(): jlab_curator = Role.query.filter_by(name='jlabcurator').one() db.session.add(ActionRoles( action='workflows-ui-read-access', role=jlab_curator, )) db.session.add(ActionRoles( action='update-collection', role=jlab_curator, ))
def init_superuser_permissions(): superuser = Role.query.filter_by(name='superuser').one() db.session.add(ActionRoles( action='superuser-access', role=superuser, )) db.session.add(ActionRoles( action='admin-access', role=superuser, ))
def init_users_and_permissions(): ds = current_app.extensions['invenio-accounts'].datastore with db.session.begin_nested(): superuser_role = ds.create_role(name='superuser') ds.create_user(email='*****@*****.**', password=encrypt_password("123456"), active=True, roles=[superuser_role]) db.session.add( ActionRoles(action='superuser-access', role=superuser_role)) db.session.add(ActionRoles(action='admin-access', role=superuser_role)) db.session.commit()
def init_hermes_permissions(): hermes_collections = Role.query.filter_by(name='hermescoll').one() db.session.add(ActionRoles( action='view-restricted-collection', argument='HERMES Internal Notes', role=hermes_collections, )) hermes_curator = Role.query.filter_by(name='hermescurator').one() db.session.add(ActionRoles( action='update-collection', argument='HERMES Internal Notes', role=hermes_curator, ))
def users(app, db): """Create admin, librarians and patrons.""" with db.session.begin_nested(): datastore = app.extensions['security'].datastore # create users patron1 = datastore.create_user(email='*****@*****.**', password='******', active=True) patron2 = datastore.create_user(email='*****@*****.**', password='******', active=True) patron3 = datastore.create_user(email='*****@*****.**', password='******', active=True) librarian = datastore.create_user(email='*****@*****.**', password='******', active=True) librarian2 = datastore.create_user(email='*****@*****.**', password='******', active=True) admin = datastore.create_user(email='*****@*****.**', password='******', active=True) # Give role to admin admin_role = Role(name='admin') db.session.add( ActionRoles(action=superuser_access.value, role=admin_role)) datastore.add_role_to_user(admin, admin_role) # Give role to librarian librarian_role = Role(name='librarian') db.session.add( ActionRoles(action=backoffice_access_action.value, role=librarian_role)) datastore.add_role_to_user(librarian, librarian_role) # Give role to librarian2 db.session.add( ActionRoles(action=backoffice_access_action.value, role=librarian_role)) datastore.add_role_to_user(librarian2, librarian_role) db.session.commit() return { 'admin': admin, 'librarian': librarian, 'librarian2': librarian2, 'patron1': patron1, 'patron2': patron2, 'patron3': patron3, }
def set_egroup_permissions(role, 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( ActionRoles.allow(DEPOSIT_ACTIONS_NEEDS(id).get( permission.get("action", ""), ""), role=role)) except: return access.get(permission["action"], {}).get('roles', []).append(role.id) elif permission.get("op", "") == "remove": try: au = ActionRoles.query.filter( ActionRoles.action == permission.get("action", ""), ActionRoles.argument == str(id), ActionRoles.role_id == role.id).first() if au: session.delete(au) except: return access.get(permission["action"], {}).get('roles', []).remove(role.id) return access
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 admin_user(db): """Permission for admin users.""" 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_read_all, object_read_all, bucket_update_all, object_delete_all, multipart_read_all, object_read_all, ] admin = Role(name='admin') for perm in perms: db.session.add(ActionRoles.allow(perm, role=admin)) admin_user = create_test_user(email='*****@*****.**', password='******', active=True) admin.users.append(admin_user) db.session.commit() yield admin_user
def test_record_patron_create(db, users, access, action, is_allowed): """Test patron create.""" # create role to be able to create records role = Role(name="records-creators") db.session.add(role) db.session.commit() # assign role to the action "create-records" ar = ActionRoles.allow(create_records_action, role_id=role.id) db.session.add(ar) db.session.commit() @identity_loaded.connect def mock_identity_provides(sender, identity): """Provide additional role to the user.""" roles = [RoleNeed(role.name)] # Gives the user additional roles, f.e. based on his groups identity.provides |= set(roles) login_user(users["patron1"]) id = uuid.uuid4() record = Record.create(access, id_=id) factory = RecordPermission(record, action) assert factory.can() if is_allowed else not factory.can()
def test_users(app): """Create test users. Created users are named 'normal' and 'admin'. Other fixtures can add other users. Returns: (dict) A dict of username->user_info. """ result = dict() accounts = app.extensions['invenio-accounts'] security = app.extensions['security'] with app.app_context(): # create a normal user result['normal'] = create_user('normal') # create admin user user_info = create_user('admin') user = accounts.datastore.get_user(user_info.id) role = security.datastore.find_or_create_role('admin') db.session.add(ActionRoles.allow( superuser_access, role=role )) security.datastore.add_role_to_user(user, role) result['admin'] = user_info # create the user which will create the test deposits creator = create_user('deposits_creator') result['deposits_creator'] = creator db.session.commit() return result
def test_deposit_publish_gives_acceess_to_members_of_exp( client, db, users, create_deposit): owner = users['superuser'] role = _datastore.find_or_create_role('*****@*****.**') db.session.add(ActionRoles.allow(exp_need_factory('CMS'), role=role)) deposit = create_deposit(owner, 'test', {}, experiment='CMS', publish=True) _, record = deposit.fetch_published() assert record['_access'] == { 'record-read': { 'users': [owner.id, users['cms_user'].id, users['cms_user2'].id], 'roles': [role.id] }, 'record-update': { 'users': [owner.id], 'roles': [] }, 'record-admin': { 'users': [owner.id], 'roles': [] } } assert ActionUsers.query.filter_by(action='record-read', argument=str(record.id), user=users['cms_user']).one() assert ActionUsers.query.filter_by(action='record-read', argument=str(record.id), user=users['cms_user2']).one() assert ActionRoles.query.filter_by(action='record-read', argument=str(record.id), role=role).one()
def test_deposit_publish_gives_acceess_to_members_of_exp(app, db, users, create_deposit): owner = users['superuser'] role = _datastore.find_or_create_role('*****@*****.**') db.session.add(ActionRoles.allow(exp_need_factory('CMS'), role=role)) deposit = create_deposit(owner, 'test-v1.0.0', {}, 'CMS', publish=True) _, record = deposit.fetch_published() assert record['_access'] == { 'record-read': { 'users': [owner.id, users['cms_user'].id, users['cms_user2'].id], 'roles': [role.id] }, 'record-update': { 'users': [owner.id], 'roles': [] }, 'record-admin': { 'users': [owner.id], 'roles': [] } } assert ActionUsers.query.filter_by(action='record-read', argument=str(record.id), user=users['cms_user']).one() assert ActionUsers.query.filter_by(action='record-read', argument=str(record.id), user=users['cms_user2']).one() assert ActionRoles.query.filter_by(action='record-read', argument=str(record.id), role=role).one()
def receive_before_insert(mapper, connection, target): """Create community admin and member roles and add their permissions.""" from b2share.modules.deposit.permissions import ( create_deposit_need_factory, read_deposit_need_factory, update_deposit_metadata_need_factory, update_deposit_publication_state_need_factory, ) from b2share.modules.deposit.api import PublicationStates admin_role = Role(name=_community_admin_role_name(target), description='Admin role of the community "{}"'.format( target.name)) member_role = Role(name=_community_member_role_name(target), description='Member role of the community "{}"'.format( target.name)) db.session.add(admin_role) db.session.add(member_role) member_needs = [ create_deposit_need_factory(str(target.id)), ] admin_needs = [ read_deposit_need_factory( community=str(target.id), publication_state=PublicationStates.submitted.name), read_deposit_need_factory( community=str(target.id), publication_state=PublicationStates.published.name), update_deposit_metadata_need_factory( community=str(target.id), publication_state=PublicationStates.submitted.name), # permission to publish a submission update_deposit_publication_state_need_factory( community=str(target.id), old_state=PublicationStates.submitted.name, new_state=PublicationStates.published.name), # permission to ask the owners to fix a submission before resubmitting update_deposit_publication_state_need_factory( community=str(target.id), old_state=PublicationStates.submitted.name, new_state=PublicationStates.draft.name) ] for need in member_needs: db.session.add(ActionRoles.allow(need, role=member_role)) for need in chain(member_needs, admin_needs): db.session.add(ActionRoles.allow(need, role=admin_role))
def init_hermes_permissions(): hermes_collections = Role.query.filter_by( name=Roles.hermescoll.value).one() db.session.add( ActionRoles( action="view-restricted-collection", argument="HERMES Internal Notes", role=hermes_collections, )) hermes_curator = Role.query.filter_by(name=Roles.hermescurator.value).one() db.session.add( ActionRoles( action="update-collection", argument="HERMES Internal Notes", role=hermes_curator, ))
def _add_egroup_permissions(self, egroup, permissions, session): for permission in permissions: session.add( ActionRoles.allow(DEPOSIT_ACTIONS_NEEDS(self.id)[permission], role=egroup)) session.flush() self['_access'][permission]['roles'].append(egroup.id)
def test_invenio_access_permission_for_roles(app): """User with a role can access to an action allowed to the role""" InvenioAccess(app) with app.test_request_context(): superuser_role = Role(name='superuser') admin_role = Role(name='admin') reader_role = Role(name='reader') opener_role = Role(name='opener') db.session.add(superuser_role) db.session.add(admin_role) db.session.add(reader_role) db.session.add(opener_role) db.session.add( ActionRoles(action='superuser-access', role=superuser_role)) db.session.add(ActionRoles(action='open', role=admin_role)) db.session.add(ActionRoles(action='open', role=opener_role)) db.session.add(ActionRoles(action='read', role=admin_role)) db.session.add(ActionRoles(action='read', role=reader_role)) db.session.commit() with app.app_context(): permission_open = DynamicPermission(ActionNeed('open')) permission_read = DynamicPermission(ActionNeed('read')) identity_superuser = FakeIdentity(RoleNeed('superuser')) identity_all = FakeIdentity(RoleNeed('admin')) identity_read = FakeIdentity(RoleNeed('reader')) identity_open = FakeIdentity(RoleNeed('opener')) assert permission_open.allows(identity_superuser) assert permission_read.allows(identity_superuser) 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 assign_egroup_to_experiment(egroup_name, exp): role = _datastore.find_or_create_role(egroup_name) exp_need = exp_need_factory(exp) db_.session.add(ActionRoles.allow(exp_need, role=role)) db_.session.commit() return role
def with_role_creator(db): """"Create a new role and assign action.""" role = Role(name="records-creators") db.session.add(role) db.session.commit() # assign role to the action "create-records" ar = ActionRoles.allow(create_records_action, role_id=role.id) db.session.add(ar) db.session.commit()
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 assign_egroup_to_experiment(egroup_name, exp): role = _datastore.find_or_create_role(egroup_name) exp_need = exp_need_factory(exp) db_.session.add(ActionRoles.allow( exp_need, role=role)) db_.session.commit() return role
def add_read_access(self, role): """Give read access to egroup.""" # @TODO make possible to give access also to users db.session.add( ActionRoles.allow( SchemaReadAction(self.id), role=role ) ) db.session.commit()
def create_role(name, permissions=None): """Create a role and assign it the given permission needs.""" security = current_app.extensions['security'] role = security.datastore.find_or_create_role(name) 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(ActionRoles.allow(permission, role=role)) return role
def init_cataloger_permissions(): cataloger = Role.query.filter_by(name='cataloger').one() db.session.add(ActionRoles( action='workflows-ui-admin-access', role=cataloger, )) db.session.add(ActionRoles( action='admin-holdingpen-authors', role=cataloger, )) db.session.add(ActionRoles( action='update-collection', role=cataloger, )) db.session.add(ActionRoles( action='editor-use-api', role=cataloger, )) db.session.add(ActionRoles( action='migrator-use-api', role=cataloger, ))
def _add_egroup_permissions(self, egroup, permissions, session): for permission in permissions: session.add( ActionRoles.allow( DEPOSIT_ACTIONS_NEEDS(self.id)[permission], role=egroup ) ) session.flush() self['_access'][permission]['roles'].append(egroup.id)
def admin(app, db): """Create admin, librarians and patrons.""" with db.session.begin_nested(): datastore = app.extensions["security"].datastore admin = datastore.create_user(email="*****@*****.**", password="******", active=True) # Give role to admin admin_role = Role(name="admin") db.session.add( ActionRoles(action=superuser_access.value, role=admin_role)) datastore.add_role_to_user(admin, admin_role) db.session.commit() return admin
def superuser_role_need(db): """Store 1 role with 'superuser-access' ActionNeed. WHY: This is needed because expansion of ActionNeed is done on the basis of a User/Role being associated with that Need. If no User/Role is associated with that Need (in the DB), the permission is expanded to an empty list. """ role = Role(name="superuser-access") db.session.add(role) action_role = ActionRoles.create(action=superuser_access, role=role) db.session.add(action_role) db.session.commit() return action_role.need
def init_permissions(): superuser = Role.query.filter_by(name='superuser').one() cataloger = Role.query.filter_by(name='cataloger').one() hermes_collections = Role.query.filter_by(name='hermescoll').one() hermes_curator = Role.query.filter_by(name='hermescurator').one() db.session.add(ActionRoles(action='superuser-access', role=superuser)) db.session.add(ActionRoles(action='admin-access', role=superuser)) db.session.add( ActionRoles(action='workflows-ui-admin-access', role=cataloger)) db.session.add( ActionRoles(action='admin-holdingpen-authors', role=cataloger)) db.session.add( ActionRoles(action='view-restricted-collection', argument='HERMES Internal Notes', role=hermes_collections)) db.session.add(ActionRoles(action='update-collection', role=cataloger)) db.session.add(ActionRoles(action='editor-use-api', role=cataloger)) db.session.add( ActionRoles(action='update-collection', argument='HERMES Internal Notes', role=hermes_curator)) db.session.commit()
def set_egroup_permissions(role, 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(ActionRoles.allow( DEPOSIT_ACTIONS_NEEDS(id).get( permission.get("action", ""), ""), role=role )) except: return access.get(permission["action"], {}).get( 'roles', []).append(role.id) elif (permission.get("op", "") == "remove"): try: au = ActionRoles.query.filter( ActionRoles.action == permission.get("action", ""), ActionRoles.argument == str(id), ActionRoles.role_id == role.id).first() if au: session.delete(au) except: return access.get(permission["action"], {}).get( 'roles', []).remove(role.id) return access
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 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 create_roles_and_permissions(community, fix=False): """Create community admin and member roles and add their permissions. :param community: the community for which we add the roles and permissions. :param fix: Enable the fixing of the database. This function doesn't fail if some roles or permissions already exist. It will just add the missing ones. """ from b2share.modules.deposit.permissions import ( create_deposit_need_factory, read_deposit_need_factory, update_deposit_metadata_need_factory, update_deposit_publication_state_need_factory, ) from b2share.modules.deposit.api import PublicationStates from b2share.modules.records.permissions import ( update_record_metadata_need_factory, ) from b2share.modules.users.permissions import ( assign_role_need_factory, search_accounts_need, ) admin_role = Role( name=_community_admin_role_name(community), description='Admin role of the community "{}"'.format(community.name) ) member_role = Role( name=_community_member_role_name(community), description='Member role of the community "{}"'.format(community.name) ) # use a nested session so that the ids are generated by the DB. with db.session.begin_nested(): admin_role = add_to_db(admin_role, skip_if_exists=fix) member_role = add_to_db(member_role, skip_if_exists=fix) member_needs = [ create_deposit_need_factory(str(community.id)), ] admin_needs = [ read_deposit_need_factory( community=str(community.id), publication_state=PublicationStates.submitted.name ), read_deposit_need_factory( community=str(community.id), publication_state=PublicationStates.published.name ), update_deposit_metadata_need_factory( community=str(community.id), publication_state=PublicationStates.submitted.name ), # permission to publish a submission update_deposit_publication_state_need_factory( community=str(community.id), old_state=PublicationStates.submitted.name, new_state=PublicationStates.published.name ), # permission to ask the owners to fix a submission before resubmitting update_deposit_publication_state_need_factory( community=str(community.id), old_state=PublicationStates.submitted.name, new_state=PublicationStates.draft.name ), # permission to update the metadata of a published record update_record_metadata_need_factory( community=str(community.id), ), # allow to assign any role owned by this community assign_role_need_factory(community=community.id), # allow to list users' accounts search_accounts_need, ] for need in member_needs: add_to_db(ActionRoles.allow(need, role=member_role), skip_if_exists=fix, role_id=member_role.id) for need in chain (member_needs, admin_needs): add_to_db(ActionRoles.allow(need, role=admin_role), skip_if_exists=fix, role_id=admin_role.id)
def test_invenio_access_permission_cache_roles_updates(app): """Testing ActionRoles cache with inserts/updates/deletes.""" # This test case is doing the same of user test case but using roles. cache = SimpleCache() InvenioAccess(app, cache=cache) with app.test_request_context(): # Creation of some data to test. role_1 = Role(name='role_1') role_2 = Role(name='role_2') role_3 = Role(name='role_3') role_4 = Role(name='role_4') role_5 = Role(name='role_5') role_6 = Role(name='role_6') db.session.add(role_1) db.session.add(role_2) db.session.add(role_3) db.session.add(role_4) db.session.add(role_5) db.session.add(role_6) db.session.add(ActionRoles(action='open', role=role_1)) db.session.add(ActionRoles(action='write', role=role_4)) db.session.flush() # Creation of identities to test. identity_fake_role_1 = FakeIdentity(RoleNeed(role_1.name)) identity_fake_role_2 = FakeIdentity(RoleNeed(role_2.name)) identity_fake_role_3 = FakeIdentity(RoleNeed(role_3.name)) identity_fake_role_4 = FakeIdentity(RoleNeed(role_4.name)) identity_fake_role_5 = FakeIdentity(RoleNeed(role_5.name)) identity_fake_role_6 = FakeIdentity(RoleNeed(role_6.name)) # Test if role 1 can open. In this case, the cache should store only # this object. permission_open = DynamicPermission(ActionNeed('open')) assert permission_open.allows(identity_fake_role_1) assert current_access.get_action_cache('open') == ( set([Need(method='role', value=role_1.name)]), set([]) ) # Test if role 4 can write. In this case, the cache should have this # new object and the previous one (Open is allowed to role_1) permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_fake_role_4) assert current_access.get_action_cache('write') == ( set([Need(method='role', value=role_4.name)]), set([]) ) assert current_access.get_action_cache('open') == ( set([Need(method='role', value=role_1.name)]), set([]) ) # If we add a new role to the action open, the open action in cache # should be removed but it should still containing the write entry. db.session.add(ActionRoles(action='open', role=role_2)) db.session.flush() assert current_access.get_action_cache('open') is None permission_open = DynamicPermission(ActionNeed('open')) assert permission_open.allows(identity_fake_role_2) assert current_access.get_action_cache('open') == ( set([Need(method='role', value=role_1.name), Need(method='role', value=role_2.name)]), set([]) ) assert current_access.get_action_cache('write') == ( set([Need(method='role', value=role_4.name)]), set([]) ) # Test if the new role is added to the action 'open' permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_fake_role_4) assert current_access.get_action_cache('open') == ( set([Need(method='role', value=role_1.name), Need(method='role', value=role_2.name)]), set([]) ) assert current_access.get_action_cache('write') == ( set([Need(method='role', value=role_4.name)]), set([]) ) # If we update an action swapping a role, the cache containing the # action, should be removed. role_4_action_write = ActionRoles.query.filter( ActionRoles.action == 'write' and ActionRoles.role == role_4).first() role_4_action_write.role = role_3 db.session.flush() assert current_access.get_action_cache('write') is None assert current_access.get_action_cache('open') is not None assert current_access.get_action_cache('open') == ( set([Need(method='role', value=role_1.name), Need(method='role', value=role_2.name)]), set([]) ) # Test if the role_3 can write now. permission_write = DynamicPermission(ActionNeed('write')) assert not permission_write.allows(identity_fake_role_4) permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_fake_role_3) assert current_access.get_action_cache('write') == ( set([Need(method='role', value=role_3.name)]), set([]) ) assert current_access.get_action_cache('open') == ( set([Need(method='role', value=role_1.name), Need(method='role', value=role_2.name)]), set([]) ) # If we remove a role from an action, the cache should clear the # action item. role_3_action_write = ActionRoles.query.filter( ActionRoles.action == 'write' and ActionRoles.role == role_3).first() db.session.delete(role_3_action_write) db.session.flush() assert current_access.get_action_cache('write') is None # If no one is allowed to perform an action then everybody is allowed. permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_fake_role_3) assert current_access.get_action_cache('write') == ( set([]), set([]) ) db.session.add(ActionRoles(action='write', role=role_5)) db.session.flush() permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_fake_role_5) permission_write = DynamicPermission(ActionNeed('write')) assert not permission_write.allows(identity_fake_role_3) assert current_access.get_action_cache('write') == ( set([Need(method='role', value=role_5.name)]), set([]) ) assert current_access.get_action_cache('open') == ( set([Need(method='role', value=role_1.name), Need(method='role', value=role_2.name)]), set([]) ) # If you update the name of an existing action, the previous action # and the new action should be remove from cache. permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_fake_role_5) assert current_access.get_action_cache('write') == ( set([Need(method='role', value=role_5.name)]), set([]) ) assert current_access.get_action_cache('open') == ( set([Need(method='role', value=role_1.name), Need(method='role', value=role_2.name)]), set([]) ) role_5_action_write = ActionRoles.query.filter( ActionRoles.action == 'write' and ActionRoles.role == role_5).first() role_5_action_write.action = 'open' db.session.flush() assert current_access.get_action_cache('write') is None assert current_access.get_action_cache('open') is None permission_open = DynamicPermission(ActionNeed('open')) assert permission_open.allows(identity_fake_role_1) assert current_access.get_action_cache('open') == ( set([Need(method='role', value=role_1.name), Need(method='role', value=role_2.name), Need(method='role', value=role_5.name)]), set([]) ) db.session.add(ActionRoles(action='write', role=role_4)) permission_write = DynamicPermission(ActionNeed('write')) assert not permission_write.allows(identity_fake_role_5) assert current_access.get_action_cache('write') == ( set([Need(method='role', value=role_4.name)]), set([]) ) db.session.add(ActionRoles(action='open', argument='1', role=role_6)) db.session.flush() permission_open_1 = DynamicPermission( ParameterizedActionNeed('open', '1')) assert not permission_open.allows(identity_fake_role_6) assert permission_open_1.allows(identity_fake_role_6) assert current_access.get_action_cache('open::1') == ( set([Need(method='role', value=role_1.name), Need(method='role', value=role_2.name), Need(method='role', value=role_5.name), Need(method='role', value=role_6.name)]), set([]) ) user_6_action_open_1 = ActionRoles.query.filter_by( action='open', argument='1', role_id=role_6.id).first() user_6_action_open_1.argument = '2' db.session.flush() assert current_access.get_action_cache('open::1') is None assert current_access.get_action_cache('open::2') is None permission_open_2 = DynamicPermission( ParameterizedActionNeed('open', '2')) assert permission_open_2.allows(identity_fake_role_6) assert current_access.get_action_cache('open::2') == ( set([Need(method='role', value=role_1.name), Need(method='role', value=role_2.name), Need(method='role', value=role_5.name), Need(method='role', value=role_6.name)]), set([]) ) # open action cache should remain as before assert current_access.get_action_cache('open') == ( set([Need(method='role', value=role_1.name), Need(method='role', value=role_2.name), Need(method='role', value=role_5.name)]), set([]) )
def receive_before_insert(mapper, connection, target): """Create community admin and member roles and add their permissions.""" from b2share.modules.deposit.permissions import ( create_deposit_need_factory, read_deposit_need_factory, update_deposit_metadata_need_factory, update_deposit_publication_state_need_factory, ) from b2share.modules.deposit.api import PublicationStates from b2share.modules.records.permissions import ( update_record_metadata_need_factory, ) from b2share.modules.users.permissions import ( assign_role_need_factory, search_accounts_need, ) admin_role = Role( name=_community_admin_role_name(target), description='Admin role of the community "{}"'.format(target.name) ) member_role = Role( name=_community_member_role_name(target), description='Member role of the community "{}"'.format(target.name) ) db.session.add(admin_role) db.session.add(member_role) member_needs = [ create_deposit_need_factory(str(target.id)), ] admin_needs = [ read_deposit_need_factory( community=str(target.id), publication_state=PublicationStates.submitted.name ), read_deposit_need_factory( community=str(target.id), publication_state=PublicationStates.published.name ), update_deposit_metadata_need_factory( community=str(target.id), publication_state=PublicationStates.submitted.name ), # permission to publish a submission update_deposit_publication_state_need_factory( community=str(target.id), old_state=PublicationStates.submitted.name, new_state=PublicationStates.published.name ), # permission to ask the owners to fix a submission before resubmitting update_deposit_publication_state_need_factory( community=str(target.id), old_state=PublicationStates.submitted.name, new_state=PublicationStates.draft.name ), # permission to update the metadata of a published record update_record_metadata_need_factory( community=str(target.id), ), # allow to assign any role owned by this community assign_role_need_factory(community=target.id), # allow to list users' accounts search_accounts_need, ] for need in member_needs: db.session.add(ActionRoles.allow(need, role=member_role)) for need in chain (member_needs, admin_needs): db.session.add(ActionRoles.allow(need, role=admin_role)) oaiset = OAISet(spec=str(target.id), name=target.name, description=target.description) db.session.add(oaiset)