gitscope
← marzneshin / v0.6.5 / app/models/proxy.py
https://dev.kronoz.win/r/marzneshin.git
app/models/proxy.py · Python
Blame Raw
  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    Shadowsocks2022 = "shadowsocks2022"
 15    Hysteria2 = "hysteria2"
 16    WireGuard = "wireguard"
 17    TUIC = "tuic"
 18    ShadowTLS = "shadowtls"
 19
 20
 21class InboundHostSecurity(str, Enum):
 22    inbound_default = "inbound_default"
 23    none = "none"
 24    tls = "tls"
 25
 26
 27InboundHostALPN = Enum(
 28    "ProxyHostALPN",
 29    {
 30        "none": "none",
 31        "h2": "h2",
 32        "http/1.1": "http/1.1",
 33        "h2,http/1.1": "h2,http/1.1",
 34        "h3": "h3",
 35        "h3,h2": "h3,h2",
 36        "h3,h2,http/1.1": "h3,h2,http/1.1",
 37    },
 38)
 39
 40
 41InboundHostFingerprint = Enum(
 42    "ProxyHostFingerprint",
 43    {
 44        "none": "",
 45        "chrome": "chrome",
 46        "firefox": "firefox",
 47        "safari": "safari",
 48        "ios": "ios",
 49        "android": "android",
 50        "edge": "edge",
 51        "360": "360",
 52        "qq": "qq",
 53        "random": "random",
 54        "randomized": "randomized",
 55    },
 56)
 57
 58
 59class FormatVariables(dict):
 60    def __missing__(self, key):
 61        return key.join("{}")
 62
 63
 64class FragmentSettings(BaseModel):
 65    packets: str = Field(pattern=r"^(:?tlshello|[\d-]{1,32})$")
 66    length: str = Field(pattern=r"^[\d-]{1,32}$")
 67    interval: str = Field(pattern=r"^[\d-]{1,32}$")
 68
 69
 70class UDPNoiseSettings(BaseModel):
 71    type: str = Field(pattern=r"^(:?rand|str|base64)$")
 72    packet: str = Field()
 73    interval: str = Field(pattern=r"^[\d-]{1,32}$")
 74
 75
 76class InboundHost(BaseModel):
 77    remark: str
 78    address: str
 79    port: int | None = Field(None)
 80    sni: str | None = Field(None)
 81    host: str | None = Field(None)
 82    path: str | None = Field(None)
 83    security: InboundHostSecurity = InboundHostSecurity.inbound_default
 84    alpn: InboundHostALPN = InboundHostALPN.none
 85    fingerprint: InboundHostFingerprint = InboundHostFingerprint.none
 86    allowinsecure: bool | None = False
 87    is_disabled: bool | None = False
 88    mux: bool = Field(False)
 89    fragment: FragmentSettings | None = Field(None)
 90    udp_noises: list[UDPNoiseSettings] | None = []
 91    http_headers: dict[str, list[str]] | None = {}
 92    mtu: int | None = None
 93    dns_servers: str | None = None
 94    allowed_ips: str | None = None
 95    weight: int = 1
 96    protocol: ProxyTypes | None = None
 97    inbound_id: int | None = None
 98    model_config = ConfigDict(from_attributes=True)
 99
100    @field_validator("remark", "address", "path")
101    @classmethod
102    def validate_fmt_variables(cls, v: str) -> str:
103        if not v:
104            return v
105
106        v.format_map(FormatVariables())
107
108        return v
109
110    @field_validator("alpn", mode="before")
111    @classmethod
112    def validate_alpn(cls, v):
113        if not v:
114            return InboundHostALPN.none
115        return v
116
117
118class InboundHostResponse(InboundHost):
119    id: int
120
121
122class Inbound(BaseModel):
123    id: int
124    tag: str
125    protocol: ProxyTypes
126    config: str
127    node: Node
128    service_ids: list[int]
129    model_config = ConfigDict(from_attributes=True)