plan: server props
This commit is contained in:
parent
b202f85d3b
commit
667fcba559
2 changed files with 49 additions and 8 deletions
|
@ -15,11 +15,12 @@ from datetime import datetime, timedelta
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from secrets import token_urlsafe
|
from secrets import token_urlsafe
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from jose import JWTError, jwt
|
from jose import JWTError, jwt
|
||||||
from jose.constants import ALGORITHMS
|
from jose.constants import ALGORITHMS
|
||||||
from passlib.context import CryptContext
|
from passlib.context import CryptContext
|
||||||
from pydantic import BaseModel, BaseSettings, Field, validator
|
from pydantic import BaseModel, BaseSettings, constr, validator
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
|
@ -64,7 +65,7 @@ class DBConfig(BaseModel):
|
||||||
user: str | None = None
|
user: str | None = None
|
||||||
password: str | None = None
|
password: str | None = None
|
||||||
host: str | None = None
|
host: str | None = None
|
||||||
database: str | None = Settings._.data_dir.joinpath("vpn.db")
|
database: str | None = Settings._.data_dir.joinpath("kiwi-vpn.db")
|
||||||
|
|
||||||
mysql_driver: str = "pymysql"
|
mysql_driver: str = "pymysql"
|
||||||
mysql_args: list[str] = ["charset=utf8mb4"]
|
mysql_args: list[str] = ["charset=utf8mb4"]
|
||||||
|
@ -168,6 +169,35 @@ class JWTConfig(BaseModel):
|
||||||
return username
|
return username
|
||||||
|
|
||||||
|
|
||||||
|
class ToggleString(BaseModel):
|
||||||
|
value: str
|
||||||
|
allow: bool
|
||||||
|
|
||||||
|
|
||||||
|
class ToggleCountry(ToggleString):
|
||||||
|
value: constr(max_length=2)
|
||||||
|
|
||||||
|
|
||||||
|
class DNParts(BaseModel):
|
||||||
|
"""
|
||||||
|
This server's "distinguished name"
|
||||||
|
"""
|
||||||
|
|
||||||
|
country: ToggleCountry
|
||||||
|
state: ToggleString
|
||||||
|
city: ToggleString
|
||||||
|
organization: ToggleString
|
||||||
|
organizational_unit: ToggleString
|
||||||
|
|
||||||
|
|
||||||
|
class CertificateAlgo(Enum):
|
||||||
|
rsa2048 = "rsa2048"
|
||||||
|
rsa4096 = "rsa4096"
|
||||||
|
secp256r1 = "secp256r1"
|
||||||
|
secp384r1 = "secp384r1"
|
||||||
|
ed25519 = "ed25519"
|
||||||
|
|
||||||
|
|
||||||
class CryptoConfig(BaseModel):
|
class CryptoConfig(BaseModel):
|
||||||
"""
|
"""
|
||||||
Configuration for hash algorithms
|
Configuration for hash algorithms
|
||||||
|
@ -175,8 +205,15 @@ class CryptoConfig(BaseModel):
|
||||||
|
|
||||||
schemes: list[str] = ["bcrypt"]
|
schemes: list[str] = ["bcrypt"]
|
||||||
|
|
||||||
|
force_cipher: ToggleString
|
||||||
|
force_tls_cipher: ToggleString
|
||||||
|
force_auth: ToggleString
|
||||||
|
|
||||||
|
cert_algo: CertificateAlgo
|
||||||
|
expiry_days: int
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def crypt_context(self) -> CryptContext:
|
def context(self) -> CryptContext:
|
||||||
return CryptContext(
|
return CryptContext(
|
||||||
schemes=self.schemes,
|
schemes=self.schemes,
|
||||||
deprecated="auto",
|
deprecated="auto",
|
||||||
|
@ -188,9 +225,13 @@ class Config(BaseModel):
|
||||||
Configuration for `kiwi-vpn-api`
|
Configuration for `kiwi-vpn-api`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
db: DBConfig = Field(default_factory=DBConfig)
|
server_name: str
|
||||||
jwt: JWTConfig = Field(default_factory=JWTConfig)
|
server_extra_config: dict[str, Any]
|
||||||
crypto: CryptoConfig = Field(default_factory=CryptoConfig)
|
|
||||||
|
db: DBConfig
|
||||||
|
jwt: JWTConfig
|
||||||
|
crypto: CryptoConfig
|
||||||
|
dnparts: DNParts
|
||||||
|
|
||||||
__singleton: Config | None = None
|
__singleton: Config | None = None
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ class UserCreate(UserBase):
|
||||||
if (current_config := Config._) is None:
|
if (current_config := Config._) is None:
|
||||||
raise ValueError("Not configured")
|
raise ValueError("Not configured")
|
||||||
|
|
||||||
values["password"] = current_config.crypto.crypt_context.hash(
|
values["password"] = current_config.crypto.context.hash(
|
||||||
password_clear)
|
password_clear)
|
||||||
|
|
||||||
return values
|
return values
|
||||||
|
@ -132,7 +132,7 @@ class User(UserBase, table=True):
|
||||||
Authenticate with name/password against users in database.
|
Authenticate with name/password against users in database.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
crypt_context = Config._.crypto.crypt_context
|
crypt_context = Config._.crypto.context
|
||||||
|
|
||||||
if (user := cls.get(name)) is None:
|
if (user := cls.get(name)) is None:
|
||||||
# nonexistent user, fake doing password verification
|
# nonexistent user, fake doing password verification
|
||||||
|
|
Loading…
Reference in a new issue