You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
4.6 KiB

10 years ago
10 years ago
10 years ago
  1. from datetime import timedelta as td
  2. import json
  3. from urllib.parse import quote, urlencode
  4. from django import forms
  5. from django.forms import URLField
  6. from django.conf import settings
  7. from django.core.exceptions import ValidationError
  8. from django.core.validators import RegexValidator
  9. from hc.front.validators import (
  10. CronExpressionValidator,
  11. TimezoneValidator,
  12. WebhookValidator,
  13. )
  14. import requests
  15. class HeadersField(forms.Field):
  16. message = """Use "Header-Name: value" pairs, one per line."""
  17. def to_python(self, value):
  18. if not value:
  19. return {}
  20. headers = {}
  21. for line in value.split("\n"):
  22. if not line.strip():
  23. continue
  24. if ":" not in value:
  25. raise ValidationError(self.message)
  26. n, v = line.split(":", maxsplit=1)
  27. n, v = n.strip(), v.strip()
  28. if not n or not v:
  29. raise ValidationError(message=self.message)
  30. headers[n] = v
  31. return headers
  32. def validate(self, value):
  33. super().validate(value)
  34. for k, v in value.items():
  35. if len(k) > 1000 or len(v) > 1000:
  36. raise ValidationError("Value too long")
  37. class NameTagsForm(forms.Form):
  38. name = forms.CharField(max_length=100, required=False)
  39. tags = forms.CharField(max_length=500, required=False)
  40. desc = forms.CharField(required=False)
  41. def clean_tags(self):
  42. result = []
  43. for part in self.cleaned_data["tags"].split(" "):
  44. part = part.strip()
  45. if part != "":
  46. result.append(part)
  47. return " ".join(result)
  48. class EmailSettingsForm(forms.Form):
  49. subject = forms.CharField(max_length=100)
  50. class TimeoutForm(forms.Form):
  51. timeout = forms.IntegerField(min_value=60, max_value=2592000)
  52. grace = forms.IntegerField(min_value=60, max_value=2592000)
  53. def clean_timeout(self):
  54. return td(seconds=self.cleaned_data["timeout"])
  55. def clean_grace(self):
  56. return td(seconds=self.cleaned_data["grace"])
  57. class CronForm(forms.Form):
  58. schedule = forms.CharField(max_length=100, validators=[CronExpressionValidator()])
  59. tz = forms.CharField(max_length=36, validators=[TimezoneValidator()])
  60. grace = forms.IntegerField(min_value=1, max_value=43200)
  61. class AddOpsGenieForm(forms.Form):
  62. error_css_class = "has-error"
  63. value = forms.CharField(max_length=40)
  64. class AddEmailForm(forms.Form):
  65. error_css_class = "has-error"
  66. value = forms.EmailField(max_length=100)
  67. down = forms.BooleanField(required=False, initial=True)
  68. up = forms.BooleanField(required=False, initial=True)
  69. class AddUrlForm(forms.Form):
  70. error_css_class = "has-error"
  71. value = forms.URLField(max_length=1000, validators=[WebhookValidator()])
  72. METHODS = ("GET", "POST", "PUT")
  73. class AddWebhookForm(forms.Form):
  74. error_css_class = "has-error"
  75. method_down = forms.ChoiceField(initial="GET", choices=zip(METHODS, METHODS))
  76. body_down = forms.CharField(max_length=1000, required=False)
  77. headers_down = HeadersField(required=False)
  78. url_down = URLField(
  79. max_length=1000, required=False, validators=[WebhookValidator()]
  80. )
  81. method_up = forms.ChoiceField(initial="GET", choices=zip(METHODS, METHODS))
  82. body_up = forms.CharField(max_length=1000, required=False)
  83. headers_up = HeadersField(required=False)
  84. url_up = forms.URLField(
  85. max_length=1000, required=False, validators=[WebhookValidator()]
  86. )
  87. def get_value(self):
  88. return json.dumps(dict(self.cleaned_data), sort_keys=True)
  89. phone_validator = RegexValidator(
  90. regex="^\+\d{5,15}$", message="Invalid phone number format."
  91. )
  92. class AddSmsForm(forms.Form):
  93. error_css_class = "has-error"
  94. label = forms.CharField(max_length=100, required=False)
  95. value = forms.CharField(max_length=16, validators=[phone_validator])
  96. down = forms.BooleanField(required=False, initial=True)
  97. up = forms.BooleanField(required=False, initial=True)
  98. class ChannelNameForm(forms.Form):
  99. name = forms.CharField(max_length=100, required=False)
  100. class AddMatrixForm(forms.Form):
  101. error_css_class = "has-error"
  102. alias = forms.CharField(max_length=40)
  103. def clean_alias(self):
  104. v = self.cleaned_data["alias"]
  105. # validate it by trying to join
  106. url = settings.MATRIX_HOMESERVER
  107. url += "/_matrix/client/r0/join/%s?" % quote(v)
  108. url += urlencode({"access_token": settings.MATRIX_ACCESS_TOKEN})
  109. doc = requests.post(url, {}).json()
  110. if "error" in doc:
  111. raise forms.ValidationError("Response from Matrix: %s" % doc["error"])
  112. self.cleaned_data["room_id"] = doc["room_id"]
  113. return v