initial commit
This commit is contained in:
+120
@@ -0,0 +1,120 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import secrets
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def load_dotenv(path: str = ".env") -> None:
|
||||
env_path = Path(path)
|
||||
if not env_path.exists():
|
||||
return
|
||||
for raw_line in env_path.read_text().splitlines():
|
||||
line = raw_line.strip()
|
||||
if not line or line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
key, value = line.split("=", 1)
|
||||
os.environ.setdefault(key.strip(), value.strip().strip('"').strip("'"))
|
||||
|
||||
|
||||
def _bool(name: str, default: bool = False) -> bool:
|
||||
value = os.environ.get(name)
|
||||
if value is None:
|
||||
return default
|
||||
return value.lower() in {"1", "true", "yes", "on"}
|
||||
|
||||
|
||||
def _csv(name: str) -> set[str]:
|
||||
return {
|
||||
item.strip().lower()
|
||||
for item in os.environ.get(name, "").split(",")
|
||||
if item.strip()
|
||||
}
|
||||
|
||||
|
||||
#: A "home" deployment serves the public landing page and nothing else: no database, no session,
|
||||
#: no OIDC. Everything that needs an identity lives on the "full" deployment at auth_base_url.
|
||||
ROLES = {"full", "home"}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Config:
|
||||
role: str
|
||||
auth_base_url: str
|
||||
base_url: str
|
||||
host: str
|
||||
port: int
|
||||
secret: str
|
||||
cookie_secure: bool
|
||||
database_url: str
|
||||
trusted_domains: set[str]
|
||||
default_ipa_group: str
|
||||
app_admin_emails: set[str]
|
||||
admin_groups: set[str]
|
||||
oidc_issuer: str
|
||||
oidc_client_id: str
|
||||
oidc_client_secret: str
|
||||
oidc_scopes: str
|
||||
smtp_host: str
|
||||
smtp_port: int
|
||||
smtp_username: str
|
||||
smtp_password: str
|
||||
smtp_from: str
|
||||
smtp_starttls: bool
|
||||
smtp_ssl: bool
|
||||
ipa_mode: str
|
||||
ipa_principal: str
|
||||
ipa_keytab: str
|
||||
ipa_default_shell: str
|
||||
ipa_home_root: str
|
||||
authentik_sync_enabled: bool
|
||||
authentik_sync_container: str
|
||||
authentik_ldap_source_slugs: tuple[str, ...]
|
||||
|
||||
|
||||
def get_config() -> Config:
|
||||
load_dotenv()
|
||||
role = os.environ.get("APP_ROLE", "full").strip().lower()
|
||||
if role not in ROLES:
|
||||
raise SystemExit(f"APP_ROLE must be one of {sorted(ROLES)}, got {role!r}")
|
||||
base_url = os.environ.get("APP_BASE_URL", "http://127.0.0.1:8080").rstrip("/")
|
||||
database_url = os.environ.get("DATABASE_URL", "")
|
||||
if role != "home" and not database_url:
|
||||
raise SystemExit("DATABASE_URL is required unless APP_ROLE=home")
|
||||
return Config(
|
||||
role=role,
|
||||
# Where the pages this deployment does not serve actually live. A "full" deployment serves
|
||||
# them itself, so its own base URL is the right answer.
|
||||
auth_base_url=os.environ.get("AUTH_BASE_URL", base_url).rstrip("/"),
|
||||
base_url=base_url,
|
||||
host=os.environ.get("APP_HOST", "127.0.0.1"),
|
||||
port=int(os.environ.get("APP_PORT", "8080")),
|
||||
secret=os.environ.get("APP_SECRET", secrets.token_hex(32)),
|
||||
cookie_secure=_bool("COOKIE_SECURE", False),
|
||||
database_url=database_url,
|
||||
trusted_domains=_csv("TRUSTED_EMAIL_DOMAINS"),
|
||||
default_ipa_group=os.environ.get("DEFAULT_IPA_GROUP", "sticknife_users"),
|
||||
app_admin_emails=_csv("APP_ADMIN_EMAILS"),
|
||||
admin_groups=_csv("APP_ADMIN_GROUPS") or {"sticknife_admins"},
|
||||
oidc_issuer=os.environ.get("OIDC_ISSUER", "https://auth.sticknife.com/application/o/charon/").rstrip("/"),
|
||||
oidc_client_id=os.environ.get("OIDC_CLIENT_ID", ""),
|
||||
oidc_client_secret=os.environ.get("OIDC_CLIENT_SECRET", ""),
|
||||
oidc_scopes=os.environ.get("OIDC_SCOPES", "openid profile email groups"),
|
||||
smtp_host=os.environ.get("SMTP_HOST", "mail.sticknife.com"),
|
||||
smtp_port=int(os.environ.get("SMTP_PORT", "587")),
|
||||
smtp_username=os.environ.get("SMTP_USERNAME", ""),
|
||||
smtp_password=os.environ.get("SMTP_PASSWORD", ""),
|
||||
smtp_from=os.environ.get("SMTP_FROM", "accounts@sticknife.com"),
|
||||
smtp_starttls=_bool("SMTP_STARTTLS", True),
|
||||
smtp_ssl=_bool("SMTP_SSL", False),
|
||||
ipa_mode=os.environ.get("STICKNIFE_IPA_PROVISION_MODE", "dry-run"),
|
||||
ipa_principal=os.environ.get("IPA_PRINCIPAL", ""),
|
||||
ipa_keytab=os.environ.get("IPA_KEYTAB", ""),
|
||||
ipa_default_shell=os.environ.get("IPA_DEFAULT_SHELL", "/bin/bash"),
|
||||
ipa_home_root=os.environ.get("IPA_HOME_ROOT", "/home"),
|
||||
authentik_sync_enabled=_bool("AUTHENTIK_SYNC_ENABLED", False),
|
||||
authentik_sync_container=os.environ.get("AUTHENTIK_SYNC_CONTAINER", "authentik-worker-1"),
|
||||
authentik_ldap_source_slugs=tuple(sorted(_csv("AUTHENTIK_LDAP_SOURCE_SLUGS"))),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user