def setUpClass(cls): super(PolicyServiceTestCase, cls).setUpClass() # Register runners runners_registrar.register_runners() # Register common policy types policies_registrar.register_policy_types(st2common) loader = fixtures.FixturesLoader() loader.save_fixtures_to_db(fixtures_pack=PACK, fixtures_dict=TEST_FIXTURES)
def setUp(self): super(RunnersUtilityTests, self).setUp() loader = fixturesloader.FixturesLoader() self.models = loader.save_fixtures_to_db( fixtures_pack=FIXTURES_PACK, fixtures_dict=TEST_FIXTURES ) self.liveaction_db = self.models['liveactions']['liveaction1.yaml'] exe_svc.create_execution_object(self.liveaction_db) self.action_db = action_db_utils.get_action_by_ref(self.liveaction_db.action)
def test_pack_name_missing(self): registrar = actions_registrar.ActionsRegistrar() loader = fixtures_loader.FixturesLoader() action_file = loader.get_fixture_file_path_abs( 'generic', 'actions', 'action_3_pack_missing.json') registrar._register_action('dummy', action_file) action_name = None with open(action_file, 'r') as fd: content = json.load(fd) action_name = str(content['name']) action_db = Action.get_by_name(action_name) self.assertEqual(action_db.pack, 'dummy', 'Content pack must be ' + 'set to dummy') Action.delete(action_db)
def test_pack_name_missing(self): registrar = actions_registrar.ActionsRegistrar() loader = fixtures_loader.FixturesLoader() action_file = loader.get_fixture_file_path_abs( "generic", "actions", "action_3_pack_missing.yaml") registrar._register_action("dummy", action_file) action_name = None with open(action_file, "r") as fd: content = yaml.safe_load(fd) action_name = str(content["name"]) action_db = Action.get_by_name(action_name) expected_msg = "Content pack must be set to dummy" self.assertEqual(action_db.pack, "dummy", expected_msg) Action.delete(action_db)
def test_register_action_invalid_parameter_type_attribute(self): registrar = actions_registrar.ActionsRegistrar() loader = fixtures_loader.FixturesLoader() action_file = loader.get_fixture_file_path_abs( "generic", "actions", "action_invalid_param_type.yaml") expected_msg = "'list' is not valid under any of the given schema" self.assertRaisesRegexp( jsonschema.ValidationError, expected_msg, registrar._register_action, "dummy", action_file, )
def test_action_update(self): registrar = actions_registrar.ActionsRegistrar() loader = fixtures_loader.FixturesLoader() action_file = loader.get_fixture_file_path_abs( 'generic', 'actions', 'action1.json') registrar._register_action('wolfpack', action_file) # try registering again. this should not throw errors. registrar._register_action('wolfpack', action_file) action_name = None with open(action_file, 'r') as fd: content = json.load(fd) action_name = str(content['name']) action_db = Action.get_by_name(action_name) self.assertEqual(action_db.pack, 'wolfpack', 'Content pack must be ' + 'set to wolfpack') Action.delete(action_db)
def test_action_update(self): registrar = actions_registrar.ActionsRegistrar() loader = fixtures_loader.FixturesLoader() action_file = loader.get_fixture_file_path_abs("generic", "actions", "action1.yaml") registrar._register_action("wolfpack", action_file) # try registering again. this should not throw errors. registrar._register_action("wolfpack", action_file) action_name = None with open(action_file, "r") as fd: content = yaml.safe_load(fd) action_name = str(content["name"]) action_db = Action.get_by_name(action_name) expected_msg = "Content pack must be set to wolfpack" self.assertEqual(action_db.pack, "wolfpack", expected_msg) Action.delete(action_db)
def test_register_action_invalid_parameter_name(self): registrar = actions_registrar.ActionsRegistrar() loader = fixtures_loader.FixturesLoader() action_file = loader.get_fixture_file_path_abs( "generic", "actions", "action_invalid_parameter_name.yaml") expected_msg = ( 'Parameter name "action-name" is invalid. Valid characters for ' "parameter name are") self.assertRaisesRegexp( jsonschema.ValidationError, expected_msg, registrar._register_action, "generic", action_file, )
from st2common.models.api.action import ActionAPI, RunnerTypeAPI from st2common.models.db.action import LiveActionDB from st2common.persistence.action import Action, LiveAction from st2common.persistence.runner import RunnerType from st2common.services import executions from st2common.transport.liveaction import LiveActionPublisher from st2common.transport.publishers import CUDPublisher from st2common.util import date as date_utils from st2tests import DbTestCase, fixturesloader from tests.unit.base import MockLiveActionPublisher from st2tests.mocks.runner import MockActionRunner TEST_FIXTURES = {'runners': ['testrunner1.yaml'], 'actions': ['action1.yaml']} PACK = 'generic' LOADER = fixturesloader.FixturesLoader() FIXTURES = LOADER.load_fixtures(fixtures_pack=PACK, fixtures_dict=TEST_FIXTURES) NON_EMPTY_RESULT = 'non-empty' RUN_RESULT = (action_constants.LIVEACTION_STATUS_SUCCEEDED, NON_EMPTY_RESULT, None) @mock.patch.object(MockActionRunner, 'run', mock.MagicMock(return_value=RUN_RESULT)) @mock.patch.object( CUDPublisher, 'publish_update', mock.MagicMock(side_effect=MockLiveActionPublisher.publish_update)) @mock.patch.object( LiveActionPublisher, 'publish_state', mock.MagicMock(side_effect=MockLiveActionPublisher.publish_state))
class InquiryRBACControllerTestCase( APIControllerWithRBACTestCase, BaseInquiryControllerTestCase, APIControllerWithIncludeAndExcludeFilterTestCase): # Attributes used by APIControllerWithIncludeAndExcludeFilterTestCase get_all_path = '/v1/inquiries' controller_cls = InquiriesController include_attribute_field_name = 'ttl' exclude_attribute_field_name = 'ttl' rbac_enabled = True fixtures_loader = fixturesloader.FixturesLoader() @mock.patch.object(action_validator, 'validate_action', mock.MagicMock(return_value=True)) def setUp(self): super(InquiryRBACControllerTestCase, self).setUp() self.models = self.fixtures_loader.save_fixtures_to_db( fixtures_pack=FIXTURES_PACK, fixtures_dict=TEST_FIXTURES) # Insert mock users, roles and assignments assignments = { "user_get_db": { "roles": ["role_get"], "permissions": [rbac_types.PermissionType.INQUIRY_VIEW], "resource_type": rbac_types.ResourceType.INQUIRY, "resource_uid": 'inquiry' }, "user_list_db": { "roles": ["role_list"], "permissions": [rbac_types.PermissionType.INQUIRY_LIST], "resource_type": rbac_types.ResourceType.INQUIRY, "resource_uid": 'inquiry' }, "user_respond_db": { "roles": ["role_respond"], "permissions": [rbac_types.PermissionType.INQUIRY_RESPOND], "resource_type": rbac_types.ResourceType.INQUIRY, "resource_uid": 'inquiry' }, "user_respond_paramtest": { "roles": ["role_respond_2"], "permissions": [rbac_types.PermissionType.INQUIRY_RESPOND], "resource_type": rbac_types.ResourceType.INQUIRY, "resource_uid": 'inquiry' }, "user_respond_inherit": { "roles": ["role_inherit"], "permissions": [rbac_types.PermissionType.ACTION_EXECUTE], "resource_type": rbac_types.ResourceType.ACTION, "resource_uid": 'action:wolfpack:inquiry-workflow' } } # Create users for user in assignments.keys(): user_db = auth_db_models.UserDB(name=user) user_db = auth_db_access.User.add_or_update(user_db) self.users[user] = user_db # Create grants and assign to roles for assignment_details in assignments.values(): grant_db = rbac_db_models.PermissionGrantDB( permission_types=assignment_details["permissions"], resource_uid=assignment_details["resource_uid"], resource_type=assignment_details["resource_type"]) grant_db = rbac_db_access.PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] for role in assignment_details["roles"]: role_db = rbac_db_models.RoleDB( name=role, permission_grants=permission_grants) rbac_db_access.Role.add_or_update(role_db) # Assign users to roles for user_name, assignment_details in assignments.items(): user_db = self.users[user_name] for role in assignment_details['roles']: role_assignment_db = rbac_db_models.UserRoleAssignmentDB( user=user_db.name, role=role, source='assignments/%s.yaml' % user_db.name) rbac_db_access.UserRoleAssignment.add_or_update( role_assignment_db) # Create Inquiry data = { 'action': 'wolfpack.ask', 'parameters': { "roles": ['role_respond'] } } result = { "schema": SCHEMA_DEFAULT, "roles": ['role_respond'], "users": [], "route": "", "ttl": 1440 } result_default = { "schema": SCHEMA_DEFAULT, "roles": [], "users": [], "route": "", "ttl": 1440 } # Use admin user for creating test objects user_db = self.users['admin'] self.use_user(user_db) # Create workflow wf_data = {'action': 'wolfpack.inquiry-workflow'} post_resp = self.app.post_json('/v1/executions', wf_data) wf_id = str(post_resp.json.get('id')) inquiry_with_parent = { 'action': 'wolfpack.ask', # 'parameters': {}, 'context': { "parent": { 'execution_id': wf_id } } } resp = self._do_create_inquiry(data, result) self.assertEqual(resp.status_int, http_client.OK) self.inquiry_id = resp.json.get('id') # Validated expected context for inquiries under RBAC expected_context = { 'pack': 'wolfpack', 'user': '******', 'rbac': { 'user': '******', 'roles': ['admin'] } } self.assertEqual(resp.json['context'], expected_context) # Create inquiry in workflow resp = self._do_create_inquiry(inquiry_with_parent, result_default) self.assertEqual(resp.status_int, http_client.OK) self.inquiry_inherit_id = resp.json.get('id') # Validated expected context for inquiries under RBAC expected_context = { 'pack': 'wolfpack', 'parent': { 'execution_id': wf_id }, 'user': '******', 'rbac': { 'user': '******', 'roles': ['admin'] } } self.assertEqual(resp.json['context'], expected_context) def tearDown(self): super(InquiryRBACControllerTestCase, self).tearDown() def test_get_user(self): """Test API with RBAC inquiry 'get' permissions """ # User with get permissions should succeed self.use_user(self.users['user_get_db']) resp = self._do_get_one(self.inquiry_id) self.assertEqual(resp.status_int, http_client.OK) # User with list permissions should not succeed self.use_user(self.users['user_list_db']) resp = self._do_get_one(self.inquiry_id, expect_errors=True) self.assertEqual(resp.status_int, http_client.FORBIDDEN) def test_list_user(self): """Test API with RBAC inquiry 'list' permissions """ # User with list permissions should succeed self.use_user(self.users['user_list_db']) resp = self._do_get_all() self.assertEqual(resp.status_int, http_client.OK) # User with get permissions should not succeed self.use_user(self.users['user_get_db']) resp = self._do_get_all(expect_errors=True) self.assertEqual(resp.status_int, http_client.FORBIDDEN) def test_respond_user(self): """Test API with RBAC inquiry 'respond' permissions """ response = {'continue': True} # User with list permissions should not succeed self.use_user(self.users['user_list_db']) resp = self._do_respond(self.inquiry_id, response, expect_errors=True) self.assertEqual(resp.status_int, http_client.FORBIDDEN) # User with respond permissions should succeed self.use_user(self.users['user_respond_db']) resp = self._do_respond(self.inquiry_id, response) self.assertEqual(resp.status_int, http_client.OK) def test_inquiry_roles_parameter(self): """Tests per-inquiry permissions enforced outside of RBAC These are permissions enforced by the PUT endpoint itself, based on the "roles" inquirer parameter """ response = {'continue': True} # user_respond_paramtest has the INQUIRY_RESPOND permission, # but does not belong to a role that is in the "roles" parameter # for this Inquiry, so it is blocked. self.use_user(self.users['user_respond_paramtest']) resp = self._do_respond(self.inquiry_id, response, expect_errors=True) self.assertEqual(resp.status_int, http_client.FORBIDDEN) # User with respond permissions should succeed self.use_user(self.users['user_respond_db']) resp = self._do_respond(self.inquiry_id, response) self.assertEqual(resp.status_int, http_client.OK) @mock.patch.object(action_service, 'request_pause', mock.MagicMock(return_value=None)) def test_inquiry_roles_inherit(self): """Tests action_execute -> inquiry_respond permission inheritance Mocked out action_service because, since this inquiry has a parent, a pause will be attempted, and we don't care to test for that here. """ # user_respond_inherit user doesn't have any inquiry permissions at all. # yet, since they are permitted to execute a workflow that contains an inquiry, # the user is still allowed to respond to that inquiry. self.use_user(self.users['user_respond_inherit']) resp = self._do_respond(self.inquiry_inherit_id, {'continue': True}) self.assertEqual(resp.status_int, http_client.OK) def test_get_all_invalid_exclude_and_include_parameter(self): pass def _insert_mock_models(self): return [self.inquiry_id, self.inquiry_inherit_id]
def __init__(self, status=action_constants.LIVEACTION_STATUS_SUCCEEDED, result=""): self.id = None self.status = status self.result = result FIXTURES_PACK = "generic" TEST_MODELS = { "actions": ["a1.yaml", "a2.yaml"], "runners": ["testrunner1.yaml"] } MODELS = fixturesloader.FixturesLoader().load_models( fixtures_pack=FIXTURES_PACK, fixtures_dict=TEST_MODELS) ACTION_1 = MODELS["actions"]["a1.yaml"] ACTION_2 = MODELS["actions"]["a2.yaml"] RUNNER = MODELS["runners"]["testrunner1.yaml"] CHAIN_1_PATH = fixturesloader.FixturesLoader().get_fixture_file_path_abs( FIXTURES_PACK, "actionchains", "chain_with_notifications.yaml") TEST_PACK = "action_chain_tests" TEST_PACK_PATH = fixturesloader.get_fixtures_packs_base_path( ) + "/" + TEST_PACK PACKS = [ TEST_PACK_PATH, fixturesloader.get_fixtures_packs_base_path() + "/core" ]