import os from functools import lru_cache from typing import List class Settings: """Application settings loaded from environment.""" def __init__(self) -> None: self.auth_mode: str = os.getenv("SKD_AUTH_MODE", "pam").lower() if self.auth_mode not in ("pam", "oidc"): self.auth_mode = "pam" self.allowed_users: List[str] = self._parse_list(os.getenv("SKD_ALLOWED_USERS", "")) self.auth_secret: str = os.getenv("SKD_AUTH_SECRET", "change-me-secret") self.token_ttl_seconds: int = int(os.getenv("SKD_TOKEN_TTL_SECONDS", "900")) self.auth_allowed_users: List[str] = self._parse_list(os.getenv("SKD_AUTH_ALLOWED_USERS", "")) self.auth_allowed_groups: List[str] = self._parse_list( os.getenv("SKD_AUTH_ALLOWED_GROUPS", "sudo") ) self.auth_pam_service: str = os.getenv("SKD_AUTH_PAM_SERVICE", "login") self.oidc_issuer: str = os.getenv("SKD_OIDC_ISSUER", "") self.oidc_client_id: str = os.getenv("SKD_OIDC_CLIENT_ID", "") self.oidc_client_secret: str = os.getenv("SKD_OIDC_CLIENT_SECRET", "") self.oidc_redirect_uri: str = os.getenv( "SKD_OIDC_REDIRECT_URI", "http://localhost:8000/login/oidc/callback" ) self.oidc_scopes: str = os.getenv("SKD_OIDC_SCOPES", "openid profile email") self.session_cookie_name: str = os.getenv("SKD_SESSION_COOKIE_NAME", "skd_session") self.session_cookie_secure: bool = ( os.getenv("SKD_SESSION_COOKIE_SECURE", "false").lower() == "true" ) self.oidc_state_cookie_name: str = os.getenv( "SKD_OIDC_STATE_COOKIE_NAME", "skd_oidc_state" ) self.oidc_enabled: bool = bool( self.oidc_issuer and self.oidc_client_id and self.oidc_client_secret ) self.default_countdown: int = int(os.getenv("SKD_DEFAULT_COUNTDOWN", "60")) self.default_sound: bool = os.getenv("SKD_DEFAULT_SOUND", "false").lower() == "true" self.notify_timeout: int = int(os.getenv("SKD_NOTIFY_TIMEOUT", "5")) self.dry_run: bool = os.getenv("SKD_DRY_RUN", "false").lower() == "true" self.update_url: str = os.getenv("SKD_UPDATE_URL", "https://update.wlkns.org") self.update_token: str = os.getenv("SKD_UPDATE_TOKEN", "") self.update_interval: int = int(os.getenv("SKD_UPDATE_INTERVAL", "3600")) self.update_status_url: str = os.getenv( "SKD_UPDATE_STATUS_URL", "https://update.wlkns.org/status" ) # Paths/tools self.notify_send_path: str = os.getenv("SKD_NOTIFY_SEND_PATH", "notify-send") self.sound_player: str = os.getenv("SKD_SOUND_PLAYER", "paplay") self.sound_file: str = os.getenv( "SKD_SOUND_FILE", "/usr/share/sounds/freedesktop/stereo/dialog-warning.oga", ) @staticmethod def _parse_list(value: str) -> List[str]: return [item for item in (part.strip() for part in value.split(",")) if item] @lru_cache(maxsize=1) def get_settings() -> Settings: return Settings()