Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# it's easier to develop when the dockerfile is local but it doesn't belong in the repository
Dockerfile

*.py[cod]

*.log
Expand Down
6 changes: 5 additions & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ version: 2
sphinx:
configuration: docs/conf.py

build:
os: ubuntu-24.04
tools:
python: "3.12"

python:
version: 3.12
install:
- requirements: requirements/doc.txt
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ def get_version(*file_paths):

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
'python': ('https://docs.python.org/3.8', None),
'python': ('https://docs.python.org/3.12', None),
}


Expand Down
221 changes: 105 additions & 116 deletions program_intent_engagement/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def root(*path_fragments):


# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get('PROGRAM_INTENT_ENGAGEMENT_SECRET_KEY', 'insecure-secret-key')
SECRET_KEY = os.environ.get("PROGRAM_INTENT_ENGAGEMENT_SECRET_KEY", "insecure-secret-key")

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
Expand All @@ -23,153 +23,142 @@ def root(*path_fragments):

# Application definition

INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'release_util',
)
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"release_util",
]

THIRD_PARTY_APPS = (
'corsheaders',
'csrf.apps.CsrfAppConfig', # Enables frontend apps to retrieve CSRF tokens
'rest_framework',
'rest_framework_swagger',
'social_django',
'waffle',
)
THIRD_PARTY_APPS = [
"corsheaders",
"csrf.apps.CsrfAppConfig", # Enables frontend apps to retrieve CSRF tokens
"rest_framework",
"social_django",
"waffle",
]

PROJECT_APPS = (
'program_intent_engagement.apps.core',
'program_intent_engagement.apps.api',
)
PROJECT_APPS = [
"program_intent_engagement.apps.core",
"program_intent_engagement.apps.api",
]

INSTALLED_APPS += THIRD_PARTY_APPS
INSTALLED_APPS += PROJECT_APPS

MIDDLEWARE = (
# Resets RequestCache utility for added safety.
'edx_django_utils.cache.middleware.RequestCacheMiddleware',

"edx_django_utils.cache.middleware.RequestCacheMiddleware",
# Monitoring middleware should be immediately after RequestCacheMiddleware
'edx_django_utils.monitoring.DeploymentMonitoringMiddleware', # python and django version
'edx_django_utils.monitoring.CookieMonitoringMiddleware', # cookie names (compliance) and sizes
'edx_django_utils.monitoring.CachedCustomMonitoringMiddleware', # support accumulate & increment
'edx_django_utils.monitoring.MonitoringMemoryMiddleware', # memory usage

'corsheaders.middleware.CorsMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'edx_rest_framework_extensions.auth.jwt.middleware.JwtAuthCookieMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'social_django.middleware.SocialAuthExceptionMiddleware',
'waffle.middleware.WaffleMiddleware',
"edx_django_utils.monitoring.DeploymentMonitoringMiddleware", # python and django version
"edx_django_utils.monitoring.CookieMonitoringMiddleware", # cookie names (compliance) and sizes
"edx_django_utils.monitoring.CachedCustomMonitoringMiddleware", # support accumulate & increment
"edx_django_utils.monitoring.MonitoringMemoryMiddleware", # memory usage
"corsheaders.middleware.CorsMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.middleware.common.CommonMiddleware",
"edx_rest_framework_extensions.auth.jwt.middleware.JwtAuthCookieMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"social_django.middleware.SocialAuthExceptionMiddleware",
"waffle.middleware.WaffleMiddleware",
# Enables force_django_cache_miss functionality for TieredCache.
'edx_django_utils.cache.middleware.TieredCacheMiddleware',
"edx_django_utils.cache.middleware.TieredCacheMiddleware",
# Outputs monitoring metrics for a request.
'edx_rest_framework_extensions.middleware.RequestMetricsMiddleware',
"edx_rest_framework_extensions.middleware.RequestMetricsMiddleware",
# Ensures proper DRF permissions in support of JWTs
'edx_rest_framework_extensions.auth.jwt.middleware.EnsureJWTAuthSettingsMiddleware',
"edx_rest_framework_extensions.auth.jwt.middleware.EnsureJWTAuthSettingsMiddleware",
)

