Ejemplo n.º 1
0
    def post(self, hook, webhook_body_api, headers, requester_user):
        body = webhook_body_api.data

        permission_type = PermissionType.WEBHOOK_SEND
        rbac_utils = get_rbac_backend().get_utils_class()
        rbac_utils.assert_user_has_resource_db_permission(
            user_db=requester_user,
            resource_db=WebhookDB(name=hook),
            permission_type=permission_type)

        headers = self._get_headers_as_dict(headers)

        # If webhook contains a trace-tag use that else create create a unique trace-tag.
        trace_context = self._create_trace_context(trace_tag=headers.pop(
            TRACE_TAG_HEADER, None),
                                                   hook=hook)

        if hook == 'st2' or hook == 'st2/':
            # When using st2 or system webhook, body needs to always be a dict
            if not isinstance(body, dict):
                type_string = get_json_type_for_python_value(body)
                msg = ('Webhook body needs to be an object, got: %s' %
                       (type_string))
                raise ValueError(msg)

            trigger = body.get('trigger', None)
            payload = body.get('payload', None)

            if not trigger:
                msg = 'Trigger not specified.'
                return abort(http_client.BAD_REQUEST, msg)

            self._trigger_dispatcher_service.dispatch_with_context(
                trigger=trigger,
                payload=payload,
                trace_context=trace_context,
                throw_on_validation_error=True)
        else:
            if not self._is_valid_hook(hook):
                self._log_request('Invalid hook.', headers, body)
                msg = 'Webhook %s not registered with st2' % hook
                return abort(http_client.NOT_FOUND, msg)

            triggers = self._hooks.get_triggers_for_hook(hook)
            payload = {}

            payload['headers'] = headers
            payload['body'] = body

            # Dispatch trigger instance for each of the trigger found
            for trigger_dict in triggers:
                # TODO: Instead of dispatching the whole dict we should just
                # dispatch TriggerDB.ref or similar
                self._trigger_dispatcher_service.dispatch_with_context(
                    trigger=trigger_dict,
                    payload=payload,
                    trace_context=trace_context,
                    throw_on_validation_error=True)

        return Response(json=body, status=http_client.ACCEPTED)
Ejemplo n.º 2
0
    def post(self, hook, webhook_body_api, headers, requester_user):
        body = webhook_body_api.data

        permission_type = PermissionType.WEBHOOK_SEND
        rbac_utils = get_rbac_backend().get_utils_class()
        rbac_utils.assert_user_has_resource_db_permission(user_db=requester_user,
                                                          resource_db=WebhookDB(name=hook),
                                                          permission_type=permission_type)

        headers = self._get_headers_as_dict(headers)

        # If webhook contains a trace-tag use that else create create a unique trace-tag.
        trace_context = self._create_trace_context(trace_tag=headers.pop(TRACE_TAG_HEADER, None),
                                                   hook=hook)

        if hook == 'st2' or hook == 'st2/':
            # When using st2 or system webhook, body needs to always be a dict
            if not isinstance(body, dict):
                type_string = get_json_type_for_python_value(body)
                msg = ('Webhook body needs to be an object, got: %s' % (type_string))
                raise ValueError(msg)

            trigger = body.get('trigger', None)
            payload = body.get('payload', None)

            if not trigger:
                msg = 'Trigger not specified.'
                return abort(http_client.BAD_REQUEST, msg)

            self._trigger_dispatcher_service.dispatch_with_context(trigger=trigger,
                   payload=payload,
                   trace_context=trace_context,
                   throw_on_validation_error=True)
        else:
            if not self._is_valid_hook(hook):
                self._log_request('Invalid hook.', headers, body)
                msg = 'Webhook %s not registered with st2' % hook
                return abort(http_client.NOT_FOUND, msg)

            triggers = self._hooks.get_triggers_for_hook(hook)
            payload = {}

            payload['headers'] = headers
            payload['body'] = body

            # Dispatch trigger instance for each of the trigger found
            for trigger_dict in triggers:
                # TODO: Instead of dispatching the whole dict we should just
                # dispatch TriggerDB.ref or similar
                self._trigger_dispatcher_service.dispatch_with_context(trigger=trigger_dict,
                   payload=payload,
                   trace_context=trace_context,
                   throw_on_validation_error=True)

        return Response(json=body, status=http_client.ACCEPTED)
Ejemplo n.º 3
0
    def _get_model_instance(self, model_cls, data):
        try:
            instance = model_cls(**data)
        except TypeError as e:
            # Throw a more user-friendly exception when input data is not an object
            if 'type object argument after ** must be a mapping, not' in str(e):
                type_string = get_json_type_for_python_value(data)
                msg = ('Input body needs to be an object, got: %s' % (type_string))
                raise ValueError(msg)

            raise e

        return instance
Ejemplo n.º 4
0
    def _get_model_instance(self, model_cls, data):
        try:
            instance = model_cls(**data)
        except TypeError as e:
            # Throw a more user-friendly exception when input data is not an object
            if 'type object argument after ** must be a mapping, not' in str(e):
                type_string = get_json_type_for_python_value(data)
                msg = ('Input body needs to be an object, got: %s' % (type_string))
                raise ValueError(msg)

            raise e

        return instance
Ejemplo n.º 5
0
    def post(self, hook, webhook_body_api, headers, requester_user):
        body = webhook_body_api.data

        permission_type = PermissionType.WEBHOOK_SEND
        rbac_utils = get_rbac_backend().get_utils_class()
        rbac_utils.assert_user_has_resource_db_permission(
            user_db=requester_user,
            resource_db=WebhookDB(name=hook),
            permission_type=permission_type,
        )

        headers = self._get_headers_as_dict(headers)
        headers = self._filter_authentication_headers(headers)

        # If webhook contains a trace-tag use that else create create a unique trace-tag.
        trace_context = self._create_trace_context(
            trace_tag=headers.pop(TRACE_TAG_HEADER, None), hook=hook
        )

        if hook == "st2" or hook == "st2/":
            # When using st2 or system webhook, body needs to always be a dict
            if not isinstance(body, dict):
                type_string = get_json_type_for_python_value(body)
                msg = "Webhook body needs to be an object, got: %s" % (type_string)
                raise ValueError(msg)

            trigger = body.get("trigger", None)
            payload = body.get("payload", None)

            if not trigger:
                msg = "Trigger not specified."
                return abort(http_client.BAD_REQUEST, msg)

            self._trigger_dispatcher_service.dispatch_with_context(
                trigger=trigger,
                payload=payload,
                trace_context=trace_context,
                throw_on_validation_error=True,
            )
        else:
            if not self._is_valid_hook(hook):
                self._log_request("Invalid hook.", headers, body)
                msg = "Webhook %s not registered with st2" % hook
                return abort(http_client.NOT_FOUND, msg)

            triggers = self._hooks.get_triggers_for_hook(hook)
            payload = {}

            payload["headers"] = headers
            payload["body"] = body

            # Dispatch trigger instance for each of the trigger found
            for trigger_dict in triggers:
                # TODO: Instead of dispatching the whole dict we should just
                # dispatch TriggerDB.ref or similar
                self._trigger_dispatcher_service.dispatch_with_context(
                    trigger=trigger_dict,
                    payload=payload,
                    trace_context=trace_context,
                    throw_on_validation_error=True,
                )

        # NOTE: For url encoded request bodies, values will be bytes instead of unicode and this
        # doesn't work with orjson so we first need to "cast" all the values from bytes to unicode

        return Response(json=body, status=http_client.ACCEPTED)