# What this PR does This PR, overrides Django URLValidator with a CustomURLValidator. It just removes tld_re part from the regex, and the other behaviour remains the same. The CustomURLValidator is defined in common.api_helpers.utils.py file and is utilized in custom_button.py. Please inform me if it needs to be defined somewhere else or be implemented with some other methods. ## Which issue(s) this PR fixes Currently, URLValidator raises exception for URLs that don't have TLD. This leads to not being able to use containers URL for outgoing webhooks as they usually don't have TLD. ## Checklist - [x] Tests updated - [ ] Documentation added - [x] `CHANGELOG.md` updated --------- Co-authored-by: Joey Orlando <joey.orlando@grafana.com> Co-authored-by: Innokentii Konstantinov <innokenty.konstantinov@grafana.com> Co-authored-by: Joey Orlando <joseph.t.orlando@gmail.com>
71 lines
2.6 KiB
Python
71 lines
2.6 KiB
Python
from collections import defaultdict
|
|
|
|
from django.core.validators import URLValidator, ValidationError
|
|
from rest_framework import serializers
|
|
from rest_framework.validators import UniqueTogetherValidator
|
|
|
|
from apps.alerts.models import CustomButton
|
|
from apps.base.utils import live_settings
|
|
from common.api_helpers.custom_fields import TeamPrimaryKeyRelatedField
|
|
from common.api_helpers.utils import CurrentOrganizationDefault, CurrentTeamDefault, URLValidatorWithoutTLD
|
|
from common.jinja_templater import apply_jinja_template
|
|
from common.jinja_templater.apply_jinja_template import JinjaTemplateError, JinjaTemplateWarning
|
|
|
|
|
|
class CustomButtonSerializer(serializers.ModelSerializer):
|
|
id = serializers.CharField(read_only=True, source="public_primary_key")
|
|
organization = serializers.HiddenField(default=CurrentOrganizationDefault())
|
|
team = TeamPrimaryKeyRelatedField(allow_null=True, default=CurrentTeamDefault())
|
|
forward_whole_payload = serializers.BooleanField(allow_null=True, required=False)
|
|
|
|
class Meta:
|
|
model = CustomButton
|
|
fields = [
|
|
"id",
|
|
"name",
|
|
"team",
|
|
"webhook",
|
|
"data",
|
|
"user",
|
|
"password",
|
|
"authorization_header",
|
|
"organization",
|
|
"forward_whole_payload",
|
|
]
|
|
extra_kwargs = {
|
|
"name": {"required": True, "allow_null": False, "allow_blank": False},
|
|
"webhook": {"required": True, "allow_null": False, "allow_blank": False},
|
|
}
|
|
|
|
validators = [UniqueTogetherValidator(queryset=CustomButton.objects.all(), fields=["name", "organization"])]
|
|
|
|
def validate_webhook(self, webhook):
|
|
if webhook:
|
|
try:
|
|
if live_settings.DANGEROUS_WEBHOOKS_ENABLED:
|
|
URLValidatorWithoutTLD()(webhook)
|
|
else:
|
|
URLValidator()(webhook)
|
|
except ValidationError:
|
|
raise serializers.ValidationError("Webhook is incorrect")
|
|
return webhook
|
|
return None
|
|
|
|
def validate_data(self, data):
|
|
if not data:
|
|
return None
|
|
|
|
try:
|
|
apply_jinja_template(data, alert_payload=defaultdict(str), alert_group_id="abcd")
|
|
except JinjaTemplateError as e:
|
|
raise serializers.ValidationError(e.fallback_message)
|
|
except JinjaTemplateWarning:
|
|
# Suppress render exceptions since we do not have a representative payload to test with
|
|
pass
|
|
|
|
return data
|
|
|
|
def validate_forward_whole_payload(self, data):
|
|
if data is None:
|
|
return False
|
|
return data
|