# Enable CORS
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = corsheaders_default_headers + (
'use-jwt-cookie',
)
CORS_ALLOW_HEADERS = corsheaders_default_headers + ("use-jwt-cookie",)
CORS_ORIGIN_WHITELIST = []

ROOT_URLCONF = 'program_intent_engagement.urls'
ROOT_URLCONF = "program_intent_engagement.urls"

# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'program_intent_engagement.wsgi.application'
WSGI_APPLICATION = "program_intent_engagement.wsgi.application"

# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
# Set this value in the environment-specific files (e.g. local.py, production.py, test.py)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.',
'NAME': '',
'USER': '',
'PASSWORD': '',
'HOST': '', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
'PORT': '', # Set to empty string for default.
"default": {
"ENGINE": "django.db.backends.",
"NAME": "",
"USER": "",
"PASSWORD": "",
"HOST": "", # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
"PORT": "", # Set to empty string for default.
}
}

# New DB primary keys default to an IntegerField.
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

# Internationalization
# https://docs.djangoproject.com/en/dev/topics/i18n/

LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = "en-us"

TIME_ZONE = 'UTC'
TIME_ZONE = "UTC"

USE_I18N = True

USE_L10N = True

USE_TZ = True

LOCALE_PATHS = (
root('conf', 'locale'),
)
LOCALE_PATHS = (root("conf", "locale"),)


# MEDIA CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root
MEDIA_ROOT = root('media')
MEDIA_ROOT = root("media")

# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url
MEDIA_URL = '/media/'
MEDIA_URL = "/media/"
# END MEDIA CONFIGURATION


# STATIC FILE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root
STATIC_ROOT = root('assets')
STATIC_ROOT = root("assets")

# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = '/static/'
STATIC_URL = "/static/"

# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS = (
root('static'),
)
STATICFILES_DIRS = (root("static"),)

# TEMPLATE CONFIGURATION
# See: https://docs.djangoproject.com/en/3.2/ref/settings/#templates
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True,
'DIRS': (
root('templates'),
),
'OPTIONS': {
'context_processors': (
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.request',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
'program_intent_engagement.apps.core.context_processors.core',
"BACKEND": "django.template.backends.django.DjangoTemplates",
"APP_DIRS": True,
"DIRS": (root("templates"),),
"OPTIONS": {
"context_processors": (
"django.contrib.auth.context_processors.auth",
"django.template.context_processors.debug",
"django.template.context_processors.i18n",
"django.template.context_processors.media",
"django.template.context_processors.request",
"django.template.context_processors.static",
"django.template.context_processors.tz",
"django.contrib.messages.context_processors.messages",
"program_intent_engagement.apps.core.context_processors.core",
),
'debug': True, # Django will only display debug pages if the global DEBUG setting is set to True.
}
"debug": True, # Django will only display debug pages if the global DEBUG setting is set to True.
},
},
]
# END TEMPLATE CONFIGURATION
Expand All @@ -179,50 +168,50 @@ def root(*path_fragments):
# The purpose of customizing the cookie names is to avoid conflicts when
# multiple Django services are running behind the same hostname.
# Detailed information at: https://docs.djangoproject.com/en/dev/ref/settings/
SESSION_COOKIE_NAME = 'program_intent_engagement_sessionid'
CSRF_COOKIE_NAME = 'program_intent_engagement_csrftoken'
LANGUAGE_COOKIE_NAME = 'program_intent_engagement_language'
SESSION_COOKIE_NAME = "program_intent_engagement_sessionid"
CSRF_COOKIE_NAME = "program_intent_engagement_csrftoken"
LANGUAGE_COOKIE_NAME = "program_intent_engagement_language"
# END COOKIE CONFIGURATION

CSRF_COOKIE_SECURE = False
CSRF_TRUSTED_ORIGINS = []

# AUTHENTICATION CONFIGURATION
LOGIN_URL = '/login/'
LOGOUT_URL = '/logout/'
LOGIN_URL = "/login/"
LOGOUT_URL = "/logout/"

AUTH_USER_MODEL = 'core.User'
AUTH_USER_MODEL = "core.User"

AUTHENTICATION_BACKENDS = (
'auth_backends.backends.EdXOAuth2',
'django.contrib.auth.backends.ModelBackend',
"auth_backends.backends.EdXOAuth2",
"django.contrib.auth.backends.ModelBackend",
)

