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 script_info(app): """Get ScriptInfo object for testing CLI.""" action_open = ActionNeed('open') action_edit = ParameterizedActionNeed('edit', None) ext = InvenioAccess(app) ext.register_action(action_open) ext.register_action(action_edit) return ScriptInfo(create_app=lambda info: app)
def cli_app(app): """Get CLI app object for testing CLI.""" action_open = ActionNeed('open') action_edit = ParameterizedActionNeed('edit', None) ext = InvenioAccess(app) ext.register_action(action_open) ext.register_action(action_edit) return app
def script_info_cli_list(base_app, request): """Get ScriptInfo object for testing CLI list command.""" action_open = ActionNeed('open') action_edit = ParameterizedActionNeed('edit', None) app_ = app(base_app, request) ext = InvenioAccess(app_) ext.register_action(action_open) ext.register_action(action_edit) return ScriptInfo(create_app=lambda info: app_)
def _deposit_need_factory(name, **kwargs): if kwargs: for key, value in enumerate(kwargs): if value is None: del kwargs[key] if not kwargs: argument = None else: argument = json.dumps(kwargs, separators=(',', ':'), sort_keys=True) return ParameterizedActionNeed(name, argument)
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 _record_need_factory(name, **kwargs): from invenio_access.permissions import ParameterizedActionNeed if kwargs: for key, value in enumerate(kwargs): if value is None: del kwargs[key] if not kwargs: argument = None else: argument = json.dumps(kwargs, separators=(',', ':'), sort_keys=True) return ParameterizedActionNeed(name, argument)
def test_allow_by_action_expands_to_user_id_with_argument(access_app): """Ensure allow permission by action that expands to user id + argument.""" editor1, editor2 = create_users("editor1", "editor2") act_edit_record_1 = expand( ParameterizedActionNeed("access-edit-record", "1"), ("allow", editor1, "1"), ) act_edit_record_2 = expand( ParameterizedActionNeed("access-edit-record", "2"), ("allow", editor2, "2"), ) permission1, permission2 = create_permissions( {"needs": [act_edit_record_1]}, {"needs": [act_edit_record_2]}) assert permission1.allows(editor1) assert not permission1.allows(editor2) assert permission2.allows(editor2) assert not permission2.allows(editor1) superuser = get_superuser() assert permission1.allows(superuser) assert permission2.allows(superuser)
def generic_need_factory(name, **kwargs): """Generic need factory using a JSON object as argument. Args: **kwargs: keywords which will be used in the JSON parameter. """ if kwargs: for key, value in enumerate(kwargs): if value is None: del kwargs[key] if not kwargs: argument = None else: argument = json.dumps(kwargs, separators=(',', ':'), sort_keys=True) return ParameterizedActionNeed(name, argument)
def _deposit_need_factory(name, **kwargs): """Generate a JSON argument string from the given keyword arguments. The JSON string is always generated the same way so that the resulting Need is equal to any other Need generated with the same name and kwargs. """ if kwargs: for key, value in enumerate(kwargs): if value is None: del kwargs[key] if not kwargs: argument = None else: argument = json.dumps(kwargs, separators=(',', ':'), sort_keys=True) return ParameterizedActionNeed(name, argument)
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 test_invenio_access_permission_cache_system_roles_updates(app): """Testing ActionSystemRoles cache with inserts/updates/deletes.""" # This test case is doing the same of user test case but using # system roles. cache = SimpleCache() InvenioAccess(app, cache=cache) with app.test_request_context(): system_role_1 = SystemRoleNeed('system_role_1') system_role_2 = SystemRoleNeed('system_role_2') system_role_3 = SystemRoleNeed('system_role_3') system_role_4 = SystemRoleNeed('system_role_4') system_role_5 = SystemRoleNeed('system_role_5') system_role_6 = SystemRoleNeed('system_role_6') current_access.system_roles = { 'system_role_1': system_role_1, 'system_role_2': system_role_2, 'system_role_3': system_role_3, 'system_role_4': system_role_4, 'system_role_5': system_role_5, 'system_role_6': system_role_6, } # Creation of some data to test. db.session.add(ActionSystemRoles(action='open', role_name=system_role_1.value)) db.session.add(ActionSystemRoles(action='write', role_name=system_role_4.value)) db.session.flush() # Creation of identities to test. identity_fake_1 = FakeIdentity(system_role_1) identity_fake_2 = FakeIdentity(system_role_2) identity_fake_3 = FakeIdentity(system_role_3) identity_fake_4 = FakeIdentity(system_role_4) identity_fake_5 = FakeIdentity(system_role_5) identity_fake_6 = FakeIdentity(system_role_6) # Test if system_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_1) assert current_access.get_action_cache('open') == ( set([system_role_1]), set([]) ) # Test if system_role_2 can write. In this case, the cache should # have this new object and the previous one (Open is allowed to # system_role_1) permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_fake_4) assert current_access.get_action_cache('write') == ( set([system_role_4]), set([]) ) assert current_access.get_action_cache('open') == ( set([system_role_1]), set([]) ) # If we add a new system role to the action open, the open action in # cache should be removed but it should still containing the write # entry. db.session.add(ActionSystemRoles(action='open', role_name=system_role_2.value)) db.session.flush() assert current_access.get_action_cache('open') is None permission_open = DynamicPermission(ActionNeed('open')) assert permission_open.allows(identity_fake_2) assert current_access.get_action_cache('open') == ( set([system_role_1, system_role_2]), set([]) ) assert current_access.get_action_cache('write') == ( set([system_role_4]), set([]) ) # Test if the new role is added to the action 'open' permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_fake_4) assert current_access.get_action_cache('open') == ( set([system_role_1, system_role_2]), set([]) ) assert current_access.get_action_cache('write') == ( set([system_role_4]), set([]) ) # If we update an action swapping a role, the cache containing the # action, should be removed. role_4_action_write = ActionSystemRoles.query.filter( ActionSystemRoles.action == 'write' and ActionSystemRoles.role_name == system_role_4.value).first() role_4_action_write.role_name = system_role_3.value 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([system_role_1, system_role_2]), set([]) ) # Test if the system_role_3 can write now. permission_write = DynamicPermission(ActionNeed('write')) assert not permission_write.allows(identity_fake_4) permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_fake_3) assert current_access.get_action_cache('write') == ( set([system_role_3]), set([]) ) assert current_access.get_action_cache('open') == ( set([system_role_1, system_role_2]), set([]) ) # If we remove a role from an action, the cache should clear the # action item. cust_action_write = ActionSystemRoles.query.filter( ActionSystemRoles.action == 'write' and ActionSystemRoles.role_name == system_role_3).first() db.session.delete(cust_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_3) assert current_access.get_action_cache('write') == ( set([]), set([]) ) db.session.add(ActionSystemRoles(action='write', role_name=system_role_5.value)) db.session.flush() permission_write = DynamicPermission(ActionNeed('write')) assert permission_write.allows(identity_fake_5) permission_write = DynamicPermission(ActionNeed('write')) assert not permission_write.allows(identity_fake_3) assert current_access.get_action_cache('write') == ( set([system_role_5]), set([]) ) assert current_access.get_action_cache('open') == ( set([system_role_1, system_role_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_fake_5) assert current_access.get_action_cache('write') == ( set([system_role_5]), set([]) ) assert current_access.get_action_cache('open') == ( set([system_role_1, system_role_2]), set([]) ) role_5_action_write = ActionSystemRoles.query.filter( ActionSystemRoles.action == 'write' and ActionSystemRoles.role_name == system_role_5.value).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_1) assert current_access.get_action_cache('open') == ( set([system_role_1, system_role_2, system_role_5]), set([]) ) db.session.add(ActionSystemRoles(action='write', role_name=system_role_4.value)) permission_write = DynamicPermission(ActionNeed('write')) assert not permission_write.allows(identity_fake_5) assert current_access.get_action_cache('write') == ( set([system_role_4]), set([]) ) db.session.add(ActionSystemRoles(action='open', argument='1', role_name=system_role_6.value)) db.session.flush() permission_open_1 = DynamicPermission( ParameterizedActionNeed('open', '1')) assert not permission_open.allows(identity_fake_6) assert permission_open_1.allows(identity_fake_6) assert current_access.get_action_cache('open::1') == ( set([system_role_1, system_role_2, system_role_5, system_role_6]), set([]) ) user_6_action_open_1 = ActionSystemRoles.query.filter_by( action='open', argument='1', role_name=system_role_6.value).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_6) assert current_access.get_action_cache('open::2') == ( set([system_role_1, system_role_2, system_role_5, system_role_6]), set([]) ) # open action cache should remain as before assert current_access.get_action_cache('open') == ( set([system_role_1, system_role_2, system_role_5]), set([]) )
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 _cant_update(collection): return not Permission( ParameterizedActionNeed( 'update-collection', collection)).can()
# -*- coding: utf-8 -*- # # This file is part of INSPIRE. # Copyright (C) 2014-2017 CERN. # # INSPIRE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # INSPIRE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with INSPIRE. If not, see <http://www.gnu.org/licenses/>. # # In applying this license, CERN does not waive the privileges and immunities # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. from __future__ import absolute_import, division, print_function from invenio_access.permissions import (Permission, ParameterizedActionNeed) action_editor_manage_tickets = ParameterizedActionNeed('editor_manage_tickets', argument=None) editor_manage_tickets_permission = Permission(action_editor_manage_tickets)
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([]) )
# or submit itself to any jurisdiction. from __future__ import absolute_import, division, print_function from flask import current_app, session from flask_principal import ActionNeed from flask_security import current_user from werkzeug.local import LocalProxy from invenio_access.models import ActionUsers from invenio_access.permissions import (DynamicPermission, ParameterizedActionNeed) from inspirehep.modules.cache import current_cache action_view_restricted_collection = ParameterizedActionNeed( 'view-restricted-collection', argument=None) all_restricted_collections = LocalProxy(lambda: load_restricted_collections()) user_collections = LocalProxy(lambda: get_user_collections()) def get_user_collections(): """Get user restricted collections.""" return session.get('restricted_collections', set()) def load_user_collections(app, user): """Load user restricted collections upon login. Receiver for flask_login.user_logged_in
def _cant_view(collection): return not DynamicPermission( ParameterizedActionNeed('view-restricted-collection', collection)).can()
# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # INSPIRE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with INSPIRE. If not, see <http://www.gnu.org/licenses/>. # # In applying this licence, CERN does not waive the privileges and immunities # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. from __future__ import absolute_import, division, print_function from invenio_access.permissions import ( DynamicPermission, ParameterizedActionNeed ) action_admin_holdingpen_authors = ParameterizedActionNeed( 'admin-holdingpen-authors', argument=None ) holdingpen_author_permission = DynamicPermission( action_admin_holdingpen_authors )
def test_access_matrix(script_info_cli_list): """Test of combinations of cli commands.""" script_info = script_info_cli_list runner = CliRunner() user_roles = { '*****@*****.**': ['admin'], '*****@*****.**': ['admin'], '*****@*****.**': ['opener'], '*****@*****.**': ['editor'], '*****@*****.**': ['opener'], } action_roles = { 'open': ['admin', 'opener'], 'edit': ['admin', 'editor'], } for role in {role for roles in user_roles.values() for role in roles}: # Role creation result = runner.invoke(roles_create, [role], obj=script_info) assert result.exit_code == 0 for email, roles in user_roles.items(): result = runner.invoke(users_create, [email, '--password', '123456', '-a'], obj=script_info) assert result.exit_code == 0 for role in roles: # Role creation result = runner.invoke(roles_add, [email, role], obj=script_info) assert result.exit_code == 0 def role_args(roles): """Generate role arguments.""" for role in roles: yield 'role' yield role for action, roles in action_roles.items(): result = runner.invoke(access, ['allow', action] + list(role_args(roles)), obj=script_info) assert result.exit_code == 0 result = runner.invoke( access, ['deny', 'edit', 'user', '*****@*****.**'], obj=script_info) assert result.exit_code == 0 result = runner.invoke( access, ['allow', '-a', '1', 'edit', 'user', '*****@*****.**'], obj=script_info) assert result.exit_code == 0 permission_open = DynamicPermission(ActionNeed('open')) permission_edit = DynamicPermission(ActionNeed('edit')) permission_edit_1 = DynamicPermission(ParameterizedActionNeed('edit', 1)) permission_edit_2 = DynamicPermission(ParameterizedActionNeed('edit', 2)) user_permissions = { '*****@*****.**': { True: [ permission_open, permission_edit, permission_edit_1, permission_edit_2, ], }, '*****@*****.**': { True: [permission_open], False: [ permission_edit, permission_edit_1, permission_edit_2, ], }, '*****@*****.**': { True: [permission_open], False: [ permission_edit, permission_edit_1, permission_edit_2, ], }, '*****@*****.**': { True: [ permission_edit, permission_edit_1, permission_edit_2, ], False: [permission_open], }, '*****@*****.**': { True: [ permission_open, permission_edit_1, ], False: [ permission_edit, permission_edit_2, ], }, } for email, permissions in user_permissions.items(): with script_info.create_app(None).test_request_context(): user = _security.datastore.find_user(email=email) login_user(user) identity = g.identity for can, actions in permissions.items(): for action in actions: assert action.allows(identity) == can, identity result = runner.invoke(access, ['remove', 'edit'], obj=script_info) assert result.exit_code == 2 result = runner.invoke(access, ['show', '-e', '*****@*****.**'], obj=script_info) assert result.exit_code == 0 assert 'user:[email protected]:edit::deny' in result.output result = runner.invoke(access, ['show', '-r', 'editor'], obj=script_info) assert 'role:editor:edit::allow\n' == result.output assert result.exit_code == 0 # # Remove all permissions. # for action, roles in action_roles.items(): result = runner.invoke(access, ['remove', action] + list(role_args(roles)), obj=script_info) assert result.exit_code == 0 result = runner.invoke( access, ['remove', 'edit', 'user', '*****@*****.**'], obj=script_info) assert result.exit_code == 0 result = runner.invoke( access, ['remove', '-a', '1', 'edit', 'user', '*****@*****.**'], obj=script_info) assert result.exit_code == 0 # All authorizations should be removed. result = runner.invoke(access, ['show', '-r', '*****@*****.**'], obj=script_info) assert result.exit_code == 0 assert result.output == ''
# Copyright (C) 2014-2018 CERN. # # INSPIRE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # INSPIRE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with INSPIRE. If not, see <http://www.gnu.org/licenses/>. # # In applying this license, CERN does not waive the privileges and immunities # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. from __future__ import absolute_import, division, print_function from invenio_access.permissions import ( ParameterizedActionNeed, Permission, ) action_migrator_use_api = ParameterizedActionNeed('migrator-use-api', argument=None) migrator_use_api_permission = Permission(action_migrator_use_api)
from functools import wraps from flask import abort, session from flask_login import current_user from invenio_access.permissions import ( ParameterizedActionNeed, Permission, ) from inspirehep.modules.pidstore.utils import get_pid_type_from_endpoint from inspirehep.modules.records.permissions import has_update_permission from inspirehep.utils.record_getter import get_db_record action_editor_use_api = ParameterizedActionNeed('editor-use-api', argument=None) editor_use_api_permission = Permission(action_editor_use_api) def editor_permission(fn): @wraps(fn) def decorator(endpoint, pid_value, **kwargs): cache_key = 'editor-permission-{0}-{1}'.format(endpoint, pid_value) is_allowed = session.get(cache_key) if is_allowed is not None: if is_allowed: return fn(endpoint, pid_value, **kwargs) else: abort(403)
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)