Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
 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)
Exemplo n.º 4
0
 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)
Exemplo n.º 5
0
    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,
        )
Exemplo n.º 6
0
 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)
Exemplo n.º 7
0
 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)
Exemplo n.º 8
0
    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))
Exemplo n.º 10
0
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"
]