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_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 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 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 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_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 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 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 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 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 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 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 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) superuser = User(email='*****@*****.**') user_can_all = User(email='*****@*****.**') user_can_read = User(email='*****@*****.**') user_can_open = User(email='*****@*****.**') db.session.add(superuser) db.session.add(user_can_all) db.session.add(user_can_read) db.session.add(user_can_open) db.session.add(ActionUsers(action='superuser-access', user=superuser)) 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.add(ActionUsers(action='not_logged', user=user_can_all)) db.session.commit() permission_open = DynamicPermission(ActionNeed('open')) permission_read = DynamicPermission(ActionNeed('read')) permission_not_logged = DynamicPermission(ActionNeed('not_logged')) identity_superuser = FakeIdentity(UserNeed(superuser.id)) identity_all = FakeIdentity(UserNeed(user_can_all.id)) identity_read = FakeIdentity(UserNeed(user_can_read.id)) identity_open = FakeIdentity(UserNeed(user_can_open.id)) identity_unknown = AnonymousIdentity() # global permissions 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_not_logged.allows(identity_all) assert permission_open.allows(identity_open) assert not permission_read.allows(identity_open) assert not permission_not_logged.allows(identity_open) assert not permission_open.allows(identity_read) assert permission_read.allows(identity_read) assert not permission_not_logged.allows(identity_read) assert not permission_open.allows(identity_unknown) assert not permission_read.allows(identity_unknown)
def test_permission_links(client, db, published_json): """Test the links when affected by permissions.""" # We test that only admins get the "delete" link (according to our policy) pid_value = published_json["pid"] user = create_test_user("*****@*****.**") db.session.add(ActionUsers(action='admin-access', user=user)) db.session.commit() login_user_via_view(client, email=user.email, password=user.password_plaintext, login_url='/login') response = client.get(f"/rdm-records/{pid_value}", headers=HEADERS) read_record_links = response.json["links"] assert (f"https://localhost:5000/api/rdm-records/{pid_value}" == read_record_links["delete"])
def users(app): """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) # Assign deposit-admin-access to admin only. db.session.add(ActionUsers( action='deposit-admin-access', user=admin )) db.session.commit() return [object_as_dict(user1), object_as_dict(user2)]
def test_invenio_access_permission(app): """Permission is always denied if not explicitly granted.""" fake_identity = FakeIdentity() InvenioAccess(app) with app.test_request_context(): db.session.begin(nested=True) user = User(email='*****@*****.**') permission = Permission(ActionNeed('read')) assert not permission.allows(fake_identity) db.session.add(ActionUsers(action='read', user=user)) db.session.commit() assert not permission.allows(fake_identity) fake_identity.provides.add(UserNeed(user.id)) assert permission.allows(fake_identity)
def users(app, db): """Create users.""" 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': user1, 'user2': user2, }
def test_invenio_access_dynamic_permission(app): """DynamicPermission allows by default.""" fake_identity = FakeIdentity() InvenioAccess(app) with app.test_request_context(): db.session.begin(nested=True) user = User(email='*****@*****.**') permission = DynamicPermission(ActionNeed('read')) # The permission is granted if nobody is assigned the "read" permission assert permission.allows(fake_identity) # Once the permission is assigned, the need is mandatory db.session.add(ActionUsers(action='read', user=user)) db.session.commit() assert not permission.allows(fake_identity) fake_identity.provides.add(UserNeed(user.id)) assert permission.allows(fake_identity)
def users(app): # Create test users hashed_password = hash_password('123456') user = User(email='*****@*****.**', password=hashed_password, active=True) user_partially_allowed = User( email='*****@*****.**', password=hashed_password, active=True, ) user_allowed = User( email='*****@*****.**', password=hashed_password, active=True, ) collection_restricted_role = Role(name='restrictedcollmaintainer') user_allowed_with_role = User(email='*****@*****.**', password=hashed_password, active=True, roles=[collection_restricted_role]) db.session.add_all([ user, user_partially_allowed, user_allowed, user_allowed_with_role, collection_restricted_role ]) 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) # Create actions for the allowed role partial_restricted_collection_role_action = ActionRoles( action='view-restricted-collection', argument='Restricted Collection', role_id=collection_restricted_role.id) role_only_collection_action = ActionRoles( action='view-restricted-collection', argument='Role only collection', role_id=collection_restricted_role.id) db.session.add_all([ restricted_collection_action, another_restricted_collection_action, partial_restricted_collection_action, partial_restricted_collection_role_action, role_only_collection_action ]) db.session.commit() yield current_cache.clear() SessionActivity.query.delete() ActionRoles.query.filter_by(action='view-restricted-collection').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.delete( Role.query.filter_by(name='restrictedcollmaintainer').one()) db.session.delete( User.query.filter_by(email='*****@*****.**').one()) db.session.commit()
def users(app, db): """Create users.""" user1 = create_test_user(email='*****@*****.**', password='******', confirmed_at=datetime.now()) user2 = create_test_user(email='*****@*****.**', password='******', confirmed_at=datetime.now()) user_admin = create_test_user(email='*****@*****.**', password='******', confirmed_at=datetime.now()) non_validated_user = create_test_user(email='*****@*****.**', password='******') user_with_blacklisted_domain = create_test_user( email='*****@*****.**', password='******', confirmed_at=datetime.now()) longtime_validated_user_with_blacklisted_domain = create_test_user( email='*****@*****.**', password='******', confirmed_at=datetime.now() - timedelta(days=40)) user_with_blacklisted_domain_and_ext_id = create_test_user( email='*****@*****.**', password='******') ud = UserIdentity(id='1', method='github', id_user=user_with_blacklisted_domain_and_ext_id.id) db.session.add(ud) 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 }, { 'email': non_validated_user.email, 'id': non_validated_user.id }, { 'email': user_with_blacklisted_domain.email, 'id': user_with_blacklisted_domain.id }, { 'email': longtime_validated_user_with_blacklisted_domain.email, 'id': longtime_validated_user_with_blacklisted_domain.id }, ]
def test_permission(app): """Test permission control to records.""" app.config.update( WTF_CSRF_ENABLED=False, SECRET_KEY='CHANGEME', SECURITY_PASSWORD_SALT='CHANGEME', # conftest switches off permission checking, so re-enable it for this # app. RECORDS_UI_DEFAULT_PERMISSION_FACTORY='invenio_records.permissions' ':read_permission_factory') Menu(app) InvenioRecordsUI(app) accounts = InvenioAccounts(app) app.register_blueprint(accounts_blueprint) InvenioAccess(app) setup_record_fixture(app) # Create admin with app.app_context(): admin = accounts.datastore.create_user( email='*****@*****.**', password=encrypt_password('123456'), active=True, ) reader = accounts.datastore.create_user( email='*****@*****.**', password=encrypt_password('123456'), active=True, ) # Get record 1 r = Resolver(pid_type='recid', object_type='rec', getter=Record.get_record) dummy_pid, record = r.resolve('1') # Setup permissions for record 1 (grant 'admin', deny 'reader') db.session.add( ActionUsers(action=records_read_all.value, argument=str(record.id), user=admin)) db.session.add( ActionUsers(action=records_read_all.value, argument=str(record.id), user=reader, exclude=True)) db.session.commit() with app.test_request_context(): login_url = url_for('security.login') record_url = url_for('invenio_records_ui.recid', pid_value='1') # Access record 1 as admin with app.test_client() as client: res = client.get(record_url) assert res.status_code == 302 res = client.post(login_url, data={ 'email': '*****@*****.**', 'password': '******' }) assert res.status_code == 302 res = client.get(record_url) res.status_code == 200 # Access record 1 as reader with app.test_client() as client: res = client.post(login_url, data={ 'email': '*****@*****.**', 'password': '******' }) assert res.status_code == 302 res = client.get(record_url) res.status_code == 403
def test_invenio_access_permission_cache_users_updates(app): """Testing ActionUsers cache with inserts/updates/deletes.""" cache = SimpleCache() InvenioAccess(app, cache=cache) with app.test_request_context(): # Creation of some data to test. user_1 = User(email='*****@*****.**') user_2 = User(email='*****@*****.**') user_3 = User(email='*****@*****.**') user_4 = User(email='*****@*****.**') user_5 = User(email='*****@*****.**') user_6 = User(email='*****@*****.**') db.session.add(user_1) db.session.add(user_2) db.session.add(user_3) db.session.add(user_4) db.session.add(user_5) db.session.add(user_6) db.session.add(ActionUsers(action='open', user=user_1)) db.session.add(ActionUsers(action='write', user=user_4)) db.session.flush() # Creation identities to test. identity_user_1 = FakeIdentity(UserNeed(user_1.id)) identity_user_2 = FakeIdentity(UserNeed(user_2.id)) identity_user_3 = FakeIdentity(UserNeed(user_3.id)) identity_user_4 = FakeIdentity(UserNeed(user_4.id)) identity_user_5 = FakeIdentity(UserNeed(user_5.id)) identity_user_6 = FakeIdentity(UserNeed(user_6.id)) # Test if user 1 can open. In this case, the cache should store only # this object. permission_open = DynamicPermission(ActionNeed('open')) assert permission_open.allows(identity_user_1) assert current_access.get_action_cache('open') == ( set([Need(method='id', value=1)]), set([]) ) # Test if user 4 can write. In this case, the cache should have this # new object and the previous one (Open is allowed to user_1) permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_user_4) assert current_access.get_action_cache('write') == ( set([Need(method='id', value=4)]), set([]) ) assert current_access.get_action_cache('open') == ( set([Need(method='id', value=1)]), set([]) ) # If we add a new user to the action open, the open action in cache # should be removed but it should still containing the write entry. db.session.add(ActionUsers(action='open', user=user_2)) db.session.flush() assert current_access.get_action_cache('open') is None permission_open = DynamicPermission(ActionNeed('open')) assert permission_open.allows(identity_user_2) assert current_access.get_action_cache('open') == ( set([Need(method='id', value=1), Need(method='id', value=2)]), set([]) ) assert current_access.get_action_cache('write') == ( set([Need(method='id', value=4)]), set([]) ) # Test if the new user is added to the action 'open' permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_user_4) assert current_access.get_action_cache('open') == ( set([Need(method='id', value=1), Need(method='id', value=2)]), set([]) ) assert current_access.get_action_cache('write') == ( set([Need(method='id', value=4)]), set([]) ) # If we update an action swapping a user, the cache containing the # action, should be removed. user_4_action_write = ActionUsers.query.filter( ActionUsers.action == 'write' and ActionUsers.user == user_4).first() user_4_action_write.user = user_3 db.session.flush() assert current_access.get_action_cache('write') is None assert current_access.get_action_cache('open') == ( set([Need(method='id', value=1), Need(method='id', value=2)]), set([]) ) # Test if the user_3 can now write. permission_write = DynamicPermission(ActionNeed('write')) assert not permission_write.allows(identity_user_4) permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_user_3) assert current_access.get_action_cache('write') == ( set([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([]) ) # If we remove a user from an action, the cache should clear the # action item. user_3_action_write = ActionUsers.query.filter( ActionUsers.action == 'write' and ActionUsers.user == user_3).first() db.session.delete(user_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_user_3) assert current_access.get_action_cache('write') == ( set([]), set([]) ) db.session.add(ActionUsers(action='write', user=user_5)) db.session.flush() permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_user_5) permission_write = DynamicPermission(ActionNeed('write')) assert not permission_write.allows(identity_user_3) assert current_access.get_action_cache('write') == ( set([Need(method='id', value=5)]), set([]) ) assert current_access.get_action_cache('open') == ( set([Need(method='id', value=1), Need(method='id', value=2)]), 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_user_5) assert current_access.get_action_cache('write') == ( set([Need(method='id', value=5)]), set([]) ) assert current_access.get_action_cache('open') == ( set([Need(method='id', value=1), Need(method='id', value=2)]), set([]) ) user_5_action_write = ActionUsers.query.filter( ActionUsers.action == 'write' and ActionUsers.user == user_5).first() user_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_user_1) assert current_access.get_action_cache('open') == ( set([Need(method='id', value=1), Need(method='id', value=2), Need(method='id', value=5)]), set([]) ) db.session.add(ActionUsers(action='write', user=user_4)) permission_write = DynamicPermission(ActionNeed('write')) assert not permission_write.allows(identity_user_5) assert current_access.get_action_cache('write') == ( set([Need(method='id', value=4)]), set([]) ) db.session.add(ActionUsers(action='open', argument='1', user=user_6)) db.session.flush() permission_open_1 = DynamicPermission( ParameterizedActionNeed('open', '1')) assert not permission_open.allows(identity_user_6) assert permission_open_1.allows(identity_user_6) assert current_access.get_action_cache('open::1') == ( set([Need(method='id', value=1), Need(method='id', value=2), Need(method='id', value=5), Need(method='id', value=6)]), set([]) ) user_6_action_open_1 = ActionUsers.query.filter_by( action='open', argument='1', user_id=user_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_user_6) assert current_access.get_action_cache('open::2') == ( set([Need(method='id', value=1), Need(method='id', value=2), Need(method='id', value=5), Need(method='id', value=6)]), set([]) ) # open action cache should remain as before assert current_access.get_action_cache('open') == ( set([Need(method='id', value=1), Need(method='id', value=2), Need(method='id', value=5)]), set([]) )
def test_intenio_access_cache_performance(app): """Performance test simulating 1000 users.""" InvenioAccess(app, cache=None) with app.test_request_context(): # CDS has (2015-11-19) 74 actions with 414 possible arguments with # 49259 users and 307 roles. In this test we are going to divide # into 50 and use the next prime number. users_number = 991 actions_users_number = 11 actions_roles_number = 7 roles = [] actions = [] for i in range(actions_roles_number): role = Role(name='role{0}'.format(i)) roles.append(role) db.session.add(role) db.session.flush() action_role = ActionRoles( action='action{0}'.format( str(i % actions_roles_number)), role=role) actions.append(action_role) db.session.add(action_role) db.session.flush() users = [] for i in range(users_number): user = User( email='invenio{0}@inveniosoftware.org'.format(str(i)), roles=[roles[i % actions_roles_number]]) users.append(user) db.session.add(user) db.session.flush() action_user = ActionUsers(action='action{0}'.format( str((i % actions_users_number) + actions_roles_number)), user=user) actions.append(action_user) db.session.add(action_user) db.session.flush() def test_permissions(): """Iterates over all users checking its permissions.""" for i in range(users_number): identity = FakeIdentity(UserNeed(users[i].id)) # Allowed permission permission_allowed_both = DynamicPermission( ActionNeed('action{0}'.format( (i % actions_users_number) + actions_roles_number)), ActionNeed('action{0}'.format(i % actions_roles_number)) ) assert permission_allowed_both.allows(identity) # Not allowed action user permission_not_allowed_user = DynamicPermission( ActionNeed('action{0}'.format( (i + 1) % actions_users_number + actions_roles_number)) ) assert not permission_not_allowed_user.allows(identity) # Not allowed action role permission_not_allowed_role = DynamicPermission( ActionNeed('action{0}'.format( (i + 1) % actions_roles_number)) ) assert not permission_not_allowed_role.allows(identity) app.extensions['invenio-access'].cache = None start_time_wo_cache = time.time() test_permissions() end_time_wo_cache = time.time() time_wo_cache = end_time_wo_cache - start_time_wo_cache app.extensions['invenio-access'].cache = SimpleCache() start_time_w_cache = time.time() test_permissions() end_time_w_cache = time.time() time_w_cache = end_time_w_cache - start_time_w_cache assert time_wo_cache / time_w_cache > 10
def test_invenio_access_argument_permission_for_users(app): """User can access to an action allowed/denied with argument to the user""" InvenioAccess(app) with app.test_request_context(): db.session.begin(nested=True) superuser = User(email='*****@*****.**') user_can_all = User(email='*****@*****.**') user_can_argument_dummy = User(email='*****@*****.**') db.session.add(superuser) db.session.add(user_can_all) db.session.add(user_can_argument_dummy) db.session.add(ActionUsers(action='superuser-access', user=superuser)) db.session.add(ActionUsers(action='argument1', user=user_can_all)) db.session.add(ActionUsers(action='argument1', argument='other', user=user_can_all)) db.session.add(ActionUsers(action='argument1', argument='dummy', user=user_can_argument_dummy)) db.session.add(ActionUsers(action='argument2', argument='other', user=user_can_all)) db.session.commit() permission_argument1 = DynamicPermission(ActionNeed('argument1')) permission_argument1_dummy = DynamicPermission( ParameterizedActionNeed('argument1', 'dummy')) permission_argument1_other = DynamicPermission( ParameterizedActionNeed('argument1', 'other')) permission_argument2 = DynamicPermission(ActionNeed('argument2')) permission_argument2_dummy = DynamicPermission( ParameterizedActionNeed('argument2', 'dummy')) permission_argument2_other = DynamicPermission( ParameterizedActionNeed('argument2', 'other')) identity_superuser = FakeIdentity(UserNeed(superuser.id)) identity_all = FakeIdentity(UserNeed(user_can_all.id)) identity_unknown = AnonymousIdentity() identity_argument_dummy = FakeIdentity( UserNeed(user_can_argument_dummy.id)) # tests for super user assert permission_argument1.allows(identity_superuser) assert permission_argument1_dummy.allows(identity_superuser) assert permission_argument1_other.allows(identity_superuser) assert permission_argument2.allows(identity_superuser) assert permission_argument2_dummy.allows(identity_superuser) assert permission_argument2_other.allows(identity_superuser) # first tests for permissions with argument assert permission_argument1.allows(identity_all) assert permission_argument1_dummy.allows(identity_all) assert permission_argument1_other.allows(identity_all) assert not permission_argument1.allows(identity_argument_dummy) assert permission_argument1_dummy.allows(identity_argument_dummy) assert not permission_argument1_other.allows(identity_argument_dummy) assert not permission_argument1.allows(identity_unknown) assert not permission_argument1_dummy.allows(identity_unknown) assert not permission_argument1_other.allows(identity_unknown) # second tests for permissions with arguments # assert permission_argument2.allows(identity_all) # assert permission_argument2_dummy.allows(identity_all) assert permission_argument2_other.allows(identity_all) # assert permission_argument2.allows(identity_argument_dummy) # assert permission_argument2_dummy.allows(identity_argument_dummy) assert not permission_argument2_other.allows(identity_argument_dummy) # assert permission_argument2.allows(identity_unknown) # assert permission_argument2_dummy.allows(identity_unknown) assert not permission_argument2_other.allows(identity_unknown)
def delete_access(self, allow, record_id=None): db.session.add( ActionUsers(action=records_delete_all.value, argument=record_id, user=self.user, exclude=not allow))