UI and security improvements

This commit is contained in:
Matthew Grotke 2026-05-18 20:02:22 -04:00
parent 9a272ee959
commit b8c4914a52
13 changed files with 136 additions and 80 deletions

View file

@ -105,14 +105,33 @@ def text(value, max_len=200):
"""General description: letters, digits, spaces, basic punctuation. No quotes/braces/brackets/slashes."""
return _strip(value, r'''["'{}\[\]\\/<>;`^~]''', max_len)
def name(value, max_len=64):
"""Label/name: letters, digits, spaces, hyphens, underscores, dots."""
return _strip(value, r'[^A-Za-z0-9 \-_.]', max_len)
def description(value, max_len=200):
"""Human-readable description: letters, digits, hyphens, parentheses, commas, forward slashes, spaces.
Whitespace collapsed; no sequential commas or slashes."""
s = re.sub(r'[^A-Za-z0-9\-()/,\s]', '', str(value))
s = re.sub(r'\s+', ' ', s)
s = re.sub(r',{2,}', ',', s)
s = re.sub(r'/{2,}', '/', s)
s = re.sub(r'-{2,}', '-', s)
s = re.sub(r'\({2,}', '(', s)
s = re.sub(r'\){2,}', ')', s)
return s.strip()[:max_len]
def hostname(value, max_len=253):
def name(value, max_len=40):
"""Identifier: lowercase letters, digits, hyphens only. No sequential hyphens."""
s = re.sub(r'[\s_]+', '-', str(value).strip().lower())
s = re.sub(r'[^a-z0-9-]', '', s)[:max_len]
s = re.sub(r'-{2,}', '-', s)
return s.strip('-')
def domainname(value, max_len=253):
"""Hostname or domain: letters, digits, hyphens, dots. Lowercased."""
return _strip(value.lower(), r'[^a-z0-9\-.]', max_len)
def domainlist(lines):
"""Sanitize a list of domain name strings, returning only non-empty results."""
return [h for v in lines if (h := domainname(v))]
def ip(value, max_len=45):
"""IPv4 or IPv6 address. Returns '' if not a valid address."""
cleaned = _strip(value, r'[^0-9a-fA-F.:]', max_len)
@ -169,6 +188,16 @@ def timezone(value):
"""Timezone string: must be in VALID_TIMEZONES list. Returns '' if not found."""
return value if value in _TIMEZONE_SET else ''
def filterlist(submitted, allowed):
"""Filter a list of submitted values to those present in the allowed set, after sanitizing each."""
allowed = set(allowed)
return [n for v in submitted if (n := name(v)) in allowed]
def filtervalue(value, allowed):
"""Return the sanitized value if it exists in the allowed set, otherwise ''."""
n = name(value)
return n if n in set(allowed) else ''
_DOTTED_TO_PREFIX = {
'255.0.0.0': 8, '255.255.0.0': 16, '255.255.255.0': 24,
'255.255.255.128': 25, '255.255.255.192': 26,