Skip to content

Commit 4ca1e31

Browse files
Adjust custom_url field validation rules and migrations (#1408)
1 parent 3c22ce7 commit 4ca1e31

File tree

5 files changed

+68
-15
lines changed

5 files changed

+68
-15
lines changed

tests/santa/test_serializers.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from django.test import TestCase
22
from django.urls import reverse
33
from django.utils.crypto import get_random_string
4+
45
from zentral.conf import settings
56
from zentral.contrib.inventory.models import EnrollmentSecret, MetaBusinessUnit
67
from zentral.contrib.santa.models import Configuration, Enrollment
7-
from zentral.contrib.santa.serializers import RuleUpdateSerializer, EnrollmentSerializer
8+
from zentral.contrib.santa.serializers import EnrollmentSerializer, RuleUpdateSerializer
89

910

1011
class SantaSerializersTestCase(TestCase):
@@ -112,6 +113,24 @@ def test_rule_custom_msg_allowlist(self):
112113
ed = serializer.errors["non_field_errors"][0]
113114
self.assertEqual(str(ed), "Custom message cannot be set for this rule policy")
114115

116+
def test_rule_custom_url_length(self):
117+
custom_url = f"https://zentral.com/{get_random_string(240)}"
118+
data = {"rule_type": "BINARY",
119+
"identifier": get_random_string(64, "0123456789abcdef"),
120+
"custom_url": custom_url,
121+
"policy": "BLOCKLIST"}
122+
serializer = RuleUpdateSerializer(data=data)
123+
self.assertTrue(serializer.is_valid())
124+
custom_url = f"https://zentral.com/{get_random_string(840)}"
125+
data = {"rule_type": "BINARY",
126+
"identifier": get_random_string(64, "0123456789abcdef"),
127+
"custom_url": custom_url,
128+
"policy": "BLOCKLIST"}
129+
serializer = RuleUpdateSerializer(data=data)
130+
self.assertFalse(serializer.is_valid())
131+
ed = serializer.errors["custom_url"][0]
132+
self.assertEqual(str(ed), "Ensure this field has no more than 800 characters.")
133+
115134
def test_rule_custom_url_allowlist(self):
116135
data = {"rule_type": "BINARY",
117136
"identifier": get_random_string(64, "0123456789abcdef"),

zentral/contrib/santa/forms.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
import json
22
import logging
33
import re
4+
45
from dateutil import parser
56
from django import forms
67
from django.contrib.postgres.forms import SimpleArrayField
78
from django.db import connection, transaction
89
from django.db.models import Count, F
9-
from django.urls import reverse, NoReverseMatch
10+
from django.urls import NoReverseMatch, reverse
11+
1012
from zentral.conf import settings
1113
from zentral.contrib.inventory.models import Tag
12-
from .events import post_santa_rule_update_event
13-
from .models import Configuration, Enrollment, Rule, RuleSet, Target, TargetState, VotingGroup
1414

15+
from .events import post_santa_rule_update_event
16+
from .models import (
17+
Configuration,
18+
Enrollment,
19+
Rule,
20+
RuleSet,
21+
Target,
22+
TargetState,
23+
VotingGroup,
24+
)
1525

1626
logger = logging.getLogger("zentral.contrib.santa.forms")
1727

@@ -318,7 +328,7 @@ class RuleForm(RuleFormMixin, forms.Form):
318328
widget=forms.Textarea(attrs={"cols": "40", "rows": "5"}))
319329
custom_msg = forms.CharField(label="Custom message", required=False,
320330
widget=forms.Textarea(attrs={"cols": "40", "rows": "2"}))
321-
custom_url = forms.URLField(label="Custom URL", required=False,
331+
custom_url = forms.URLField(label="Custom URL", required=False, max_length=800,
322332
widget=forms.URLInput(attrs={"size": 40}),)
323333
description = forms.CharField(required=False, widget=forms.Textarea(attrs={"cols": "40", "rows": "2"}))
324334
serial_numbers = SimpleArrayField(forms.CharField(), required=False)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 5.2.11 on 2026-02-25 09:31
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('santa', '0040_rule_custom_url'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='rule',
15+
name='custom_url',
16+
field=models.URLField(blank=True, max_length=800),
17+
),
18+
]

zentral/contrib/santa/models.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
1-
from collections import namedtuple
21
import logging
32
import uuid
4-
from django.core.validators import MaxValueValidator, MinLengthValidator, MinValueValidator
3+
from collections import namedtuple
4+
55
from django.contrib.postgres.fields import ArrayField
6+
from django.core.validators import (
7+
MaxValueValidator,
8+
MinLengthValidator,
9+
MinValueValidator,
10+
)
611
from django.db import connection, models
712
from django.db.models import Count, Q
813
from django.urls import reverse
914
from django.utils.crypto import get_random_string
1015
from django.utils.functional import cached_property
1116
from django.utils.translation import gettext_lazy as _
1217
from realms.models import Realm, RealmGroup, RealmUser
13-
from zentral.core.incidents.models import Severity
18+
1419
from zentral.contrib.inventory.models import BaseEnrollment, Certificate, File, Tag
20+
from zentral.core.incidents.models import Severity
1521
from zentral.utils.text import shard
1622

17-
1823
logger = logging.getLogger("zentral.contrib.santa.models")
1924

2025

@@ -987,7 +992,7 @@ def rule_choices(cls):
987992
policy = models.PositiveSmallIntegerField(choices=Policy.rule_choices())
988993
cel_expr = models.TextField(blank=True)
989994
custom_msg = models.TextField(blank=True)
990-
custom_url = models.URLField(blank=True)
995+
custom_url = models.URLField(blank=True, max_length=800)
991996
description = models.TextField(blank=True)
992997
version = models.PositiveIntegerField(default=1)
993998
is_voting_rule = models.BooleanField(default=False, editable=False)

zentral/contrib/santa/serializers.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
from datetime import datetime
2-
from itertools import chain
31
import logging
42
import os.path
3+
from datetime import datetime
4+
from itertools import chain
55

66
from django.db import transaction
77
from django.db.models import F
88
from django.urls import reverse
99
from rest_framework import serializers
10+
1011
from zentral.conf import settings
1112
from zentral.contrib.inventory.models import EnrollmentSecret
1213
from zentral.contrib.inventory.serializers import EnrollmentSecretSerializer
14+
1315
from .events import post_santa_rule_update_event
14-
from .models import Configuration, Rule, Target, Enrollment
1516
from .forms import cleanup_target_identifier
16-
17+
from .models import Configuration, Enrollment, Rule, Target
1718

1819
logger = logging.getLogger("zentral.contrib.santa.serializers")
1920

@@ -218,7 +219,7 @@ class RuleUpdateSerializer(serializers.Serializer):
218219
sha256 = serializers.RegexField(r'^[a-f0-9]{64}\Z', required=False) # Legacy field TODO remove eventually
219220
identifier = serializers.CharField(required=False)
220221
custom_msg = serializers.CharField(required=False)
221-
custom_url = serializers.CharField(required=False)
222+
custom_url = serializers.URLField(required=False, max_length=800)
222223
description = serializers.CharField(required=False)
223224
serial_numbers = serializers.ListField(
224225
child=serializers.CharField(min_length=1),

0 commit comments

Comments
 (0)