mirror of
https://github.com/sissbruecker/linkding.git
synced 2025-08-08 11:18:28 +02:00
Merge siteroot application
This commit is contained in:
317
bookmarks/settings/base.py
Normal file
317
bookmarks/settings/base.py
Normal file
@@ -0,0 +1,317 @@
|
||||
"""
|
||||
Django settings for linkding webapp.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 2.2.2.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/2.2/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/2.2/ref/settings/
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import shlex
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
# BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = "kgq$h3@!!vbb6*nzfz(dbze=*)zsroqa8gvc0#1gx$3cd8z99^"
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = False
|
||||
|
||||
ALLOWED_HOSTS = ["*"]
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
"bookmarks.apps.BookmarksConfig",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"widget_tweaks",
|
||||
"rest_framework",
|
||||
"rest_framework.authtoken",
|
||||
"huey.contrib.djhuey",
|
||||
"mozilla_django_oidc",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"bookmarks.middlewares.LinkdingMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
"django.middleware.locale.LocaleMiddleware",
|
||||
]
|
||||
|
||||
ROOT_URLCONF = "bookmarks.urls"
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [],
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.debug",
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
"bookmarks.context_processors.toasts",
|
||||
"bookmarks.context_processors.app_version",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||
|
||||
WSGI_APPLICATION = "bookmarks.wsgi.application"
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
||||
},
|
||||
]
|
||||
|
||||
# Website context path.
|
||||
LD_CONTEXT_PATH = os.getenv("LD_CONTEXT_PATH", "")
|
||||
|
||||
LOGIN_URL = "/" + LD_CONTEXT_PATH + "login"
|
||||
LOGIN_REDIRECT_URL = "/" + LD_CONTEXT_PATH + "bookmarks"
|
||||
LOGOUT_REDIRECT_URL = "/" + LD_CONTEXT_PATH + "login"
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/2.2/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = "en-us"
|
||||
|
||||
TIME_ZONE = os.getenv("TZ", "UTC")
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/2.2/howto/static-files/
|
||||
|
||||
STATIC_URL = "/" + LD_CONTEXT_PATH + "static/"
|
||||
|
||||
# Collect static files in static folder
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, "static")
|
||||
|
||||
# REST framework
|
||||
REST_FRAMEWORK = {
|
||||
"DEFAULT_AUTHENTICATION_CLASSES": [
|
||||
"bookmarks.api.auth.LinkdingTokenAuthentication",
|
||||
"rest_framework.authentication.SessionAuthentication",
|
||||
],
|
||||
"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.IsAuthenticated"],
|
||||
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
|
||||
"PAGE_SIZE": 100,
|
||||
}
|
||||
|
||||
# Registration switch
|
||||
ALLOW_REGISTRATION = False
|
||||
|
||||
# URL validation flag
|
||||
LD_DISABLE_URL_VALIDATION = os.getenv("LD_DISABLE_URL_VALIDATION", False) in (
|
||||
True,
|
||||
"True",
|
||||
"1",
|
||||
)
|
||||
|
||||
# Background task enabled setting
|
||||
LD_DISABLE_BACKGROUND_TASKS = os.getenv("LD_DISABLE_BACKGROUND_TASKS", False) in (
|
||||
True,
|
||||
"True",
|
||||
"1",
|
||||
)
|
||||
|
||||
# Huey task queue
|
||||
HUEY = {
|
||||
"huey_class": "huey.SqliteHuey",
|
||||
"filename": os.path.join(BASE_DIR, "data", "tasks.sqlite3"),
|
||||
"immediate": False,
|
||||
"results": False,
|
||||
"store_none": False,
|
||||
"utc": True,
|
||||
"consumer": {
|
||||
"workers": 2,
|
||||
"worker_type": "thread",
|
||||
"initial_delay": 5,
|
||||
"backoff": 1.15,
|
||||
"max_delay": 10,
|
||||
"scheduler_interval": 10,
|
||||
"periodic": True,
|
||||
"check_worker_health": True,
|
||||
"health_check_interval": 10,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
# Enable OICD support if configured
|
||||
LD_ENABLE_OIDC = os.getenv("LD_ENABLE_OIDC", False) in (True, "True", "1")
|
||||
|
||||
AUTHENTICATION_BACKENDS = ["django.contrib.auth.backends.ModelBackend"]
|
||||
|
||||
if LD_ENABLE_OIDC:
|
||||
AUTHENTICATION_BACKENDS.append("mozilla_django_oidc.auth.OIDCAuthenticationBackend")
|
||||
|
||||
OIDC_USERNAME_ALGO = "bookmarks.utils.generate_username"
|
||||
OIDC_OP_AUTHORIZATION_ENDPOINT = os.getenv("OIDC_OP_AUTHORIZATION_ENDPOINT")
|
||||
OIDC_OP_TOKEN_ENDPOINT = os.getenv("OIDC_OP_TOKEN_ENDPOINT")
|
||||
OIDC_OP_USER_ENDPOINT = os.getenv("OIDC_OP_USER_ENDPOINT")
|
||||
OIDC_OP_JWKS_ENDPOINT = os.getenv("OIDC_OP_JWKS_ENDPOINT")
|
||||
OIDC_RP_CLIENT_ID = os.getenv("OIDC_RP_CLIENT_ID")
|
||||
OIDC_RP_CLIENT_SECRET = os.getenv("OIDC_RP_CLIENT_SECRET")
|
||||
OIDC_RP_SIGN_ALGO = os.getenv("OIDC_RP_SIGN_ALGO", "RS256")
|
||||
OIDC_RP_SCOPES = os.getenv("OIDC_RP_SCOPES", "openid email profile")
|
||||
OIDC_USE_PKCE = os.getenv("OIDC_USE_PKCE", True) in (True, "True", "1")
|
||||
OIDC_VERIFY_SSL = os.getenv("OIDC_VERIFY_SSL", True) in (True, "True", "1")
|
||||
OIDC_USERNAME_CLAIM = os.getenv("OIDC_USERNAME_CLAIM", "email")
|
||||
|
||||
# Enable authentication proxy support if configured
|
||||
LD_ENABLE_AUTH_PROXY = os.getenv("LD_ENABLE_AUTH_PROXY", False) in (True, "True", "1")
|
||||
LD_AUTH_PROXY_USERNAME_HEADER = os.getenv(
|
||||
"LD_AUTH_PROXY_USERNAME_HEADER", "REMOTE_USER"
|
||||
)
|
||||
LD_AUTH_PROXY_LOGOUT_URL = os.getenv("LD_AUTH_PROXY_LOGOUT_URL", None)
|
||||
|
||||
if LD_ENABLE_AUTH_PROXY:
|
||||
# Add middleware that automatically authenticates requests that have a known username
|
||||
# in the LD_AUTH_PROXY_USERNAME_HEADER request header
|
||||
MIDDLEWARE.append("bookmarks.middlewares.CustomRemoteUserMiddleware")
|
||||
# Configure auth backend that does not require a password credential
|
||||
AUTHENTICATION_BACKENDS = ["django.contrib.auth.backends.RemoteUserBackend"]
|
||||
# Configure logout URL
|
||||
if LD_AUTH_PROXY_LOGOUT_URL:
|
||||
LOGOUT_REDIRECT_URL = LD_AUTH_PROXY_LOGOUT_URL
|
||||
|
||||
# CSRF trusted origins
|
||||
trusted_origins = os.getenv("LD_CSRF_TRUSTED_ORIGINS", "")
|
||||
if trusted_origins:
|
||||
CSRF_TRUSTED_ORIGINS = trusted_origins.split(",")
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
||||
|
||||
LD_DB_ENGINE = os.getenv("LD_DB_ENGINE", "sqlite")
|
||||
LD_DB_HOST = os.getenv("LD_DB_HOST", "localhost")
|
||||
LD_DB_DATABASE = os.getenv("LD_DB_DATABASE", "linkding")
|
||||
LD_DB_USER = os.getenv("LD_DB_USER", "linkding")
|
||||
LD_DB_PASSWORD = os.getenv("LD_DB_PASSWORD", None)
|
||||
LD_DB_PORT = os.getenv("LD_DB_PORT", None)
|
||||
LD_DB_OPTIONS = json.loads(os.getenv("LD_DB_OPTIONS") or "{}")
|
||||
|
||||
if LD_DB_ENGINE == "postgres":
|
||||
default_database = {
|
||||
"ENGINE": "django.db.backends.postgresql_psycopg2",
|
||||
"NAME": LD_DB_DATABASE,
|
||||
"USER": LD_DB_USER,
|
||||
"PASSWORD": LD_DB_PASSWORD,
|
||||
"HOST": LD_DB_HOST,
|
||||
"PORT": LD_DB_PORT,
|
||||
"OPTIONS": LD_DB_OPTIONS,
|
||||
}
|
||||
else:
|
||||
default_database = {
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": os.path.join(BASE_DIR, "data", "db.sqlite3"),
|
||||
"OPTIONS": LD_DB_OPTIONS,
|
||||
# Creating a connection loads the ICU extension into the SQLite
|
||||
# connection, and also loads an ICU collation. The latter causes a
|
||||
# memory leak, so try to counter that by making connections indefinitely
|
||||
# persistent.
|
||||
"CONN_MAX_AGE": None,
|
||||
}
|
||||
|
||||
DATABASES = {"default": default_database}
|
||||
|
||||
SQLITE_ICU_EXTENSION_PATH = "./libicu.so"
|
||||
USE_SQLITE = default_database["ENGINE"] == "django.db.backends.sqlite3"
|
||||
USE_SQLITE_ICU_EXTENSION = USE_SQLITE and os.path.exists(SQLITE_ICU_EXTENSION_PATH)
|
||||
|
||||
# Favicons
|
||||
LD_DEFAULT_FAVICON_PROVIDER = "https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url={url}&size=32"
|
||||
LD_FAVICON_PROVIDER = os.getenv("LD_FAVICON_PROVIDER", LD_DEFAULT_FAVICON_PROVIDER)
|
||||
LD_FAVICON_FOLDER = os.path.join(BASE_DIR, "data", "favicons")
|
||||
LD_ENABLE_REFRESH_FAVICONS = os.getenv("LD_ENABLE_REFRESH_FAVICONS", True) in (
|
||||
True,
|
||||
"True",
|
||||
"1",
|
||||
)
|
||||
|
||||
# Previews settings
|
||||
LD_PREVIEW_FOLDER = os.path.join(BASE_DIR, "data", "previews")
|
||||
LD_PREVIEW_MAX_SIZE = int(os.getenv("LD_PREVIEW_MAX_SIZE", 5242880))
|
||||
LD_PREVIEW_ALLOWED_EXTENSIONS = [
|
||||
".jpg",
|
||||
".jpeg",
|
||||
".png",
|
||||
".gif",
|
||||
".svg",
|
||||
".webp",
|
||||
]
|
||||
|
||||
# Asset / snapshot settings
|
||||
LD_ASSET_FOLDER = os.path.join(BASE_DIR, "data", "assets")
|
||||
|
||||
LD_ENABLE_SNAPSHOTS = os.getenv("LD_ENABLE_SNAPSHOTS", False) in (
|
||||
True,
|
||||
"True",
|
||||
"1",
|
||||
)
|
||||
LD_DISABLE_ASSET_UPLOAD = os.getenv("LD_DISABLE_ASSET_UPLOAD", False) in (
|
||||
True,
|
||||
"True",
|
||||
"1",
|
||||
)
|
||||
LD_SINGLEFILE_PATH = os.getenv("LD_SINGLEFILE_PATH", "single-file")
|
||||
LD_SINGLEFILE_UBLOCK_OPTIONS = os.getenv(
|
||||
"LD_SINGLEFILE_UBLOCK_OPTIONS",
|
||||
shlex.join(
|
||||
[
|
||||
'--browser-arg="--headless=new"',
|
||||
'--browser-arg="--user-data-dir=./chromium-profile"',
|
||||
'--browser-arg="--no-sandbox"',
|
||||
'--browser-arg="--load-extension=uBOLite.chromium.mv3"',
|
||||
]
|
||||
),
|
||||
)
|
||||
LD_SINGLEFILE_OPTIONS = os.getenv("LD_SINGLEFILE_OPTIONS", "")
|
||||
LD_SINGLEFILE_TIMEOUT_SEC = float(os.getenv("LD_SINGLEFILE_TIMEOUT_SEC", 120))
|
||||
|
||||
# Monolith isn't used at the moment, as the local snapshot implementation
|
||||
# switched to single-file after the prototype. Keeping this around in case
|
||||
# it turns out to be useful in the future.
|
||||
LD_MONOLITH_PATH = os.getenv("LD_MONOLITH_PATH", "monolith")
|
||||
LD_MONOLITH_OPTIONS = os.getenv("LD_MONOLITH_OPTIONS", "-a -v -s")
|
Reference in New Issue
Block a user