def validate(self, attrs): if ("type" in attrs) != ("target_type" in attrs) != ("target_identifier" in attrs): raise serializers.ValidationError( "type, targetType and targetIdentifier must be passed together" ) type = attrs.get("type") target_type = attrs.get("target_type") access = self.context["access"] identifier = attrs.get("target_identifier") if type is not None: type_info = AlertRuleTriggerAction.get_registered_type(type) if target_type not in type_info.supported_target_types: allowed_target_types = ",".join( action_target_type_to_string[type_name] for type_name in type_info.supported_target_types ) raise serializers.ValidationError( { "target_type": "Invalid target type for %s. Valid types are [%s]" % (type_info.slug, allowed_target_types) } ) if attrs.get("type") == AlertRuleTriggerAction.Type.EMAIL: if target_type == AlertRuleTriggerAction.TargetType.TEAM: try: team = Team.objects.get(id=identifier) except Team.DoesNotExist: raise serializers.ValidationError("Team does not exist") if not access.has_team(team): raise serializers.ValidationError("Team does not exist") elif target_type == AlertRuleTriggerAction.TargetType.USER: try: user = User.objects.get(id=identifier) except User.DoesNotExist: raise serializers.ValidationError("User does not exist") if not OrganizationMember.objects.filter( organization=self.context["organization"], user=user ).exists(): raise serializers.ValidationError("User does not belong to this organization") elif attrs.get("type") == AlertRuleTriggerAction.Type.SLACK: if not attrs.get("integration"): raise serializers.ValidationError( {"integration": "Integration must be provided for slack"} ) elif attrs.get("type") == AlertRuleTriggerAction.Type.SENTRY_APP: if not attrs.get("sentry_app"): raise serializers.ValidationError( {"sentry_app": "SentryApp must be provided for sentry_app"} ) attrs["use_async_lookup"] = self.context.get("use_async_lookup") attrs["input_channel_id"] = self.context.get("input_channel_id") should_validate_channel_id = self.context.get("validate_channel_id", True) # validate_channel_id is assumed to be true unless explicitly passed as false if attrs["input_channel_id"] and should_validate_channel_id: validate_channel_id(identifier, attrs["integration"].id, attrs["input_channel_id"]) return attrs
def validate(self, attrs): if ("type" in attrs) != ("target_type" in attrs) != ("target_identifier" in attrs): raise serializers.ValidationError( "type, targetType and targetIdentifier must be passed together" ) type = attrs.get("type") target_type = attrs.get("target_type") access = self.context["access"] identifier = attrs.get("target_identifier") if type is not None: type_info = AlertRuleTriggerAction.get_registered_type(type) if target_type not in type_info.supported_target_types: allowed_target_types = ",".join( ACTION_TARGET_TYPE_TO_STRING[type_name] for type_name in type_info.supported_target_types) raise serializers.ValidationError({ "target_type": "Invalid target type for %s. Valid types are [%s]" % (type_info.slug, allowed_target_types) }) if attrs.get("type") == AlertRuleTriggerAction.Type.EMAIL: if target_type == AlertRuleTriggerAction.TargetType.TEAM: try: team = Team.objects.get(id=identifier) except Team.DoesNotExist: raise serializers.ValidationError("Team does not exist") if not access.has_team(team): raise serializers.ValidationError("Team does not exist") elif target_type == AlertRuleTriggerAction.TargetType.USER: try: user = User.objects.get(id=identifier) except User.DoesNotExist: raise serializers.ValidationError("User does not exist") if not OrganizationMember.objects.filter( organization=self.context["organization"], user=user).exists(): raise serializers.ValidationError( "User does not belong to this organization") elif attrs.get("type") == AlertRuleTriggerAction.Type.SLACK: if not attrs.get("integration"): raise serializers.ValidationError( {"integration": "Integration must be provided for slack"}) elif attrs.get("type") == AlertRuleTriggerAction.Type.SENTRY_APP: if not attrs.get("sentry_app"): raise serializers.ValidationError({ "sentry_app": "SentryApp must be provided for sentry_app" }) if attrs.get("sentry_app_config"): if attrs.get("sentry_app_installation_uuid") is None: raise serializers.ValidationError({ "sentry_app": "Missing parameter: sentry_app_installation_uuid" }) try: install = SentryAppInstallation.objects.get( uuid=attrs.get("sentry_app_installation_uuid")) except SentryAppInstallation.DoesNotExist: raise serializers.ValidationError( {"sentry_app": "The installation does not exist."}) # Check response from creator and bubble up errors from providers as a ValidationError result = alert_rule_actions.AlertRuleActionCreator.run( install=install, fields=attrs.get("sentry_app_config"), ) if not result["success"]: raise serializers.ValidationError( {"sentry_app": result["message"]}) del attrs["sentry_app_installation_uuid"] attrs["use_async_lookup"] = self.context.get("use_async_lookup") attrs["input_channel_id"] = self.context.get("input_channel_id") should_validate_channel_id = self.context.get("validate_channel_id", True) # validate_channel_id is assumed to be true unless explicitly passed as false if attrs["input_channel_id"] and should_validate_channel_id: validate_channel_id(identifier, attrs["integration"].id, attrs["input_channel_id"]) return attrs