Restrict user input to more sensible ranges
All checks were successful
Tests / test (push) Successful in 26s

ref #223
This commit is contained in:
Tobias Kunze 2025-10-24 12:40:10 +02:00 committed by Tobias Brunner
parent 4365563fca
commit eea743e5ae
Signed by: tobru
SSH key fingerprint: SHA256:kOXg1R6c11XW3/Pt9dbLdQvOJGFAy+B2K6v6PtRWBGQ
2 changed files with 123 additions and 7 deletions

View file

@ -6,6 +6,7 @@ from auditlog.registry import auditlog
from django.conf import settings
from django.contrib.sites.shortcuts import get_current_site
from django.core.mail import send_mail
from django.core.validators import RegexValidator
from django.db import models, transaction
from django.http import HttpRequest
from django.utils.functional import cached_property
@ -20,7 +21,18 @@ from servala.core.odoo import CLIENT
class Organization(ServalaModelMixin, models.Model):
name = models.CharField(max_length=100, verbose_name=_("Name"))
name = models.CharField(
max_length=32,
verbose_name=_("Name"),
validators=[
RegexValidator(
regex=r"^[A-Za-z0-9\s]+$",
message=_(
"Organization name can only contain letters, numbers, and spaces."
),
)
],
)
# The namespace is generated as "org-{id}" in accordance with RFC 1035 Label Names.
# It is nullable as we need to write to the database in order to read the ID, but should
# not be null in practical use.

View file

@ -1,5 +1,6 @@
from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.forms import ModelForm
from django.utils.translation import gettext_lazy as _
@ -16,9 +17,43 @@ class OrganizationForm(HtmxMixin, ModelForm):
class Meta:
model = Organization
fields = ("name",)
widgets = {
"name": forms.TextInput(
attrs={
"maxlength": "32",
"pattern": "[A-Za-z0-9\\s]+",
"title": _(
"Organization name can only contain letters, numbers, and spaces"
),
}
),
}
class OrganizationCreateForm(OrganizationForm):
address_validator = RegexValidator(
regex=r"^[\w\s\.,\-/()\']+$",
message=_(
"This field can only contain letters, numbers, spaces, and basic punctuation (.,-/()')."
),
)
city_validator = RegexValidator(
regex=r"^[\w\s\-\']+$",
message=_("City name contains invalid characters."),
)
postal_code_validator = RegexValidator(
regex=r"^[\w\s\-]+$",
message=_(
"Postal code can only contain letters, numbers, spaces, and hyphens."
),
)
phone_validator = RegexValidator(
regex=r"^[0-9\s\+\-()]+$",
message=_(
"Phone number can only contain numbers, spaces, and basic punctuation (+,-,())."
),
)
billing_processing_choice = forms.ChoiceField(
choices=[
("existing", _("Use an existing billing address")),
@ -34,17 +69,86 @@ class OrganizationCreateForm(OrganizationForm):
)
# Fields for creating a new billing address in Odoo, prefixed with 'invoice_'
invoice_street = forms.CharField(label=_("Line 1"), required=False, max_length=100)
invoice_street2 = forms.CharField(label=_("Line 2"), required=False, max_length=100)
invoice_city = forms.CharField(label=_("City"), required=False, max_length=100)
invoice_zip = forms.CharField(label=_("Postal Code"), required=False, max_length=20)
invoice_street = forms.CharField(
label=_("Line 1"),
required=False,
max_length=128,
validators=[address_validator],
widget=forms.TextInput(
attrs={
"maxlength": "128",
"title": _(
"Letters, numbers, spaces, and basic punctuation allowed. Emoji not allowed."
),
}
),
)
invoice_street2 = forms.CharField(
label=_("Line 2"),
required=False,
max_length=128,
validators=[address_validator],
widget=forms.TextInput(
attrs={
"maxlength": "128",
"title": _(
"Letters, numbers, spaces, and basic punctuation allowed. Emoji not allowed."
),
}
),
)
invoice_city = forms.CharField(
label=_("City"),
required=False,
max_length=64,
validators=[city_validator],
widget=forms.TextInput(
attrs={
"maxlength": "64",
"title": _(
"Letters, spaces, hyphens, and apostrophes allowed. Emoji not allowed."
),
}
),
)
invoice_zip = forms.CharField(
label=_("Postal Code"),
required=False,
max_length=20,
validators=[postal_code_validator],
widget=forms.TextInput(
attrs={
"maxlength": "20",
"title": _(
"Letters, numbers, spaces, and hyphens allowed. Emoji not allowed."
),
}
),
)
invoice_country = forms.ChoiceField(
label=_("Country"),
required=False,
choices=get_odoo_countries(),
)
invoice_email = forms.EmailField(label=_("Billing Email"), required=False)
invoice_phone = forms.CharField(label=_("Phone"), required=False, max_length=30)
invoice_email = forms.EmailField(
label=_("Billing Email"),
required=False,
max_length=254,
widget=forms.EmailInput(attrs={"maxlength": "254"}),
)
invoice_phone = forms.CharField(
label=_("Phone"),
required=False,
max_length=30,
validators=[phone_validator],
widget=forms.TextInput(
attrs={
"maxlength": "30",
"pattern": r"[0-9\s\+\-()]+",
"title": _("Only numbers, spaces, and basic punctuation allowed"),
}
),
)
class Meta(OrganizationForm.Meta):
pass