add number validation
This commit is contained in:
+30
-1
@@ -1,3 +1,4 @@
|
|||||||
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
|
|
||||||
@@ -138,6 +139,24 @@ def _normalize_mac(mac: str) -> str:
|
|||||||
return mac.strip().upper().replace(":", "-")
|
return mac.strip().upper().replace(":", "-")
|
||||||
|
|
||||||
|
|
||||||
|
_PHONE_ERROR = "Enter a valid phone number"
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_phone(raw: str) -> str:
|
||||||
|
"""Validate a Maldivian mobile number and return the 7-digit local form.
|
||||||
|
|
||||||
|
Rules: 7 digits, starts with 9 or 7. A 960/+960 country code is stripped ONLY
|
||||||
|
when the number is 10 digits (960 + 7) — a bare 7-digit number like 9601234 is
|
||||||
|
a valid local number and is never stripped.
|
||||||
|
"""
|
||||||
|
digits = re.sub(r"\D", "", raw or "")
|
||||||
|
if len(digits) == 10 and digits.startswith("960"):
|
||||||
|
digits = digits[3:]
|
||||||
|
if len(digits) == 7 and digits[0] in ("7", "9"):
|
||||||
|
return digits
|
||||||
|
raise ValueError(_PHONE_ERROR)
|
||||||
|
|
||||||
|
|
||||||
class DeviceOut(BaseModel):
|
class DeviceOut(BaseModel):
|
||||||
mac_address: str
|
mac_address: str
|
||||||
group: str | None = None # radusergroup.groupname
|
group: str | None = None # radusergroup.groupname
|
||||||
@@ -151,7 +170,7 @@ class DeviceCreate(BaseModel):
|
|||||||
mac_address: str = Field(pattern=_MAC_RE, max_length=17)
|
mac_address: str = Field(pattern=_MAC_RE, max_length=17)
|
||||||
group: str = Field(min_length=1, max_length=64)
|
group: str = Field(min_length=1, max_length=64)
|
||||||
name: str = Field(min_length=1, max_length=128, description="Customer name (metadata, ignored by RADIUS)")
|
name: str = Field(min_length=1, max_length=128, description="Customer name (metadata, ignored by RADIUS)")
|
||||||
phone: str = Field(min_length=1, max_length=32, description="Phone number (metadata, ignored by RADIUS)")
|
phone: str = Field(min_length=1, max_length=32, description="7-digit mobile (9/7…), 960/+960 optional")
|
||||||
alias: str | None = Field(default=None, max_length=64, description="Optional device alias (metadata)")
|
alias: str | None = Field(default=None, max_length=64, description="Optional device alias (metadata)")
|
||||||
|
|
||||||
@field_validator("mac_address")
|
@field_validator("mac_address")
|
||||||
@@ -159,6 +178,11 @@ class DeviceCreate(BaseModel):
|
|||||||
def _norm(cls, v: str) -> str:
|
def _norm(cls, v: str) -> str:
|
||||||
return _normalize_mac(v)
|
return _normalize_mac(v)
|
||||||
|
|
||||||
|
@field_validator("phone")
|
||||||
|
@classmethod
|
||||||
|
def _norm_phone(cls, v: str) -> str:
|
||||||
|
return _normalize_phone(v)
|
||||||
|
|
||||||
|
|
||||||
class DeviceEdit(BaseModel):
|
class DeviceEdit(BaseModel):
|
||||||
mac_address: str = Field(pattern=_MAC_RE, max_length=17)
|
mac_address: str = Field(pattern=_MAC_RE, max_length=17)
|
||||||
@@ -173,6 +197,11 @@ class DeviceEdit(BaseModel):
|
|||||||
def _norm(cls, v: str) -> str:
|
def _norm(cls, v: str) -> str:
|
||||||
return _normalize_mac(v)
|
return _normalize_mac(v)
|
||||||
|
|
||||||
|
@field_validator("phone")
|
||||||
|
@classmethod
|
||||||
|
def _norm_phone(cls, v: str | None) -> str | None:
|
||||||
|
return None if v is None else _normalize_phone(v)
|
||||||
|
|
||||||
@model_validator(mode="after")
|
@model_validator(mode="after")
|
||||||
def _at_least_one(self):
|
def _at_least_one(self):
|
||||||
if all(v is None for v in (self.group, self.status, self.name, self.phone, self.alias)):
|
if all(v is None for v in (self.group, self.status, self.name, self.phone, self.alias)):
|
||||||
|
|||||||
Reference in New Issue
Block a user