Make database, oauth, smtp server, mail verificaiton configurable in .env

This commit is contained in:
krek0 2026-05-02 14:18:02 +02:00
parent 3a73bb8887
commit 7fbc81b9e1
8 changed files with 109 additions and 31 deletions

View file

@ -14,3 +14,39 @@ ADMINS=admin:photos-admin@lists.crans.org
# Email address used as sender for server emails
SERVER_EMAIL=photos@crans.org
# Email verification: 'mandatory', 'optional', or 'none'
EMAIL_VERIFICATION=mandatory
# Mail server settings
SMTP_HOST=localhost
SMTP_PORT=25
#SMTP_USER=
#SMTP_PASSWORD=
SMTP_USE_TLS=False
# OAuth2 settings
# Enable OAuth2 login
OAUTH_ENABLED=False
# Disable normal username/password login (requires OAUTH_ENABLED=True)
OAUTH_ONLY=False
# OAuth2 server base URL (e.g. auth.example.com)
#OAUTH_SERVER_URL=
# OAuth2 app credentials
#OAUTH_CLIENT_ID=
#OAUTH_CLIENT_SECRET=
# Button appearance on the login page
#OAUTH_BUTTON_TEXT=Login with OAuth
#OAUTH_BUTTON_IMAGE=
# Space-separated OAuth2 scopes
#OAUTH_SCOPE=openid profile email
# Database engine: 'sqlite' or 'postgres'
DB_ENGINE=sqlite
# PostgreSQL settings (only used when DB_ENGINE=postgres)
#DB_NAME=photo21
#DB_USER=photo21
#DB_PASSWORD=
#DB_HOST=localhost
#DB_PORT=5432

View file

@ -1,3 +1,5 @@
# This file is part of photo21
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = "allauth_oauth.apps.AllauthOAuthConfig"

View file

@ -7,15 +7,15 @@ from allauth.socialaccount.providers.base import ProviderAccount
from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider
class NoteKfetAccount(ProviderAccount):
class OAuthAccount(ProviderAccount):
def to_str(self):
return self.account.extra_data.get("username")
class NoteKfetProvider(OAuth2Provider):
id = "notekfet"
name = "Note Kfet"
account_class = NoteKfetAccount
class OAuthProvider(OAuth2Provider):
id = "oauth"
name = "OAuth"
account_class = OAuthAccount
def extract_uid(self, data):
return str(data["username"])
@ -39,4 +39,4 @@ class NoteKfetProvider(OAuth2Provider):
return ret
provider_classes = [NoteKfetProvider]
provider_classes = [OAuthProvider]

View file

@ -4,6 +4,6 @@
from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns
from .provider import NoteKfetProvider
from .provider import OAuthProvider
urlpatterns = default_urlpatterns(NoteKfetProvider)
urlpatterns = default_urlpatterns(OAuthProvider)

View file

