From 667fcba559921e93b9d2c0efe333300fb7606ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn-Michael=20Miehe?= <40151420+ldericher@users.noreply.github.com> Date: Wed, 30 Mar 2022 10:15:24 +0000 Subject: [PATCH] plan: server props --- api/kiwi_vpn_api/config.py | 53 ++++++++++++++++++++++++++++++++----- api/kiwi_vpn_api/db/user.py | 4 +-- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/api/kiwi_vpn_api/config.py b/api/kiwi_vpn_api/config.py index 2ba228a..c4ff5f2 100644 --- a/api/kiwi_vpn_api/config.py +++ b/api/kiwi_vpn_api/config.py @@ -15,11 +15,12 @@ from datetime import datetime, timedelta from enum import Enum from pathlib import Path from secrets import token_urlsafe +from typing import Any from jose import JWTError, jwt from jose.constants import ALGORITHMS from passlib.context import CryptContext -from pydantic import BaseModel, BaseSettings, Field, validator +from pydantic import BaseModel, BaseSettings, constr, validator class Settings(BaseSettings): @@ -64,7 +65,7 @@ class DBConfig(BaseModel): user: str | None = None password: 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_args: list[str] = ["charset=utf8mb4"] @@ -168,6 +169,35 @@ class JWTConfig(BaseModel): 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): """ Configuration for hash algorithms @@ -175,8 +205,15 @@ class CryptoConfig(BaseModel): schemes: list[str] = ["bcrypt"] + force_cipher: ToggleString + force_tls_cipher: ToggleString + force_auth: ToggleString + + cert_algo: CertificateAlgo + expiry_days: int + @property - def crypt_context(self) -> CryptContext: + def context(self) -> CryptContext: return CryptContext( schemes=self.schemes, deprecated="auto", @@ -188,9 +225,13 @@ class Config(BaseModel): Configuration for `kiwi-vpn-api` """ - db: DBConfig = Field(default_factory=DBConfig) - jwt: JWTConfig = Field(default_factory=JWTConfig) - crypto: CryptoConfig = Field(default_factory=CryptoConfig) + server_name: str + server_extra_config: dict[str, Any] + + db: DBConfig + jwt: JWTConfig + crypto: CryptoConfig + dnparts: DNParts __singleton: Config | None = None diff --git a/api/kiwi_vpn_api/db/user.py b/api/kiwi_vpn_api/db/user.py index b59be6d..be387da 100644 --- a/api/kiwi_vpn_api/db/user.py +++ b/api/kiwi_vpn_api/db/user.py @@ -56,7 +56,7 @@ class UserCreate(UserBase): if (current_config := Config._) is None: raise ValueError("Not configured") - values["password"] = current_config.crypto.crypt_context.hash( + values["password"] = current_config.crypto.context.hash( password_clear) return values @@ -132,7 +132,7 @@ class User(UserBase, table=True): 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: # nonexistent user, fake doing password verification