ENABLE_AUTO_AUTH = False
AUTO_AUTH_USERNAME_PREFIX = 'auto_auth_'
AUTO_AUTH_USERNAME_PREFIX = "auto_auth_"

SOCIAL_AUTH_STRATEGY = 'auth_backends.strategies.EdxDjangoStrategy'
SOCIAL_AUTH_STRATEGY = "auth_backends.strategies.EdxDjangoStrategy"

# Set these to the correct values for your OAuth2 provider (e.g., LMS)
SOCIAL_AUTH_EDX_OAUTH2_KEY = 'replace-me'
SOCIAL_AUTH_EDX_OAUTH2_SECRET = 'replace-me'
SOCIAL_AUTH_EDX_OAUTH2_URL_ROOT = 'replace-me'
SOCIAL_AUTH_EDX_OAUTH2_LOGOUT_URL = 'replace-me'
BACKEND_SERVICE_EDX_OAUTH2_KEY = 'replace-me'
BACKEND_SERVICE_EDX_OAUTH2_SECRET = 'replace-me'
SOCIAL_AUTH_EDX_OAUTH2_KEY = "replace-me"
SOCIAL_AUTH_EDX_OAUTH2_SECRET = "replace-me"
SOCIAL_AUTH_EDX_OAUTH2_URL_ROOT = "replace-me"
SOCIAL_AUTH_EDX_OAUTH2_LOGOUT_URL = "replace-me"
BACKEND_SERVICE_EDX_OAUTH2_KEY = "replace-me"
BACKEND_SERVICE_EDX_OAUTH2_SECRET = "replace-me"

JWT_AUTH = {
'JWT_AUTH_HEADER_PREFIX': 'JWT',
'JWT_ISSUER': 'http://127.0.0.1:8000/oauth2',
'JWT_ALGORITHM': 'HS256',
'JWT_VERIFY_EXPIRATION': True,
'JWT_PAYLOAD_GET_USERNAME_HANDLER': lambda d: d.get('preferred_username'),
'JWT_LEEWAY': 1,
'JWT_DECODE_HANDLER': 'edx_rest_framework_extensions.auth.jwt.decoder.jwt_decode_handler',
'JWT_PUBLIC_SIGNING_JWK_SET': None,
'JWT_AUTH_COOKIE': 'edx-jwt-cookie',
'JWT_AUTH_COOKIE_HEADER_PAYLOAD': 'edx-jwt-cookie-header-payload',
'JWT_AUTH_COOKIE_SIGNATURE': 'edx-jwt-cookie-signature',
"JWT_AUTH_HEADER_PREFIX": "JWT",
"JWT_ISSUER": "http://127.0.0.1:8000/oauth2",
"JWT_ALGORITHM": "HS256",
"JWT_VERIFY_EXPIRATION": True,
"JWT_PAYLOAD_GET_USERNAME_HANDLER": lambda d: d.get("preferred_username"),
"JWT_LEEWAY": 1,
"JWT_DECODE_HANDLER": "edx_rest_framework_extensions.auth.jwt.decoder.jwt_decode_handler",
"JWT_PUBLIC_SIGNING_JWK_SET": None,
"JWT_AUTH_COOKIE": "edx-jwt-cookie",
"JWT_AUTH_COOKIE_HEADER_PAYLOAD": "edx-jwt-cookie-header-payload",
"JWT_AUTH_COOKIE_SIGNATURE": "edx-jwt-cookie-signature",
}

# Carry fields from the JWT token and LMS user into the local user
Expand All @@ -238,15 +227,15 @@ def root(*path_fragments):
}

# Request the user's permissions in the ID token
EXTRA_SCOPE = ['permissions']
EXTRA_SCOPE = ["permissions"]

# TODO Set this to another (non-staff, ideally) path.
LOGIN_REDIRECT_URL = '/admin/'
LOGIN_REDIRECT_URL = "/admin/"
# END AUTHENTICATION CONFIGURATION


# OPENEDX-SPECIFIC CONFIGURATION
PLATFORM_NAME = 'Your Platform Name Here'
PLATFORM_NAME = "Your Platform Name Here"
# END OPENEDX-SPECIFIC CONFIGURATION

# Set up logging for development use (logging to stdout)
Expand Down
Loading
Loading