|
7 | 7 | from urllib.parse import urlparse |
8 | 8 |
|
9 | 9 | from celery.schedules import crontab |
10 | | -from decouple import Csv, config |
| 10 | +from decouple import ( |
| 11 | + Config, |
| 12 | + Csv, |
| 13 | + RepositorySecret, |
| 14 | + Undefined, |
| 15 | + UndefinedValueError, |
| 16 | + config, |
| 17 | + undefined, |
| 18 | +) |
11 | 19 | from django.core.cache import CacheKeyWarning |
12 | 20 |
|
13 | 21 | # Build paths inside the project like this: BASE_DIR / 'subdir'. |
14 | 22 | BASE_DIR = Path(__file__).resolve().parent.parent |
15 | 23 |
|
16 | 24 |
|
| 25 | +def secret(key, default=undefined, **kwargs): |
| 26 | + """Try to read a config value from a secret file. |
| 27 | +
|
| 28 | + If only the filename is given, try to read from /run/secrets/<key>. |
| 29 | + If an absolute path is specified, try to read from this path. |
| 30 | + """ |
| 31 | + if isinstance(default, Undefined): |
| 32 | + default = None |
| 33 | + |
| 34 | + file = config(key, default, **kwargs) |
| 35 | + |
| 36 | + if file is None: |
| 37 | + return undefined |
| 38 | + if file == default: |
| 39 | + return default |
| 40 | + |
| 41 | + path = Path(file) |
| 42 | + try: |
| 43 | + if path.is_absolute(): |
| 44 | + return Config(RepositorySecret(path.parent))(path.stem, default, **kwargs) |
| 45 | + return Config(RepositorySecret())(file, default, **kwargs) |
| 46 | + except ( |
| 47 | + FileNotFoundError, |
| 48 | + IsADirectoryError, |
| 49 | + UndefinedValueError, |
| 50 | + ) as err: |
| 51 | + msg = f"File from {key} not found. Please check the path and filename." |
| 52 | + raise UndefinedValueError(msg) from err |
| 53 | + |
| 54 | + |
17 | 55 | # Quick-start development settings - unsuitable for production |
18 | 56 | # See https://docs.djangoproject.com/en/stable/howto/deployment/checklist/ |
19 | 57 |
|
20 | 58 | # SECURITY WARNING: keep the secret key used in production secret! |
21 | | -SECRET_KEY = config("SECRET", default="secret") |
| 59 | +SECRET_KEY = config( |
| 60 | + "SECRET", |
| 61 | + default=secret("SECRET_FILE", default="ifx7bdUWo5EwC2NQNihjRjOrW00Cdv5Y"), |
| 62 | +) |
| 63 | + |
22 | 64 |
|
23 | 65 | # SECURITY WARNING: don't run with debug turned on in production! |
24 | 66 | DEBUG = config("DEBUG", default=False, cast=bool) |
|
132 | 174 | "default": { |
133 | 175 | "ENGINE": "django.db.backends.postgresql", |
134 | 176 | "HOST": config("DB_HOST"), |
135 | | - "NAME": config("DB_NAME"), |
136 | | - "USER": config("DB_USER"), |
137 | | - "PASSWORD": config("DB_PASSWORD"), |
| 177 | + "NAME": config("DB_NAME", default=secret("DB_NAME_FILE")), |
| 178 | + "USER": config("DB_USER", default=secret("DB_USER_FILE")), |
| 179 | + "PASSWORD": config("DB_PASSWORD", default=secret("DB_PASSWORD_FILE")), |
138 | 180 | "PORT": config("DB_PORT"), |
139 | 181 | }, |
140 | 182 | } |
|
246 | 288 | # Yamtrack settings |
247 | 289 |
|
248 | 290 | # For CSV imports |
249 | | -FILE_UPLOAD_MAX_MEMORY_SIZE = 10 * 1024 * 1024 # 10 MB |
| 291 | +FILE_UPLOAD_MAX_MEMORY_SIZE = 10 * 1024 * 1024 # 10 MB |
250 | 292 |
|
251 | 293 | VERSION = config("VERSION", default="dev") |
252 | 294 |
|
|
259 | 301 | REQUEST_TIMEOUT = 120 # seconds |
260 | 302 | PER_PAGE = 24 |
261 | 303 |
|
262 | | -TMDB_API = config("TMDB_API", default="61572be02f0a068658828f6396aacf60") |
| 304 | +TMDB_API = config( |
| 305 | + "TMDB_API", |
| 306 | + default=secret( |
| 307 | + "TMDB_API_FILE", |
| 308 | + "61572be02f0a068658828f6396aacf60", |
| 309 | + ), |
| 310 | +) |
263 | 311 | TMDB_NSFW = config("TMDB_NSFW", default=False, cast=bool) |
264 | 312 | TMDB_LANG = config("TMDB_LANG", default="en") |
265 | 313 |
|
266 | | -MAL_API = config("MAL_API", default="25b5581dafd15b3e7d583bb79e9a1691") |
| 314 | +MAL_API = config( |
| 315 | + "MAL_API", |
| 316 | + default=secret( |
| 317 | + "MAL_API_FILE", |
| 318 | + "25b5581dafd15b3e7d583bb79e9a1691", |
| 319 | + ), |
| 320 | +) |
267 | 321 | MAL_NSFW = config("MAL_NSFW", default=False, cast=bool) |
268 | 322 |
|
269 | 323 | MU_NSFW = config("MU_NSFW", default=False, cast=bool) |
270 | 324 |
|
271 | | -IGDB_ID = config("IGDB_ID", default="8wqmm7x1n2xxtnz94lb8mthadhtgrt") |
272 | | -IGDB_SECRET = config("IGDB_SECRET", default="ovbq0hwscv58hu46yxn50hovt4j8kj") |
| 325 | +IGDB_ID = config( |
| 326 | + "IGDB_ID", |
| 327 | + default=secret( |
| 328 | + "IGDB_ID_FILE", |
| 329 | + "8wqmm7x1n2xxtnz94lb8mthadhtgrt", |
| 330 | + ), |
| 331 | +) |
| 332 | +IGDB_SECRET = config( |
| 333 | + "IGDB_SECRET", |
| 334 | + default=secret( |
| 335 | + "IGDB_SECRET_FILE", |
| 336 | + "ovbq0hwscv58hu46yxn50hovt4j8kj", |
| 337 | + ), |
| 338 | +) |
273 | 339 | IGDB_NSFW = config("IGDB_NSFW", default=False, cast=bool) |
274 | 340 |
|
275 | 341 | HARDCOVER_API = config( |
276 | 342 | "HARDCOVER_API", |
277 | | - default="Bearer eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJIYXJkY292ZXIiLCJ2ZXJzaW9uIjoiOCIsImp0aSI6ImJhNGNjZmUwLTgwZmQtNGI3NC1hZDdhLTlkNDM5ZTA5YWMzOSIsImFwcGxpY2F0aW9uSWQiOjIsInN1YiI6IjM0OTUxIiwiYXVkIjoiMSIsImlkIjoiMzQ5NTEiLCJsb2dnZWRJbiI6dHJ1ZSwiaWF0IjoxNzQ2OTc3ODc3LCJleHAiOjE3Nzg1MTM4NzcsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9jbGFpbXMiOnsieC1oYXN1cmEtYWxsb3dlZC1yb2xlcyI6WyJ1c2VyIl0sIngtaGFzdXJhLWRlZmF1bHQtcm9sZSI6InVzZXIiLCJ4LWhhc3VyYS1yb2xlIjoidXNlciIsIlgtaGFzdXJhLXVzZXItaWQiOiIzNDk1MSJ9LCJ1c2VyIjp7ImlkIjozNDk1MX19.edcEqLAeO3uH5xxBTFDKtyWwi-B-WfXX_yiLFdOAJ3c", # noqa: E501 |
| 343 | + default=secret( |
| 344 | + "HARDCOVER_API_FILE", |
| 345 | + "Bearer eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJIYXJkY292ZXIiLCJ2ZXJzaW9uIjoiOCIsImp0" |
| 346 | + "aSI6ImJhNGNjZmUwLTgwZmQtNGI3NC1hZDdhLTlkNDM5ZTA5YWMzOSIsImFwcGxpY2F0aW9uSWQi" |
| 347 | + "OjIsInN1YiI6IjM0OTUxIiwiYXVkIjoiMSIsImlkIjoiMzQ5NTEiLCJsb2dnZWRJbiI6dHJ1ZSwi" |
| 348 | + "aWF0IjoxNzQ2OTc3ODc3LCJleHAiOjE3Nzg1MTM4NzcsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9j" |
| 349 | + "bGFpbXMiOnsieC1oYXN1cmEtYWxsb3dlZC1yb2xlcyI6WyJ1c2VyIl0sIngtaGFzdXJhLWRlZmF1" |
| 350 | + "bHQtcm9sZSI6InVzZXIiLCJ4LWhhc3VyYS1yb2xlIjoidXNlciIsIlgtaGFzdXJhLXVzZXItaWQi" |
| 351 | + "OiIzNDk1MSJ9LCJ1c2VyIjp7ImlkIjozNDk1MX19.edcEqLAeO3uH5xxBTFDKtyWwi-B-WfXX_yi" |
| 352 | + "LFdOAJ3c", |
| 353 | + ), |
278 | 354 | ) |
279 | 355 |
|
280 | 356 | COMICVINE_API = config( |
281 | 357 | "COMICVINE_API", |
282 | | - default="cdab0706269e4bca03a096fbc39920dadf7e4992", |
| 358 | + default=secret( |
| 359 | + "COMICVINE_API_FILE", |
| 360 | + "cdab0706269e4bca03a096fbc39920dadf7e4992", |
| 361 | + ), |
283 | 362 | ) |
284 | 363 |
|
285 | | - |
286 | 364 | TRAKT_API = config( |
287 | 365 | "TRAKT_API", |
288 | | - default="b4d9702b11cfaddf5e863001f68ce9d4394b678926e8a3f64d47bf69a55dd0fe", |
| 366 | + default=secret( |
| 367 | + "TRAKT_API_FILE", |
| 368 | + "b4d9702b11cfaddf5e863001f68ce9d4394b678926e8a3f64d47bf69a55dd0fe", |
| 369 | + ), |
289 | 370 | ) |
290 | 371 | SIMKL_ID = config( |
291 | 372 | "SIMKL_ID", |
292 | | - default="f1df351ddbace7e2c52f0010efdeb1fd59d379d9cdfb88e9a847c68af410db0e", |
| 373 | + default=secret( |
| 374 | + "SIMKL_ID_FILE", |
| 375 | + "f1df351ddbace7e2c52f0010efdeb1fd59d379d9cdfb88e9a847c68af410db0e", |
| 376 | + ), |
293 | 377 | ) |
294 | 378 | SIMKL_SECRET = config( |
295 | 379 | "SIMKL_SECRET", |
296 | | - default="9bb254894a598894bee14f61eafdcdca47622ab346632f951ed7220a3de289b5", |
| 380 | + default=secret( |
| 381 | + "SIMKL_SECRET_FILE", |
| 382 | + "9bb254894a598894bee14f61eafdcdca47622ab346632f951ed7220a3de289b5", |
| 383 | + ), |
297 | 384 | ) |
298 | 385 |
|
299 | 386 | TESTING = False |
|
407 | 494 |
|
408 | 495 | SOCIALACCOUNT_PROVIDERS = config( |
409 | 496 | "SOCIALACCOUNT_PROVIDERS", |
410 | | - default="{}", |
| 497 | + default=secret( |
| 498 | + "SOCIALACCOUNT_PROVIDERS_FILE", |
| 499 | + default="{}", |
| 500 | + ), |
411 | 501 | cast=json.loads, |
412 | 502 | ) |
413 | 503 |
|
|
0 commit comments