agent
This commit is contained in:
2
agent/app/utils/__init__.py
Normal file
2
agent/app/utils/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
"""Utility helpers."""
|
||||
|
||||
55
agent/app/utils/validators.py
Normal file
55
agent/app/utils/validators.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
APP_ID_RE = re.compile(r"^[a-zA-Z0-9._+-]+$")
|
||||
PACKAGE_NAME_RE = re.compile(r"^[a-zA-Z0-9._+-]+$")
|
||||
SERVICE_NAME_RE = re.compile(r"^[a-zA-Z0-9._@+-]+\.service$")
|
||||
VERSION_RE = re.compile(r"^[a-zA-Z0-9._:+~=-]+$")
|
||||
SHA256_RE = re.compile(r"^[0-9a-fA-F]{64}$")
|
||||
|
||||
|
||||
def validate_app_id(value: str) -> str:
|
||||
if not value or not APP_ID_RE.fullmatch(value):
|
||||
raise ValueError("appId contains invalid characters")
|
||||
return value
|
||||
|
||||
|
||||
def validate_package_name(value: str) -> str:
|
||||
if not value or not PACKAGE_NAME_RE.fullmatch(value):
|
||||
raise ValueError("packageName contains invalid characters")
|
||||
return value
|
||||
|
||||
|
||||
def validate_service_name(value: str | None) -> str | None:
|
||||
if value is None or value == "":
|
||||
return None
|
||||
if not SERVICE_NAME_RE.fullmatch(value):
|
||||
raise ValueError("serviceName must be a systemd .service name")
|
||||
return value
|
||||
|
||||
|
||||
def validate_version(value: str) -> str:
|
||||
if not value or not VERSION_RE.fullmatch(value):
|
||||
raise ValueError("version contains invalid characters")
|
||||
return value
|
||||
|
||||
|
||||
def validate_sha256(value: str) -> str:
|
||||
if not value or not SHA256_RE.fullmatch(value):
|
||||
raise ValueError("sha256/checksum must be a 64 character hex digest")
|
||||
return value.lower()
|
||||
|
||||
|
||||
def validate_url_host(url: str, allowed_hosts: list[str]) -> str:
|
||||
parsed = urlparse(url)
|
||||
if parsed.scheme not in {"http", "https"}:
|
||||
raise ValueError("download URL must use http or https")
|
||||
if not parsed.hostname:
|
||||
raise ValueError("download URL is missing a host")
|
||||
if parsed.hostname not in set(allowed_hosts):
|
||||
raise ValueError(f"download host is not allowed: {parsed.hostname}")
|
||||
return url
|
||||
|
||||
Reference in New Issue
Block a user