From ad67554162d880d296231fa457c0eff05836a130 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Wed, 14 Aug 2019 12:52:43 +0200 Subject: [PATCH 1/3] Add a test case which verifies that "action_execute" grant either directly on the action or on the pack implicity grants "action_execute" to the corresponding action or all actions inside a particular pack. --- tests/unit/test_rbac_resolvers.py | 5 ++ tests/unit/test_rbac_resolvers_action.py | 78 +++++++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_rbac_resolvers.py b/tests/unit/test_rbac_resolvers.py index 31320b1..98f2a58 100644 --- a/tests/unit/test_rbac_resolvers.py +++ b/tests/unit/test_rbac_resolvers.py @@ -221,6 +221,11 @@ def _insert_common_mock_resources(self): pack_2_db = Pack.add_or_update(pack_2_db) self.resources['pack_2'] = pack_2_db + pack_3_db = PackDB(name='test_pack_3', ref='test_pack_3', description='', + version='0.1.0', author='foo', email='test@example.com') + pack_3_db = Pack.add_or_update(pack_3_db) + self.resources['pack_3'] = pack_3_db + def _insert_common_mock_roles(self): # Insert common mock roles admin_role_db = rbac_service.get_role_by_name(name=SystemRole.ADMIN) diff --git a/tests/unit/test_rbac_resolvers_action.py b/tests/unit/test_rbac_resolvers_action.py index a3c1761..b1903dc 100644 --- a/tests/unit/test_rbac_resolvers_action.py +++ b/tests/unit/test_rbac_resolvers_action.py @@ -73,6 +73,14 @@ def setUp(self): user_10_db = User.add_or_update(user_10_db) self.users['custom_role_action_list_grant'] = user_10_db + user_11_db = UserDB(name='custom_role_action_execute_action_4_grant') + user_11_db = User.add_or_update(user_11_db) + self.users['custom_role_action_execute_action_4_grant'] = user_11_db + + user_12_db = UserDB(name='custom_role_action_execute_action_5_pack_grant') + user_12_db = User.add_or_update(user_12_db) + self.users['custom_role_action_execute_action_5_pack_grant'] = user_12_db + # Create some mock resources on which permissions can be granted action_1_db = ActionDB(pack='test_pack_1', name='action1', entry_point='', runner_type={'name': 'local-shell-cmd'}) @@ -89,6 +97,16 @@ def setUp(self): action_3_db = Action.add_or_update(action_3_db) self.resources['action_3'] = action_3_db + action_4_db = ActionDB(pack='test_pack_4', name='action4', entry_point='', + runner_type={'name': 'local-shell-cmd'}) + action_4_db = Action.add_or_update(action_4_db) + self.resources['action_4'] = action_4_db + + action_5_db = ActionDB(pack='test_pack_3', name='action5', entry_point='', + runner_type={'name': 'local-shell-cmd'}) + action_5_db = Action.add_or_update(action_5_db) + self.resources['action_5'] = action_5_db + # Create some mock roles with associated permission grants # Custom role 2 - one grant on parent pack # "action_view" on pack_1 @@ -200,6 +218,28 @@ def setUp(self): role_10_db = Role.add_or_update(role_10_db) self.roles['custom_role_action_list_grant'] = role_10_db + # Custom role - "action_execute" on action_4 + grant_db = PermissionGrantDB(resource_uid=self.resources['action_4'].get_uid(), + resource_type=ResourceType.ACTION, + permission_types=[PermissionType.ACTION_EXECUTE]) + grant_db = PermissionGrant.add_or_update(grant_db) + permission_grants = [str(grant_db.id)] + role_11_db = RoleDB(name='custom_role_action_execute_action_4_grant', + permission_grants=permission_grants) + role_11_db = Role.add_or_update(role_11_db) + self.roles['custom_role_action_execute_action_4_grant'] = role_11_db + + # Custom role - "action_execute" on action_5 parent pack + grant_db = PermissionGrantDB(resource_uid=self.resources['pack_3'].get_uid(), + resource_type=ResourceType.PACK, + permission_types=[PermissionType.ACTION_EXECUTE]) + grant_db = PermissionGrant.add_or_update(grant_db) + permission_grants = [str(grant_db.id)] + role_12_db = RoleDB(name='custom_role_action_execute_action_5_pack_grant', + permission_grants=permission_grants) + role_12_db = Role.add_or_update(role_12_db) + self.roles['custom_role_action_execute_action_5_pack_grant'] = role_12_db + # Create some mock role assignments user_db = self.users['custom_role_action_pack_grant'] role_assignment_db = UserRoleAssignmentDB( @@ -261,6 +301,19 @@ def setUp(self): source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) + user_db = self.users['custom_role_action_execute_action_4_grant'] + role_assignment_db = UserRoleAssignmentDB( + user=user_db.name, role=self.roles['custom_role_action_execute_action_4_grant'].name, + source='assignments/%s.yaml' % user_db.name) + UserRoleAssignment.add_or_update(role_assignment_db) + + user_db = self.users['custom_role_action_execute_action_5_pack_grant'] + role_assignment_db = UserRoleAssignmentDB( + user=user_db.name, + role=self.roles['custom_role_action_execute_action_5_pack_grant'].name, + source='assignments/%s.yaml' % user_db.name) + UserRoleAssignment.add_or_update(role_assignment_db) + def test_user_has_permission(self): resolver = ActionPermissionsResolver() @@ -518,7 +571,30 @@ def test_user_has_resource_db_permission(self): resource_db=resource_db, permission_type=PermissionType.ACTION_EXECUTE) - # "execute" also grants "view" + # Direct "action_execute" grant on action_4 which also grants action_view + user_db = self.users['custom_role_action_execute_action_4_grant'] + resource_db = self.resources['action_4'] + self.assertUserHasResourceDbPermission( + resolver=resolver, + user_db=user_db, + resource_db=resource_db, + permission_type=PermissionType.ACTION_VIEW) + + permission_types = [ + PermissionType.ACTION_CREATE, + PermissionType.ACTION_MODIFY, + PermissionType.ACTION_DELETE + ] + self.assertUserDoesntHaveResourceDbPermissions( + resolver=resolver, + user_db=user_db, + resource_db=resource_db, + permission_types=permission_types) + + # "action_execute" grant on action_5 parent pack which also grants "action_view" to + # all actions inside that pack + user_db = self.users['custom_role_action_execute_action_5_pack_grant'] + resource_db = self.resources['action_5'] self.assertUserHasResourceDbPermission( resolver=resolver, user_db=user_db, From e43cb879bcaa913bb289814383ef7aefeecf4ae2 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Wed, 14 Aug 2019 13:44:05 +0200 Subject: [PATCH 2/3] Update RBAC permission resolvers to "action_execution" permission on the action or pack also grants "execution_view" on all the executions for that particular action / actions which are parent of that particular pack. --- st2rbac_enterprise_backend/resolvers.py | 16 ++- tests/unit/test_rbac_resolvers_execution.py | 141 ++++++++++++++++++-- 2 files changed, 141 insertions(+), 16 deletions(-) diff --git a/st2rbac_enterprise_backend/resolvers.py b/st2rbac_enterprise_backend/resolvers.py index 9bcedc2..38663b4 100644 --- a/st2rbac_enterprise_backend/resolvers.py +++ b/st2rbac_enterprise_backend/resolvers.py @@ -675,22 +675,24 @@ def user_has_resource_db_permission(self, user_db, resource_db, permission_type) action_uid = action['uid'] action_pack_uid = pack_db.get_uid() - # Note: "action_execute" also grants / implies "execution_re_run" and "execution_stop" + # NOTE: "action_execute" also grants / implies "execution_re_run" and "execution_stop" if permission_type == PermissionType.EXECUTION_VIEW: - action_permission_type = PermissionType.ACTION_VIEW + # NOTE: action_execute also grants action_view + action_permission_types = [PermissionType.ACTION_VIEW, + PermissionType.ACTION_EXECUTE] elif permission_type in [PermissionType.EXECUTION_RE_RUN, PermissionType.EXECUTION_STOP]: - action_permission_type = PermissionType.ACTION_EXECUTE + action_permission_types = [PermissionType.ACTION_EXECUTE] elif permission_type == PermissionType.EXECUTION_ALL: - action_permission_type = PermissionType.ACTION_ALL + action_permission_types = [PermissionType.ACTION_ALL] elif permission_type == PermissionType.EXECUTION_VIEWS_FILTERS_LIST: - action_permission_type = PermissionType.EXECUTION_VIEWS_FILTERS_LIST + action_permission_types = [PermissionType.EXECUTION_VIEWS_FILTERS_LIST] else: raise ValueError('Invalid permission type: %s' % (permission_type)) # Check grants on the pack of the action to which execution belongs to resource_types = [ResourceType.PACK] - permission_types = [PermissionType.ACTION_ALL, action_permission_type] + permission_types = [PermissionType.ACTION_ALL] + action_permission_types permission_grants = rbac_service.get_all_permission_grants_for_user(user_db=user_db, resource_uid=action_pack_uid, resource_types=resource_types, @@ -702,7 +704,7 @@ def user_has_resource_db_permission(self, user_db, resource_db, permission_type) # Check grants on the action the execution belongs to resource_types = [ResourceType.ACTION] - permission_types = [PermissionType.ACTION_ALL, action_permission_type] + permission_types = [PermissionType.ACTION_ALL] + action_permission_types permission_grants = rbac_service.get_all_permission_grants_for_user(user_db=user_db, resource_uid=action_uid, resource_types=resource_types, diff --git a/tests/unit/test_rbac_resolvers_execution.py b/tests/unit/test_rbac_resolvers_execution.py index 8e70947..a6c487f 100644 --- a/tests/unit/test_rbac_resolvers_execution.py +++ b/tests/unit/test_rbac_resolvers_execution.py @@ -68,15 +68,33 @@ def setUp(self): self.users['custom_role_action_all_grant'] = user_8_db user_9_db = UserDB(name='custom_role_execution_list_grant') - user_9_db = User.add_or_update(user_5_db) + user_9_db = User.add_or_update(user_9_db) self.users['custom_role_execution_list_grant'] = user_9_db + user_10_db = UserDB(name='custom_role_action_execute_action_2_grant') + user_10_db = User.add_or_update(user_10_db) + self.users['custom_role_action_execute_action_2_grant'] = user_10_db + + user_11_db = UserDB(name='custom_role_action_execute_action_2_pack_grant') + user_11_db = User.add_or_update(user_11_db) + self.users['custom_role_action_execute_action_2_pack_grant'] = user_11_db + # Create some mock resources on which permissions can be granted action_1_db = ActionDB(pack='test_pack_2', name='action1', entry_point='', runner_type={'name': 'local-shell-cmd'}) action_1_db = Action.add_or_update(action_1_db) self.resources['action_1'] = action_1_db + action_2_db = ActionDB(pack='test_pack_3', name='action2', entry_point='', + runner_type={'name': 'local-shell-cmd'}) + action_2_db = Action.add_or_update(action_2_db) + self.resources['action_2'] = action_2_db + + action_3_db = ActionDB(pack='test_pack_3', name='action3', entry_point='', + runner_type={'name': 'local-shell-cmd'}) + action_3_db = Action.add_or_update(action_3_db) + self.resources['action_3'] = action_3_db + runner = {'name': 'python-script'} liveaction = {'action': 'test_pack_2.action1'} status = action_constants.LIVEACTION_STATUS_REQUESTED @@ -87,6 +105,18 @@ def setUp(self): exec_1_db = ActionExecution.add_or_update(exec_1_db) self.resources['exec_1'] = exec_1_db + action = {'uid': action_2_db.get_uid(), 'pack': 'test_pack_3'} + exec_2_db = ActionExecutionDB(action=action, runner=runner, liveaction=liveaction, + status=status) + exec_2_db = ActionExecution.add_or_update(exec_2_db) + self.resources['exec_2'] = exec_2_db + + action = {'uid': action_3_db.get_uid(), 'pack': 'test_pack_3'} + exec_3_db = ActionExecutionDB(action=action, runner=runner, liveaction=liveaction, + status=status) + exec_3_db = ActionExecution.add_or_update(exec_3_db) + self.resources['exec_3'] = exec_3_db + # Create some mock roles with associated permission grants # Custom role - one grant to an unrelated pack grant_db = PermissionGrantDB(resource_uid=self.resources['pack_1'].get_uid(), @@ -189,6 +219,28 @@ def setUp(self): role_5_db = Role.add_or_update(role_5_db) self.roles['custom_role_execution_list_grant'] = role_5_db + # Custom role - "action_execute" on action_2 + grant_db = PermissionGrantDB(resource_uid=self.resources['action_2'].get_uid(), + resource_type=ResourceType.ACTION, + permission_types=[PermissionType.ACTION_EXECUTE]) + grant_db = PermissionGrant.add_or_update(grant_db) + permission_grants = [str(grant_db.id)] + role_6_db = RoleDB(name='custom_role_action_execute_action_2_grant', + permission_grants=permission_grants) + role_6_db = Role.add_or_update(role_6_db) + self.roles['custom_role_action_execute_action_2_grant'] = role_6_db + + # Custom role - "action_execute" on action_2 parent pack + grant_db = PermissionGrantDB(resource_uid=self.resources['pack_3'].get_uid(), + resource_type=ResourceType.PACK, + permission_types=[PermissionType.ACTION_EXECUTE]) + grant_db = PermissionGrant.add_or_update(grant_db) + permission_grants = [str(grant_db.id)] + role_7_db = RoleDB(name='custom_role_action_execute_action_2_pack_grant', + permission_grants=permission_grants) + role_7_db = Role.add_or_update(role_7_db) + self.roles['custom_role_action_execute_action_2_pack_grant'] = role_7_db + # Create some mock role assignments user_db = self.users['custom_role_unrelated_pack_action_grant'] role_assignment_db = UserRoleAssignmentDB( @@ -245,6 +297,20 @@ def setUp(self): source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) + user_db = self.users['custom_role_action_execute_action_2_grant'] + role_assignment_db = UserRoleAssignmentDB( + user=user_db.name, + role=self.roles['custom_role_action_execute_action_2_grant'].name, + source='assignments/%s.yaml' % user_db.name) + UserRoleAssignment.add_or_update(role_assignment_db) + + user_db = self.users['custom_role_action_execute_action_2_pack_grant'] + role_assignment_db = UserRoleAssignmentDB( + user=user_db.name, + role=self.roles['custom_role_action_execute_action_2_pack_grant'].name, + source='assignments/%s.yaml' % user_db.name) + UserRoleAssignment.add_or_update(role_assignment_db) + def test_user_has_permission(self): resolver = ExecutionPermissionsResolver() @@ -379,36 +445,42 @@ def test_user_has_resource_db_permission(self): ) # Custom role with "action_execute" grant on the pack of the action resource belongs to + # NOTE: action_execution also grants execution_view on all the executions which belong to + # that action user_db = self.users['custom_role_pack_action_execute_grant'] - permission_types = [PermissionType.EXECUTION_RE_RUN, PermissionType.EXECUTION_STOP] + permission_types = [PermissionType.EXECUTION_RE_RUN, + PermissionType.EXECUTION_STOP, PermissionType.EXECUTION_VIEW] self.assertUserHasResourceDbPermissions( resolver=resolver, user_db=user_db, resource_db=resource_db, permission_types=permission_types) - permission_types = [PermissionType.EXECUTION_VIEW, PermissionType.EXECUTION_ALL] - self.assertUserDoesntHaveResourceDbPermissions( + permission_type = PermissionType.EXECUTION_ALL + self.assertUserDoesntHaveResourceDbPermission( resolver=resolver, user_db=user_db, resource_db=resource_db, - permission_types=permission_types) + permission_type=permission_type) # Custom role with "action_execute" grant on the action resource belongs to + # NOTE: action_execution also grants execution_view on all the executions which belong to + # that action user_db = self.users['custom_role_action_execute_grant'] - permission_types = [PermissionType.EXECUTION_RE_RUN, PermissionType.EXECUTION_STOP] + permission_types = [PermissionType.EXECUTION_RE_RUN, + PermissionType.EXECUTION_STOP, PermissionType.EXECUTION_VIEW] self.assertUserHasResourceDbPermissions( resolver=resolver, user_db=user_db, resource_db=resource_db, permission_types=permission_types) - permission_types = [PermissionType.EXECUTION_VIEW, PermissionType.EXECUTION_ALL] - self.assertUserDoesntHaveResourceDbPermissions( + permission_type = PermissionType.EXECUTION_ALL + self.assertUserDoesntHaveResourceDbPermission( resolver=resolver, user_db=user_db, resource_db=resource_db, - permission_types=permission_types) + permission_type=permission_type) # Custom role - "action_all" grant on the action parent pack the execution belongs to user_db = self.users['custom_role_pack_action_all_grant'] @@ -427,3 +499,54 @@ def test_user_has_resource_db_permission(self): user_db=user_db, resource_db=resource_db, permission_types=all_permission_types) + + # Custom role - "action_execute" on action_2, user should be able to view all the + # executions belonging to that action + user_db = self.users['custom_role_action_execute_action_2_grant'] + + resource_db = self.resources['exec_2'] + self.assertUserHasResourceDbPermission( + resolver=resolver, + user_db=user_db, + resource_db=resource_db, + permission_type=PermissionType.EXECUTION_VIEW) + + resource_db = self.resources['exec_1'] + self.assertUserDoesntHaveResourceDbPermission( + resolver=resolver, + user_db=user_db, + resource_db=resource_db, + permission_type=PermissionType.EXECUTION_VIEW) + + resource_db = self.resources['exec_3'] + self.assertUserDoesntHaveResourceDbPermission( + resolver=resolver, + user_db=user_db, + resource_db=resource_db, + permission_type=PermissionType.EXECUTION_VIEW) + + + # Custom role - "action_execute" on action_2 parent pack, user should be able to view all + # the executions for actions which belong to that pack + user_db = self.users['custom_role_action_execute_action_2_pack_grant'] + + resource_db = self.resources['exec_2'] + self.assertUserHasResourceDbPermission( + resolver=resolver, + user_db=user_db, + resource_db=resource_db, + permission_type=PermissionType.EXECUTION_VIEW) + + resource_db = self.resources['exec_2'] + self.assertUserHasResourceDbPermission( + resolver=resolver, + user_db=user_db, + resource_db=resource_db, + permission_type=PermissionType.EXECUTION_VIEW) + + resource_db = self.resources['exec_1'] + self.assertUserDoesntHaveResourceDbPermission( + resolver=resolver, + user_db=user_db, + resource_db=resource_db, + permission_type=PermissionType.EXECUTION_VIEW) From 4387a28d79bd73603751e81e9578677d639b737d Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Wed, 14 Aug 2019 13:59:31 +0200 Subject: [PATCH 3/3] Fix lint. --- tests/unit/test_rbac_resolvers_execution.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/test_rbac_resolvers_execution.py b/tests/unit/test_rbac_resolvers_execution.py index a6c487f..2f49a43 100644 --- a/tests/unit/test_rbac_resolvers_execution.py +++ b/tests/unit/test_rbac_resolvers_execution.py @@ -525,7 +525,6 @@ def test_user_has_resource_db_permission(self): resource_db=resource_db, permission_type=PermissionType.EXECUTION_VIEW) - # Custom role - "action_execute" on action_2 parent pack, user should be able to view all # the executions for actions which belong to that pack user_db = self.users['custom_role_action_execute_action_2_pack_grant']