Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 40 additions & 31 deletions src/website/tracker/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,27 @@
import sys
from os import environ as env
from pathlib import Path
from typing import Annotated

import dj_database_url
import sentry_sdk
from pydantic import BaseModel, DirectoryPath, Field
from pydantic import BaseModel, DirectoryPath, Field, PlainSerializer
from pydantic_settings import BaseSettings, SettingsConfigDict
from sentry_sdk.integrations.django import DjangoIntegration


def get_secret(name: str, encoding: str = "utf-8") -> str:
credentials_dir = Secrets().CREDENTIALS_DIRECTORY # type: ignore[reportCallIssue]

try:
with open(f"{credentials_dir}/{name}", encoding=encoding) as f:
secret = f.read().removesuffix("\n")
except FileNotFoundError:
raise RuntimeError(f"No secret named {name} found in {credentials_dir}.")

return secret


class Secrets(BaseSettings):
CREDENTIALS_DIRECTORY: DirectoryPath

Expand Down Expand Up @@ -90,32 +103,43 @@ class DjangoSettings(BaseModel):
default=[],
)

DJANGO_SETTINGS: DjangoSettings
class SocialAccountProviders(BaseModel):
class GitHub(BaseModel):
SCOPE: list[str] = Field(
description="Access scopes required by the application"
)

class AppSettings(BaseModel):
client_id: Annotated[str, PlainSerializer(get_secret)]
secret: Annotated[str, PlainSerializer(get_secret)]
key: str = ""

for key, value in Settings().dict()["DJANGO_SETTINGS"].items(): # type: ignore[reportCallIssue]
setattr(sys.modules[__name__], key, value)
APPS: list[AppSettings] = []

# TODO(@fricklerhandwerk): move all configuration over to pydantic-settings
github: GitHub | None

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
_GitHub = SocialAccountProviders.GitHub
_App = SocialAccountProviders.GitHub.AppSettings

SOCIALACCOUNT_PROVIDERS: SocialAccountProviders = SocialAccountProviders(
github=_GitHub(
SCOPE=["read:user", "read:org"],
APPS=[_App(client_id="GH_CLIENT_ID", secret="GH_SECRET")],
),
)

def get_secret(name: str, encoding: str = "utf-8") -> str:
credentials_dir = Secrets().CREDENTIALS_DIRECTORY # type: ignore[reportCallIssue]
DJANGO_SETTINGS: DjangoSettings

try:
with open(f"{credentials_dir}/{name}", encoding=encoding) as f:
secret = f.read().removesuffix("\n")
except FileNotFoundError:
raise RuntimeError(f"No secret named {name} found in {credentials_dir}.")

return secret
for key, value in Settings().model_dump()["DJANGO_SETTINGS"].items(): # type: ignore[reportCallIssue]
setattr(sys.modules[__name__], key, value)

# TODO(@fricklerhandwerk): move all configuration over to pydantic-settings

## GlitchTip setup
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

## GlitchTip setup
if "GLITCHTIP_DSN" in env:
sentry_sdk.init(
dsn=get_secret("GLITCHTIP_DSN"),
Expand Down Expand Up @@ -312,21 +336,6 @@ def get_secret(name: str, encoding: str = "utf-8") -> str:
"allauth.account.auth_backends.AuthenticationBackend",
]

SOCIALACCOUNT_PROVIDERS = {
"github": {
"SCOPE": [
"read:user",
"read:org",
],
"APPS": [
{
"client_id": get_secret("GH_CLIENT_ID"),
"secret": get_secret("GH_SECRET"),
"key": "",
}
],
}
}

REST_FRAMEWORK = {
"DEFAULT_FILTER_BACKENDS": ["django_filters.rest_framework.DjangoFilterBackend"]
Expand Down