From be7c7be8e49b22547a5359f2152a7b47b08e59e7 Mon Sep 17 00:00:00 2001 From: Mike Graves Date: Tue, 26 Nov 2019 12:11:16 -0500 Subject: [PATCH] Add python-dotenv to manage.py This partially addresses #177. Completely fixing this issue is going to require much deeper work, I think, and will be better addressed across multiple PRs. --- Pipfile | 1 + Pipfile.lock | 28 +++++++++++++------- manage.py | 4 +++ solenoid/settings/base.py | 56 +++++++++++++++++++++++++++------------ 4 files changed, 62 insertions(+), 27 deletions(-) diff --git a/Pipfile b/Pipfile index dafe4d3..2530400 100644 --- a/Pipfile +++ b/Pipfile @@ -9,6 +9,7 @@ python_version = "3.7" [dev-packages] coverage = ">=4.5.1" freezegun = "*" +python-dotenv = "*" [packages] # Only needed for Heroku diff --git a/Pipfile.lock b/Pipfile.lock index 5551148..99b6b52 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "82d5299afe1e34d1e005d9715704d16dfa5249c182e83fce3e7e0ec32f74ba7d" + "sha256": "522f7dc7de79de5a74fea0347f93a69226cac0fc5c15a51686dd58fc97abbf52" }, "pipfile-spec": 6, "requires": { @@ -90,11 +90,11 @@ }, "django-crispy-forms": { "hashes": [ - "sha256:0320b303420fec9ce94e045321dfd180ca0e31e0336211c5d30ad0bda5ebbb5d", - "sha256:22b6634e3a6316623e4eb062527fe5be5f97ea8b83020c65bcd8fac4747807b5" + "sha256:0afc0ba730f52a13c02bfbd0e1423af4577a337d73a8a0ef96f2cbbc5f345ffa", + "sha256:2db711ce31f6f9ef42c16829cc3636e3819f97c1b22a3b706afed679bc417e88" ], "index": "pypi", - "version": "==1.8.0" + "version": "==1.8.1" }, "django-debug-toolbar": { "hashes": [ @@ -120,11 +120,11 @@ }, "gunicorn": { "hashes": [ - "sha256:0806b5e8a2eb8ba9ac1be65d7b743ec896fc25f5d6cb16c5e051540157b315bb", - "sha256:ef69dea4814df95e64e3f40b47b7ffedc6911c5009233be9d01cfd0d14aa3f50" + "sha256:1d8012b859f4cd9e45753f1ccb33a94df1ab9e1b7af4f81ac871680b4042b08b", + "sha256:5c6f119298dd692ba49d83ea351aeefdb63d33e32179d91d173d942525115890" ], "index": "pypi", - "version": "==20.0.0" + "version": "==20.0.3" }, "idna": { "hashes": [ @@ -306,11 +306,11 @@ }, "sentry-sdk": { "hashes": [ - "sha256:09e1e8f00f22ea580348f83bbbd880adf40b29f1dec494a8e4b33e22f77184fb", - "sha256:ff1fa7fb85703ae9414c8b427ee73f8363232767c9cd19158f08f6e4f0b58fc7" + "sha256:e3302e8df82e68599eeeef564f08d15aa62efc1cb013d8e1cccc5bf526d375a4", + "sha256:e795f1744066493f9e1eb3d17e0ee19a042a45789b9edd9f553b8b61bc8d399e" ], "index": "pypi", - "version": "==0.13.2" + "version": "==0.13.3" }, "six": { "hashes": [ @@ -420,6 +420,14 @@ ], "version": "==2.8.1" }, + "python-dotenv": { + "hashes": [ + "sha256:debd928b49dbc2bf68040566f55cdb3252458036464806f4094487244e2a4093", + "sha256:f157d71d5fec9d4bd5f51c82746b6344dffa680ee85217c123f4a0c8117c4544" + ], + "index": "pypi", + "version": "==0.10.3" + }, "six": { "hashes": [ "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", diff --git a/manage.py b/manage.py index 4d1be29..873db57 100755 --- a/manage.py +++ b/manage.py @@ -2,7 +2,11 @@ import os import sys +from dotenv import load_dotenv + + if __name__ == "__main__": + load_dotenv() os.environ.setdefault("DJANGO_SETTINGS_MODULE", "solenoid.settings.base") from django.core.management import execute_from_command_line diff --git a/solenoid/settings/base.py b/solenoid/settings/base.py index ec5ae5c..5ce34f5 100644 --- a/solenoid/settings/base.py +++ b/solenoid/settings/base.py @@ -11,11 +11,38 @@ """ import os +import dj_database_url from django.urls import reverse_lazy BASE_DIR = os.path.dirname( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +def boolean(value): + """Turn the given string value into a boolean. + + Any truthy value will be interpreted as True and anything else will + be False. For convenience, this function will also accept a boolean + value (and simply return it) and the value None, which will be + interpreted as False. + """ + if isinstance(value, bool) or value is None: + return bool(value) + return value.lower() in ('true', 't', 'yes', 'y', '1') + + +def make_list(value): + """Return a list of items from a comma-separated string. + + Surrounding whitespace will be stripped from the list items. If the + provided string is empty, an empty list will be returned. This function + will also accept the value None and return an empty list. + """ + if value is None: + return [] + return list(filter(None, [s.strip() for s in value.split(',')])) + + # ----------------------------------------------------------------------------- # ------------------------> core django configurations <----------------------- # ----------------------------------------------------------------------------- @@ -60,15 +87,7 @@ # DEBUG # ----------------------------------------------------------------------------- -# By setting this an an environment variable, it is easy to switch debug on in -# servers to do a quick test. -# DEBUG SHOULD BE FALSE ON PRODUCTION for security reasons. -PROTO_DEBUG = os.environ.get('DJANGO_DEBUG') - -if PROTO_DEBUG == 'True' or PROTO_DEBUG is True: - DEBUG = True -else: - DEBUG = False +DEBUG = boolean(os.getenv('DEBUG', False)) # DATABASE CONFIGURATION # ----------------------------------------------------------------------------- @@ -76,10 +95,9 @@ # https://docs.djangoproject.com/en/1.8/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - } + 'default': dj_database_url.config( + default=os.getenv('DATABASE_URL', 'sqlite:///db.sqlite3'), + conn_max_age=600) } @@ -87,11 +105,14 @@ # ----------------------------------------------------------------------------- # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '_c+yx&rwl@mg$c()!p+78($if4uqa^p$czhl-tl$)*1v5#xus0' +SECRET_KEY = os.environ['SECRET_KEY'] + +# This will accept a comma-separated list of allowed hosts +ALLOWED_HOSTS = make_list(os.getenv('ALLOWED_HOSTS')) -# In production, this list should contain the URL of the server and nothing -# else, for security reasons. For local testing '*' is OK. -ALLOWED_HOSTS = ['*'] +if 'HEROKU_APP_NAME' in os.environ: + ALLOWED_HOSTS.append( + '{}.herokuapp.com'.format(os.environ['HEROKU_APP_NAME'])) ROOT_URLCONF = 'solenoid.urls' @@ -99,6 +120,7 @@ SITE_ID = 1 +SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') # INTERNATIONALIZATION CONFIGURATION # -----------------------------------------------------------------------------