diff --git a/codeforlife/settings/__init__.py b/codeforlife/settings/__init__.py index afe83a8..e3d889d 100644 --- a/codeforlife/settings/__init__.py +++ b/codeforlife/settings/__init__.py @@ -9,11 +9,10 @@ # Place this at the top of your file. from codeforlife import settings as cfl_settings -# Do something with EXAMPLE_SETTING from codeforlife's settings. +# Do something with EXAMPLE_SETTING from codeforlife's settings. cfl_settings.EXAMPLE_SETTING ` """ - from .custom import * from .django import * from .third_party import * diff --git a/codeforlife/settings/custom.py b/codeforlife/settings/custom.py index 853cec1..7a78801 100644 --- a/codeforlife/settings/custom.py +++ b/codeforlife/settings/custom.py @@ -1,7 +1,6 @@ """ This file contains all of our custom settings we define for our own purposes. """ - import os # The name of the current service. @@ -21,6 +20,5 @@ if not SERVICE_IS_ROOT: SERVICE_BASE_URL += f"/{SERVICE_NAME}" - # The api url of the current service. SERVICE_API_URL = f"{SERVICE_BASE_URL}/api" diff --git a/codeforlife/settings/django.py b/codeforlife/settings/django.py index 5dd2572..47da079 100644 --- a/codeforlife/settings/django.py +++ b/codeforlife/settings/django.py @@ -1,8 +1,7 @@ """ -This file contains all of the settings Django supports out of the box. +This file contains all the settings Django supports out of the box. https://docs.djangoproject.com/en/3.2/ref/settings/ """ - import os from django.utils.translation import gettext_lazy as _ @@ -12,6 +11,24 @@ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = bool(int(os.getenv("DEBUG", "1"))) +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ + +ALLOWED_HOSTS = ["*"] + +# Application definition + +MIDDLEWARE = [ + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.locale.LocaleMiddleware", + "corsheaders.middleware.CorsMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.middleware.security.SecurityMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", +] + # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.getenv("SECRET_KEY", "replace-me") @@ -44,12 +61,19 @@ SESSION_COOKIE_SAMESITE = "None" SESSION_COOKIE_DOMAIN = "localhost" if DEBUG else "codeforlife.education" +# Security +# https://docs.djangoproject.com/en/3.2/topics/security/ + +SECURE_CONTENT_TYPE_NOSNIFF = True +SECURE_BROWSER_XSS_FILTER = True +SECURE_REFERRER_POLICY = "strict-origin-when-cross-origin" + # Internationalization # https://docs.djangoproject.com/en/3.2/topics/i18n/ LANGUAGE_CODE = "en-gb" LANGUAGES = [("en-gb", _("English"))] -TIME_ZONE = "Europe/London" # TODO: use UTC? +TIME_ZONE = "Europe/London" USE_I18N = True USE_L10N = True USE_TZ = True @@ -57,14 +81,16 @@ # Default primary key field type # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field -DEFAULT_AUTO_FIELD = "django.db.models.AutoField" # TODO: use BigAutoField +DEFAULT_AUTO_FIELD = "django.db.models.AutoField" # CSRF # https://docs.djangoproject.com/en/3.2/ref/csrf/ +# TODO: Decide on CSRF approach CSRF_COOKIE_NAME = f"{SERVICE_NAME}_csrftoken" CSRF_COOKIE_SAMESITE = "None" CSRF_COOKIE_SECURE = True +# CSRF_USE_SESSION = True # Logging # https://docs.djangoproject.com/en/3.2/topics/logging/ @@ -91,12 +117,12 @@ } # URLs -# https://docs.djangoproject.com/en/4.2/ref/settings/#root-urlconf +# https://docs.djangoproject.com/en/3.2/ref/settings/#root-urlconf ROOT_URLCONF = "service.urls" # App -# https://docs.djangoproject.com/en/4.2/ref/settings/#wsgi-application +# https://docs.djangoproject.com/en/3.2/ref/settings/#wsgi-application WSGI_APPLICATION = "service.wsgi.application" @@ -104,8 +130,10 @@ # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators # TODO: compare Django's default common password validator with our own and -# decide which to keep: -# codeforlife.user.auth.password_validators.CommonPasswordValidator +# decide which to keep +# NOTE: Django's common password validator, while similar to ours, +# seems based on a deprecated list of passwords. +# codeforlife.user.auth.password_validators.CommonPasswordValidator # pylint: disable=line-too-long AUTH_PASSWORD_VALIDATORS = [ { diff --git a/codeforlife/settings/third_party.py b/codeforlife/settings/third_party.py index 700f6ee..e547197 100644 --- a/codeforlife/settings/third_party.py +++ b/codeforlife/settings/third_party.py @@ -1,7 +1,6 @@ """ This file contains custom settings defined by third party extensions. """ - from .django import DEBUG # CORS diff --git a/codeforlife/user/auth/backends/__init__.py b/codeforlife/user/auth/backends/__init__.py index 698d332..8c7f34a 100644 --- a/codeforlife/user/auth/backends/__init__.py +++ b/codeforlife/user/auth/backends/__init__.py @@ -2,7 +2,7 @@ © Ocado Group Created on 01/02/2024 at 14:48:57(+00:00). """ - +# TODO: Create a custom auth backend for Django admin permissions from .email_and_password import EmailAndPasswordBackend from .first_name_and_password_and_class_id import ( FirstNameAndPasswordAndClassIdBackend,