def test_grant_and_revoke_role(self): user_db = UserDB(name='test-user-1') user_db = User.add_or_update(user_db) # Initial state, no roles role_dbs = rbac_services.get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, []) role_dbs = user_db.get_roles() self.assertItemsEqual(role_dbs, []) # Assign a role, should have one role assigned rbac_services.assign_role_to_user(role_db=self.roles['custom_role_1'], user_db=user_db) role_dbs = rbac_services.get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, [self.roles['custom_role_1']]) role_dbs = user_db.get_roles() self.assertItemsEqual(role_dbs, [self.roles['custom_role_1']]) # Revoke previously assigned role, should have no roles again rbac_services.revoke_role_from_user(role_db=self.roles['custom_role_1'], user_db=user_db) role_dbs = rbac_services.get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, []) role_dbs = user_db.get_roles() self.assertItemsEqual(role_dbs, [])
class TestTokenController(FunctionalTest): @classmethod def setUpClass(cls, **kwargs): kwargs['extra_environ'] = {'REMOTE_USER': USERNAME} super(TestTokenController, cls).setUpClass(**kwargs) def test_token_model(self): dt = date_utils.get_datetime_utc_now() tk1 = TokenAPI(user='******', token=uuid.uuid4().hex, expiry=isotime.format(dt, offset=False)) tkdb1 = TokenAPI.to_model(tk1) self.assertIsNotNone(tkdb1) self.assertIsInstance(tkdb1, TokenDB) self.assertEqual(tkdb1.user, tk1.user) self.assertEqual(tkdb1.token, tk1.token) self.assertEqual(tkdb1.expiry, isotime.parse(tk1.expiry)) tkdb2 = Token.add_or_update(tkdb1) self.assertEqual(tkdb1, tkdb2) self.assertIsNotNone(tkdb2.id) tk2 = TokenAPI.from_model(tkdb2) self.assertEqual(tk2.user, tk1.user) self.assertEqual(tk2.token, tk1.token) self.assertEqual(tk2.expiry, tk1.expiry) def test_token_model_null_token(self): dt = date_utils.get_datetime_utc_now() tk = TokenAPI(user='******', token=None, expiry=isotime.format(dt)) self.assertRaises(ValueError, Token.add_or_update, TokenAPI.to_model(tk)) def test_token_model_null_user(self): dt = date_utils.get_datetime_utc_now() tk = TokenAPI(user=None, token=uuid.uuid4().hex, expiry=isotime.format(dt)) self.assertRaises(ValueError, Token.add_or_update, TokenAPI.to_model(tk)) def test_token_model_null_expiry(self): tk = TokenAPI(user='******', token=uuid.uuid4().hex, expiry=None) self.assertRaises(ValueError, Token.add_or_update, TokenAPI.to_model(tk)) def _test_token_post(self, path=TOKEN_V1_PATH): ttl = cfg.CONF.auth.token_ttl timestamp = date_utils.get_datetime_utc_now() response = self.app.post_json(path, {}, expect_errors=False) expected_expiry = date_utils.get_datetime_utc_now( ) + datetime.timedelta(seconds=ttl) expected_expiry = date_utils.add_utc_tz(expected_expiry) self.assertEqual(response.status_int, 201) self.assertIsNotNone(response.json['token']) self.assertEqual(response.json['user'], USERNAME) actual_expiry = isotime.parse(response.json['expiry']) self.assertLess(timestamp, actual_expiry) self.assertLess(actual_expiry, expected_expiry) def test_token_post_unauthorized(self): response = self.app.post_json(TOKEN_V1_PATH, {}, expect_errors=True, extra_environ={'REMOTE_USER': ''}) self.assertEqual(response.status_int, 401) @mock.patch.object(User, 'get_by_name', mock.MagicMock(side_effect=Exception())) @mock.patch.object(User, 'add_or_update', mock.Mock(return_value=UserDB(name=USERNAME))) def test_token_post_new_user(self): self._test_token_post() @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_existing_user(self): self._test_token_post() @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_default_url_path(self): self._test_token_post(path=TOKEN_DEFAULT_PATH) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_set_ttl(self): timestamp = date_utils.add_utc_tz(date_utils.get_datetime_utc_now()) response = self.app.post_json(TOKEN_V1_PATH, {'ttl': 60}, expect_errors=False) expected_expiry = date_utils.get_datetime_utc_now( ) + datetime.timedelta(seconds=60) self.assertEqual(response.status_int, 201) actual_expiry = isotime.parse(response.json['expiry']) self.assertLess(timestamp, actual_expiry) self.assertLess(actual_expiry, expected_expiry) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_no_data_in_body_text_plain_context_type_used(self): response = self.app.post(TOKEN_V1_PATH, expect_errors=False, content_type='text/plain') self.assertEqual(response.status_int, 201) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_set_ttl_over_policy(self): ttl = cfg.CONF.auth.token_ttl response = self.app.post_json(TOKEN_V1_PATH, {'ttl': ttl + 60}, expect_errors=True) self.assertEqual(response.status_int, 400) message = 'TTL specified %s is greater than max allowed %s.' % ( ttl + 60, ttl) self.assertEqual(response.json['faultstring'], message) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_post_set_bad_ttl(self): response = self.app.post_json(TOKEN_V1_PATH, {'ttl': -1}, expect_errors=True) self.assertEqual(response.status_int, 400) response = self.app.post_json(TOKEN_V1_PATH, {'ttl': 0}, expect_errors=True) self.assertEqual(response.status_int, 400) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_get_unauthorized(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. 401 is expected because an API key or token is not provided in header. data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, expect_errors=True) self.assertEqual(response.status_int, 401) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_get_unauthorized_bad_api_key(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. 401 is expected because the API key is bad. headers = {'St2-Api-Key': 'foobar'} data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=True) self.assertEqual(response.status_int, 401) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_get_unauthorized_bad_token(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. 401 is expected because the token is bad. headers = {'X-Auth-Token': 'foobar'} data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=True) self.assertEqual(response.status_int, 401) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) @mock.patch.object( ApiKey, 'get', mock.MagicMock(return_value=ApiKeyDB(user=USERNAME, key_hash='foobar')) ) def test_token_get_auth_with_api_key(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, expect_errors=False) # Verify the token. Use an API key to authenticate with the st2 auth get token endpoint. headers = {'St2-Api-Key': 'foobar'} data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=True) self.assertEqual(response.status_int, 200) self.assertTrue(response.json['valid']) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) def test_token_get_auth_with_token(self): # Create a new token. response = self.app.post_json(TOKEN_V1_PATH, {}, expect_errors=False) # Verify the token. Use a token to authenticate with the st2 auth get token endpoint. headers = {'X-Auth-Token': str(response.json['token'])} data = {'token': str(response.json['token'])} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=True) self.assertEqual(response.status_int, 200) self.assertTrue(response.json['valid']) @mock.patch.object(User, 'get_by_name', mock.MagicMock(return_value=UserDB(name=USERNAME))) @mock.patch.object( ApiKey, 'get', mock.MagicMock(return_value=ApiKeyDB(user=USERNAME, key_hash='foobar')) ) @mock.patch.object( Token, 'get', mock.MagicMock( return_value=TokenDB(user=USERNAME, token='12345', expiry=date_utils.get_datetime_utc_now() - datetime.timedelta(minutes=1)))) def test_token_get_unauthorized_bad_ttl(self): # Verify the token. 400 is expected because the token has expired. headers = {'St2-Api-Key': 'foobar'} data = {'token': '12345'} response = self.app.post_json(TOKEN_VERIFY_PATH, data, headers=headers, expect_errors=False) self.assertEqual(response.status_int, 200) self.assertFalse(response.json['valid'])
def put(self, id, liveaction_api, requester_user, show_secrets=False): """ Updates a single execution. Handles requests: PUT /executions/<id> """ if not requester_user: requester_user = UserDB(cfg.CONF.system_user.user) from_model_kwargs = { "mask_secrets": self._get_mask_secrets(requester_user, show_secrets=show_secrets) } execution_api = self._get_one_by_id( id=id, requester_user=requester_user, from_model_kwargs=from_model_kwargs, permission_type=PermissionType.EXECUTION_STOP, ) if not execution_api: abort(http_client.NOT_FOUND, "Execution with id %s not found." % id) liveaction_id = execution_api.liveaction["id"] if not liveaction_id: abort( http_client.INTERNAL_SERVER_ERROR, "Execution object missing link to liveaction %s." % liveaction_id, ) try: liveaction_db = LiveAction.get_by_id(liveaction_id) except: abort( http_client.INTERNAL_SERVER_ERROR, "Execution object missing link to liveaction %s." % liveaction_id, ) if liveaction_db.status in action_constants.LIVEACTION_COMPLETED_STATES: abort(http_client.BAD_REQUEST, "Execution is already in completed state.") def update_status(liveaction_api, liveaction_db): status = liveaction_api.status result = getattr(liveaction_api, "result", None) liveaction_db = action_service.update_status(liveaction_db, status, result, set_result_size=True) actionexecution_db = ActionExecution.get( liveaction__id=str(liveaction_db.id)) return (liveaction_db, actionexecution_db) try: if (liveaction_db.status == action_constants.LIVEACTION_STATUS_CANCELING and liveaction_api.status == action_constants.LIVEACTION_STATUS_CANCELED): if action_service.is_children_active(liveaction_id): liveaction_api.status = action_constants.LIVEACTION_STATUS_CANCELING liveaction_db, actionexecution_db = update_status( liveaction_api, liveaction_db) elif (liveaction_api.status == action_constants.LIVEACTION_STATUS_CANCELING or liveaction_api.status == action_constants.LIVEACTION_STATUS_CANCELED): liveaction_db, actionexecution_db = action_service.request_cancellation( liveaction_db, requester_user.name or cfg.CONF.system_user.user) elif (liveaction_db.status == action_constants.LIVEACTION_STATUS_PAUSING and liveaction_api.status == action_constants.LIVEACTION_STATUS_PAUSED): if action_service.is_children_active(liveaction_id): liveaction_api.status = action_constants.LIVEACTION_STATUS_PAUSING liveaction_db, actionexecution_db = update_status( liveaction_api, liveaction_db) elif (liveaction_api.status == action_constants.LIVEACTION_STATUS_PAUSING or liveaction_api.status == action_constants.LIVEACTION_STATUS_PAUSED): liveaction_db, actionexecution_db = action_service.request_pause( liveaction_db, requester_user.name or cfg.CONF.system_user.user) elif liveaction_api.status == action_constants.LIVEACTION_STATUS_RESUMING: liveaction_db, actionexecution_db = action_service.request_resume( liveaction_db, requester_user.name or cfg.CONF.system_user.user) else: liveaction_db, actionexecution_db = update_status( liveaction_api, liveaction_db) except runner_exc.InvalidActionRunnerOperationError as e: LOG.exception("Failed updating liveaction %s. %s", liveaction_db.id, six.text_type(e)) abort( http_client.BAD_REQUEST, "Failed updating execution. %s" % six.text_type(e), ) except runner_exc.UnexpectedActionExecutionStatusError as e: LOG.exception("Failed updating liveaction %s. %s", liveaction_db.id, six.text_type(e)) abort( http_client.BAD_REQUEST, "Failed updating execution. %s" % six.text_type(e), ) except Exception as e: LOG.exception("Failed updating liveaction %s. %s", liveaction_db.id, six.text_type(e)) abort( http_client.INTERNAL_SERVER_ERROR, "Failed updating execution due to unexpected error.", ) mask_secrets = self._get_mask_secrets(requester_user, show_secrets=show_secrets) execution_api = ActionExecutionAPI.from_model( actionexecution_db, mask_secrets=mask_secrets) return execution_api
def _handle_schedule_execution(self, liveaction_api, requester_user, context_string=None, show_secrets=False): """ :param liveaction: LiveActionAPI object. :type liveaction: :class:`LiveActionAPI` """ if not requester_user: requester_user = UserDB(cfg.CONF.system_user.user) # Assert action ref is valid action_ref = liveaction_api.action action_db = action_utils.get_action_by_ref(action_ref) if not action_db: message = 'Action "%s" cannot be found.' % (action_ref) LOG.warning(message) abort(http_client.BAD_REQUEST, message) # Assert the permissions permission_type = PermissionType.ACTION_EXECUTE rbac_utils = get_rbac_backend().get_utils_class() rbac_utils.assert_user_has_resource_db_permission( user_db=requester_user, resource_db=action_db, permission_type=permission_type, ) # Validate that the authenticated user is admin if user query param is provided user = liveaction_api.user or requester_user.name rbac_utils.assert_user_is_admin_if_user_query_param_is_provided( user_db=requester_user, user=user) try: return self._schedule_execution( liveaction=liveaction_api, requester_user=requester_user, user=user, context_string=context_string, show_secrets=show_secrets, action_db=action_db, ) except ValueError as e: LOG.exception("Unable to execute action.") abort(http_client.BAD_REQUEST, six.text_type(e)) except jsonschema.ValidationError as e: LOG.exception( "Unable to execute action. Parameter validation failed.") abort( http_client.BAD_REQUEST, re.sub("u'([^']*)'", r"'\1'", getattr(e, "message", six.text_type(e))), ) except trace_exc.TraceNotFoundException as e: abort(http_client.BAD_REQUEST, six.text_type(e)) except validation_exc.ValueValidationException as e: raise e except Exception as e: LOG.exception( "Unable to execute action. Unexpected error encountered.") abort(http_client.INTERNAL_SERVER_ERROR, six.text_type(e))
def setUp(self): super(TraceControllerRBACTestCase, self).setUp() self.models = self.fixtures_loader.save_fixtures_to_db(fixtures_pack=FIXTURES_PACK, fixtures_dict=TEST_FIXTURES) file_name = 'trace_for_test_enforce.yaml' TraceControllerRBACTestCase.TRACE_1 = self.fixtures_loader.load_fixtures( fixtures_pack=FIXTURES_PACK, fixtures_dict={'traces': [file_name]})['traces'][file_name] file_name = 'trace_for_test_enforce_2.yaml' TraceControllerRBACTestCase.TRACE_1 = self.fixtures_loader.load_fixtures( fixtures_pack=FIXTURES_PACK, fixtures_dict={'traces': [file_name]})['traces'][file_name] file_name = 'trace_for_test_enforce_3.yaml' TraceControllerRBACTestCase.TRACE_1 = self.fixtures_loader.load_fixtures( fixtures_pack=FIXTURES_PACK, fixtures_dict={'traces': [file_name]})['traces'][file_name] # Insert mock users, roles and assignments # Users user_1_db = UserDB(name='trace_list') user_1_db = User.add_or_update(user_1_db) self.users['trace_list'] = user_1_db user_2_db = UserDB(name='trace_view') user_2_db = User.add_or_update(user_2_db) self.users['trace_view'] = user_2_db # Roles # trace_list grant_db = PermissionGrantDB(resource_uid=None, resource_type=ResourceType.TRACE, permission_types=[PermissionType.TRACE_LIST]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_1_db = RoleDB(name='trace_list', permission_grants=permission_grants) role_1_db = Role.add_or_update(role_1_db) self.roles['trace_list'] = role_1_db # trace_view on trace 1 trace_uid = self.models['traces']['trace_for_test_enforce.yaml'].get_uid() grant_db = PermissionGrantDB(resource_uid=trace_uid, resource_type=ResourceType.TRACE, permission_types=[PermissionType.TRACE_VIEW]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_1_db = RoleDB(name='trace_view', permission_grants=permission_grants) role_1_db = Role.add_or_update(role_1_db) self.roles['trace_view'] = role_1_db # Role assignments role_assignment_db = UserRoleAssignmentDB( user=self.users['trace_list'].name, role=self.roles['trace_list'].name, source='assignments/%s.yaml' % self.users['trace_list'].name) UserRoleAssignment.add_or_update(role_assignment_db) role_assignment_db = UserRoleAssignmentDB( user=self.users['trace_view'].name, role=self.roles['trace_view'].name, source='assignments/%s.yaml' % self.users['trace_view'].name) UserRoleAssignment.add_or_update(role_assignment_db)
def setUp(self): super(ActionPermissionsResolverTestCase, self).setUp() # Create some mock users user_1_db = UserDB(name='1_role_action_pack_grant') user_1_db = User.add_or_update(user_1_db) self.users['custom_role_action_pack_grant'] = user_1_db user_2_db = UserDB(name='1_role_action_grant') user_2_db = User.add_or_update(user_2_db) self.users['custom_role_action_grant'] = user_2_db user_3_db = UserDB(name='custom_role_pack_action_all_grant') user_3_db = User.add_or_update(user_3_db) self.users['custom_role_pack_action_all_grant'] = user_3_db user_4_db = UserDB(name='custom_role_action_all_grant') user_4_db = User.add_or_update(user_4_db) self.users['custom_role_action_all_grant'] = user_4_db user_5_db = UserDB(name='custom_role_action_execute_grant') user_5_db = User.add_or_update(user_5_db) self.users['custom_role_action_execute_grant'] = user_5_db user_6_db = UserDB(name='action_pack_action_create_grant') user_6_db = User.add_or_update(user_6_db) self.users['action_pack_action_create_grant'] = user_6_db user_7_db = UserDB(name='action_pack_action_all_grant') user_7_db = User.add_or_update(user_7_db) self.users['action_pack_action_all_grant'] = user_7_db user_8_db = UserDB(name='action_action_create_grant') user_8_db = User.add_or_update(user_8_db) self.users['action_action_create_grant'] = user_8_db user_9_db = UserDB(name='action_action_all_grant') user_9_db = User.add_or_update(user_9_db) self.users['action_action_all_grant'] = user_9_db user_10_db = UserDB(name='custom_role_action_list_grant') user_10_db = User.add_or_update(user_10_db) self.users['custom_role_action_list_grant'] = user_10_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'}) action_1_db = Action.add_or_update(action_1_db) self.resources['action_1'] = action_1_db action_2_db = ActionDB(pack='test_pack_1', name='action2', entry_point='', runner_type={'name': 'local-shell-cmd'}) action_2_db = Action.add_or_update(action_1_db) self.resources['action_2'] = action_2_db action_3_db = ActionDB(pack='test_pack_2', 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 # Create some mock roles with associated permission grants # Custom role 2 - one grant on parent pack # "action_view" on pack_1 grant_db = PermissionGrantDB( resource_uid=self.resources['pack_1'].get_uid(), resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_VIEW]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_3_db = RoleDB(name='custom_role_action_pack_grant', permission_grants=permission_grants) role_3_db = Role.add_or_update(role_3_db) self.roles['custom_role_action_pack_grant'] = role_3_db # Custom role 4 - one grant on action # "action_view" on action_3 grant_db = PermissionGrantDB( resource_uid=self.resources['action_3'].get_uid(), resource_type=ResourceType.ACTION, permission_types=[PermissionType.ACTION_VIEW]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_4_db = RoleDB(name='custom_role_action_grant', permission_grants=permission_grants) role_4_db = Role.add_or_update(role_4_db) self.roles['custom_role_action_grant'] = role_4_db # Custom role - "action_all" grant on a parent action pack grant_db = PermissionGrantDB( resource_uid=self.resources['pack_1'].get_uid(), resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_ALL]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_4_db = RoleDB(name='custom_role_pack_action_all_grant', permission_grants=permission_grants) role_4_db = Role.add_or_update(role_4_db) self.roles['custom_role_pack_action_all_grant'] = role_4_db # Custom role - "action_all" grant on action grant_db = PermissionGrantDB( resource_uid=self.resources['action_1'].get_uid(), resource_type=ResourceType.ACTION, permission_types=[PermissionType.ACTION_ALL]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_4_db = RoleDB(name='custom_role_action_all_grant', permission_grants=permission_grants) role_4_db = Role.add_or_update(role_4_db) self.roles['custom_role_action_all_grant'] = role_4_db # Custom role - "action_execute" on action_1 grant_db = PermissionGrantDB( resource_uid=self.resources['action_1'].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_5_db = RoleDB(name='custom_role_action_execute_grant', permission_grants=permission_grants) role_5_db = Role.add_or_update(role_5_db) self.roles['custom_role_action_execute_grant'] = role_5_db # Custom role - "action_create" grant on pack_1 grant_db = PermissionGrantDB( resource_uid=self.resources['pack_1'].get_uid(), resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_CREATE]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_6_db = RoleDB(name='action_pack_action_create_grant', permission_grants=permission_grants) role_6_db = Role.add_or_update(role_6_db) self.roles['action_pack_action_create_grant'] = role_6_db # Custom role - "action_all" grant on pack_1 grant_db = PermissionGrantDB( resource_uid=self.resources['pack_1'].get_uid(), resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_ALL]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_7_db = RoleDB(name='action_pack_action_all_grant', permission_grants=permission_grants) role_7_db = Role.add_or_update(role_7_db) self.roles['action_pack_action_all_grant'] = role_7_db # Custom role - "action_create" grant on action_1 grant_db = PermissionGrantDB( resource_uid=self.resources['action_1'].get_uid(), resource_type=ResourceType.ACTION, permission_types=[PermissionType.ACTION_CREATE]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_8_db = RoleDB(name='action_action_create_grant', permission_grants=permission_grants) role_8_db = Role.add_or_update(role_8_db) self.roles['action_action_create_grant'] = role_8_db # Custom role - "action_all" grant on action_1 grant_db = PermissionGrantDB( resource_uid=self.resources['action_1'].get_uid(), resource_type=ResourceType.ACTION, permission_types=[PermissionType.ACTION_ALL]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_9_db = RoleDB(name='action_action_all_grant', permission_grants=permission_grants) role_9_db = Role.add_or_update(role_9_db) self.roles['action_action_all_grant'] = role_9_db # Custom role - "action_list" grant grant_db = PermissionGrantDB( resource_uid=None, resource_type=None, permission_types=[PermissionType.ACTION_LIST]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_10_db = RoleDB(name='custom_role_action_list_grant', permission_grants=permission_grants) role_10_db = Role.add_or_update(role_10_db) self.roles['custom_role_action_list_grant'] = role_10_db # Create some mock role assignments user_db = self.users['custom_role_action_pack_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_action_pack_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_action_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_action_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_pack_action_all_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_pack_action_all_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_action_all_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_action_all_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_action_execute_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_action_execute_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['action_pack_action_create_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['action_pack_action_create_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['action_pack_action_all_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['action_pack_action_all_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['action_action_create_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['action_action_create_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['action_action_all_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['action_action_all_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_action_list_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_action_list_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db)
def test_get_all_all_scope(self): # Test which cases various scenarios which ensure non-admin users can't read / view keys # from other users user_db_1 = UserDB(name='user1') user_db_2 = UserDB(name='user2') user_db_3 = UserDB(name='user3') # Insert some mock data # System scoped keys put_resp = self.__do_put('system1', {'name': 'system1', 'value': 'val1', 'scope': 'st2kv.system'}) self.assertEqual(put_resp.status_int, 200) self.assertEqual(put_resp.json['name'], 'system1') self.assertEqual(put_resp.json['scope'], 'st2kv.system') put_resp = self.__do_put('system2', {'name': 'system2', 'value': 'val2', 'scope': 'st2kv.system'}) self.assertEqual(put_resp.status_int, 200) self.assertEqual(put_resp.json['name'], 'system2') self.assertEqual(put_resp.json['scope'], 'st2kv.system') # user1 scoped keys self.use_user(user_db_1) put_resp = self.__do_put('user1', {'name': 'user1', 'value': 'user1', 'scope': 'st2kv.user'}) self.assertEqual(put_resp.status_int, 200) self.assertEqual(put_resp.json['name'], 'user1') self.assertEqual(put_resp.json['scope'], 'st2kv.user') self.assertEqual(put_resp.json['value'], 'user1') put_resp = self.__do_put('userkey', {'name': 'userkey', 'value': 'user1', 'scope': 'st2kv.user'}) self.assertEqual(put_resp.status_int, 200) self.assertEqual(put_resp.json['name'], 'userkey') self.assertEqual(put_resp.json['scope'], 'st2kv.user') self.assertEqual(put_resp.json['value'], 'user1') # user2 scoped keys self.use_user(user_db_2) put_resp = self.__do_put('user2', {'name': 'user2', 'value': 'user2', 'scope': 'st2kv.user'}) self.assertEqual(put_resp.status_int, 200) self.assertEqual(put_resp.json['name'], 'user2') self.assertEqual(put_resp.json['scope'], 'st2kv.user') self.assertEqual(put_resp.json['value'], 'user2') put_resp = self.__do_put('userkey', {'name': 'userkey', 'value': 'user2', 'scope': 'st2kv.user'}) self.assertEqual(put_resp.status_int, 200) self.assertEqual(put_resp.json['name'], 'userkey') self.assertEqual(put_resp.json['scope'], 'st2kv.user') self.assertEqual(put_resp.json['value'], 'user2') # user3 scoped keys self.use_user(user_db_3) put_resp = self.__do_put('user3', {'name': 'user3', 'value': 'user3', 'scope': 'st2kv.user'}) self.assertEqual(put_resp.status_int, 200) self.assertEqual(put_resp.json['name'], 'user3') self.assertEqual(put_resp.json['scope'], 'st2kv.user') self.assertEqual(put_resp.json['value'], 'user3') put_resp = self.__do_put('userkey', {'name': 'userkey', 'value': 'user3', 'scope': 'st2kv.user'}) self.assertEqual(put_resp.status_int, 200) self.assertEqual(put_resp.json['name'], 'userkey') self.assertEqual(put_resp.json['scope'], 'st2kv.user') self.assertEqual(put_resp.json['value'], 'user3') # 1. "all" scope as user1 - should only be able to view system + current user items self.use_user(user_db_1) resp = self.app.get('/v1/keys?scope=all') self.assertEqual(len(resp.json), 2 + 2) # 2 system, 2 user self.assertEqual(resp.json[0]['name'], 'system1') self.assertEqual(resp.json[0]['scope'], 'st2kv.system') self.assertEqual(resp.json[1]['name'], 'system2') self.assertEqual(resp.json[1]['scope'], 'st2kv.system') self.assertEqual(resp.json[2]['name'], 'user1') self.assertEqual(resp.json[2]['scope'], 'st2kv.user') self.assertEqual(resp.json[2]['user'], 'user1') self.assertEqual(resp.json[3]['name'], 'userkey') self.assertEqual(resp.json[3]['scope'], 'st2kv.user') self.assertEqual(resp.json[3]['user'], 'user1') # Verify user can't retrieve values for other users by manipulating "prefix" resp = self.app.get('/v1/keys?scope=all&prefix=user2:') self.assertEqual(resp.json, []) resp = self.app.get('/v1/keys?scope=all&prefix=user') self.assertEqual(len(resp.json), 2) # 2 user self.assertEqual(resp.json[0]['name'], 'user1') self.assertEqual(resp.json[0]['scope'], 'st2kv.user') self.assertEqual(resp.json[0]['user'], 'user1') self.assertEqual(resp.json[1]['name'], 'userkey') self.assertEqual(resp.json[1]['scope'], 'st2kv.user') self.assertEqual(resp.json[1]['user'], 'user1') # 2. "all" scope user user2 - should only be able to view system + current user items self.use_user(user_db_2) resp = self.app.get('/v1/keys?scope=all') self.assertEqual(len(resp.json), 2 + 2) # 2 system, 2 user self.assertEqual(resp.json[0]['name'], 'system1') self.assertEqual(resp.json[0]['scope'], 'st2kv.system') self.assertEqual(resp.json[1]['name'], 'system2') self.assertEqual(resp.json[1]['scope'], 'st2kv.system') self.assertEqual(resp.json[2]['name'], 'user2') self.assertEqual(resp.json[2]['scope'], 'st2kv.user') self.assertEqual(resp.json[2]['user'], 'user2') self.assertEqual(resp.json[3]['name'], 'userkey') self.assertEqual(resp.json[3]['scope'], 'st2kv.user') self.assertEqual(resp.json[3]['user'], 'user2') # Verify user can't retrieve values for other users by manipulating "prefix" resp = self.app.get('/v1/keys?scope=all&prefix=user1:') self.assertEqual(resp.json, []) resp = self.app.get('/v1/keys?scope=all&prefix=user') self.assertEqual(len(resp.json), 2) # 2 user self.assertEqual(resp.json[0]['name'], 'user2') self.assertEqual(resp.json[0]['scope'], 'st2kv.user') self.assertEqual(resp.json[0]['user'], 'user2') self.assertEqual(resp.json[1]['name'], 'userkey') self.assertEqual(resp.json[1]['scope'], 'st2kv.user') self.assertEqual(resp.json[1]['user'], 'user2') # Verify non-admon user can't retrieve key for an arbitrary users resp = self.app.get('/v1/keys?scope=user&user=user1', expect_errors=True) expected_error = '"user" attribute can only be provided by admins when RBAC is enabled' self.assertEqual(resp.status_int, http_client.FORBIDDEN) self.assertEqual(resp.json['faultstring'], expected_error) # 3. "all" scope user user3 - should only be able to view system + current user items self.use_user(user_db_3) resp = self.app.get('/v1/keys?scope=all') self.assertEqual(len(resp.json), 2 + 2) # 2 system, 2 user self.assertEqual(resp.json[0]['name'], 'system1') self.assertEqual(resp.json[0]['scope'], 'st2kv.system') self.assertEqual(resp.json[1]['name'], 'system2') self.assertEqual(resp.json[1]['scope'], 'st2kv.system') self.assertEqual(resp.json[2]['name'], 'user3') self.assertEqual(resp.json[2]['scope'], 'st2kv.user') self.assertEqual(resp.json[2]['user'], 'user3') self.assertEqual(resp.json[3]['name'], 'userkey') self.assertEqual(resp.json[3]['scope'], 'st2kv.user') self.assertEqual(resp.json[3]['user'], 'user3') # Verify user can't retrieve values for other users by manipulating "prefix" resp = self.app.get('/v1/keys?scope=all&prefix=user1:') self.assertEqual(resp.json, []) resp = self.app.get('/v1/keys?scope=all&prefix=user') self.assertEqual(len(resp.json), 2) # 2 user self.assertEqual(resp.json[0]['name'], 'user3') self.assertEqual(resp.json[0]['scope'], 'st2kv.user') self.assertEqual(resp.json[0]['user'], 'user3') self.assertEqual(resp.json[1]['name'], 'userkey') self.assertEqual(resp.json[1]['scope'], 'st2kv.user') self.assertEqual(resp.json[1]['user'], 'user3') # Clean up self.__do_delete('system1') self.__do_delete('system2') self.use_user(user_db_1) self.__do_delete('user1?scope=user') self.__do_delete('userkey?scope=user') self.use_user(user_db_2) self.__do_delete('user2?scope=user') self.__do_delete('userkey?scope=user') self.use_user(user_db_3) self.__do_delete('user3?scope=user') self.__do_delete('userkey?scope=user')
def create_token(username, ttl=None, metadata=None, add_missing_user=True, service=False): """ :param username: Username of the user to create the token for. If the account for this user doesn't exist yet it will be created. :type username: ``str`` :param ttl: Token TTL (in seconds). :type ttl: ``int`` :param metadata: Optional metadata to associate with the token. :type metadata: ``dict`` :param add_missing_user: Add the user given by `username` if they don't exist :type add_missing_user: ``bool`` :param service: True if this is a service (non-user) token. :type service: ``bool`` """ if ttl: # Note: We allow arbitrary large TTLs for service tokens. if not service and ttl > cfg.CONF.auth.token_ttl: msg = ('TTL specified %s is greater than max allowed %s.' % (ttl, cfg.CONF.auth.token_ttl)) raise TTLTooLargeException(msg) else: ttl = cfg.CONF.auth.token_ttl if username: try: User.get_by_name(username) except: if add_missing_user: user_db = UserDB(name=username) User.add_or_update(user_db) extra = {'username': username, 'user': user_db} LOG.audit('Registered new user "%s".' % (username), extra=extra) else: raise UserNotFoundError() token = uuid.uuid4().hex expiry = date_utils.get_datetime_utc_now() + datetime.timedelta( seconds=ttl) token = TokenDB(user=username, token=token, expiry=expiry, metadata=metadata, service=service) Token.add_or_update(token) username_string = username if username else 'an anonymous user' token_expire_string = isotime.format(expiry, offset=False) extra = {'username': username, 'token_expiration': token_expire_string} LOG.audit('Access granted to "%s" with the token set to expire at "%s".' % (username_string, token_expire_string), extra=extra) return token
def put(self, rule, rule_ref_or_id, requester_user): rule_db = self._get_by_ref_or_id(rule_ref_or_id) permission_type = PermissionType.RULE_MODIFY rbac_utils.assert_user_has_resource_db_permission( user_db=requester_user, resource_db=rule, permission_type=permission_type) LOG.debug('PUT /rules/ lookup with id=%s found object: %s', rule_ref_or_id, rule_db) if not requester_user: requester_user = UserDB(cfg.CONF.system_user.user) # Validate that the authenticated user is admin if user query param is provided user = requester_user.name assert_user_is_admin_if_user_query_param_is_provided( user_db=requester_user, user=user) if not hasattr(rule, 'context'): rule.context = dict() rule.context['user'] = user try: if rule.id is not None and rule.id is not '' and rule.id != rule_ref_or_id: LOG.warning( 'Discarding mismatched id=%s found in payload and using uri_id=%s.', rule.id, rule_ref_or_id) old_rule_db = rule_db try: rule_db = RuleAPI.to_model(rule) except TriggerDoesNotExistException as e: abort(http_client.BAD_REQUEST, str(e)) return # Check referenced trigger and action permissions # Note: This needs to happen after "to_model" call since to_model performs some # validation (trigger exists, etc.) assert_user_has_rule_trigger_and_action_permission( user_db=requester_user, rule_api=rule) rule_db.id = rule_ref_or_id rule_db = Rule.add_or_update(rule_db) # After the rule has been added modify the ref_count. This way a failure to add # the rule due to violated constraints will have no impact on ref_count. increment_trigger_ref_count(rule_api=rule) except (ValueValidationException, jsonschema.ValidationError, ValueError) as e: LOG.exception('Validation failed for rule data=%s', rule) abort(http_client.BAD_REQUEST, str(e)) return # use old_rule_db for cleanup. cleanup_trigger_db_for_rule(old_rule_db) extra = {'old_rule_db': old_rule_db, 'new_rule_db': rule_db} LOG.audit('Rule updated. Rule.id=%s.' % (rule_db.id), extra=extra) rule_api = RuleAPI.from_model(rule_db) return rule_api
def setUp(self): super(RuleControllerRBACTestCase, self).setUp() self.fixtures_loader.save_fixtures_to_db(fixtures_pack=FIXTURES_PACK, fixtures_dict=TEST_FIXTURES) file_name = 'rule_with_webhook_trigger.yaml' RuleControllerRBACTestCase.RULE_1 = self.fixtures_loader.load_fixtures( fixtures_pack=FIXTURES_PACK, fixtures_dict={'rules': [file_name]})['rules'][file_name] file_name = 'rule_example_pack.yaml' RuleControllerRBACTestCase.RULE_2 = self.fixtures_loader.load_fixtures( fixtures_pack=FIXTURES_PACK, fixtures_dict={'rules': [file_name]})['rules'][file_name] # Insert mock users, roles and assignments self = self self.users = {} self.roles = {} # Users user_1_db = UserDB(name='rule_create') user_1_db = User.add_or_update(user_1_db) self.users['rule_create'] = user_1_db user_2_db = UserDB(name='rule_create_webhook_create') user_2_db = User.add_or_update(user_2_db) self.users['rule_create_webhook_create'] = user_2_db user_3_db = UserDB( name='rule_create_webhook_create_core_local_execute') user_3_db = User.add_or_update(user_3_db) self.users['rule_create_webhook_create_core_local_execute'] = user_3_db # Roles # rule_create grant on parent pack grant_db = PermissionGrantDB( resource_uid='pack:examples', resource_type=ResourceType.PACK, permission_types=[PermissionType.RULE_CREATE]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_1_db = RoleDB(name='rule_create', permission_grants=permission_grants) role_1_db = Role.add_or_update(role_1_db) self.roles['rule_create'] = role_1_db # rule_create grant on parent pack, webhook_create on webhook "sample" grant_1_db = PermissionGrantDB( resource_uid='pack:examples', resource_type=ResourceType.PACK, permission_types=[PermissionType.RULE_CREATE]) grant_1_db = PermissionGrant.add_or_update(grant_1_db) grant_2_db = PermissionGrantDB( resource_uid='webhook:sample', resource_type=ResourceType.WEBHOOK, permission_types=[PermissionType.WEBHOOK_CREATE]) grant_2_db = PermissionGrant.add_or_update(grant_2_db) permission_grants = [str(grant_1_db.id), str(grant_2_db.id)] role_2_db = RoleDB(name='rule_create_webhook_create', permission_grants=permission_grants) role_2_db = Role.add_or_update(role_2_db) self.roles['rule_create_webhook_create'] = role_2_db # rule_create grant on parent pack, webhook_create on webhook "sample", action_execute on # core.local grant_1_db = PermissionGrantDB( resource_uid='pack:examples', resource_type=ResourceType.PACK, permission_types=[PermissionType.RULE_CREATE]) grant_1_db = PermissionGrant.add_or_update(grant_1_db) grant_2_db = PermissionGrantDB( resource_uid='webhook:sample', resource_type=ResourceType.WEBHOOK, permission_types=[PermissionType.WEBHOOK_CREATE]) grant_2_db = PermissionGrant.add_or_update(grant_2_db) grant_3_db = PermissionGrantDB( resource_uid='action:core:local', resource_type=ResourceType.ACTION, permission_types=[PermissionType.ACTION_EXECUTE]) grant_3_db = PermissionGrant.add_or_update(grant_3_db) permission_grants = [ str(grant_1_db.id), str(grant_2_db.id), str(grant_3_db.id) ] role_3_db = RoleDB( name='rule_create_webhook_create_core_local_execute', permission_grants=permission_grants) role_3_db = Role.add_or_update(role_3_db) self.roles['rule_create_webhook_create_core_local_execute'] = role_3_db # Role assignments user_db = self.users['rule_create'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['rule_create'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['rule_create_webhook_create'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['rule_create_webhook_create'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['rule_create_webhook_create_core_local_execute'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['rule_create_webhook_create_core_local_execute']. name) UserRoleAssignment.add_or_update(role_assignment_db)
def _post(self, payload, requester_user, show_secrets=False, match_multiple=False): action_alias_name = payload.name if payload else None if not action_alias_name: abort(http_client.BAD_REQUEST, 'Alias execution "name" is required') return if not requester_user: requester_user = UserDB(cfg.CONF.system_user.user) format_str = payload.format or '' command = payload.command or '' try: action_alias_db = ActionAlias.get_by_name(action_alias_name) except ValueError: action_alias_db = None if not action_alias_db: msg = 'Unable to identify action alias with name "%s".' % ( action_alias_name) abort(http_client.NOT_FOUND, msg) return if not action_alias_db.enabled: msg = 'Action alias with name "%s" is disabled.' % ( action_alias_name) abort(http_client.BAD_REQUEST, msg) return if match_multiple: multiple_execution_parameters = extract_parameters_for_action_alias_db( action_alias_db=action_alias_db, format_str=format_str, param_stream=command, match_multiple=match_multiple) else: multiple_execution_parameters = [ extract_parameters_for_action_alias_db( action_alias_db=action_alias_db, format_str=format_str, param_stream=command, match_multiple=match_multiple) ] notify = self._get_notify_field(payload) context = { 'action_alias_ref': reference.get_ref_from_model(action_alias_db), 'api_user': payload.user, 'user': requester_user.name, 'source_channel': payload.source_channel, } inject_immutable_parameters( action_alias_db=action_alias_db, multiple_execution_parameters=multiple_execution_parameters, action_context=context) results = [] for execution_parameters in multiple_execution_parameters: execution = self._schedule_execution( action_alias_db=action_alias_db, params=execution_parameters, notify=notify, context=context, show_secrets=show_secrets, requester_user=requester_user) result = { 'execution': execution, 'actionalias': ActionAliasAPI.from_model(action_alias_db) } if action_alias_db.ack: try: if 'format' in action_alias_db.ack: message = render( {'alias': action_alias_db.ack['format']}, result)['alias'] result.update({'message': message}) except UndefinedError as e: result.update({ 'message': ('Cannot render "format" in field "ack" for alias. ' + six.text_type(e)) }) try: if 'extra' in action_alias_db.ack: result.update({ 'extra': render(action_alias_db.ack['extra'], result) }) except UndefinedError as e: result.update({ 'extra': ('Cannot render "extra" in field "ack" for alias. ' + six.text_type(e)) }) results.append(result) return results
def setUp(self): super(KeyValuesControllerRBACTestCase, self).setUp() self.kvps = {} # Insert mock users user_1_db = UserDB(name='user1') user_1_db = User.add_or_update(user_1_db) self.users['user_1'] = user_1_db user_2_db = UserDB(name='user2') user_2_db = User.add_or_update(user_2_db) self.users['user_2'] = user_2_db # Insert mock kvp objects kvp_api = KeyValuePairSetAPI(name='test_system_scope', value='value1', scope=FULL_SYSTEM_SCOPE) kvp_db = KeyValuePairSetAPI.to_model(kvp_api) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps['kvp_1'] = kvp_db kvp_api = KeyValuePairSetAPI(name='test_system_scope_secret', value='value_secret', scope=FULL_SYSTEM_SCOPE, secret=True) kvp_db = KeyValuePairSetAPI.to_model(kvp_api) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps['kvp_2'] = kvp_db name = get_key_reference(scope=FULL_USER_SCOPE, name='test_user_scope_1', user='******') kvp_db = KeyValuePairDB(name=name, value='valueu12', scope=FULL_USER_SCOPE) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps['kvp_3'] = kvp_db name = get_key_reference(scope=FULL_USER_SCOPE, name='test_user_scope_2', user='******') kvp_api = KeyValuePairSetAPI(name=name, value='user_secret', scope=FULL_USER_SCOPE, secret=True) kvp_db = KeyValuePairSetAPI.to_model(kvp_api) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps['kvp_4'] = kvp_db name = get_key_reference(scope=FULL_USER_SCOPE, name='test_user_scope_3', user='******') kvp_db = KeyValuePairDB(name=name, value='valueu21', scope=FULL_USER_SCOPE) kvp_db = KeyValuePair.add_or_update(kvp_db) kvp_db = KeyValuePairAPI.from_model(kvp_db) self.kvps['kvp_5'] = kvp_db self.system_scoped_items_count = 2 self.user_scoped_items_count = 3 self.user_scoped_items_per_user_count = {'user1': 2, 'user2': 1}
def setUp(self): super(RBACUtilsTestCase, self).setUp() self.mocks = {} user_db = UserDB(name='test1') self.mocks['user_db'] = user_db
def put(self, kvp, name, requester_user, scope=FULL_SYSTEM_SCOPE): """ Create a new entry or update an existing one. """ if not scope: scope = FULL_SYSTEM_SCOPE if not requester_user: requester_user = UserDB(cfg.CONF.system_user.user) scope = getattr(kvp, 'scope', scope) scope = get_datastore_full_scope(scope) self._validate_scope(scope=scope) user = getattr(kvp, 'user', requester_user.name) or requester_user.name # Validate that the authenticated user is admin if user query param is provided assert_user_is_admin_if_user_query_param_is_provided(user_db=requester_user, user=user) key_ref = get_key_reference(scope=scope, name=name, user=user) lock_name = self._get_lock_name_for_key(name=key_ref, scope=scope) LOG.debug('PUT scope: %s, name: %s', scope, name) # TODO: Custom permission check since the key doesn't need to exist here # Note: We use lock to avoid a race with self._coordinator.get_lock(lock_name): try: existing_kvp_api = self._get_one_by_scope_and_name( scope=scope, name=key_ref ) except StackStormDBObjectNotFoundError: existing_kvp_api = None kvp.name = key_ref kvp.scope = scope try: kvp_db = KeyValuePairAPI.to_model(kvp) if existing_kvp_api: kvp_db.id = existing_kvp_api.id kvp_db = KeyValuePair.add_or_update(kvp_db) except (ValidationError, ValueError) as e: LOG.exception('Validation failed for key value data=%s', kvp) abort(http_client.BAD_REQUEST, str(e)) return except CryptoKeyNotSetupException as e: LOG.exception(str(e)) abort(http_client.BAD_REQUEST, str(e)) return except InvalidScopeException as e: LOG.exception(str(e)) abort(http_client.BAD_REQUEST, str(e)) return extra = {'kvp_db': kvp_db} LOG.audit('KeyValuePair updated. KeyValuePair.id=%s' % (kvp_db.id), extra=extra) kvp_api = KeyValuePairAPI.from_model(kvp_db) return kvp_api
def handle_auth(self, request, headers=None, remote_addr=None, remote_user=None, authorization=None, **kwargs): auth_backend = self._auth_backend.__class__.__name__ extra = {'auth_backend': auth_backend, 'remote_addr': remote_addr} if not authorization: LOG.audit('Authorization header not provided', extra=extra) abort_request() return auth_type, auth_value = authorization if auth_type.lower() not in ['basic']: extra['auth_type'] = auth_type LOG.audit('Unsupported authorization type: %s' % (auth_type), extra=extra) abort_request() return try: auth_value = base64.b64decode(auth_value) except Exception: LOG.audit('Invalid authorization header', extra=extra) abort_request() return split = auth_value.split(b':', 1) if len(split) != 2: LOG.audit('Invalid authorization header', extra=extra) abort_request() return username, password = split if six.PY3 and isinstance(username, six.binary_type): username = username.decode('utf-8') if six.PY3 and isinstance(password, six.binary_type): password = password.decode('utf-8') result = self._auth_backend.authenticate(username=username, password=password) if result is True: ttl = getattr(request, 'ttl', None) username = self._get_username_for_request(username, request) try: token = self._create_token_for_user(username=username, ttl=ttl) except TTLTooLargeException as e: abort_request(status_code=http_client.BAD_REQUEST, message=six.text_type(e)) return # If remote group sync is enabled, sync the remote groups with local StackStorm roles if cfg.CONF.rbac.sync_remote_groups and cfg.CONF.rbac.backend != 'noop': LOG.debug('Retrieving auth backend groups for user "%s"' % (username), extra=extra) try: user_groups = self._auth_backend.get_user_groups( username=username) except (NotImplementedError, AttributeError): LOG.debug( 'Configured auth backend doesn\'t expose user group membership ' 'information, skipping sync...') return token if not user_groups: # No groups, return early return token extra['username'] = username extra['user_groups'] = user_groups LOG.debug('Found "%s" groups for user "%s"' % (len(user_groups), username), extra=extra) user_db = UserDB(name=username) rbac_backend = get_rbac_backend() syncer = rbac_backend.get_remote_group_to_role_syncer() try: syncer.sync(user_db=user_db, groups=user_groups) except Exception as e: # Note: Failed sync is not fatal LOG.exception( 'Failed to synchronize remote groups for user "%s"' % (username), extra=extra) else: LOG.debug( 'Successfully synchronized groups for user "%s"' % (username), extra=extra) return token return token LOG.audit('Invalid credentials provided', extra=extra) abort_request()
def setUp(self): super(RBACServicesTestCase, self).setUp() # TODO: Share mocks self.users = {} self.roles = {} self.resources = {} # Create some mock users user_1_db = UserDB(name='admin') user_1_db = User.add_or_update(user_1_db) self.users['admin'] = user_1_db user_2_db = UserDB(name='observer') user_2_db = User.add_or_update(user_2_db) self.users['observer'] = user_2_db user_3_db = UserDB(name='no_roles') user_3_db = User.add_or_update(user_3_db) self.users['no_roles'] = user_3_db user_5_db = UserDB(name='user_5') user_5_db = User.add_or_update(user_5_db) self.users['user_5'] = user_5_db user_4_db = UserDB(name='custom_role') user_4_db = User.add_or_update(user_4_db) self.users['1_custom_role'] = user_4_db # Create some mock roles role_1_db = rbac_services.create_role(name='custom_role_1') role_2_db = rbac_services.create_role(name='custom_role_2', description='custom role 2') self.roles['custom_role_1'] = role_1_db self.roles['custom_role_2'] = role_2_db rbac_services.create_role(name='role_1') rbac_services.create_role(name='role_2') rbac_services.create_role(name='role_3') rbac_services.create_role(name='role_4') # Create some mock role assignments role_assignment_1 = UserRoleAssignmentDB( user=self.users['1_custom_role'].name, role=self.roles['custom_role_1'].name) role_assignment_1 = UserRoleAssignment.add_or_update(role_assignment_1) # Note: User use pymongo to insert mock data because we want to insert a # raw document and skip mongoengine to leave is_remote field unpopulated client = MongoClient() db = client['st2-test'] db.user_role_assignment_d_b.insert_one({ 'user': '******', 'role': 'role_1' }) db.user_role_assignment_d_b.insert_one({ 'user': '******', 'role': 'role_2' }) db.user_role_assignment_d_b.insert_one({ 'user': '******', 'role': 'role_3', 'is_remote': False }) db.user_role_assignment_d_b.insert_one({ 'user': '******', 'role': 'role_4', 'is_remote': True }) # Create some mock resources on which permissions can be granted rule_1_db = RuleDB(pack='test1', name='rule1', ref='test1.rule1') rule_1_db = Rule.add_or_update(rule_1_db) self.resources['rule_1'] = rule_1_db
def post(self, rule, requester_user): """ Create a new rule. Handles requests: POST /rules/ """ permission_type = PermissionType.RULE_CREATE rbac_utils.assert_user_has_resource_api_permission( user_db=requester_user, resource_api=rule, permission_type=permission_type) if not requester_user: requester_user = UserDB(cfg.CONF.system_user.user) # Validate that the authenticated user is admin if user query param is provided user = requester_user.name assert_user_is_admin_if_user_query_param_is_provided( user_db=requester_user, user=user) if not hasattr(rule, 'context'): rule.context = dict() rule.context['user'] = user try: rule_db = RuleAPI.to_model(rule) LOG.debug('/rules/ POST verified RuleAPI and formulated RuleDB=%s', rule_db) # Check referenced trigger and action permissions # Note: This needs to happen after "to_model" call since to_model performs some # validation (trigger exists, etc.) assert_user_has_rule_trigger_and_action_permission( user_db=requester_user, rule_api=rule) rule_db = Rule.add_or_update(rule_db) # After the rule has been added modify the ref_count. This way a failure to add # the rule due to violated constraints will have no impact on ref_count. increment_trigger_ref_count(rule_api=rule) except (ValidationError, ValueError) as e: LOG.exception('Validation failed for rule data=%s.', rule) abort(http_client.BAD_REQUEST, str(e)) return except (ValueValidationException, jsonschema.ValidationError) as e: LOG.exception('Validation failed for rule data=%s.', rule) abort(http_client.BAD_REQUEST, str(e)) return except TriggerDoesNotExistException as e: msg = ( 'Trigger "%s" defined in the rule does not exist in system or it\'s missing ' 'required "parameters" attribute' % (rule.trigger['type'])) LOG.exception(msg) abort(http_client.BAD_REQUEST, msg) return extra = {'rule_db': rule_db} LOG.audit('Rule created. Rule.id=%s' % (rule_db.id), extra=extra) rule_api = RuleAPI.from_model(rule_db) return Response(json=rule_api, status=exc.HTTPCreated.code)
def setUp(self): super(SensorPermissionsResolverTestCase, self).setUp() # Create some mock users user_1_db = UserDB(name='1_role_sensor_pack_grant') user_1_db = User.add_or_update(user_1_db) self.users['custom_role_sensor_pack_grant'] = user_1_db user_2_db = UserDB(name='1_role_sensor_grant') user_2_db = User.add_or_update(user_2_db) self.users['custom_role_sensor_grant'] = user_2_db user_3_db = UserDB(name='custom_role_pack_sensor_all_grant') user_3_db = User.add_or_update(user_3_db) self.users['custom_role_pack_sensor_all_grant'] = user_3_db user_4_db = UserDB(name='custom_role_sensor_all_grant') user_4_db = User.add_or_update(user_4_db) self.users['custom_role_sensor_all_grant'] = user_4_db # Create some mock resources on which permissions can be granted sensor_1_db = SensorTypeDB(pack='test_pack_1', name='sensor1') sensor_1_db = SensorType.add_or_update(sensor_1_db) self.resources['sensor_1'] = sensor_1_db sensor_2_db = SensorTypeDB(pack='test_pack_1', name='sensor2') sensor_2_db = SensorType.add_or_update(sensor_2_db) self.resources['sensor_2'] = sensor_2_db sensor_3_db = SensorTypeDB(pack='test_pack_2', name='sensor3') sensor_3_db = SensorType.add_or_update(sensor_3_db) self.resources['sensor_3'] = sensor_3_db # Create some mock roles with associated permission grants # Custom role 2 - one grant on parent pack # "sensor_view" on pack_1 grant_db = PermissionGrantDB( resource_uid=self.resources['pack_1'].get_uid(), resource_type=ResourceType.PACK, permission_types=[PermissionType.SENSOR_VIEW]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_3_db = RoleDB(name='custom_role_sensor_pack_grant', permission_grants=permission_grants) role_3_db = Role.add_or_update(role_3_db) self.roles['custom_role_sensor_pack_grant'] = role_3_db # Custom role 4 - one grant on pack # "sensor_view on sensor_3 grant_db = PermissionGrantDB( resource_uid=self.resources['sensor_3'].get_uid(), resource_type=ResourceType.SENSOR, permission_types=[PermissionType.SENSOR_VIEW]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_4_db = RoleDB(name='custom_role_sensor_grant', permission_grants=permission_grants) role_4_db = Role.add_or_update(role_4_db) self.roles['custom_role_sensor_grant'] = role_4_db # Custom role - "sensor_all" grant on a parent sensor pack grant_db = PermissionGrantDB( resource_uid=self.resources['pack_1'].get_uid(), resource_type=ResourceType.PACK, permission_types=[PermissionType.SENSOR_ALL]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_4_db = RoleDB(name='custom_role_pack_sensor_all_grant', permission_grants=permission_grants) role_4_db = Role.add_or_update(role_4_db) self.roles['custom_role_pack_sensor_all_grant'] = role_4_db # Custom role - "sensor_all" grant on a sensor grant_db = PermissionGrantDB( resource_uid=self.resources['sensor_1'].get_uid(), resource_type=ResourceType.SENSOR, permission_types=[PermissionType.SENSOR_ALL]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_4_db = RoleDB(name='custom_role_sensor_all_grant', permission_grants=permission_grants) role_4_db = Role.add_or_update(role_4_db) self.roles['custom_role_sensor_all_grant'] = role_4_db # Create some mock role assignments user_db = self.users['custom_role_sensor_pack_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_sensor_pack_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_sensor_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_sensor_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_pack_sensor_all_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_pack_sensor_all_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_sensor_all_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_sensor_all_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db)
def test_user_custom_all_permissions_for_system_scope_kvps(self): kvp_1_uid = "%s:%s:key1" % (ResourceType.KEY_VALUE_PAIR, FULL_SYSTEM_SCOPE) kvp_1_db = self.resources[kvp_1_uid] kvp_2_uid = "%s:%s:key2" % (ResourceType.KEY_VALUE_PAIR, FULL_SYSTEM_SCOPE) kvp_2_db = self.resources[kvp_2_uid] # Setup user, grant, role, and assignment records user_db = UserDB(name="system_key1_all") user_db = User.add_or_update(user_db) self.users[user_db.name] = user_db grant_db = PermissionGrantDB( resource_uid=kvp_1_db.get_uid(), resource_type=ResourceType.KEY_VALUE_PAIR, permission_types=[PermissionType.KEY_VALUE_PAIR_ALL], ) grant_db = PermissionGrant.add_or_update(grant_db) role_db = RoleDB( name="custom_role_system_key1_all_grant", permission_grants=[str(grant_db.id)], ) role_db = Role.add_or_update(role_db) self.roles[role_db.name] = role_db role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=role_db.name, source="assignments/%s.yaml" % user_db.name, ) UserRoleAssignment.add_or_update(role_assignment_db) # Set context to user self.use_user(self.users[user_db.name]) # User should be able to list the system and user scoped kvps that user has permission to. resp = self.app.get("/v1/keys/") self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 1) self.assertEqual(resp.json[0]["name"], "key1") self.assertEqual(resp.json[0]["scope"], FULL_SYSTEM_SCOPE) # User should have read and write permissions on system kvp key1. k, v = kvp_1_db.name, "val1" resp = self.app.get("/v1/keys/%s?decrypt=True&scope=system" % k) self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(resp.json["value"], v) d = { "name": k, "value": "value for %s" % k, "scope": FULL_SYSTEM_SCOPE, "secret": True, } resp = self.app.put_json("/v1/keys/%s?scope=system" % k, d) self.assertEqual(resp.status_int, http_client.OK) resp = self.app.get("/v1/keys/%s?decrypt=True&scope=system" % k) self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(resp.json["value"], "value for %s" % k) resp = self.app.delete("/v1/keys/%s?scope=system" % k) self.assertEqual(resp.status_code, http_client.NO_CONTENT) resp = self.app.get("/v1/keys/%s?scope=system" % k, expect_errors=True) self.assertEqual(resp.status_int, http_client.NOT_FOUND) # User should not have read and write permissions on system kvp key2. k = kvp_2_db.name resp = self.app.get("/v1/keys/%s?scope=system" % k, expect_errors=True) self.assertEqual(resp.status_int, http_client.FORBIDDEN) d = { "name": k, "value": "value for %s" % k, "scope": FULL_SYSTEM_SCOPE, } resp = self.app.put_json("/v1/keys/%s?scope=system" % k, d, expect_errors=True) self.assertEqual(resp.status_int, http_client.FORBIDDEN) resp = self.app.delete("/v1/keys/%s?scope=system" % k, expect_errors=True) self.assertEqual(resp.status_code, http_client.FORBIDDEN)
def setUp(self): super(ActionControllerRBACTestCase, self).setUp() self.models = self.fixtures_loader.save_fixtures_to_db( fixtures_pack=FIXTURES_PACK, fixtures_dict=TEST_FIXTURES) file_name = 'action1.yaml' ActionControllerRBACTestCase.ACTION_1 = self.fixtures_loader.load_fixtures( fixtures_pack=FIXTURES_PACK, fixtures_dict={'actions': [file_name]})['actions'][file_name] # Insert mock users, roles and assignments # Users user_2_db = UserDB(name='action_create') user_2_db = User.add_or_update(user_2_db) self.users['action_create'] = user_2_db # Roles # action_create grant on parent pack grant_db = PermissionGrantDB( resource_uid='pack:examples', resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_CREATE]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_1_db = RoleDB(name='action_create', permission_grants=permission_grants) role_1_db = Role.add_or_update(role_1_db) self.roles['action_create'] = role_1_db # Role assignments user_db = self.users['action_create'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['action_create'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) # creating `action_clone` user with all permissions related to cloning an action user_3_db = UserDB(name="action_clone") user_3_db = User.add_or_update(user_3_db) self.users["action_clone"] = user_3_db # roles of action_clone user grant_db = PermissionGrantDB( resource_uid="pack:clonepack", resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_CREATE]) grant_db = PermissionGrant.add_or_update(grant_db) grant_db_view = PermissionGrantDB( resource_uid="pack:examples", resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_VIEW]) grant_db_view = PermissionGrant.add_or_update(grant_db_view) grant_db_create = PermissionGrantDB( resource_uid="pack:examples", resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_CREATE]) grant_db_create = PermissionGrant.add_or_update(grant_db_create) grant_db_delete = PermissionGrantDB( resource_uid="pack:clonepack", resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_DELETE]) grant_db_delete = PermissionGrant.add_or_update(grant_db_delete) permission_grants = [ str(grant_db.id), str(grant_db_view.id), str(grant_db_create.id), str(grant_db_delete.id), ] role_1_db = RoleDB(name="action_clone", permission_grants=permission_grants) role_1_db = Role.add_or_update(role_1_db) self.roles["action_clone"] = role_1_db # role assignments for action_clone user user_db = self.users["action_clone"] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles["action_clone"].name, source="assignments/%s.yaml" % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) # creating `no_create_permission` user with action_view permission on source action # but no create_action permission on destination pack user_2_db = UserDB(name="no_create_permission") user_2_db = User.add_or_update(user_2_db) self.users["no_create_permission"] = user_2_db # roles of no_create_permission user grant_db = PermissionGrantDB( resource_uid="pack:examples", resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_VIEW]) grant_db = PermissionGrant.add_or_update(grant_db) grant_db_delete = PermissionGrantDB( resource_uid="pack:clonepack", resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_DELETE]) grant_db_delete = PermissionGrant.add_or_update(grant_db_delete) permission_grants = [str(grant_db.id), str(grant_db_delete.id)] role_1_db = RoleDB(name="no_create_permission", permission_grants=permission_grants) role_1_db = Role.add_or_update(role_1_db) self.roles["no_create_permission"] = role_1_db # role assignments for no_create_permission user user_db = self.users["no_create_permission"] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles["no_create_permission"].name, source="assignments/%s.yaml" % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) # creating `no_delete_permission` user with action_view permission on source action, # action_create on destination pack but no create_delete permission on destination pack user_2_db = UserDB(name="no_delete_permission") user_2_db = User.add_or_update(user_2_db) self.users["no_delete_permission"] = user_2_db # roles of no_delete_permission user grant_db_view = PermissionGrantDB( resource_uid="pack:examples", resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_VIEW]) grant_db_view = PermissionGrant.add_or_update(grant_db_view) grant_db_create = PermissionGrantDB( resource_uid="pack:clonepack", resource_type=ResourceType.PACK, permission_types=[PermissionType.ACTION_CREATE]) grant_db_create = PermissionGrant.add_or_update(grant_db_create) permission_grants = [str(grant_db_view.id), str(grant_db_create.id)] role_1_db = RoleDB(name="no_delete_permission", permission_grants=permission_grants) role_1_db = Role.add_or_update(role_1_db) self.roles["no_delete_permission"] = role_1_db # role assignments for no_delete_permission user user_db = self.users["no_delete_permission"] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles["no_delete_permission"].name, source="assignments/%s.yaml" % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db)
def setUp(self): super(KeyValueSystemScopeControllerRBACTestCase, self).setUp() # Insert system scoped key value pairs. kvp_1_api = KeyValuePairSetAPI( uid="%s:%s:key1" % (ResourceType.KEY_VALUE_PAIR, FULL_SYSTEM_SCOPE), scope=FULL_SYSTEM_SCOPE, name="key1", value="val1", secret=True, ) kvp_1_db = KeyValuePairSetAPI.to_model(kvp_1_api) kvp_1_db = KeyValuePair.add_or_update(kvp_1_db) self.resources[kvp_1_db.uid] = kvp_1_db kvp_2_api = KeyValuePairSetAPI( uid="%s:%s:key2" % (ResourceType.KEY_VALUE_PAIR, FULL_SYSTEM_SCOPE), scope=FULL_SYSTEM_SCOPE, name="key2", value="val2", secret=True, ) kvp_2_db = KeyValuePairSetAPI.to_model(kvp_2_api) kvp_2_db = KeyValuePair.add_or_update(kvp_2_db) self.resources[kvp_2_db.uid] = kvp_2_db # Setup users for user scoped KVPs. user_1_db = UserDB(name="user101") user_1_db = User.add_or_update(user_1_db) self.users[user_1_db.name] = user_1_db user_2_db = UserDB(name="user102") user_2_db = User.add_or_update(user_2_db) self.users[user_2_db.name] = user_2_db # Insert user scoped key value pairs for user1. key_1_name = "mykey1" key_1_ref = get_key_reference(FULL_USER_SCOPE, key_1_name, user_1_db.name) kvp_1_db = KeyValuePairDB( uid="%s:%s:%s" % (ResourceType.KEY_VALUE_PAIR, FULL_USER_SCOPE, key_1_ref), scope=FULL_USER_SCOPE, name=key_1_ref, value="myval1", ) kvp_1_db = KeyValuePair.add_or_update(kvp_1_db) self.resources[kvp_1_db.uid] = kvp_1_db key_2_name = "mykey2" key_2_ref = get_key_reference(FULL_USER_SCOPE, key_2_name, user_1_db.name) kvp_2_db = KeyValuePairDB( uid="%s:%s:%s" % (ResourceType.KEY_VALUE_PAIR, FULL_USER_SCOPE, key_2_ref), scope=FULL_USER_SCOPE, name=key_2_ref, value="myval2", ) kvp_2_db = KeyValuePair.add_or_update(kvp_2_db) self.resources[kvp_2_db.uid] = kvp_2_db
def put(self, id, liveaction_api, requester_user, show_secrets=False): """ Updates a single execution. Handles requests: PUT /executions/<id> """ if not requester_user: requester_user = UserDB(cfg.CONF.system_user.user) from_model_kwargs = { 'mask_secrets': self._get_mask_secrets(requester_user, show_secrets=show_secrets) } execution_api = self._get_one_by_id( id=id, requester_user=requester_user, from_model_kwargs=from_model_kwargs, permission_type=PermissionType.EXECUTION_STOP) if not execution_api: abort(http_client.NOT_FOUND, 'Execution with id %s not found.' % id) liveaction_id = execution_api.liveaction['id'] if not liveaction_id: abort( http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) try: liveaction_db = LiveAction.get_by_id(liveaction_id) except: abort( http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) if liveaction_db.status in action_constants.LIVEACTION_COMPLETED_STATES: abort(http_client.BAD_REQUEST, 'Execution is already in completed state.') if (getattr(liveaction_api, 'result', None) is not None and liveaction_api.status in [ action_constants.LIVEACTION_STATUS_PAUSING, action_constants.LIVEACTION_STATUS_PAUSED, action_constants.LIVEACTION_STATUS_RESUMING ]): abort( http_client.BAD_REQUEST, 'The result is not applicable for pausing and resuming execution.' ) try: if (liveaction_api.status == action_constants.LIVEACTION_STATUS_PAUSING or liveaction_api.status == action_constants.LIVEACTION_STATUS_PAUSED): liveaction_db, actionexecution_db = action_service.request_pause( liveaction_db, requester_user.name or cfg.CONF.system_user.user) elif liveaction_api.status == action_constants.LIVEACTION_STATUS_RESUMING: liveaction_db, actionexecution_db = action_service.request_resume( liveaction_db, requester_user.name or cfg.CONF.system_user.user) else: liveaction_db = action_service.update_status( liveaction_db, liveaction_api.status, result=getattr(liveaction_api, 'result', None)) actionexecution_db = ActionExecution.get( liveaction__id=str(liveaction_db.id)) except runner_exc.InvalidActionRunnerOperationError as e: LOG.exception('Failed updating liveaction %s. %s', liveaction_db.id, str(e)) abort(http_client.BAD_REQUEST, 'Failed updating execution. %s' % str(e)) except runner_exc.UnexpectedActionExecutionStatusError as e: LOG.exception('Failed updating liveaction %s. %s', liveaction_db.id, str(e)) abort(http_client.BAD_REQUEST, 'Failed updating execution. %s' % str(e)) except Exception as e: LOG.exception('Failed updating liveaction %s. %s', liveaction_db.id, str(e)) abort(http_client.INTERNAL_SERVER_ERROR, 'Failed updating execution due to unexpected error.') mask_secrets = self._get_mask_secrets(requester_user, show_secrets=show_secrets) execution_api = ActionExecutionAPI.from_model( actionexecution_db, mask_secrets=mask_secrets) return execution_api
def test_user_permissions_for_user_scope_kvps(self): # Insert user scoped key value pairs for user1. user_1_db = UserDB(name="user111") user_1_db = User.add_or_update(user_1_db) self.users[user_1_db.name] = user_1_db key_1_name = "mykey1" key_1_ref = get_key_reference(FULL_USER_SCOPE, key_1_name, user_1_db.name) kvp_1_api = KeyValuePairSetAPI( uid="%s:%s:%s" % (ResourceType.KEY_VALUE_PAIR, FULL_USER_SCOPE, key_1_ref), scope=FULL_USER_SCOPE, name=key_1_ref, value="myval1", secret=True, ) kvp_1_db = KeyValuePairSetAPI.to_model(kvp_1_api) kvp_1_db = KeyValuePair.add_or_update(kvp_1_db) self.resources[kvp_1_db.uid] = kvp_1_db # Insert user scoped key value pairs for user2. user_2_db = UserDB(name="user112") user_2_db = User.add_or_update(user_2_db) self.users[user_2_db.name] = user_2_db key_2_name = "mykey2" key_2_ref = get_key_reference(FULL_USER_SCOPE, key_2_name, user_2_db.name) kvp_2_api = KeyValuePairSetAPI( uid="%s:%s:%s" % (ResourceType.KEY_VALUE_PAIR, FULL_USER_SCOPE, key_2_ref), scope=FULL_USER_SCOPE, name=key_2_ref, value="myval2", secret=True, ) kvp_2_db = KeyValuePairSetAPI.to_model(kvp_2_api) kvp_2_db = KeyValuePair.add_or_update(kvp_2_db) self.resources[kvp_2_db.uid] = kvp_2_db # Set context to user self.use_user(self.users[user_1_db.name]) # User should be able to list the system and user scoped kvps that user has permission to. resp = self.app.get( "/v1/keys?limit=-1") # server defaults no scope to system scope self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 0) resp = self.app.get( "/v1/keys/") # server defaults no scope to system scope self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 0) resp = self.app.get("/v1/keys?scope=all") self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 1) self.assertTrue( all([item["scope"] == FULL_USER_SCOPE for item in resp.json])) resp = self.app.get("/v1/keys?scope=system") self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 0) resp = self.app.get("/v1/keys?scope=user") self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 1) self.assertTrue( all([item["scope"] == FULL_USER_SCOPE for item in resp.json])) # User should have read and write permissions to his/her own kvps. k, v = key_1_name, kvp_1_api.value resp = self.app.get("/v1/keys/%s?decrypt=True&scope=user" % k) self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(resp.json["value"], v) d = { "name": key_1_ref, "value": "value for %s" % k, "scope": FULL_USER_SCOPE, "secret": True, } resp = self.app.put_json("/v1/keys/%s?scope=user" % k, d) self.assertEqual(resp.status_int, http_client.OK) resp = self.app.get("/v1/keys/%s?decrypt=True&scope=user" % k) self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(resp.json["value"], "value for %s" % k) resp = self.app.delete("/v1/keys/%s?scope=user" % k) self.assertEqual(resp.status_code, http_client.NO_CONTENT) resp = self.app.get("/v1/keys/%s?scope=user" % k, expect_errors=True) self.assertEqual(resp.status_int, http_client.NOT_FOUND)
def test_sync_assignments_are_removed_user_doesnt_exist_in_db(self): # Make sure that the assignments for the users which don't exist in the db are correctly # removed syncer = RBACDefinitionsDBSyncer() self._insert_mock_roles() username = '******' # Initial state, no roles user_db = UserDB(name=username) self.assertEqual(len(User.query(name=username)), 0) role_dbs = get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, []) # Do the sync with two roles defined api = UserRoleAssignmentFileFormatAPI( username=user_db.name, roles=['role_1', 'role_2'], file_path='assignments/%s.yaml' % user_db.name) syncer.sync_users_role_assignments(role_assignment_apis=[api]) role_dbs = get_roles_for_user(user_db=user_db) self.assertEqual(len(role_dbs), 2) self.assertEqual(role_dbs[0], self.roles['role_1']) self.assertEqual(role_dbs[1], self.roles['role_2']) # Sync with no roles on disk - existing roles should be removed syncer.sync_users_role_assignments(role_assignment_apis=[]) role_dbs = get_roles_for_user(user_db=user_db) self.assertEqual(len(role_dbs), 0) username = '******' # Initial state, no roles user_db = UserDB(name=username) self.assertEqual(len(User.query(name=username)), 0) role_dbs = get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, []) # Do the sync with three roles defined api = UserRoleAssignmentFileFormatAPI( username=user_db.name, roles=['role_1', 'role_2', 'role_3'], file_path='assignments/%s.yaml' % user_db.name) syncer.sync_users_role_assignments(role_assignment_apis=[api]) role_dbs = get_roles_for_user(user_db=user_db) self.assertEqual(len(role_dbs), 3) self.assertEqual(role_dbs[0], self.roles['role_1']) self.assertEqual(role_dbs[1], self.roles['role_2']) self.assertEqual(role_dbs[2], self.roles['role_3']) role_assignment_dbs = get_role_assignments_for_user(user_db=user_db) self.assertEqual(len(role_assignment_dbs), 3) self.assertEqual(role_assignment_dbs[0].source, 'assignments/%s.yaml' % user_db.name) # Sync with one role on disk - two roles should be removed api = UserRoleAssignmentFileFormatAPI( username=user_db.name, roles=['role_3'], file_path='assignments/%s.yaml' % user_db.name) syncer.sync_users_role_assignments(role_assignment_apis=[api]) role_dbs = get_roles_for_user(user_db=user_db) self.assertEqual(len(role_dbs), 1) self.assertEqual(role_dbs[0], self.roles['role_3'])
def test_user_permissions_for_another_user_kvps(self): # Setup users. user_1_db = UserDB(name="user113") user_1_db = User.add_or_update(user_1_db) self.users[user_1_db.name] = user_1_db user_2_db = UserDB(name="user114") user_2_db = User.add_or_update(user_2_db) self.users[user_2_db.name] = user_2_db # Insert user scoped key value pairs for user1. key_1_name = "mykey3" key_1_ref = get_key_reference(FULL_USER_SCOPE, key_1_name, user_1_db.name) kvp_1_api = KeyValuePairSetAPI( uid="%s:%s:%s" % (ResourceType.KEY_VALUE_PAIR, FULL_USER_SCOPE, key_1_ref), scope=FULL_USER_SCOPE, name=key_1_ref, value="myval3", secret=True, ) kvp_1_db = KeyValuePairSetAPI.to_model(kvp_1_api) kvp_1_db = KeyValuePair.add_or_update(kvp_1_db) self.resources[kvp_1_db.uid] = kvp_1_db # Setup bad grant, role, and assignment records where administrator # accidentally or intentionally try to grant a user's kvps to another user. grant_db = PermissionGrantDB( resource_uid=kvp_1_db.get_uid(), resource_type=ResourceType.KEY_VALUE_PAIR, permission_types=[PermissionType.KEY_VALUE_PAIR_ALL], ) grant_db = PermissionGrant.add_or_update(grant_db) role_db = RoleDB( name="custom_role_user_key3_all_grant", permission_grants=[str(grant_db.id)], ) role_db = Role.add_or_update(role_db) self.roles[role_db.name] = role_db role_assignment_db = UserRoleAssignmentDB( user=user_2_db.name, role=role_db.name, source="assignments/%s.yaml" % user_2_db.name, ) UserRoleAssignment.add_or_update(role_assignment_db) # Set context to user self.use_user(self.users[user_2_db.name]) # User2 should not be able to list user1's kvp. resp = self.app.get( "/v1/keys?limit=-1") # server defaults no scope to system scope self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 0) resp = self.app.get( "/v1/keys/") # server defaults no scope to system scope self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 0) resp = self.app.get("/v1/keys?scope=all") self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 0) resp = self.app.get("/v1/keys?scope=system") self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 0) resp = self.app.get("/v1/keys?scope=user") self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 0) # User2 should not have read and write permissions on user1's kvp. k = key_1_name url = "/v1/keys/%s?scope=user&user=%s" % (k, user_1_db.name) resp = self.app.get(url, expect_errors=True) self.assertEqual(resp.status_int, http_client.FORBIDDEN) d = { "name": key_1_ref, "value": "value for %s" % k, "scope": FULL_USER_SCOPE, "user": user_1_db.name, } resp = self.app.put_json(url, d, expect_errors=True) self.assertEqual(resp.status_int, http_client.FORBIDDEN) resp = self.app.delete(url, expect_errors=True) self.assertEqual(resp.status_code, http_client.FORBIDDEN)
def _schedule_execution( self, liveaction, requester_user, action_db, user=None, context_string=None, show_secrets=False, ): # Initialize execution context if it does not exist. if not hasattr(liveaction, "context"): liveaction.context = dict() liveaction.context["user"] = user liveaction.context["pack"] = action_db.pack LOG.debug("User is: %s" % liveaction.context["user"]) # Retrieve other st2 context from request header. if context_string: context = try_loads(context_string) if not isinstance(context, dict): raise ValueError( "Unable to convert st2-context from the headers into JSON" f" (was {type(context)}).") liveaction.context.update(context) # Include RBAC context (if RBAC is available and enabled) if cfg.CONF.rbac.enable: user_db = UserDB(name=user) rbac_service = get_rbac_backend().get_service_class() role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) roles = [role_db.name for role_db in role_dbs] liveaction.context["rbac"] = {"user": user, "roles": roles} # Schedule the action execution. liveaction_db = LiveActionAPI.to_model(liveaction) runnertype_db = action_utils.get_runnertype_by_name( action_db.runner_type["name"]) try: liveaction_db.parameters = param_utils.render_live_params( runnertype_db.runner_parameters, action_db.parameters, liveaction_db.parameters, liveaction_db.context, ) except param_exc.ParamException: # We still need to create a request, so liveaction_db is assigned an ID liveaction_db, actionexecution_db = action_service.create_request( liveaction=liveaction_db, action_db=action_db, runnertype_db=runnertype_db, ) # By this point the execution is already in the DB therefore need to mark it failed. _, e, tb = sys.exc_info() action_service.update_status( liveaction=liveaction_db, new_status=action_constants.LIVEACTION_STATUS_FAILED, result={ "error": six.text_type(e), "traceback": "".join(traceback.format_tb(tb, 20)), }, ) # Might be a good idea to return the actual ActionExecution rather than bubble up # the exception. raise validation_exc.ValueValidationException(six.text_type(e)) # The request should be created after the above call to render_live_params # so any templates in live parameters have a chance to render. liveaction_db, actionexecution_db = action_service.create_request( liveaction=liveaction_db, action_db=action_db, runnertype_db=runnertype_db) _, actionexecution_db = action_service.publish_request( liveaction_db, actionexecution_db) mask_secrets = self._get_mask_secrets(requester_user, show_secrets=show_secrets) execution_api = ActionExecutionAPI.from_model( actionexecution_db, mask_secrets=mask_secrets) return Response(json=execution_api, status=http_client.CREATED)
def test_admin_permissions_for_user_scoped_kvps(self): # Insert user scoped key value pairs for user1. user_1_db = UserDB(name="user115") user_1_db = User.add_or_update(user_1_db) self.users[user_1_db.name] = user_1_db key_1_name = "mykey5" key_1_ref = get_key_reference(FULL_USER_SCOPE, key_1_name, user_1_db.name) kvp_1_api = KeyValuePairSetAPI( uid="%s:%s:%s" % (ResourceType.KEY_VALUE_PAIR, FULL_USER_SCOPE, key_1_ref), scope=FULL_USER_SCOPE, name=key_1_ref, value="myval5", secret=True, ) kvp_1_db = KeyValuePairSetAPI.to_model(kvp_1_api) kvp_1_db = KeyValuePair.add_or_update(kvp_1_db) self.resources[kvp_1_db.uid] = kvp_1_db # Set context to user self.use_user(self.users["admin"]) # Admin user should have general list permissions on user1's kvps. resp = self.app.get("/v1/keys?limit=-1&scope=user&user=%s" % user_1_db.name) self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 1) resp = self.app.get("/v1/keys?scope=user&user=%s" % user_1_db.name) self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 1) self.assertEqual(resp.json[0]["name"], key_1_name) self.assertEqual(resp.json[0]["user"], user_1_db.name) resp = self.app.get("/v1/keys?decrypt=True&scope=user&user=%s" % user_1_db.name) self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 1) self.assertEqual(resp.json[0]["name"], key_1_name) self.assertEqual(resp.json[0]["user"], user_1_db.name) self.assertEqual(resp.json[0]["value"], kvp_1_api.value) resp = self.app.get("/v1/keys?scope=all") self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 2) self.assertTrue( all([item["scope"] == FULL_SYSTEM_SCOPE for item in resp.json])) resp = self.app.get("/v1/keys?scope=system") self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 2) self.assertTrue( all([item["scope"] == FULL_SYSTEM_SCOPE for item in resp.json])) resp = self.app.get("/v1/keys?scope=user") self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(len(resp.json), 0) # Admin user should have read and write permissions to user1's kvps. k, v = key_1_name, kvp_1_api.value url = "/v1/keys/%s?decrypt=True&scope=user&user=%s" % (k, user_1_db.name) resp = self.app.get(url) self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(resp.json["value"], v) d = { "name": key_1_ref, "value": "value for %s" % k, "scope": FULL_USER_SCOPE, "user": user_1_db.name, "secret": True, } resp = self.app.put_json(url, d) self.assertEqual(resp.status_int, http_client.OK) resp = self.app.get(url) self.assertEqual(resp.status_int, http_client.OK) self.assertEqual(resp.json["value"], "value for %s" % k) resp = self.app.delete(url) self.assertEqual(resp.status_code, http_client.NO_CONTENT) resp = self.app.get(url, expect_errors=True) self.assertEqual(resp.status_int, http_client.NOT_FOUND)
def delete(self, id, requester_user, show_secrets=False): """ Stops a single execution. Handles requests: DELETE /executions/<id> """ if not requester_user: requester_user = UserDB(cfg.CONF.system_user.user) from_model_kwargs = { "mask_secrets": self._get_mask_secrets(requester_user, show_secrets=show_secrets) } execution_api = self._get_one_by_id( id=id, requester_user=requester_user, from_model_kwargs=from_model_kwargs, permission_type=PermissionType.EXECUTION_STOP, ) if not execution_api: abort(http_client.NOT_FOUND, "Execution with id %s not found." % id) liveaction_id = execution_api.liveaction["id"] if not liveaction_id: abort( http_client.INTERNAL_SERVER_ERROR, "Execution object missing link to liveaction %s." % liveaction_id, ) try: liveaction_db = LiveAction.get_by_id(liveaction_id) except: abort( http_client.INTERNAL_SERVER_ERROR, "Execution object missing link to liveaction %s." % liveaction_id, ) if liveaction_db.status == action_constants.LIVEACTION_STATUS_CANCELED: LOG.info('Action %s already in "canceled" state; \ returning execution object.' % liveaction_db.id) return execution_api if liveaction_db.status not in action_constants.LIVEACTION_CANCELABLE_STATES: abort( http_client.OK, "Action cannot be canceled. State = %s." % liveaction_db.status, ) try: (liveaction_db, execution_db) = action_service.request_cancellation( liveaction_db, requester_user.name or cfg.CONF.system_user.user) except: LOG.exception("Failed requesting cancellation for liveaction %s.", liveaction_db.id) abort(http_client.INTERNAL_SERVER_ERROR, "Failed canceling execution.") return ActionExecutionAPI.from_model( execution_db, mask_secrets=from_model_kwargs["mask_secrets"])
def setUp(self): super(RulePermissionsResolverTestCase, self).setUp() # Register internal triggers - this is needed so we can reference an internal trigger # inside a mock rule register_internal_trigger_types() # Create some mock users user_1_db = UserDB(name='1_role_rule_pack_grant') user_1_db = User.add_or_update(user_1_db) self.users['custom_role_rule_pack_grant'] = user_1_db user_2_db = UserDB(name='1_role_rule_grant') user_2_db = User.add_or_update(user_2_db) self.users['custom_role_rule_grant'] = user_2_db user_3_db = UserDB(name='custom_role_pack_rule_all_grant') user_3_db = User.add_or_update(user_3_db) self.users['custom_role_pack_rule_all_grant'] = user_3_db user_4_db = UserDB(name='custom_role_rule_all_grant') user_4_db = User.add_or_update(user_4_db) self.users['custom_role_rule_all_grant'] = user_4_db user_5_db = UserDB(name='custom_role_rule_modify_grant') user_5_db = User.add_or_update(user_5_db) self.users['custom_role_rule_modify_grant'] = user_5_db user_6_db = UserDB(name='rule_pack_rule_create_grant') user_6_db = User.add_or_update(user_6_db) self.users['rule_pack_rule_create_grant'] = user_6_db user_7_db = UserDB(name='rule_pack_rule_all_grant') user_7_db = User.add_or_update(user_7_db) self.users['rule_pack_rule_all_grant'] = user_7_db user_8_db = UserDB(name='rule_rule_create_grant') user_8_db = User.add_or_update(user_8_db) self.users['rule_rule_create_grant'] = user_8_db user_9_db = UserDB(name='rule_rule_all_grant') user_9_db = User.add_or_update(user_9_db) self.users['rule_rule_all_grant'] = user_9_db user_10_db = UserDB(name='custom_role_rule_list_grant') user_10_db = User.add_or_update(user_10_db) self.users['custom_role_rule_list_grant'] = user_10_db # Create some mock resources on which permissions can be granted rule_1_db = RuleDB(pack='test_pack_1', name='rule1', action={'ref': 'core.local'}, trigger='core.st2.key_value_pair.create') rule_1_db = Rule.add_or_update(rule_1_db) self.resources['rule_1'] = rule_1_db rule_2_db = RuleDB(pack='test_pack_1', name='rule2') rule_2_db = Rule.add_or_update(rule_2_db) self.resources['rule_2'] = rule_2_db rule_3_db = RuleDB(pack='test_pack_2', name='rule3') rule_3_db = Rule.add_or_update(rule_3_db) self.resources['rule_3'] = rule_3_db # Create some mock roles with associated permission grants # Custom role 2 - one grant on parent pack # "rule_view" on pack_1 grant_db = PermissionGrantDB( resource_uid=self.resources['pack_1'].get_uid(), resource_type=ResourceType.PACK, permission_types=[PermissionType.RULE_VIEW]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_3_db = RoleDB(name='custom_role_rule_pack_grant', permission_grants=permission_grants) role_3_db = Role.add_or_update(role_3_db) self.roles['custom_role_rule_pack_grant'] = role_3_db # Custom role 4 - one grant on rule # "rule_view on rule_3 grant_db = PermissionGrantDB( resource_uid=self.resources['rule_3'].get_uid(), resource_type=ResourceType.RULE, permission_types=[PermissionType.RULE_VIEW]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_4_db = RoleDB(name='custom_role_rule_grant', permission_grants=permission_grants) role_4_db = Role.add_or_update(role_4_db) self.roles['custom_role_rule_grant'] = role_4_db # Custom role - "rule_all" grant on a parent rule pack grant_db = PermissionGrantDB( resource_uid=self.resources['pack_1'].get_uid(), resource_type=ResourceType.PACK, permission_types=[PermissionType.RULE_ALL]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_4_db = RoleDB(name='custom_role_pack_rule_all_grant', permission_grants=permission_grants) role_4_db = Role.add_or_update(role_4_db) self.roles['custom_role_pack_rule_all_grant'] = role_4_db # Custom role - "rule_all" grant on a rule grant_db = PermissionGrantDB( resource_uid=self.resources['rule_1'].get_uid(), resource_type=ResourceType.RULE, permission_types=[PermissionType.RULE_ALL]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_4_db = RoleDB(name='custom_role_rule_all_grant', permission_grants=permission_grants) role_4_db = Role.add_or_update(role_4_db) self.roles['custom_role_rule_all_grant'] = role_4_db # Custom role - "rule_modify" on role_1 grant_db = PermissionGrantDB( resource_uid=self.resources['rule_1'].get_uid(), resource_type=ResourceType.RULE, permission_types=[PermissionType.RULE_MODIFY]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_5_db = RoleDB(name='custom_role_rule_modify_grant', permission_grants=permission_grants) role_5_db = Role.add_or_update(role_5_db) self.roles['custom_role_rule_modify_grant'] = role_5_db # Custom role - "rule_create" grant on pack_1 grant_db = PermissionGrantDB( resource_uid=self.resources['pack_1'].get_uid(), resource_type=ResourceType.PACK, permission_types=[PermissionType.RULE_CREATE]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_6_db = RoleDB(name='rule_pack_rule_create_grant', permission_grants=permission_grants) role_6_db = Role.add_or_update(role_6_db) self.roles['rule_pack_rule_create_grant'] = role_6_db # Custom role - "rule_all" grant on pack_1 grant_db = PermissionGrantDB( resource_uid=self.resources['pack_1'].get_uid(), resource_type=ResourceType.PACK, permission_types=[PermissionType.RULE_ALL]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_7_db = RoleDB(name='rule_pack_rule_all_grant', permission_grants=permission_grants) role_7_db = Role.add_or_update(role_7_db) self.roles['rule_pack_rule_all_grant'] = role_7_db # Custom role - "rule_create" grant on rule_1 grant_db = PermissionGrantDB( resource_uid=self.resources['rule_1'].get_uid(), resource_type=ResourceType.RULE, permission_types=[PermissionType.RULE_CREATE]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_8_db = RoleDB(name='rule_rule_create_grant', permission_grants=permission_grants) role_8_db = Role.add_or_update(role_8_db) self.roles['rule_rule_create_grant'] = role_8_db # Custom role - "rule_all" grant on rule_1 grant_db = PermissionGrantDB( resource_uid=self.resources['rule_1'].get_uid(), resource_type=ResourceType.RULE, permission_types=[PermissionType.RULE_ALL]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_9_db = RoleDB(name='rule_rule_all_grant', permission_grants=permission_grants) role_9_db = Role.add_or_update(role_9_db) self.roles['rule_rule_all_grant'] = role_9_db # Custom role - "rule_list" grant grant_db = PermissionGrantDB( resource_uid=None, resource_type=None, permission_types=[PermissionType.RULE_LIST]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_10_db = RoleDB(name='custom_role_rule_list_grant', permission_grants=permission_grants) role_10_db = Role.add_or_update(role_10_db) self.roles['custom_role_rule_list_grant'] = role_10_db # Create some mock role assignments user_db = self.users['custom_role_rule_pack_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_rule_pack_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_rule_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_rule_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_pack_rule_all_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_pack_rule_all_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_rule_all_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_rule_all_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_rule_modify_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_rule_modify_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['rule_pack_rule_create_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['rule_pack_rule_create_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['rule_pack_rule_all_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['rule_pack_rule_all_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['rule_rule_create_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['rule_rule_create_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['rule_rule_all_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['rule_rule_all_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_rule_list_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_rule_list_grant'].name) UserRoleAssignment.add_or_update(role_assignment_db)
def setUp(self): super(InquiryPermissionsResolverTestCase, self).setUp() # Create some mock users user_1_db = UserDB(name='custom_role_inquiry_list_grant') user_1_db = User.add_or_update(user_1_db) self.users['custom_role_inquiry_list_grant'] = user_1_db user_2_db = UserDB(name='custom_role_inquiry_view_grant') user_2_db = User.add_or_update(user_2_db) self.users['custom_role_inquiry_view_grant'] = user_2_db user_3_db = UserDB(name='custom_role_inquiry_respond_grant') user_3_db = User.add_or_update(user_3_db) self.users['custom_role_inquiry_respond_grant'] = user_3_db user_4_db = UserDB(name='custom_role_inquiry_all_grant') user_4_db = User.add_or_update(user_4_db) self.users['custom_role_inquiry_all_grant'] = user_4_db user_5_db = UserDB(name='custom_role_inquiry_inherit') user_5_db = User.add_or_update(user_5_db) self.users['custom_role_inquiry_inherit'] = user_5_db # Create a workflow for testing inheritance of action_execute permission # to inquiry_respond permission wf_db = ActionDB(pack='examples', name='mistral-ask-basic', entry_point='', runner_type={'name': 'mistral-v2'}) wf_db = Action.add_or_update(wf_db) self.resources['wf'] = wf_db runner = {'name': 'mistral-v2'} liveaction = {'action': 'examples.mistral-ask-basic'} status = action_constants.LIVEACTION_STATUS_PAUSED # Spawn workflow action = {'uid': wf_db.get_uid(), 'pack': 'examples'} wf_exc_db = ActionExecutionDB(action=action, runner=runner, liveaction=liveaction, status=status) wf_exc_db = ActionExecution.add_or_update(wf_exc_db) # Create an Inquiry on which permissions can be granted action_1_db = ActionDB(pack='core', name='ask', entry_point='', runner_type={'name': 'inquirer'}) action_1_db = Action.add_or_update(action_1_db) self.resources['action_1'] = action_1_db runner = {'name': 'inquirer'} liveaction = {'action': 'core.ask'} status = action_constants.LIVEACTION_STATUS_PENDING # For now, Inquiries are "borrowing" the ActionExecutionDB model, # so we have to test with that model action = {'uid': action_1_db.get_uid(), 'pack': 'core'} inquiry_1_db = ActionExecutionDB(action=action, runner=runner, liveaction=liveaction, status=status) # A separate inquiry that has a parent (so we can test workflow permission inheritance) inquiry_2_db = ActionExecutionDB(action=action, runner=runner, liveaction=liveaction, status=status, parent=str(wf_exc_db.id)) # A bit gross, but it's what we have to do since Inquiries # don't yet have their own data model def get_uid(): return "inquiry" inquiry_1_db.get_uid = get_uid inquiry_2_db.get_uid = get_uid inquiry_1_db = ActionExecution.add_or_update(inquiry_1_db) inquiry_2_db = ActionExecution.add_or_update(inquiry_2_db) self.resources['inquiry_1'] = inquiry_1_db self.resources['inquiry_2'] = inquiry_2_db ############################################################ # Create some mock roles with associated permission grants # ############################################################ # Custom role - "inquiry_list" grant grant_db = PermissionGrantDB(resource_uid=self.resources['inquiry_1'].get_uid(), resource_type=ResourceType.INQUIRY, permission_types=[PermissionType.INQUIRY_LIST]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_db = RoleDB(name='custom_role_inquiry_list_grant', permission_grants=permission_grants) role_db = Role.add_or_update(role_db) self.roles['custom_role_inquiry_list_grant'] = role_db # Custom role - "inquiry_view" grant grant_db = PermissionGrantDB(resource_uid=self.resources['inquiry_1'].get_uid(), resource_type=ResourceType.INQUIRY, permission_types=[PermissionType.INQUIRY_VIEW]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_db = RoleDB(name='custom_role_inquiry_view_grant', permission_grants=permission_grants) role_db = Role.add_or_update(role_db) self.roles['custom_role_inquiry_view_grant'] = role_db # Custom role - "inquiry_respond" grant grant_db = PermissionGrantDB(resource_uid=self.resources['inquiry_1'].get_uid(), resource_type=ResourceType.INQUIRY, permission_types=[PermissionType.INQUIRY_RESPOND]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_db = RoleDB(name='custom_role_inquiry_respond_grant', permission_grants=permission_grants) role_db = Role.add_or_update(role_db) self.roles['custom_role_inquiry_respond_grant'] = role_db # Custom role - "inquiry_all" grant grant_db = PermissionGrantDB(resource_uid=self.resources['inquiry_1'].get_uid(), resource_type=ResourceType.INQUIRY, permission_types=[PermissionType.INQUIRY_ALL]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_db = RoleDB(name='custom_role_inquiry_all_grant', permission_grants=permission_grants) role_db = Role.add_or_update(role_db) self.roles['custom_role_inquiry_all_grant'] = role_db # Custom role - inheritance grant grant_db = PermissionGrantDB(resource_uid=self.resources['wf'].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_db = RoleDB(name='custom_role_inquiry_inherit', permission_grants=permission_grants) role_db = Role.add_or_update(role_db) self.roles['custom_role_inquiry_inherit'] = role_db ##################################### # Create some mock role assignments # ##################################### user_db = self.users['custom_role_inquiry_list_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_inquiry_list_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_inquiry_view_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_inquiry_view_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_inquiry_respond_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_inquiry_respond_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_inquiry_all_grant'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_inquiry_all_grant'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db) user_db = self.users['custom_role_inquiry_inherit'] role_assignment_db = UserRoleAssignmentDB( user=user_db.name, role=self.roles['custom_role_inquiry_inherit'].name, source='assignments/%s.yaml' % user_db.name) UserRoleAssignment.add_or_update(role_assignment_db)
def setUp(self): super(ApiKeyControllerRBACTestCase, self).setUp() self.models = self.fixtures_loader.save_fixtures_to_db( fixtures_pack=FIXTURES_PACK, fixtures_dict=TEST_FIXTURES) file_name = 'apikey1.yaml' ApiKeyControllerRBACTestCase.API_KEY_1 = self.fixtures_loader.load_fixtures( fixtures_pack=FIXTURES_PACK, fixtures_dict={'apikeys': [file_name]})['apikeys'][file_name] file_name = 'apikey2.yaml' ApiKeyControllerRBACTestCase.API_KEY_1 = self.fixtures_loader.load_fixtures( fixtures_pack=FIXTURES_PACK, fixtures_dict={'apikeys': [file_name]})['apikeys'][file_name] # Insert mock users, roles and assignments # Users user_1_db = UserDB(name='api_key_list') user_1_db = User.add_or_update(user_1_db) self.users['api_key_list'] = user_1_db user_2_db = UserDB(name='api_key_view') user_2_db = User.add_or_update(user_2_db) self.users['api_key_view'] = user_2_db user_3_db = UserDB(name='api_key_create') user_3_db = User.add_or_update(user_3_db) self.users['api_key_create'] = user_3_db # Roles # api_key_list grant_db = PermissionGrantDB( resource_uid=None, resource_type=ResourceType.API_KEY, permission_types=[PermissionType.API_KEY_LIST]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_1_db = RoleDB(name='api_key_list', permission_grants=permission_grants) role_1_db = Role.add_or_update(role_1_db) self.roles['api_key_list'] = role_1_db # api_key_view on apikey1 api_key_uid = self.models['apikeys']['apikey1.yaml'].get_uid() grant_db = PermissionGrantDB( resource_uid=api_key_uid, resource_type=ResourceType.API_KEY, permission_types=[PermissionType.API_KEY_VIEW]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_1_db = RoleDB(name='api_key_view', permission_grants=permission_grants) role_1_db = Role.add_or_update(role_1_db) self.roles['api_key_view'] = role_1_db # api_key_list grant_db = PermissionGrantDB( resource_uid=None, resource_type=ResourceType.API_KEY, permission_types=[PermissionType.API_KEY_CREATE]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_1_db = RoleDB(name='api_key_create', permission_grants=permission_grants) role_1_db = Role.add_or_update(role_1_db) self.roles['api_key_create'] = role_1_db # Role assignments role_assignment_db = UserRoleAssignmentDB( user=self.users['api_key_list'].name, role=self.roles['api_key_list'].name, source='assignments/%s.yaml' % self.users['api_key_list'].name) UserRoleAssignment.add_or_update(role_assignment_db) role_assignment_db = UserRoleAssignmentDB( user=self.users['api_key_view'].name, role=self.roles['api_key_view'].name, source='assignments/%s.yaml' % self.users['api_key_view'].name) UserRoleAssignment.add_or_update(role_assignment_db) role_assignment_db = UserRoleAssignmentDB( user=self.users['api_key_create'].name, role=self.roles['api_key_create'].name, source='assignments/%s.yaml' % self.users['api_key_create'].name) UserRoleAssignment.add_or_update(role_assignment_db)