from __future__ import annotations from enum import Enum import json from pathlib import Path from typing import Optional from jose.constants import ALGORITHMS from passlib.context import CryptContext from peewee import Database, SqliteDatabase from pydantic import BaseModel, Field DB = SqliteDatabase("tmp/vpn.db") PRODUCTION_MODE = False # to get a string like this run: # openssl rand -hex 32 SECRET_KEY = "2f7875b0d2be8a76eba8077ab4d9f8b1c749e02647e9ac9e0f909c3acbfc9856" ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30 CRYPT_CONTEXT = CryptContext(schemes=["bcrypt"], deprecated="auto") class DBType(Enum): sqlite = "sqlite" mysql = "mysql" class DBConfig(BaseModel): db_type: DBType = DBType.sqlite @property def database(self) -> Database: return SqliteDatabase("tmp/vpn.db") class JWTConfig(BaseModel): secret: Optional[str] = None hash_algorithm: str = ALGORITHMS.HS256 expiry_minutes: int = 30 class CryptoConfig(BaseModel): schemes: list[str] = ["bcrypt"] @property def cryptContext(self) -> CryptContext: return CryptContext(schemes=self.schemes, deprecated="auto") class BaseConfig(BaseModel): db: DBConfig = Field(default_factory=DBConfig) jwt: JWTConfig = Field(default_factory=JWTConfig) crypto: CryptoConfig = Field(default_factory=CryptoConfig) def save(self, filename: Path) -> None: with open(filename, "w") as kv: kv.write(self.json(indent=2)) CONFIG_FILE = "tmp/config.json" async def get_default_config() -> BaseConfig: return BaseConfig() async def is_configured() -> bool: return Path(CONFIG_FILE).is_file() async def get_current_config() -> BaseConfig: with open(CONFIG_FILE, "r") as kv: return BaseConfig.parse_obj(json.load(kv))