From dbf581245b46c42c544738eee6185420032d82ba Mon Sep 17 00:00:00 2001 From: Mark Veidemanis Date: Sat, 14 Jan 2023 14:45:19 +0000 Subject: [PATCH] Validate interval and window fields in form --- core/forms.py | 9 ++++----- core/lib/rules.py | 26 +++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/core/forms.py b/core/forms.py index bc3ef87..97e3a7c 100644 --- a/core/forms.py +++ b/core/forms.py @@ -4,7 +4,7 @@ from django.core.exceptions import FieldDoesNotExist from django.forms import ModelForm from core.db import QueryError -from core.lib.rules import NotificationRuleData +from core.lib.rules import NotificationRuleData, RuleParseError from .models import NotificationRule, NotificationSettings, User @@ -106,11 +106,10 @@ class NotificationRuleForm(RestrictedFormMixin, ModelForm): def clean(self): cleaned_data = super(NotificationRuleForm, self).clean() - data = cleaned_data.get("data") try: - parsed_data = NotificationRuleData(self.request.user, data) - except ValueError as e: - self.add_error("data", f"Parsing error: {e}") + parsed_data = NotificationRuleData(self.request.user, cleaned_data) + except RuleParseError as e: + self.add_error(e.field, f"Parsing error: {e}") return except QueryError as e: self.add_error("data", f"Query error: {e}") diff --git a/core/lib/rules.py b/core/lib/rules.py index fae7724..e90593d 100644 --- a/core/lib/rules.py +++ b/core/lib/rules.py @@ -17,6 +17,12 @@ from core.util import logs log = logs.get_logger("rules") +class RuleParseError(Exception): + def __init__(self, message, field): + super().__init__(message) + self.field = field + + def rule_matched(rule, message, matched): title = f"Rule {rule.name} matched" @@ -99,13 +105,27 @@ def process_rules(data): class NotificationRuleData(object): - def __init__(self, user, data): + def __init__(self, user, cleaned_data): self.user = user - self.data = data + self.cleaned_data = cleaned_data + self.data = self.cleaned_data.get("data") self.parsed = None self.parse_data() self.validate_permissions() + self.validate_time_fields() + + def validate_time_fields(self): + """ + Validate the interval and window fields. + Prohibit window being specified with an ondemand interval. + """ + interval = self.cleaned_data.get("interval") + window = self.cleaned_data.get("window") + if interval == "ondemand" and window is not None: + raise RuleParseError( + "Window cannot be specified with ondemand interval", "window" + ) def validate_permissions(self): """ @@ -142,7 +162,7 @@ class NotificationRuleData(object): try: self.parsed = load(self.data, Loader=Loader) except (ScannerError, ParserError) as e: - raise ValueError(f"Invalid YAML: {e}") + raise RuleParseError("data", f"Invalid YAML: {e}") def __str__(self): return dump(self.parsed, Dumper=Dumper)