Coverage for seedboxsync/front/forms/validators/validators.py: 86%

21 statements  

« prev     ^ index     » next       coverage.py v7.16.1, created at 2026-09-26 17:14 +0000

1# 

2# Copyright (C) 2015-2026 Guillaume Kulakowski <guillaume@kulakowski.fr> 

3# 

4# For the full copyright and license information, please view the LICENSE 

5# file that was distributed with this source code. 

6# 

7"""SeedboxSync WTForms domain or IP validator.""" 

8 

9from ipaddress import ip_address 

10import re 

11from wtforms import ValidationError 

12 

13# Python-compatible regex to validate domain names without variable-width lookbehinds. 

14DOMAIN_REGEX = re.compile(r"^(?:(?!-)[A-Za-z0-9-]{0,61}[A-Za-z0-9]\.)+[A-Za-z]{2,}$") 

15 

16 

17class DomainOrIP: 

18 """WTForms validator accepting either a valid domain name or an IP address.""" 

19 

20 def __init__(self, message: str | None = None) -> None: 

21 """Initialize the DomainOrIP validator. 

22 

23 Args: 

24 message: Custom validation error message. If not provided, 

25 a default error message will be used. 

26 """ 

27 if not message: 

28 message = "Value must be a valid domain name or IP address." 

29 self.message = message 

30 

31 def __call__(self, form: object, field: object) -> None: 

32 """Validate the input field content. 

33 

34 Args: 

35 form: The WTForms form instance being validated. 

36 field: The field containing the data to validate. 

37 

38 Raises: 

39 ValidationError: If the value is neither a valid IP address 

40 nor a valid domain name. 

41 """ 

42 value = getattr(field, "data", "") 

43 

44 if not value: 

45 return # Let DataRequired/Optional handle empty fields 

46 

47 # 1. Check if input is a valid IP address (IPv4 or IPv6) 

48 try: 

49 ip_address(value) 

50 except ValueError: 

51 pass 

52 else: 

53 return # Valid IP address 

54 

55 # 2. Check if input is a valid domain name 

56 if DOMAIN_REGEX.match(value): 

57 return # Valid domain name 

58 

59 # 3. Raise validation error if both checks fail 

60 raise ValidationError(self.message)