Files
taylanbakircioglu 71c717364c fix: allow dot character in entity names for UI and backend validation
Bulk import accepted dots in frontend/backend/server names but UI and
backend validators rejected them with ^[a-zA-Z0-9_-]+$. After import,
entities with dots could not be edited. HAProxy itself allows dots in
section names, so the regex is expanded to ^[a-zA-Z0-9_.-]+$ across
all 12 validation points (5 React form rules, 1 ACL char-strip,
3 Pydantic validators, 1 WAF validator, 2 config-validator warnings).
2026-04-14 01:26:03 +03:00

74 lines
2.6 KiB
Python

from pydantic import BaseModel, validator
from typing import Optional, List
import re
import ipaddress
class WAFRule(BaseModel):
name: str
rule_type: str # 'rate_limit', 'ip_filter', 'header_filter', 'request_filter', 'geo_block', 'size_limit'
action: str = 'block' # 'block', 'allow', 'log', 'redirect'
priority: int = 100
is_active: bool = True
config: dict # This will hold all rule-specific configurations
description: Optional[str] = None
# Frontend associations (multiple) - optional during creation
frontend_ids: Optional[List[int]] = None
# CRITICAL VALIDATION RULES FOR HAPROXY WAF
@validator('name')
def validate_name(cls, v):
if not v or not v.strip():
raise ValueError('WAF rule name cannot be empty')
# HAProxy ACL names cannot contain spaces or special characters
if not re.match(r'^[a-zA-Z0-9_.-]+$', v.strip()):
raise ValueError('WAF rule name can only contain letters, numbers, dot (.), underscore (_) and dash (-). Spaces and special characters are not allowed.')
if len(v.strip()) > 50:
raise ValueError('WAF rule name cannot exceed 50 characters')
return v.strip()
@validator('rule_type')
def validate_rule_type(cls, v):
valid_types = ['rate_limit', 'ip_filter', 'header_filter', 'request_filter', 'geo_block', 'size_limit', 'path_filter']
if v not in valid_types:
raise ValueError(f'Invalid rule type. Must be one of: {", ".join(valid_types)}')
return v
@validator('action')
def validate_action(cls, v):
valid_actions = ['block', 'allow', 'log', 'redirect']
if v not in valid_actions:
raise ValueError(f'Invalid action. Must be one of: {", ".join(valid_actions)}')
return v
@validator('priority')
def validate_priority(cls, v):
if not isinstance(v, int) or v < 1 or v > 1000:
raise ValueError('Priority must be between 1 and 1000')
return v
class WAFRuleUpdate(WAFRule):
name: Optional[str] = None
rule_type: Optional[str] = None
action: Optional[str] = None
priority: Optional[int] = None
is_active: Optional[bool] = None
config: Optional[dict] = None
description: Optional[str] = None
frontend_ids: Optional[List[int]] = None
class FrontendWAFRule(BaseModel):
waf_rule_id: int
is_active: bool = True
class SSLCertificate(BaseModel):
name: str
domain: str
certificate_content: str
private_key_content: str
chain_content: Optional[str] = None
expiry_date: Optional[str] = None