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)
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)
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
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
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)