1from enum import Enum
2
3from pydantic import ConfigDict, BaseModel, Field, field_validator
4
5from app.models.node import Node
6
7
8class ProxyTypes(str, Enum):
9 # proxy_type = protocol
10 VMess = "vmess"
11 VLESS = "vless"
12 Trojan = "trojan"
13 Shadowsocks = "shadowsocks"
14
15
16class InboundHostSecurity(str, Enum):
17 inbound_default = "inbound_default"
18 none = "none"
19 tls = "tls"
20
21
22InboundHostALPN = Enum(
23 "ProxyHostALPN",
24 {
25 "none": "",
26 "h2": "h2",
27 "http/1.1": "http/1.1",
28 "h2,http/1.1": "h2,http/1.1",
29 },
30)
31
32
33InboundHostFingerprint = Enum(
34 "ProxyHostFingerprint",
35 {
36 "none": "",
37 "chrome": "chrome",
38 "firefox": "firefox",
39 "safari": "safari",
40 "ios": "ios",
41 "android": "android",
42 "edge": "edge",
43 "360": "360",
44 "qq": "qq",
45 "random": "random",
46 "randomized": "randomized",
47 },
48)
49
50
51class FormatVariables(dict):
52 def __missing__(self, key):
53 return key.join("{}")
54
55
56class FragmentSettings(BaseModel):
57 packets: str = Field(pattern=r"^(:?tlshello|[\d-]{1,32})$")
58 length: str = Field(pattern=r"^[\d-]{1,32}$")
59 interval: str = Field(pattern=r"^[\d-]{1,32}$")
60
61
62class InboundHost(BaseModel):
63 remark: str
64 address: str
65 port: int | None = Field(None)
66 sni: str | None = Field(None)
67 host: str | None = Field(None)
68 path: str | None = Field(None)
69 security: InboundHostSecurity = InboundHostSecurity.inbound_default
70 alpn: InboundHostALPN = InboundHostALPN.none
71 fingerprint: InboundHostFingerprint = InboundHostFingerprint.none
72 allowinsecure: bool | None = None
73 is_disabled: bool | None = None
74 mux: bool = Field(False)
75 fragment: FragmentSettings | None = Field(None)
76 model_config = ConfigDict(from_attributes=True)
77
78 @field_validator("remark", "address", "path")
79 @classmethod
80 def validate_fmt_variables(cls, v: str) -> str:
81 if not v:
82 return v
83
84 v.format_map(FormatVariables())
85
86 return v
87
88
89class InboundHostResponse(InboundHost):
90 id: int
91
92
93class Inbound(BaseModel):
94 id: int
95 tag: str
96 protocol: ProxyTypes
97 config: str
98 node: Node
99 service_ids: list[int]
100 model_config = ConfigDict(from_attributes=True)