@ -10,11 +10,11 @@ from allauth.socialaccount.providers.oauth2.views import (
OAuth2LoginView,
)
from .provider import NoteKfetProvider
from .provider import OAuthProvider
class NoteKfetOAuth2Adapter(OAuth2Adapter):
provider_id = NoteKfetProvider.id
class OAuthAdapter(OAuth2Adapter):
provider_id = OAuthProvider.id
def complete_login(self, request, app, token, **kwargs):
headers = {
@ -31,7 +31,7 @@ class NoteKfetOAuth2Adapter(OAuth2Adapter):
@property
def domain(self):
return self.settings.get("DOMAIN", "note.crans.org")
return self.settings.get("DOMAIN", "")
@property
def access_token_url(self):
@ -46,5 +46,5 @@ class NoteKfetOAuth2Adapter(OAuth2Adapter):
return f"https://{self.domain}/api/me/"
oauth2_login = OAuth2LoginView.adapter_view(NoteKfetOAuth2Adapter)
oauth2_callback = OAuth2CallbackView.adapter_view(NoteKfetOAuth2Adapter)
oauth2_login = OAuth2LoginView.adapter_view(OAuthAdapter)
oauth2_callback = OAuth2CallbackView.adapter_view(OAuthAdapter)

View file

@ -56,6 +56,15 @@ SECURE_HSTS_PRELOAD = True
# Application definition
OAUTH_ENABLED = config("OAUTH_ENABLED", default=False, cast=bool)
OAUTH_ONLY = config("OAUTH_ONLY", default=False, cast=bool)
OAUTH_CLIENT_ID = config("OAUTH_CLIENT_ID", default="")
OAUTH_CLIENT_SECRET = config("OAUTH_CLIENT_SECRET", default="")
OAUTH_SERVER_URL = config("OAUTH_SERVER_URL", default="")
OAUTH_BUTTON_TEXT = config("OAUTH_BUTTON_TEXT", default="Login with OAuth")
OAUTH_BUTTON_IMAGE = config("OAUTH_BUTTON_IMAGE", default="")
OAUTH_SCOPE = config("OAUTH_SCOPE", default="openid profile email", cast=Csv(delimiter=" "))
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.admindocs",
@ -69,12 +78,14 @@ INSTALLED_APPS = [
"allauth",
"allauth.account",
"allauth.socialaccount",
"allauth_note_kfet",
"crispy_forms",
"photologue",
"photo21",
]
if OAUTH_ENABLED:
INSTALLED_APPS += ["allauth_oauth"]
if DEBUG:
INSTALLED_APPS += ["debug_toolbar",] # For debug and optimisations
@ -125,15 +136,31 @@ WSGI_APPLICATION = "photo21.wsgi.application"
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
"OPTIONS": {
"timeout": 10,
},
_db_engine = config("DB_ENGINE", default="sqlite").strip().lower()
if _db_engine == "postgres":
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": config("DB_NAME", default="photo21"),
"USER": config("DB_USER", default="photo21"),
"PASSWORD": config("DB_PASSWORD", default=""),
"HOST": config("DB_HOST", default="localhost"),
"PORT": config("DB_PORT", default="5432"),
}
}
}
elif _db_engine == "sqlite":
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
"OPTIONS": {
"timeout": 10,
},
}
}
else:
raise ValueError(f"Unknown DB_ENGINE '{_db_engine}'. Must be 'sqlite' or 'postgres'.")
CACHES = {
"default": {
@ -221,6 +248,11 @@ if DEBUG:
SERVER_EMAIL = config("SERVER_EMAIL", default="photos@crans.org")
DEFAULT_FROM_EMAIL = f"Serveur photos <{SERVER_EMAIL}>"
EMAIL_SUBJECT_PREFIX = "[Serveur photos] "
EMAIL_HOST = config("SMTP_HOST", default="localhost")
EMAIL_PORT = config("SMTP_PORT", default=25, cast=int)
EMAIL_HOST_USER = config("SMTP_USER", default="")
EMAIL_HOST_PASSWORD = config("SMTP_PASSWORD", default="")
EMAIL_USE_TLS = config("SMTP_USE_TLS", default=False, cast=bool)
# After login redirect user to transfer page
LOGIN_REDIRECT_URL = "/"
@ -240,16 +272,23 @@ MESSAGE_TAGS = {
# Allauth configuration ## For the django =< 5.0
ACCOUNT_EMAIL_REQUIRED = True
# ACCOUNT_SIGNUP_FIELDS = ['email*', 'username*', 'password1*', 'password2*'] ## For the django =< 5.0
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
ACCOUNT_EMAIL_VERIFICATION = config("EMAIL_VERIFICATION", default="mandatory")
ACCOUNT_AUTHENTICATION_METHOD = "username_email"
# ACCOUNT_LOGIN_METHODS = {'username', 'email'}
ACCOUNT_FORMS = {"signup": "photo21.forms.CustomSignupForm"}
SOCIALACCOUNT_PROVIDERS = {
"notekfet": {
# Fetch user profile
"SCOPE": ["1_1"],
},
}
if OAUTH_ENABLED:
SOCIALACCOUNT_ONLY = OAUTH_ONLY
SOCIALACCOUNT_PROVIDERS = {
"oauth": {
"SCOPE": OAUTH_SCOPE,
"DOMAIN": OAUTH_SERVER_URL,
"APP": {
"client_id": OAUTH_CLIENT_ID,
"secret": OAUTH_CLIENT_SECRET,
},
},
}
# Use Bootstrap forms
CRISPY_TEMPLATE_PACK = "bootstrap4"

View file

@ -7,3 +7,4 @@ Pillow>=6.0.0
django-debug-toolbar>=3.2.0
python-decouple>=3.6
whitenoise>=6.0
psycopg2>=2.9

View file

@ -27,7 +27,7 @@ deps =
pep8-naming
pyflakes
commands =
flake8 allauth_note_kfet photo21 photologue
flake8 allauth_oauth photo21 photologue
[flake8]
ignore = W503, I100, I101