refactor: move explicitly shared settings into new common module

This commit is contained in:
Taylor Payne
2025-06-18 10:59:36 -06:00
committed by Kyle McCormick
parent ef6dbd9e03
commit a98dd3f748
12 changed files with 823 additions and 813 deletions

View File

@@ -25,6 +25,7 @@ omit =
common/djangoapps/*/migrations/*
openedx/core/djangoapps/*/migrations/*
openedx/core/djangoapps/debug/*
openedx/envs/*
openedx/features/*/migrations/*
concurrency=multiprocessing

View File

@@ -24,6 +24,7 @@ omit =
common/djangoapps/*/migrations/*
openedx/core/djangoapps/*/migrations/*
openedx/core/djangoapps/debug/*
openedx/envs/*
openedx/features/*/migrations/*
concurrency=multiprocessing

View File

@@ -20,7 +20,7 @@ jobs:
- module-name: openedx-1
path: "openedx/core/types/ openedx/core/djangoapps/ace_common/ openedx/core/djangoapps/agreements/ openedx/core/djangoapps/api_admin/ openedx/core/djangoapps/auth_exchange/ openedx/core/djangoapps/bookmarks/ openedx/core/djangoapps/cache_toolbox/ openedx/core/djangoapps/catalog/ openedx/core/djangoapps/ccxcon/ openedx/core/djangoapps/commerce/ openedx/core/djangoapps/common_initialization/ openedx/core/djangoapps/common_views/ openedx/core/djangoapps/config_model_utils/ openedx/core/djangoapps/content/ openedx/core/djangoapps/content_libraries/ openedx/core/djangoapps/content_staging/ openedx/core/djangoapps/contentserver/ openedx/core/djangoapps/cookie_metadata/ openedx/core/djangoapps/cors_csrf/ openedx/core/djangoapps/course_apps/ openedx/core/djangoapps/course_date_signals/ openedx/core/djangoapps/course_groups/ openedx/core/djangoapps/courseware_api/ openedx/core/djangoapps/crawlers/ openedx/core/djangoapps/credentials/ openedx/core/djangoapps/credit/ openedx/core/djangoapps/dark_lang/ openedx/core/djangoapps/debug/ openedx/core/djangoapps/discussions/ openedx/core/djangoapps/django_comment_common/ openedx/core/djangoapps/embargo/ openedx/core/djangoapps/enrollments/ openedx/core/djangoapps/external_user_ids/ openedx/core/djangoapps/zendesk_proxy/ openedx/core/djangolib/ openedx/core/lib/ openedx/core/djangoapps/course_live/"
- module-name: openedx-2
path: "openedx/core/djangoapps/geoinfo/ openedx/core/djangoapps/header_control/ openedx/core/djangoapps/heartbeat/ openedx/core/djangoapps/lang_pref/ openedx/core/djangoapps/models/ openedx/core/djangoapps/monkey_patch/ openedx/core/djangoapps/oauth_dispatch/ openedx/core/djangoapps/olx_rest_api/ openedx/core/djangoapps/password_policy/ openedx/core/djangoapps/plugin_api/ openedx/core/djangoapps/plugins/ openedx/core/djangoapps/profile_images/ openedx/core/djangoapps/programs/ openedx/core/djangoapps/safe_sessions/ openedx/core/djangoapps/schedules/ openedx/core/djangoapps/service_status/ openedx/core/djangoapps/session_inactivity_timeout/ openedx/core/djangoapps/signals/ openedx/core/djangoapps/site_configuration/ openedx/core/djangoapps/system_wide_roles/ openedx/core/djangoapps/theming/ openedx/core/djangoapps/user_api/ openedx/core/djangoapps/user_authn/ openedx/core/djangoapps/util/ openedx/core/djangoapps/verified_track_content/ openedx/core/djangoapps/video_config/ openedx/core/djangoapps/video_pipeline/ openedx/core/djangoapps/waffle_utils/ openedx/core/djangoapps/xblock/ openedx/core/djangoapps/xmodule_django/ openedx/core/tests/ openedx/features/ openedx/testing/ openedx/tests/ openedx/core/djangoapps/notifications/ openedx/core/djangoapps/staticfiles/ openedx/core/djangoapps/content_tagging/"
path: "openedx/core/djangoapps/geoinfo/ openedx/core/djangoapps/header_control/ openedx/core/djangoapps/heartbeat/ openedx/core/djangoapps/lang_pref/ openedx/core/djangoapps/models/ openedx/core/djangoapps/monkey_patch/ openedx/core/djangoapps/oauth_dispatch/ openedx/core/djangoapps/olx_rest_api/ openedx/core/djangoapps/password_policy/ openedx/core/djangoapps/plugin_api/ openedx/core/djangoapps/plugins/ openedx/core/djangoapps/profile_images/ openedx/core/djangoapps/programs/ openedx/core/djangoapps/safe_sessions/ openedx/core/djangoapps/schedules/ openedx/core/djangoapps/service_status/ openedx/core/djangoapps/session_inactivity_timeout/ openedx/core/djangoapps/signals/ openedx/core/djangoapps/site_configuration/ openedx/core/djangoapps/system_wide_roles/ openedx/core/djangoapps/theming/ openedx/core/djangoapps/user_api/ openedx/core/djangoapps/user_authn/ openedx/core/djangoapps/util/ openedx/core/djangoapps/verified_track_content/ openedx/core/djangoapps/video_config/ openedx/core/djangoapps/video_pipeline/ openedx/core/djangoapps/waffle_utils/ openedx/core/djangoapps/xblock/ openedx/core/djangoapps/xmodule_django/ openedx/core/tests/ openedx/features/ openedx/testing/ openedx/tests/ openedx/envs/ openedx/core/djangoapps/notifications/ openedx/core/djangoapps/staticfiles/ openedx/core/djangoapps/content_tagging/"
- module-name: common
path: "common"
- module-name: cms

View File

@@ -45,87 +45,21 @@ import sys
from corsheaders.defaults import default_headers as corsheaders_default_headers
from datetime import timedelta
from django.utils.translation import gettext_lazy as _
import lms.envs.common
# Although this module itself may not use these imported variables, other dependent modules may.
# Warning: Do NOT add any new variables to this list. This is incompatible with future plans to
# have more logical separation between LMS and Studio (CMS). It is also incompatible with the
# direction documented in OEP-45: Configuring and Operating Open edX:
# https://open-edx-proposals.readthedocs.io/en/latest/oep-0045-arch-ops-and-config.html
from openedx.core.constants import COURSE_KEY_REGEX, COURSE_KEY_PATTERN, COURSE_ID_PATTERN
from openedx.envs.common import * # pylint: disable=wildcard-import
from lms.envs.common import (
USE_TZ, ALL_LANGUAGES, ASSET_IGNORE_REGEX,
PARENTAL_CONSENT_AGE_LIMIT, REGISTRATION_EMAIL_PATTERNS_ALLOWED,
# The following PROFILE_IMAGE_* settings are included as they are
# indirectly accessed through the email opt-in API, which is
# technically accessible through the CMS via legacy URLs.
PROFILE_IMAGE_BACKEND, PROFILE_IMAGE_DEFAULT_FILENAME, PROFILE_IMAGE_DEFAULT_FILE_EXTENSION,
PROFILE_IMAGE_HASH_SEED, PROFILE_IMAGE_MIN_BYTES, PROFILE_IMAGE_MAX_BYTES, PROFILE_IMAGE_SIZES_MAP,
# The following setting is included as it is used to check whether to
# display credit eligibility table on the CMS or not.
COURSE_MODE_DEFAULTS, DEFAULT_COURSE_ABOUT_IMAGE_URL,
# NOTE: Do not add any new imports here. Use openedx.envs.common instead for
# platform wide settings.
# User-uploaded content
MEDIA_ROOT,
MEDIA_URL,
# Lazy Gettext
_,
# Django REST framework configuration
REST_FRAMEWORK,
STATICI18N_OUTPUT_DIR,
# Heartbeat
HEARTBEAT_CHECKS,
HEARTBEAT_EXTENDED_CHECKS,
HEARTBEAT_CELERY_TIMEOUT,
HEARTBEAT_CELERY_ROUTING_KEY,
# Default site to use if no site exists matching request headers
SITE_ID,
# constants for redirects app
REDIRECT_CACHE_TIMEOUT,
REDIRECT_CACHE_KEY_PREFIX,
# This is required for the migrations in oauth_dispatch.models
# otherwise it fails saying this attribute is not present in Settings
# Although Studio does not enable OAuth2 Provider capability, the new approach
# to generating test databases will discover and try to create all tables
# and this setting needs to be present
OAUTH2_PROVIDER_APPLICATION_MODEL,
JWT_AUTH,
USERNAME_REGEX_PARTIAL,
USERNAME_PATTERN,
# django-debug-toolbar
DEBUG_TOOLBAR_PATCH_SETTINGS,
COURSE_ENROLLMENT_MODES,
CONTENT_TYPE_GATE_GROUP_IDS,
DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH,
GENERATE_PROFILE_SCORES,
# Enterprise service settings
ENTERPRISE_CATALOG_INTERNAL_ROOT_URL,
ENTERPRISE_BACKEND_SERVICE_EDX_OAUTH2_KEY,
ENTERPRISE_BACKEND_SERVICE_EDX_OAUTH2_SECRET,
ENTERPRISE_BACKEND_SERVICE_EDX_OAUTH2_PROVIDER_URL,
# Methods to derive settings
_make_mako_template_dirs,
_make_locale_paths,
# Password Validator Settings
AUTH_PASSWORD_VALIDATORS
)
from lms.envs.common import (
# FIXME: The HIBP settings are only used in the LMS, but CMS unit tests fail
# without them. Perhaps moving some code would allow us to remove these from
# this file.
# this file. GitHub Issue: https://github.com/openedx/edx-platform/issues/36992.
ENABLE_AUTHN_LOGIN_BLOCK_HIBP_POLICY,
ENABLE_AUTHN_LOGIN_NUDGE_HIBP_POLICY,
ENABLE_AUTHN_REGISTER_HIBP_POLICY,
@@ -133,15 +67,6 @@ from lms.envs.common import (
HIBP_LOGIN_BLOCK_PASSWORD_FREQUENCY_THRESHOLD,
HIBP_LOGIN_NUDGE_PASSWORD_FREQUENCY_THRESHOLD,
HIBP_REGISTRATION_PASSWORD_FREQUENCY_THRESHOLD,
USE_EXTRACTED_WORD_CLOUD_BLOCK,
USE_EXTRACTED_ANNOTATABLE_BLOCK,
USE_EXTRACTED_POLL_QUESTION_BLOCK,
USE_EXTRACTED_LTI_BLOCK,
USE_EXTRACTED_HTML_BLOCK,
USE_EXTRACTED_DISCUSSION_BLOCK,
USE_EXTRACTED_PROBLEM_BLOCK,
USE_EXTRACTED_VIDEO_BLOCK,
)
from path import Path as path
from django.urls import reverse_lazy
@@ -700,7 +625,7 @@ TEMPLATES = [
# Don't look for template source files inside installed applications.
'APP_DIRS': False,
# Instead, look for template source files in these dirs.
'DIRS': Derived(_make_mako_template_dirs),
'DIRS': Derived(make_mako_template_dirs),
# Options specific to this backend.
'OPTIONS': {
'loaders': (
@@ -719,7 +644,7 @@ TEMPLATES = [
'NAME': 'mako',
'BACKEND': 'common.djangoapps.edxmako.backend.Mako',
'APP_DIRS': False,
'DIRS': Derived(_make_mako_template_dirs),
'DIRS': Derived(make_mako_template_dirs),
'OPTIONS': {
'context_processors': CONTEXT_PROCESSORS,
'debug': False,
@@ -823,12 +748,6 @@ ELASTIC_SEARCH_CONFIG = [
}
]
# These are standard regexes for pulling out info like course_ids, usage_ids, etc.
# They are used so that URLs with deprecated-format strings still work.
from lms.envs.common import (
COURSE_KEY_PATTERN, COURSE_KEY_REGEX, COURSE_ID_PATTERN, USAGE_KEY_PATTERN, ASSET_KEY_PATTERN
)
######################### CSRF #########################################
# Forwards-compatibility with Django 1.7
@@ -1254,12 +1173,6 @@ STATICFILES_DIRS = [
CELERY_TIMEZONE = 'UTC'
TIME_ZONE = 'UTC'
LANGUAGE_CODE = 'en' # http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGES_BIDI = lms.envs.common.LANGUAGES_BIDI
LANGUAGE_COOKIE_NAME = lms.envs.common.LANGUAGE_COOKIE_NAME
LANGUAGES = lms.envs.common.LANGUAGES
LANGUAGE_DICT = dict(LANGUAGES)
# Languages supported for custom course certificate templates
CERTIFICATE_TEMPLATE_LANGUAGES = {
@@ -1273,8 +1186,6 @@ USE_L10N = True
STATICI18N_FILENAME_FUNCTION = 'statici18n.utils.legacy_filename'
STATICI18N_ROOT = PROJECT_ROOT / "static"
LOCALE_PATHS = Derived(_make_locale_paths)
# Messages
MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
@@ -1540,6 +1451,10 @@ CELERY_BROKER_VHOST = ''
CELERY_BROKER_USE_SSL = False
CELERY_EVENT_QUEUE_TTL = None
############################## HEARTBEAT ######################################
HEARTBEAT_CELERY_ROUTING_KEY = HIGH_PRIORITY_QUEUE
############################## Video ##########################################
YOUTUBE = {

View File

@@ -65,12 +65,10 @@ from enterprise.constants import (
)
from openedx.core.constants import COURSE_KEY_REGEX, COURSE_KEY_PATTERN, COURSE_ID_PATTERN
from openedx.core.djangoapps.theming.helpers_dirs import (
get_themes_unchecked,
get_theme_base_dirs_from_settings
)
from openedx.core.lib.derived import Derived
from openedx.core.release import doc_version
from openedx.envs.common import * # pylint: disable=wildcard-import
from lms.djangoapps.lms_xblock.mixin import LmsBlockMixin
################################### FEATURES ###################################
@@ -1083,15 +1081,9 @@ FEATURES = {
# e.g. COURSE_BLOCKS_API_EXTRA_FIELDS = [ ('course', 'other_course_settings'), ("problem", "weight") ]
COURSE_BLOCKS_API_EXTRA_FIELDS = []
ASSET_IGNORE_REGEX = r"(^\._.*$)|(^\.DS_Store$)|(^.*~$)"
# Used for A/B testing
DEFAULT_GROUPS = []
# If this is true, random scores will be generated for the purpose of debugging the profile graphs
GENERATE_PROFILE_SCORES = False
# .. setting_name: GRADEBOOK_FREEZE_DAYS
# .. setting_default: 30
# .. setting_description: Sets the number of days after which the gradebook will freeze following the course's end.
@@ -1282,9 +1274,6 @@ OAUTH2_PROVIDER = {
'REQUEST_APPROVAL_PROMPT': 'auto_even_if_expired',
'ERROR_RESPONSE_WITH_SCOPES': True,
}
# This is required for the migrations in oauth_dispatch.models
# otherwise it fails saying this attribute is not present in Settings
OAUTH2_PROVIDER_APPLICATION_MODEL = 'oauth2_provider.Application'
# Automatically clean up edx-django-oauth2-provider tokens on use
OAUTH_DELETE_EXPIRED = True
@@ -1324,19 +1313,6 @@ MAKO_TEMPLATE_DIRS_BASE = [
OPENEDX_ROOT / 'features' / 'course_experience' / 'templates',
]
def _make_mako_template_dirs(settings):
"""
Derives the final Mako template directories list from other settings.
"""
if settings.ENABLE_COMPREHENSIVE_THEMING:
themes_dirs = get_theme_base_dirs_from_settings(settings.COMPREHENSIVE_THEME_DIRS)
for theme in get_themes_unchecked(themes_dirs, settings.PROJECT_ROOT):
if theme.themes_base_dir not in settings.MAKO_TEMPLATE_DIRS_BASE:
settings.MAKO_TEMPLATE_DIRS_BASE.insert(0, theme.themes_base_dir)
return settings.MAKO_TEMPLATE_DIRS_BASE
CONTEXT_PROCESSORS = [
'django.template.context_processors.request',
'django.template.context_processors.static',
@@ -1364,9 +1340,7 @@ CONTEXT_PROCESSORS = [
'lms.djangoapps.mobile_api.context_processor.is_from_mobile_app',
# Context processor necessary for the survey report message appear on the admin site
'openedx.features.survey_report.context_processors.admin_extra_context'
'openedx.features.survey_report.context_processors.admin_extra_context',
]
# Django templating
@@ -1404,7 +1378,7 @@ TEMPLATES = [
# Don't look for template source files inside installed applications.
'APP_DIRS': False,
# Instead, look for template source files in these dirs.
'DIRS': Derived(_make_mako_template_dirs),
'DIRS': Derived(make_mako_template_dirs),
# Options specific to this backend.
'OPTIONS': {
'context_processors': CONTEXT_PROCESSORS,
@@ -1514,36 +1488,10 @@ WIKI_ENABLED = True
###
COURSE_MODE_DEFAULTS = {
'android_sku': None,
'bulk_sku': None,
'currency': 'usd',
'description': None,
'expiration_datetime': None,
'ios_sku': None,
'min_price': 0,
'name': _('Audit'),
'sku': None,
'slug': 'audit',
'suggested_prices': '',
}
# IP addresses that are allowed to reload the course, etc.
# TODO (vshnayder): Will probably need to change as we get real access control in.
LMS_MIGRATION_ALLOWED_IPS = []
USAGE_KEY_PATTERN = r'(?P<usage_key_string>(?:i4x://?[^/]+/[^/]+/[^/]+/[^@]+(?:@[^/]+)?)|(?:[^/]+))'
ASSET_KEY_PATTERN = r'(?P<asset_key_string>(?:/?c4x(:/)?/[^/]+/[^/]+/[^/]+/[^@]+(?:@[^/]+)?)|(?:[^/]+))'
USAGE_ID_PATTERN = r'(?P<usage_id>(?:i4x://?[^/]+/[^/]+/[^/]+/[^@]+(?:@[^/]+)?)|(?:[^/]+))'
# The space is required for space-dependent languages like Arabic and Farsi.
# However, backward compatibility with Ficus older releases is still maintained (space is still not valid)
# in the AccountCreationForm and the user_api through the ENABLE_UNICODE_USERNAME feature flag.
USERNAME_REGEX_PARTIAL = r'[\w .@_+-]+'
USERNAME_PATTERN = fr'(?P<username>{USERNAME_REGEX_PARTIAL})'
############################## EVENT TRACKING #################################
LMS_SEGMENT_KEY = None
@@ -1862,7 +1810,6 @@ CODE_JAIL_REST_SERVICE_READ_TIMEOUT = 3.5 # time in seconds
############################### DJANGO BUILT-INS ###############################
# Change DEBUG in your environment settings files, not here
DEBUG = False
USE_TZ = True
SESSION_COOKIE_SECURE = False
SESSION_SAVE_EVERY_REQUEST = False
SESSION_SERIALIZER = 'openedx.core.lib.session_serializers.PickleSerializer'
@@ -1937,106 +1884,11 @@ STATICFILES_DIRS = [
]
FAVICON_PATH = 'images/favicon.ico'
DEFAULT_COURSE_ABOUT_IMAGE_URL = 'images/pencils.jpg'
# User-uploaded content
MEDIA_ROOT = '/edx/var/edxapp/media/'
MEDIA_URL = '/media/'
# Locale/Internationalization
CELERY_TIMEZONE = 'UTC'
TIME_ZONE = 'UTC'
LANGUAGE_CODE = 'en' # http://www.i18nguy.com/unicode/language-identifiers.html
# these languages display right to left
LANGUAGES_BIDI = ("he", "ar", "fa", "ur", "fa-ir", "rtl")
LANGUAGE_COOKIE_NAME = "openedx-language-preference"
# Sourced from http://www.localeplanet.com/icu/ and wikipedia
LANGUAGES = [
('en', 'English'),
('rtl', 'Right-to-Left Test Language'),
('eo', 'Dummy Language (Esperanto)'), # Dummy languaged used for testing
('am', 'አማርኛ'), # Amharic
('ar', 'العربية'), # Arabic
('az', 'azərbaycanca'), # Azerbaijani
('bg-bg', 'български (България)'), # Bulgarian (Bulgaria)
('bn-bd', 'বাংলা (বাংলাদেশ)'), # Bengali (Bangladesh)
('bn-in', 'বাংলা (ভারত)'), # Bengali (India)
('bs', 'bosanski'), # Bosnian
('ca', 'Català'), # Catalan
('ca@valencia', 'Català (València)'), # Catalan (Valencia)
('cs', 'Čeština'), # Czech
('cy', 'Cymraeg'), # Welsh
('da', 'dansk'), # Danish
('de-de', 'Deutsch (Deutschland)'), # German (Germany)
('el', 'Ελληνικά'), # Greek
('en-uk', 'English (United Kingdom)'), # English (United Kingdom)
('en@lolcat', 'LOLCAT English'), # LOLCAT English
('en@pirate', 'Pirate English'), # Pirate English
('es-419', 'Español (Latinoamérica)'), # Spanish (Latin America)
('es-ar', 'Español (Argentina)'), # Spanish (Argentina)
('es-ec', 'Español (Ecuador)'), # Spanish (Ecuador)
('es-es', 'Español (España)'), # Spanish (Spain)
('es-mx', 'Español (México)'), # Spanish (Mexico)
('es-pe', 'Español (Perú)'), # Spanish (Peru)
('et-ee', 'Eesti (Eesti)'), # Estonian (Estonia)
('eu-es', 'euskara (Espainia)'), # Basque (Spain)
('fa', 'فارسی'), # Persian
('fa-ir', 'فارسی (ایران)'), # Persian (Iran)
('fi-fi', 'Suomi (Suomi)'), # Finnish (Finland)
('fil', 'Filipino'), # Filipino
('fr', 'Français'), # French
('gl', 'Galego'), # Galician
('gu', 'ગુજરાતી'), # Gujarati
('he', 'עברית'), # Hebrew
('hi', 'हिन्दी'), # Hindi
('hr', 'hrvatski'), # Croatian
('hu', 'magyar'), # Hungarian
('hy-am', 'Հայերեն (Հայաստան)'), # Armenian (Armenia)
('id', 'Bahasa Indonesia'), # Indonesian
('it-it', 'Italiano (Italia)'), # Italian (Italy)
('ja-jp', '日本語 (日本)'), # Japanese (Japan)
('kk-kz', 'қазақ тілі (Қазақстан)'), # Kazakh (Kazakhstan)
('km-kh', 'ភាសាខ្មែរ (កម្ពុជា)'), # Khmer (Cambodia)
('kn', 'ಕನ್ನಡ'), # Kannada
('ko-kr', '한국어 (대한민국)'), # Korean (Korea)
('lt-lt', 'Lietuvių (Lietuva)'), # Lithuanian (Lithuania)
('ml', 'മലയാളം'), # Malayalam
('mn', 'Монгол хэл'), # Mongolian
('mr', 'मराठी'), # Marathi
('ms', 'Bahasa Melayu'), # Malay
('nb', 'Norsk bokmål'), # Norwegian Bokmål
('ne', 'नेपाली'), # Nepali
('nl-nl', 'Nederlands (Nederland)'), # Dutch (Netherlands)
('or', 'ଓଡ଼ିଆ'), # Oriya
('pl', 'Polski'), # Polish
('pt-br', 'Português (Brasil)'), # Portuguese (Brazil)
('pt-pt', 'Português (Portugal)'), # Portuguese (Portugal)
('ro', 'română'), # Romanian
('ru', 'Русский'), # Russian
('si', 'සිංහල'), # Sinhala
('sk', 'Slovenčina'), # Slovak
('sl', 'Slovenščina'), # Slovenian
('sq', 'shqip'), # Albanian
('sr', 'Српски'), # Serbian
('sv', 'svenska'), # Swedish
('sw', 'Kiswahili'), # Swahili
('ta', 'தமிழ்'), # Tamil
('te', 'తెలుగు'), # Telugu
('th', 'ไทย'), # Thai
('tr-tr', 'Türkçe (Türkiye)'), # Turkish (Turkey)
('uk', 'Українська'), # Ukranian
('ur', 'اردو'), # Urdu
('vi', 'Tiếng Việt'), # Vietnamese
('uz', 'Ўзбек'), # Uzbek
('zh-cn', '中文 (简体)'), # Chinese (China)
('zh-hk', '中文 (香港)'), # Chinese (Hong Kong)
('zh-tw', '中文 (台灣)'), # Chinese (Taiwan)
]
LANGUAGE_DICT = dict(LANGUAGES)
# Languages supported for custom course certificate templates
CERTIFICATE_TEMPLATE_LANGUAGES = {
@@ -2049,20 +1901,6 @@ USE_L10N = True
STATICI18N_FILENAME_FUNCTION = 'statici18n.utils.legacy_filename'
STATICI18N_ROOT = PROJECT_ROOT / "static"
STATICI18N_OUTPUT_DIR = "js/i18n"
# Localization strings (e.g. django.po) are under these directories
def _make_locale_paths(settings): # pylint: disable=missing-function-docstring
locale_paths = list(settings.PREPEND_LOCALE_PATHS)
locale_paths += [settings.REPO_ROOT + '/conf/locale'] # edx-platform/conf/locale/
if settings.ENABLE_COMPREHENSIVE_THEMING:
# Add locale paths to settings for comprehensive theming.
for locale_path in settings.COMPREHENSIVE_THEME_LOCALE_PATHS:
locale_paths += (path(locale_path), )
return locale_paths
LOCALE_PATHS = Derived(_make_locale_paths)
# Messages
MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
@@ -2191,12 +2029,6 @@ EDXNOTES_CONNECT_TIMEOUT = 0.5 # time in seconds
# edx_notes_api service internal endpoint.
EDXNOTES_READ_TIMEOUT = 1.5 # time in seconds
########################## Parental controls config #######################
# The age at which a learner no longer requires parental consent, or None
# if parental consent is never required.
PARENTAL_CONSENT_AGE_LIMIT = 13
######################### Branded Footer ###################################
# Constants for the footer used on the site and shared with other sites
# (such as marketing and the blog) via the branding API.
@@ -2816,14 +2648,6 @@ WEBPACK_LOADER = {
}
}
########################## DJANGO DEBUG TOOLBAR ###############################
# We don't enable Django Debug Toolbar universally, but whenever we do, we want
# to avoid patching settings. Patched settings can cause circular import
# problems: https://django-debug-toolbar.readthedocs.org/en/1.0/installation.html#explicit-setup
DEBUG_TOOLBAR_PATCH_SETTINGS = False
################################# CELERY ######################################
CELERY_IMPORTS = [
@@ -2913,18 +2737,6 @@ CELERY_BROKER_PASSWORD = 'celery'
############################## HEARTBEAT ######################################
# Checks run in normal mode by the heartbeat djangoapp
HEARTBEAT_CHECKS = [
'openedx.core.djangoapps.heartbeat.default_checks.check_modulestore',
'openedx.core.djangoapps.heartbeat.default_checks.check_database',
]
# Other checks to run by default in "extended"/heavy mode
HEARTBEAT_EXTENDED_CHECKS = (
'openedx.core.djangoapps.heartbeat.default_checks.check_celery',
)
HEARTBEAT_CELERY_TIMEOUT = 5
HEARTBEAT_CELERY_ROUTING_KEY = HIGH_PRIORITY_QUEUE
################################ Block Structures ###################################
@@ -3417,34 +3229,6 @@ CROSS_DOMAIN_CSRF_COOKIE_DOMAIN = ''
######################### Django Rest Framework ########################
REST_FRAMEWORK = {
# These default classes add observability around endpoints using defaults, and should
# not be used anywhere else.
# Notes on Order:
# 1. `JwtAuthentication` does not check `is_active`, so email validation does not affect it. However,
# `SessionAuthentication` does. These work differently, and order changes in what way, which really stinks. See
# https://github.com/openedx/public-engineering/issues/165 for details.
# 2. `JwtAuthentication` may also update the database based on contents. Since the LMS creates these JWTs, this
# shouldn't have any affect at this time. But it could, when and if another service started creating the JWTs.
'DEFAULT_AUTHENTICATION_CLASSES': [
'openedx.core.djangolib.default_auth_classes.DefaultJwtAuthentication',
'openedx.core.djangolib.default_auth_classes.DefaultSessionAuthentication',
],
'DEFAULT_PAGINATION_CLASS': 'edx_rest_framework_extensions.paginators.DefaultPagination',
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
),
'EXCEPTION_HANDLER': 'openedx.core.lib.request_utils.ignored_error_exception_handler',
'PAGE_SIZE': 10,
'URL_FORMAT_OVERRIDE': None,
'DEFAULT_THROTTLE_RATES': {
'user': '60/minute',
'service_user': '800/minute',
'registration_validation': '30/minute',
'high_service_user': '2000/minute',
},
}
# .. setting_name: REGISTRATION_VALIDATION_RATELIMIT
# .. setting_default: 30/7d
# .. setting_description: Whenever a user tries to register on edx, the data entered during registration
@@ -3664,7 +3448,6 @@ VERIFICATION_EXPIRY_EMAIL = {
"DEFAULT_EMAILS": 2,
}
DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH = "verify_student_disable_account_activation_requirement"
################ Enable credit eligibility feature ####################
ENABLE_CREDIT_ELIGIBILITY = True
@@ -3757,10 +3540,6 @@ REGISTRATION_FIELD_ORDER = [
"terms_of_service",
]
# Optional setting to restrict registration / account creation to only emails
# that match a regex in this list. Set to None to allow any email (default).
REGISTRATION_EMAIL_PATTERNS_ALLOWED = None
# String length for the configurable part of the auto-generated username
AUTO_GENERATED_USERNAME_RANDOM_STRING_LENGTH = 4
@@ -3802,24 +3581,6 @@ FINANCIAL_REPORTS = {
POLICY_CHANGE_TASK_RATE_LIMIT = '900/h'
#### PASSWORD POLICY SETTINGS #####
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "common.djangoapps.util.password_policy_validators.MinimumLengthValidator",
"OPTIONS": {
"min_length": 8
}
},
{
"NAME": "common.djangoapps.util.password_policy_validators.MaximumLengthValidator",
"OPTIONS": {
"max_length": 75
}
},
]
PASSWORD_POLICY_COMPLIANCE_ROLLOUT_CONFIG = {
'ENFORCE_COMPLIANCE_ON_LOGIN': False
}
@@ -3900,200 +3661,6 @@ VIDEO_TRANSCRIPTS_SETTINGS = dict(
VIDEO_TRANSCRIPTS_MAX_AGE = 31536000
# Source:
# http://loc.gov/standards/iso639-2/ISO-639-2_utf-8.txt according to http://en.wikipedia.org/wiki/ISO_639-1
# Note that this is used as the set of choices to the `code` field of the
# `LanguageProficiency` model.
ALL_LANGUAGES = [
["aa", "Afar"],
["ab", "Abkhazian"],
["af", "Afrikaans"],
["ak", "Akan"],
["sq", "Albanian"],
["am", "Amharic"],
["ar", "Arabic"],
["an", "Aragonese"],
["hy", "Armenian"],
["as", "Assamese"],
["av", "Avaric"],
["ae", "Avestan"],
["ay", "Aymara"],
["az", "Azerbaijani"],
["ba", "Bashkir"],
["bm", "Bambara"],
["eu", "Basque"],
["be", "Belarusian"],
["bn", "Bengali"],
["bh", "Bihari languages"],
["bi", "Bislama"],
["bs", "Bosnian"],
["br", "Breton"],
["bg", "Bulgarian"],
["my", "Burmese"],
["ca", "Catalan"],
["ch", "Chamorro"],
["ce", "Chechen"],
["zh", "Chinese"],
["zh_HANS", "Simplified Chinese"],
["zh_HANT", "Traditional Chinese"],
["cu", "Church Slavic"],
["cv", "Chuvash"],
["kw", "Cornish"],
["co", "Corsican"],
["cr", "Cree"],
["cs", "Czech"],
["da", "Danish"],
["dv", "Divehi"],
["nl", "Dutch"],
["dz", "Dzongkha"],
["en", "English"],
["eo", "Esperanto"],
["et", "Estonian"],
["ee", "Ewe"],
["fo", "Faroese"],
["fj", "Fijian"],
["fi", "Finnish"],
["fr", "French"],
["fy", "Western Frisian"],
["ff", "Fulah"],
["ka", "Georgian"],
["de", "German"],
["gd", "Gaelic"],
["ga", "Irish"],
["gl", "Galician"],
["gv", "Manx"],
["el", "Greek"],
["gn", "Guarani"],
["gu", "Gujarati"],
["ht", "Haitian"],
["ha", "Hausa"],
["he", "Hebrew"],
["hz", "Herero"],
["hi", "Hindi"],
["ho", "Hiri Motu"],
["hr", "Croatian"],
["hu", "Hungarian"],
["ig", "Igbo"],
["is", "Icelandic"],
["io", "Ido"],
["ii", "Sichuan Yi"],
["iu", "Inuktitut"],
["ie", "Interlingue"],
["ia", "Interlingua"],
["id", "Indonesian"],
["ik", "Inupiaq"],
["it", "Italian"],
["jv", "Javanese"],
["ja", "Japanese"],
["kl", "Kalaallisut"],
["kn", "Kannada"],
["ks", "Kashmiri"],
["kr", "Kanuri"],
["kk", "Kazakh"],
["km", "Central Khmer"],
["ki", "Kikuyu"],
["rw", "Kinyarwanda"],
["ky", "Kirghiz"],
["kv", "Komi"],
["kg", "Kongo"],
["ko", "Korean"],
["kj", "Kuanyama"],
["ku", "Kurdish"],
["lo", "Lao"],
["la", "Latin"],
["lv", "Latvian"],
["li", "Limburgan"],
["ln", "Lingala"],
["lt", "Lithuanian"],
["lb", "Luxembourgish"],
["lu", "Luba-Katanga"],
["lg", "Ganda"],
["mk", "Macedonian"],
["mh", "Marshallese"],
["ml", "Malayalam"],
["mi", "Maori"],
["mr", "Marathi"],
["ms", "Malay"],
["mg", "Malagasy"],
["mt", "Maltese"],
["mn", "Mongolian"],
["na", "Nauru"],
["nv", "Navajo"],
["nr", "Ndebele, South"],
["nd", "Ndebele, North"],
["ng", "Ndonga"],
["ne", "Nepali"],
["nn", "Norwegian Nynorsk"],
["nb", "Bokmål, Norwegian"],
["no", "Norwegian"],
["ny", "Chichewa"],
["oc", "Occitan"],
["oj", "Ojibwa"],
["or", "Oriya"],
["om", "Oromo"],
["os", "Ossetian"],
["pa", "Panjabi"],
["fa", "Persian"],
["pi", "Pali"],
["pl", "Polish"],
["pt", "Portuguese"],
["ps", "Pushto"],
["qu", "Quechua"],
["rm", "Romansh"],
["ro", "Romanian"],
["rn", "Rundi"],
["ru", "Russian"],
["sg", "Sango"],
["sa", "Sanskrit"],
["si", "Sinhala"],
["sk", "Slovak"],
["sl", "Slovenian"],
["se", "Northern Sami"],
["sm", "Samoan"],
["sn", "Shona"],
["sd", "Sindhi"],
["so", "Somali"],
["st", "Sotho, Southern"],
["es", "Spanish"],
["sc", "Sardinian"],
["sr", "Serbian"],
["ss", "Swati"],
["su", "Sundanese"],
["sw", "Swahili"],
["sv", "Swedish"],
["ty", "Tahitian"],
["ta", "Tamil"],
["tt", "Tatar"],
["te", "Telugu"],
["tg", "Tajik"],
["tl", "Tagalog"],
["th", "Thai"],
["bo", "Tibetan"],
["ti", "Tigrinya"],
["to", "Tonga (Tonga Islands)"],
["tn", "Tswana"],
["ts", "Tsonga"],
["tk", "Turkmen"],
["tr", "Turkish"],
["tw", "Twi"],
["ug", "Uighur"],
["uk", "Ukrainian"],
["ur", "Urdu"],
["uz", "Uzbek"],
["ve", "Venda"],
["vi", "Vietnamese"],
["vo", "Volapük"],
["cy", "Welsh"],
["wa", "Walloon"],
["wo", "Wolof"],
["xh", "Xhosa"],
["yi", "Yiddish"],
["yo", "Yoruba"],
["za", "Zhuang"],
["zu", "Zulu"]
]
### Apps only installed in some instances
# The order of INSTALLED_APPS matters, so this tuple is the app name and the item in INSTALLED_APPS
# that this app should be inserted *before*. A None here means it should be appended to the list.
@@ -4390,35 +3957,6 @@ FIELD_OVERRIDE_PROVIDERS = ()
MODULESTORE_FIELD_OVERRIDE_PROVIDERS = ('openedx.features.content_type_gating.'
'field_override.ContentTypeGatingFieldOverride',)
# PROFILE IMAGE CONFIG
# WARNING: Certain django storage backends do not support atomic
# file overwrites (including the default, OverwriteStorage) - instead
# there are separate calls to delete and then write a new file in the
# storage backend. This introduces the risk of a race condition
# occurring when a user uploads a new profile image to replace an
# earlier one (the file will temporarily be deleted).
PROFILE_IMAGE_BACKEND = {
'class': 'openedx.core.storage.OverwriteStorage',
'options': {
'location': os.path.join(MEDIA_ROOT, 'profile-images/'),
'base_url': os.path.join(MEDIA_URL, 'profile-images/'),
},
}
PROFILE_IMAGE_DEFAULT_FILENAME = 'images/profiles/default'
PROFILE_IMAGE_DEFAULT_FILE_EXTENSION = 'png'
# This key is used in generating unguessable URLs to users'
# profile images. Once it has been set, changing it will make the
# platform unaware of current image URLs.
PROFILE_IMAGE_HASH_SEED = 'placeholder_secret_key'
PROFILE_IMAGE_MAX_BYTES = 1024 * 1024
PROFILE_IMAGE_MIN_BYTES = 100
PROFILE_IMAGE_SIZES_MAP = {
'full': 500,
'large': 120,
'medium': 50,
'small': 30
}
# Sets the maximum number of courses listed on the homepage
# If set to None, all courses will be listed on the homepage
HOMEPAGE_COURSE_MAX = None
@@ -4444,9 +3982,6 @@ CREDIT_TASK_DEFAULT_RETRY_DELAY = 30
# to throttling.
CREDIT_TASK_MAX_RETRIES = 5
# Dummy secret key for dev/test
SECRET_KEY = 'dev key'
# Secret keys shared with credit providers.
# Used to digitally sign credit requests (us --> provider)
# and validate responses (provider --> us).
@@ -4496,45 +4031,6 @@ DEFAULT_JWT_ISSUER = {
JWT_EXPIRATION = 30
JWT_PRIVATE_SIGNING_KEY = None
JWT_AUTH = {
'JWT_VERIFY_EXPIRATION': True,
'JWT_PAYLOAD_GET_USERNAME_HANDLER': lambda d: d.get('username'),
'JWT_LEEWAY': 1,
'JWT_DECODE_HANDLER': 'edx_rest_framework_extensions.auth.jwt.decoder.jwt_decode_handler',
'JWT_AUTH_COOKIE': 'edx-jwt-cookie',
# Number of seconds before JWTs expire
'JWT_EXPIRATION': 30,
'JWT_IN_COOKIE_EXPIRATION': 60 * 60,
'JWT_LOGIN_CLIENT_ID': 'login-service-client-id',
'JWT_LOGIN_SERVICE_USERNAME': 'login_service_user',
'JWT_SUPPORTED_VERSION': '1.2.0',
'JWT_ALGORITHM': 'HS256',
'JWT_SECRET_KEY': SECRET_KEY,
'JWT_SIGNING_ALGORITHM': 'RS512',
'JWT_PRIVATE_SIGNING_JWK': None,
'JWT_PUBLIC_SIGNING_JWK_SET': None,
'JWT_ISSUER': 'http://127.0.0.1:8000/oauth2',
'JWT_AUDIENCE': 'change-me',
'JWT_ISSUERS': [
{
'ISSUER': 'http://127.0.0.1:8000/oauth2',
'AUDIENCE': 'change-me',
'SECRET_KEY': SECRET_KEY
}
],
'JWT_AUTH_COOKIE_HEADER_PAYLOAD': 'edx-jwt-cookie-header-payload',
'JWT_AUTH_COOKIE_SIGNATURE': 'edx-jwt-cookie-signature',
'JWT_AUTH_HEADER_PREFIX': 'JWT',
}
EDX_DRF_EXTENSIONS = {
# Set this value to an empty dict in order to prevent automatically updating
# user data from values in (possibly stale) JWTs.
@@ -4600,12 +4096,6 @@ CREDENTIALS_COURSE_COMPLETION_STATE = 'awarded'
# Queue to use for award program certificates
PROGRAM_CERTIFICATES_ROUTING_KEY = 'edx.lms.core.default'
# Settings for Comprehensive Theming app
# See https://github.com/openedx/edx-django-sites-extensions for more info
# Default site to use if site matching request headers does not exist
SITE_ID = 1
# .. setting_name: COMPREHENSIVE_THEME_DIRS
# .. setting_default: []
# .. setting_description: A list of paths to directories, each of which will
@@ -4664,13 +4154,6 @@ AUTH_DOCUMENTATION_URL = 'https://course-catalog-api-guide.readthedocs.io/en/lat
# Affiliate cookie tracking
AFFILIATE_COOKIE_NAME = 'dev_affiliate_id'
############## Settings for RedirectMiddleware ###############
# Setting this to None causes Redirect data to never expire
# The cache is cleared when Redirect models are saved/deleted
REDIRECT_CACHE_TIMEOUT = None # The length of time we cache Redirect model data
REDIRECT_CACHE_KEY_PREFIX = 'redirects'
############## Settings for LMS Context Sensitive Help ##############
HELP_TOKENS_INI_FILE = REPO_ROOT / "lms" / "envs" / "help_tokens.ini"
@@ -4713,7 +4196,6 @@ ENTERPRISE_CONSENT_API_URL = LMS_INTERNAL_ROOT_URL + '/consent/api/v1/'
ENTERPRISE_SERVICE_WORKER_USERNAME = 'enterprise_worker'
ENTERPRISE_API_CACHE_TIMEOUT = 3600 # Value is in seconds
ENTERPRISE_CUSTOMER_LOGO_IMAGE_SIZE = 512 # Enterprise logo image size limit in KB's
ENTERPRISE_CATALOG_INTERNAL_ROOT_URL = 'http://enterprise.catalog.app:18160'
# Defines the usernames of service users who should be throttled
# at a higher rate than normal users when making requests of enterprise endpoints.
ENTERPRISE_ALL_SERVICE_USERNAMES = [
@@ -4801,90 +4283,6 @@ ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS = {}
ENTERPRISE_TAGLINE = ''
TRANSCRIPT_LANG_CACHE_TIMEOUT = 60 * 60 * 24 # 24 hours
############## Settings for Course Enrollment Modes ######################
# The min_price key refers to the minimum price allowed for an instance
# of a particular type of course enrollment mode. This is not to be confused
# with the min_price field of the CourseMode model, which refers to the actual
# price of the CourseMode.
COURSE_ENROLLMENT_MODES = {
"audit": {
"id": 1,
"slug": "audit",
"display_name": _("Audit"),
"min_price": 0,
},
"verified": {
"id": 2,
"slug": "verified",
"display_name": _("Verified"),
"min_price": 1,
},
"professional": {
"id": 3,
"slug": "professional",
"display_name": _("Professional"),
"min_price": 1,
},
"no-id-professional": {
"id": 4,
"slug": "no-id-professional",
"display_name": _("No-Id-Professional"),
"min_price": 0,
},
"credit": {
"id": 5,
"slug": "credit",
"display_name": _("Credit"),
"min_price": 0,
},
"honor": {
"id": 6,
"slug": "honor",
"display_name": _("Honor"),
"min_price": 0,
},
"masters": {
"id": 7,
"slug": "masters",
"display_name": _("Master's"),
"min_price": 0,
},
"executive-education": {
"id": 8,
"slug": "executive-educations",
"display_name": _("Executive Education"),
"min_price": 1
},
"unpaid-executive-education": {
"id": 9,
"slug": "unpaid-executive-education",
"display_name": _("Unpaid Executive Education"),
"min_price": 0
},
"paid-executive-education": {
"id": 10,
"slug": "paid-executive-education",
"display_name": _("Paid Executive Education"),
"min_price": 1
},
"unpaid-bootcamp": {
"id": 11,
"slug": "unpaid-bootcamp",
"display_name": _("Unpaid Bootcamp"),
"min_price": 0
},
"paid-bootcamp": {
"id": 12,
"slug": "paid-bootcamp",
"display_name": _("Paid Bootcamp"),
"min_price": 1
},
}
CONTENT_TYPE_GATE_GROUP_IDS = {
'limited_access': 1,
'full_access': 2,
}
############## Settings for the Discovery App ######################
@@ -5357,11 +4755,6 @@ IS_ELIGIBLE_FOR_FINANCIAL_ASSISTANCE_URL = '/core/api/course_eligibility/'
FINANCIAL_ASSISTANCE_APPLICATION_STATUS_URL = "/core/api/financial_assistance_application/status/"
CREATE_FINANCIAL_ASSISTANCE_APPLICATION_URL = '/core/api/financial_assistance_applications'
######################## Enterprise API Client ########################
ENTERPRISE_BACKEND_SERVICE_EDX_OAUTH2_KEY = "enterprise-backend-service-key"
ENTERPRISE_BACKEND_SERVICE_EDX_OAUTH2_SECRET = "enterprise-backend-service-secret"
ENTERPRISE_BACKEND_SERVICE_EDX_OAUTH2_PROVIDER_URL = "http://127.0.0.1:8000/oauth2"
# keys for big blue button live provider
COURSE_LIVE_GLOBAL_CREDENTIALS = {}
@@ -5604,94 +4997,6 @@ SURVEY_REPORT_EXTRA_DATA = {}
LMS_COMM_DEFAULT_FROM_EMAIL = "no-reply@example.com"
####################### Setting for built-in Blocks Extraction #######################
# The following Django settings flags have been introduced temporarily to facilitate
# the rollout of the extracted built-in Blocks. Flags will use to toggle between
# the old and new block quickly without putting course content or user state at risk.
#
# Ticket: https://github.com/openedx/edx-platform/issues/35308
# .. toggle_name: USE_EXTRACTED_WORD_CLOUD_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted Word Cloud XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until https://github.com/openedx/edx-platform/issues/34840 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_WORD_CLOUD_BLOCK = False
# .. toggle_name: USE_EXTRACTED_ANNOTATABLE_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted annotatable XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until https://github.com/openedx/edx-platform/issues/34841 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_ANNOTATABLE_BLOCK = False
# .. toggle_name: USE_EXTRACTED_POLL_QUESTION_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted poll question XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until https://github.com/openedx/edx-platform/issues/34839 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_POLL_QUESTION_BLOCK = False
# .. toggle_name: USE_EXTRACTED_LTI_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted LTI XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until relevant subtask https://github.com/openedx/edx-platform/issues/34827 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_LTI_BLOCK = False
# .. toggle_name: USE_EXTRACTED_HTML_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted HTML XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until relevant subtask https://github.com/openedx/edx-platform/issues/34827 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_HTML_BLOCK = False
# .. toggle_name: USE_EXTRACTED_DISCUSSION_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted Discussion XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until relevant subtask https://github.com/openedx/edx-platform/issues/34827 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_DISCUSSION_BLOCK = False
# .. toggle_name: USE_EXTRACTED_PROBLEM_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted Problem XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until relevant subtask https://github.com/openedx/edx-platform/issues/34827 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_PROBLEM_BLOCK = False
# .. toggle_name: USE_EXTRACTED_VIDEO_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted Video XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until relevant subtask https://github.com/openedx/edx-platform/issues/34827 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_VIDEO_BLOCK = False
# .. setting_name: RECAPTCHA_PRIVATE_KEY
# .. setting_default: empty string
# .. setting_description: Add recaptcha private key to use captcha feature in discussion app.

View File

@@ -469,19 +469,19 @@ DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL = True
# If you want to enable theming in devstack, uncomment this section and add any relevant
# theme directories to COMPREHENSIVE_THEME_DIRS
# We have to import the private method here because production.py calls
# derive_settings('lms.envs.production') which runs _make_mako_template_dirs with
# We have to import the make_mako_template_dirs method here because production.py calls
# derive_settings('lms.envs.production') which runs make_mako_template_dirs with
# the settings from production, which doesn't include these theming settings. Thus,
# the templating engine is unable to find the themed templates because they don't exist
# in it's path. Re-calling derive_settings doesn't work because the settings was already
# changed from a function to a list, and it can't be derived again.
# from .common import _make_mako_template_dirs
# from openedx.envs.common import make_mako_template_dirs
# ENABLE_COMPREHENSIVE_THEMING = True
# COMPREHENSIVE_THEME_DIRS = [
# "/edx/app/edxapp/edx-platform/themes/"
# ]
# TEMPLATES[1]["DIRS"] = _make_mako_template_dirs
# TEMPLATES[1]["DIRS"] = make_mako_template_dirs
# derive_settings(__name__)
# Uncomment the lines below if you'd like to see SQL statements in your devstack LMS log.

View File

@@ -1,7 +1,7 @@
LMS Configuration Settings
##########################
The ``lms.envs`` module contains project-wide settings, defined in python modules
The ``lms.envs`` module contains lms related settings, defined in python modules
using the standard `Django Settings`_ mechanism, plus some Open edX
particularities, which we describe below.
@@ -70,7 +70,7 @@ when nested within each other:
.. code-block:: python
def _make_mako_template_dirs(settings):
def make_mako_template_dirs(settings):
"""
Derives the final Mako template directories list from other settings.
"""
@@ -91,6 +91,6 @@ when nested within each other:
'NAME': 'mako',
'BACKEND': 'common.djangoapps.edxmako.backend.Mako',
'APP_DIRS': False,
'DIRS': Derived(_make_mako_template_dirs),
'DIRS': Derived(make_mako_template_dirs),
},
]

View File

@@ -2962,7 +2962,7 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase, OpenEdxEventsTestM
)
])
def test_password_empty_validation_decision(self):
# 2 is the default setting for minimum length found in lms/envs/common.py
# 2 is the default setting for minimum length found in openedx/envs/common.py
# under AUTH_PASSWORD_VALIDATORS.MinimumLengthValidator
msg = 'This password is too short. It must contain at least 4 characters.'
self.assertValidationDecision(
@@ -2977,7 +2977,7 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase, OpenEdxEventsTestM
])
def test_password_bad_min_length_validation_decision(self):
password = 'p'
# 2 is the default setting for minimum length found in lms/envs/common.py
# 2 is the default setting for minimum length found in openedx/envs/common.py
# under AUTH_PASSWORD_VALIDATORS.MinimumLengthValidator
msg = 'This password is too short. It must contain at least 4 characters.'
self.assertValidationDecision(
@@ -2987,7 +2987,7 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase, OpenEdxEventsTestM
def test_password_bad_max_length_validation_decision(self):
password = 'p' * DEFAULT_MAX_PASSWORD_LENGTH
# 75 is the default setting for maximum length found in lms/envs/common.py
# 75 is the default setting for maximum length found in openedx/envs/common.py
# under AUTH_PASSWORD_VALIDATORS.MaximumLengthValidator
msg = 'This password is too long. It must contain no more than 75 characters.'
self.assertValidationDecision(

0
openedx/envs/__init__.py Normal file
View File

788
openedx/envs/common.py Normal file
View File

@@ -0,0 +1,788 @@
"""
Common Django settings for Open edX services.
This module defines configuration shared between the LMS and CMS (Studio)
environments. It centralizes common settings in one place and reduces duplication.
Service-specific settings should import from this module and override as needed.
Note: More settings will be added to this file as the effort to simplify
settings moves forward. See docs/decisions/0022-settings-simplification.rst for
more details on the effort to simplify settings across Open edX services.
To create section headers in this file, use the following function:
```python
def center_with_hashes(text: str, width: int = 76):
print(f"{f' {text} ':#^{width}}")
```
"""
import os
from path import Path as path
from django.utils.translation import gettext_lazy as _
from openedx.core.lib.derived import Derived
from openedx.core.djangoapps.theming.helpers_dirs import (
get_themes_unchecked,
get_theme_base_dirs_from_settings
)
from openedx.core.constants import ( # pylint: disable=unused-import
ASSET_KEY_PATTERN,
COURSE_KEY_REGEX,
COURSE_KEY_PATTERN,
COURSE_ID_PATTERN,
USAGE_KEY_PATTERN,
USAGE_ID_PATTERN,
)
################ Shared Functions for Derived Configuration ################
def make_mako_template_dirs(settings):
"""
Derives the final list of Mako template directories based on the provided settings.
Args:
settings: A Django settings module object.
Returns:
list: A list of Mako template directories, potentially updated with additional
theme directories.
"""
if settings.ENABLE_COMPREHENSIVE_THEMING:
themes_dirs = get_theme_base_dirs_from_settings(settings.COMPREHENSIVE_THEME_DIRS)
for theme in get_themes_unchecked(themes_dirs, settings.PROJECT_ROOT):
if theme.themes_base_dir not in settings.MAKO_TEMPLATE_DIRS_BASE:
settings.MAKO_TEMPLATE_DIRS_BASE.insert(0, theme.themes_base_dir)
return settings.MAKO_TEMPLATE_DIRS_BASE
def _make_locale_paths(settings):
"""
Constructs a list of paths to locale directories used for translation.
Localization (l10n) strings (e.g. django.po) are found in these directories.
Args:
settings: A Django settings module object.
Returns:
list: A list of paths, `str` or `path.Path`, to locale directories.
"""
locale_paths = list(settings.PREPEND_LOCALE_PATHS)
locale_paths += [settings.REPO_ROOT + '/conf/locale'] # edx-platform/conf/locale/
if settings.ENABLE_COMPREHENSIVE_THEMING:
# Add locale paths to settings for comprehensive theming.
for locale_path in settings.COMPREHENSIVE_THEME_LOCALE_PATHS:
locale_paths += (path(locale_path), )
return locale_paths
############################# Django Built-Ins #############################
USE_TZ = True
# User-uploaded content
MEDIA_ROOT = '/edx/var/edxapp/media/'
MEDIA_URL = '/media/'
# Dummy secret key for dev/test
SECRET_KEY = 'dev key'
STATICI18N_OUTPUT_DIR = "js/i18n"
# Sourced from http://www.localeplanet.com/icu/ and wikipedia
LANGUAGES = [
('en', 'English'),
('rtl', 'Right-to-Left Test Language'),
('eo', 'Dummy Language (Esperanto)'), # Dummy languaged used for testing
('am', 'አማርኛ'), # Amharic
('ar', 'العربية'), # Arabic
('az', 'azərbaycanca'), # Azerbaijani
('bg-bg', 'български (България)'), # Bulgarian (Bulgaria)
('bn-bd', 'বাংলা (বাংলাদেশ)'), # Bengali (Bangladesh)
('bn-in', 'বাংলা (ভারত)'), # Bengali (India)
('bs', 'bosanski'), # Bosnian
('ca', 'Català'), # Catalan
('ca@valencia', 'Català (València)'), # Catalan (Valencia)
('cs', 'Čeština'), # Czech
('cy', 'Cymraeg'), # Welsh
('da', 'dansk'), # Danish
('de-de', 'Deutsch (Deutschland)'), # German (Germany)
('el', 'Ελληνικά'), # Greek
('en-uk', 'English (United Kingdom)'), # English (United Kingdom)
('en@lolcat', 'LOLCAT English'), # LOLCAT English
('en@pirate', 'Pirate English'), # Pirate English
('es-419', 'Español (Latinoamérica)'), # Spanish (Latin America)
('es-ar', 'Español (Argentina)'), # Spanish (Argentina)
('es-ec', 'Español (Ecuador)'), # Spanish (Ecuador)
('es-es', 'Español (España)'), # Spanish (Spain)
('es-mx', 'Español (México)'), # Spanish (Mexico)
('es-pe', 'Español (Perú)'), # Spanish (Peru)
('et-ee', 'Eesti (Eesti)'), # Estonian (Estonia)
('eu-es', 'euskara (Espainia)'), # Basque (Spain)
('fa', 'فارسی'), # Persian
('fa-ir', 'فارسی (ایران)'), # Persian (Iran)
('fi-fi', 'Suomi (Suomi)'), # Finnish (Finland)
('fil', 'Filipino'), # Filipino
('fr', 'Français'), # French
('gl', 'Galego'), # Galician
('gu', 'ગુજરાતી'), # Gujarati
('he', 'עברית'), # Hebrew
('hi', 'हिन्दी'), # Hindi
('hr', 'hrvatski'), # Croatian
('hu', 'magyar'), # Hungarian
('hy-am', 'Հայերեն (Հայաստան)'), # Armenian (Armenia)
('id', 'Bahasa Indonesia'), # Indonesian
('it-it', 'Italiano (Italia)'), # Italian (Italy)
('ja-jp', '日本語 (日本)'), # Japanese (Japan)
('kk-kz', 'қазақ тілі (Қазақстан)'), # Kazakh (Kazakhstan)
('km-kh', 'ភាសាខ្មែរ (កម្ពុជា)'), # Khmer (Cambodia)
('kn', 'ಕನ್ನಡ'), # Kannada
('ko-kr', '한국어 (대한민국)'), # Korean (Korea)
('lt-lt', 'Lietuvių (Lietuva)'), # Lithuanian (Lithuania)
('ml', 'മലയാളം'), # Malayalam
('mn', 'Монгол хэл'), # Mongolian
('mr', 'मराठी'), # Marathi
('ms', 'Bahasa Melayu'), # Malay
('nb', 'Norsk bokmål'), # Norwegian Bokmål
('ne', 'नेपाली'), # Nepali
('nl-nl', 'Nederlands (Nederland)'), # Dutch (Netherlands)
('or', 'ଓଡ଼ିଆ'), # Oriya
('pl', 'Polski'), # Polish
('pt-br', 'Português (Brasil)'), # Portuguese (Brazil)
('pt-pt', 'Português (Portugal)'), # Portuguese (Portugal)
('ro', 'română'), # Romanian
('ru', 'Русский'), # Russian
('si', 'සිංහල'), # Sinhala
('sk', 'Slovenčina'), # Slovak
('sl', 'Slovenščina'), # Slovenian
('sq', 'shqip'), # Albanian
('sr', 'Српски'), # Serbian
('sv', 'svenska'), # Swedish
('sw', 'Kiswahili'), # Swahili
('ta', 'தமிழ்'), # Tamil
('te', 'తెలుగు'), # Telugu
('th', 'ไทย'), # Thai
('tr-tr', 'Türkçe (Türkiye)'), # Turkish (Turkey)
('uk', 'Українська'), # Ukranian
('ur', 'اردو'), # Urdu
('vi', 'Tiếng Việt'), # Vietnamese
('uz', 'Ўзбек'), # Uzbek
('zh-cn', '中文 (简体)'), # Chinese (China)
('zh-hk', '中文 (香港)'), # Chinese (Hong Kong)
('zh-tw', '中文 (台灣)'), # Chinese (Taiwan)
]
# these languages display right to left
LANGUAGES_BIDI = ("he", "ar", "fa", "ur", "fa-ir", "rtl")
LANGUAGE_COOKIE_NAME = "openedx-language-preference"
LOCALE_PATHS = Derived(_make_locale_paths)
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "common.djangoapps.util.password_policy_validators.MinimumLengthValidator",
"OPTIONS": {
"min_length": 8
}
},
{
"NAME": "common.djangoapps.util.password_policy_validators.MaximumLengthValidator",
"OPTIONS": {
"max_length": 75
}
},
]
# See https://github.com/openedx/edx-django-sites-extensions for more info.
# Default site to use if site matching request headers does not exist.
SITE_ID = 1
################################# Language #################################
# Source:
# http://loc.gov/standards/iso639-2/ISO-639-2_utf-8.txt according to http://en.wikipedia.org/wiki/ISO_639-1
# Note that this is used as the set of choices to the `code` field of the `LanguageProficiency` model.
ALL_LANGUAGES = [
["aa", "Afar"],
["ab", "Abkhazian"],
["af", "Afrikaans"],
["ak", "Akan"],
["sq", "Albanian"],
["am", "Amharic"],
["ar", "Arabic"],
["an", "Aragonese"],
["hy", "Armenian"],
["as", "Assamese"],
["av", "Avaric"],
["ae", "Avestan"],
["ay", "Aymara"],
["az", "Azerbaijani"],
["ba", "Bashkir"],
["bm", "Bambara"],
["eu", "Basque"],
["be", "Belarusian"],
["bn", "Bengali"],
["bh", "Bihari languages"],
["bi", "Bislama"],
["bs", "Bosnian"],
["br", "Breton"],
["bg", "Bulgarian"],
["my", "Burmese"],
["ca", "Catalan"],
["ch", "Chamorro"],
["ce", "Chechen"],
["zh", "Chinese"],
["zh_HANS", "Simplified Chinese"],
["zh_HANT", "Traditional Chinese"],
["cu", "Church Slavic"],
["cv", "Chuvash"],
["kw", "Cornish"],
["co", "Corsican"],
["cr", "Cree"],
["cs", "Czech"],
["da", "Danish"],
["dv", "Divehi"],
["nl", "Dutch"],
["dz", "Dzongkha"],
["en", "English"],
["eo", "Esperanto"],
["et", "Estonian"],
["ee", "Ewe"],
["fo", "Faroese"],
["fj", "Fijian"],
["fi", "Finnish"],
["fr", "French"],
["fy", "Western Frisian"],
["ff", "Fulah"],
["ka", "Georgian"],
["de", "German"],
["gd", "Gaelic"],
["ga", "Irish"],
["gl", "Galician"],
["gv", "Manx"],
["el", "Greek"],
["gn", "Guarani"],
["gu", "Gujarati"],
["ht", "Haitian"],
["ha", "Hausa"],
["he", "Hebrew"],
["hz", "Herero"],
["hi", "Hindi"],
["ho", "Hiri Motu"],
["hr", "Croatian"],
["hu", "Hungarian"],
["ig", "Igbo"],
["is", "Icelandic"],
["io", "Ido"],
["ii", "Sichuan Yi"],
["iu", "Inuktitut"],
["ie", "Interlingue"],
["ia", "Interlingua"],
["id", "Indonesian"],
["ik", "Inupiaq"],
["it", "Italian"],
["jv", "Javanese"],
["ja", "Japanese"],
["kl", "Kalaallisut"],
["kn", "Kannada"],
["ks", "Kashmiri"],
["kr", "Kanuri"],
["kk", "Kazakh"],
["km", "Central Khmer"],
["ki", "Kikuyu"],
["rw", "Kinyarwanda"],
["ky", "Kirghiz"],
["kv", "Komi"],
["kg", "Kongo"],
["ko", "Korean"],
["kj", "Kuanyama"],
["ku", "Kurdish"],
["lo", "Lao"],
["la", "Latin"],
["lv", "Latvian"],
["li", "Limburgan"],
["ln", "Lingala"],
["lt", "Lithuanian"],
["lb", "Luxembourgish"],
["lu", "Luba-Katanga"],
["lg", "Ganda"],
["mk", "Macedonian"],
["mh", "Marshallese"],
["ml", "Malayalam"],
["mi", "Maori"],
["mr", "Marathi"],
["ms", "Malay"],
["mg", "Malagasy"],
["mt", "Maltese"],
["mn", "Mongolian"],
["na", "Nauru"],
["nv", "Navajo"],
["nr", "Ndebele, South"],
["nd", "Ndebele, North"],
["ng", "Ndonga"],
["ne", "Nepali"],
["nn", "Norwegian Nynorsk"],
["nb", "Bokmål, Norwegian"],
["no", "Norwegian"],
["ny", "Chichewa"],
["oc", "Occitan"],
["oj", "Ojibwa"],
["or", "Oriya"],
["om", "Oromo"],
["os", "Ossetian"],
["pa", "Panjabi"],
["fa", "Persian"],
["pi", "Pali"],
["pl", "Polish"],
["pt", "Portuguese"],
["ps", "Pushto"],
["qu", "Quechua"],
["rm", "Romansh"],
["ro", "Romanian"],
["rn", "Rundi"],
["ru", "Russian"],
["sg", "Sango"],
["sa", "Sanskrit"],
["si", "Sinhala"],
["sk", "Slovak"],
["sl", "Slovenian"],
["se", "Northern Sami"],
["sm", "Samoan"],
["sn", "Shona"],
["sd", "Sindhi"],
["so", "Somali"],
["st", "Sotho, Southern"],
["es", "Spanish"],
["sc", "Sardinian"],
["sr", "Serbian"],
["ss", "Swati"],
["su", "Sundanese"],
["sw", "Swahili"],
["sv", "Swedish"],
["ty", "Tahitian"],
["ta", "Tamil"],
["tt", "Tatar"],
["te", "Telugu"],
["tg", "Tajik"],
["tl", "Tagalog"],
["th", "Thai"],
["bo", "Tibetan"],
["ti", "Tigrinya"],
["to", "Tonga (Tonga Islands)"],
["tn", "Tswana"],
["ts", "Tsonga"],
["tk", "Turkmen"],
["tr", "Turkish"],
["tw", "Twi"],
["ug", "Uighur"],
["uk", "Ukrainian"],
["ur", "Urdu"],
["uz", "Uzbek"],
["ve", "Venda"],
["vi", "Vietnamese"],
["vo", "Volapük"],
["cy", "Welsh"],
["wa", "Walloon"],
["wo", "Wolof"],
["xh", "Xhosa"],
["yi", "Yiddish"],
["yo", "Yoruba"],
["za", "Zhuang"],
["zu", "Zulu"]
]
LANGUAGE_DICT = dict(LANGUAGES)
########################## Django Rest Framework ###########################
REST_FRAMEWORK = {
# These default classes add observability around endpoints using defaults, and should
# not be used anywhere else.
# Notes on Order:
# 1. `JwtAuthentication` does not check `is_active`, so email validation does not affect it. However,
# `SessionAuthentication` does. These work differently, and order changes in what way, which really stinks. See
# https://github.com/openedx/public-engineering/issues/165 for details.
# 2. `JwtAuthentication` may also update the database based on contents. Since the LMS creates these JWTs, this
# shouldn't have any affect at this time. But it could, when and if another service started creating the JWTs.
'DEFAULT_AUTHENTICATION_CLASSES': [
'openedx.core.djangolib.default_auth_classes.DefaultJwtAuthentication',
'openedx.core.djangolib.default_auth_classes.DefaultSessionAuthentication',
],
'DEFAULT_PAGINATION_CLASS': 'edx_rest_framework_extensions.paginators.DefaultPagination',
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
),
'EXCEPTION_HANDLER': 'openedx.core.lib.request_utils.ignored_error_exception_handler',
'PAGE_SIZE': 10,
'URL_FORMAT_OVERRIDE': None,
'DEFAULT_THROTTLE_RATES': {
'user': '60/minute',
'service_user': '800/minute',
'registration_validation': '30/minute',
'high_service_user': '2000/minute',
},
}
################################ Heartbeat #################################
# Checks run in normal mode by the heartbeat djangoapp
HEARTBEAT_CHECKS = [
'openedx.core.djangoapps.heartbeat.default_checks.check_modulestore',
'openedx.core.djangoapps.heartbeat.default_checks.check_database',
]
# Other checks to run by default in "extended"/heavy mode
HEARTBEAT_EXTENDED_CHECKS = (
'openedx.core.djangoapps.heartbeat.default_checks.check_celery',
)
HEARTBEAT_CELERY_TIMEOUT = 5
############################ RedirectMiddleware ############################
# Setting this to None causes Redirect data to never expire
# The cache is cleared when Redirect models are saved/deleted
REDIRECT_CACHE_TIMEOUT = None # The length of time we cache Redirect model data
REDIRECT_CACHE_KEY_PREFIX = 'redirects'
########################### Django Debug Toolbar ###########################
# We don't enable Django Debug Toolbar universally, but whenever we do, we want
# to avoid patching settings. Patched settings can cause circular import
# problems: https://django-debug-toolbar.readthedocs.org/en/1.0/installation.html#explicit-setup
DEBUG_TOOLBAR_PATCH_SETTINGS = False
################################### JWT ####################################
JWT_AUTH = {
'JWT_VERIFY_EXPIRATION': True,
'JWT_PAYLOAD_GET_USERNAME_HANDLER': lambda d: d.get('username'),
'JWT_LEEWAY': 1,
'JWT_DECODE_HANDLER': 'edx_rest_framework_extensions.auth.jwt.decoder.jwt_decode_handler',
'JWT_AUTH_COOKIE': 'edx-jwt-cookie',
# Number of seconds before JWTs expire
'JWT_EXPIRATION': 30,
'JWT_IN_COOKIE_EXPIRATION': 60 * 60,
'JWT_LOGIN_CLIENT_ID': 'login-service-client-id',
'JWT_LOGIN_SERVICE_USERNAME': 'login_service_user',
'JWT_SUPPORTED_VERSION': '1.2.0',
'JWT_ALGORITHM': 'HS256',
'JWT_SECRET_KEY': SECRET_KEY,
'JWT_SIGNING_ALGORITHM': 'RS512',
'JWT_PRIVATE_SIGNING_JWK': None,
'JWT_PUBLIC_SIGNING_JWK_SET': None,
'JWT_ISSUER': 'http://127.0.0.1:8000/oauth2',
'JWT_AUDIENCE': 'change-me',
'JWT_ISSUERS': [
{
'ISSUER': 'http://127.0.0.1:8000/oauth2',
'AUDIENCE': 'change-me',
'SECRET_KEY': SECRET_KEY
}
],
'JWT_AUTH_COOKIE_HEADER_PAYLOAD': 'edx-jwt-cookie-header-payload',
'JWT_AUTH_COOKIE_SIGNATURE': 'edx-jwt-cookie-signature',
'JWT_AUTH_HEADER_PREFIX': 'JWT',
}
############################ Parental Controls #############################
# .. setting_name: PARENTAL_CONSENT_AGE_LIMIT
# .. setting_default: 13
# .. setting_description: The age at which a learner no longer requires parental consent,
# or ``None`` if parental consent is never required.
PARENTAL_CONSENT_AGE_LIMIT = 13
############################### Registration ###############################
# .. setting_name: REGISTRATION_EMAIL_PATTERNS_ALLOWED
# .. setting_default: None
# .. setting_description: Optional setting to restrict registration / account creation
# to only emails that match a regex in this list. Set to ``None`` to allow any email (default).
REGISTRATION_EMAIL_PATTERNS_ALLOWED = None
######################### Course Enrollment Modes ##########################
# The min_price key refers to the minimum price allowed for an instance
# of a particular type of course enrollment mode. This is not to be confused
# with the min_price field of the CourseMode model, which refers to the actual
# price of the CourseMode.
COURSE_ENROLLMENT_MODES = {
"audit": {
"id": 1,
"slug": "audit",
"display_name": _("Audit"),
"min_price": 0,
},
"verified": {
"id": 2,
"slug": "verified",
"display_name": _("Verified"),
"min_price": 1,
},
"professional": {
"id": 3,
"slug": "professional",
"display_name": _("Professional"),
"min_price": 1,
},
"no-id-professional": {
"id": 4,
"slug": "no-id-professional",
"display_name": _("No-Id-Professional"),
"min_price": 0,
},
"credit": {
"id": 5,
"slug": "credit",
"display_name": _("Credit"),
"min_price": 0,
},
"honor": {
"id": 6,
"slug": "honor",
"display_name": _("Honor"),
"min_price": 0,
},
"masters": {
"id": 7,
"slug": "masters",
"display_name": _("Master's"),
"min_price": 0,
},
"executive-education": {
"id": 8,
"slug": "executive-educations",
"display_name": _("Executive Education"),
"min_price": 1
},
"unpaid-executive-education": {
"id": 9,
"slug": "unpaid-executive-education",
"display_name": _("Unpaid Executive Education"),
"min_price": 0
},
"paid-executive-education": {
"id": 10,
"slug": "paid-executive-education",
"display_name": _("Paid Executive Education"),
"min_price": 1
},
"unpaid-bootcamp": {
"id": 11,
"slug": "unpaid-bootcamp",
"display_name": _("Unpaid Bootcamp"),
"min_price": 0
},
"paid-bootcamp": {
"id": 12,
"slug": "paid-bootcamp",
"display_name": _("Paid Bootcamp"),
"min_price": 1
},
}
CONTENT_TYPE_GATE_GROUP_IDS = {
'limited_access': 1,
'full_access': 2,
}
########################## Enterprise Api Client ###########################
ENTERPRISE_CATALOG_INTERNAL_ROOT_URL = 'http://enterprise.catalog.app:18160'
ENTERPRISE_BACKEND_SERVICE_EDX_OAUTH2_KEY = "enterprise-backend-service-key"
ENTERPRISE_BACKEND_SERVICE_EDX_OAUTH2_SECRET = "enterprise-backend-service-secret"
ENTERPRISE_BACKEND_SERVICE_EDX_OAUTH2_PROVIDER_URL = "http://127.0.0.1:8000/oauth2"
############################### ModuleStore ################################
ASSET_IGNORE_REGEX = r"(^\._.*$)|(^\.DS_Store$)|(^.*~$)"
########################### Django OAuth Toolkit ###########################
# This is required for the migrations in oauth_dispatch.models
# otherwise it fails saying this attribute is not present in Settings
# Although Studio does not enable OAuth2 Provider capability, the new approach
# to generating test databases will discover and try to create all tables
# and this setting needs to be present
OAUTH2_PROVIDER_APPLICATION_MODEL = 'oauth2_provider.Application'
############################## Profile Image ###############################
# The following PROFILE_IMAGE_* settings are included as common settings as
# they are indirectly accessed through the email opt-in API, which is
# technically accessible through the CMS via legacy URLs.
# WARNING: Certain django storage backends do not support atomic
# file overwrites (including the default, OverwriteStorage) - instead
# there are separate calls to delete and then write a new file in the
# storage backend. This introduces the risk of a race condition
# occurring when a user uploads a new profile image to replace an
# earlier one (the file will temporarily be deleted).
PROFILE_IMAGE_BACKEND = {
'class': 'openedx.core.storage.OverwriteStorage',
'options': {
'location': os.path.join(MEDIA_ROOT, 'profile-images/'),
'base_url': os.path.join(MEDIA_URL, 'profile-images/'),
},
}
PROFILE_IMAGE_DEFAULT_FILENAME = 'images/profiles/default'
PROFILE_IMAGE_DEFAULT_FILE_EXTENSION = 'png'
# This key is used in generating unguessable URLs to users'
# profile images. Once it has been set, changing it will make the
# platform unaware of current image URLs.
PROFILE_IMAGE_HASH_SEED = 'placeholder_secret_key'
PROFILE_IMAGE_MAX_BYTES = 1024 * 1024
PROFILE_IMAGE_MIN_BYTES = 100
PROFILE_IMAGE_SIZES_MAP = {
'full': 500,
'large': 120,
'medium': 50,
'small': 30
}
######################## Built-in Blocks Extraction ########################
# The following Django settings flags have been introduced temporarily to facilitate
# the rollout of the extracted built-in Blocks. Flags will use to toggle between
# the old and new block quickly without putting course content or user state at risk.
#
# Ticket: https://github.com/openedx/edx-platform/issues/35308
# .. toggle_name: USE_EXTRACTED_WORD_CLOUD_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted Word Cloud XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until https://github.com/openedx/edx-platform/issues/34840 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_WORD_CLOUD_BLOCK = False
# .. toggle_name: USE_EXTRACTED_ANNOTATABLE_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted annotatable XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until https://github.com/openedx/edx-platform/issues/34841 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_ANNOTATABLE_BLOCK = False
# .. toggle_name: USE_EXTRACTED_POLL_QUESTION_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted poll question XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until https://github.com/openedx/edx-platform/issues/34839 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_POLL_QUESTION_BLOCK = False
# .. toggle_name: USE_EXTRACTED_LTI_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted LTI XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until relevant subtask https://github.com/openedx/edx-platform/issues/34827 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_LTI_BLOCK = False
# .. toggle_name: USE_EXTRACTED_HTML_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted HTML XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until relevant subtask https://github.com/openedx/edx-platform/issues/34827 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_HTML_BLOCK = False
# .. toggle_name: USE_EXTRACTED_DISCUSSION_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted Discussion XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until relevant subtask https://github.com/openedx/edx-platform/issues/34827 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_DISCUSSION_BLOCK = False
# .. toggle_name: USE_EXTRACTED_PROBLEM_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted Problem XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until relevant subtask https://github.com/openedx/edx-platform/issues/34827 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_PROBLEM_BLOCK = False
# .. toggle_name: USE_EXTRACTED_VIDEO_BLOCK
# .. toggle_default: False
# .. toggle_implementation: DjangoSetting
# .. toggle_description: Enables the use of the extracted Video XBlock, which has been shifted to the 'openedx/xblocks-contrib' repo.
# .. toggle_use_cases: temporary
# .. toggle_warning: Not production-ready until relevant subtask https://github.com/openedx/edx-platform/issues/34827 is done.
# .. toggle_creation_date: 2024-11-10
# .. toggle_target_removal_date: 2025-06-01
USE_EXTRACTED_VIDEO_BLOCK = False
############################## Miscellaneous ###############################
COURSE_MODE_DEFAULTS = {
'android_sku': None,
'bulk_sku': None,
'currency': 'usd',
'description': None,
'expiration_datetime': None,
'ios_sku': None,
'min_price': 0,
'name': _('Audit'),
'sku': None,
'slug': 'audit',
'suggested_prices': '',
}
DEFAULT_COURSE_ABOUT_IMAGE_URL = 'images/pencils.jpg'
DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH = "verify_student_disable_account_activation_requirement"
# If this is true, random scores will be generated for the purpose of debugging the profile graphs
GENERATE_PROFILE_SCORES = False
# The space is required for space-dependent languages like Arabic and Farsi.
# However, backward compatibility with Ficus older releases is still maintained (space is still not valid)
# in the AccountCreationForm and the user_api through the ENABLE_UNICODE_USERNAME feature flag.
USERNAME_REGEX_PARTIAL = r'[\w .@_+-]+'
USERNAME_PATTERN = fr'(?P<username>{USERNAME_REGEX_PARTIAL})'
# These are standard regexes for pulling out info like course_ids, usage_ids, etc.
# They are used so that URLs with deprecated-format strings still work.
USAGE_KEY_PATTERN = r'(?P<usage_key_string>(?:i4x://?[^/]+/[^/]+/[^/]+/[^@]+(?:@[^/]+)?)|(?:[^/]+))'
ASSET_KEY_PATTERN = r'(?P<asset_key_string>(?:/?c4x(:/)?/[^/]+/[^/]+/[^/]+/[^@]+(?:@[^/]+)?)|(?:[^/]+))'
USAGE_ID_PATTERN = r'(?P<usage_id>(?:i4x://?[^/]+/[^/]+/[^/]+/[^@]+(?:@[^/]+)?)|(?:[^/]+))'

View File

@@ -37,7 +37,7 @@ echo '' > "$OUTPUT_FILE"
# exclude test code from analysis, as it isn't explicitly called by other
# code. Additionally, application code that is only called by tests
# should be considered dead
EXCLUSIONS='/test,/acceptance,cms/envs,lms/envs,migrations/,signals.py'
EXCLUSIONS='/test,/acceptance,cms/envs,lms/envs,openedx/envs,migrations/,signals.py'
MIN_CONFIDENCE=90
# paths to the code on which to run the analysis
CODE_PATHS=('cms' 'common' 'lms' 'openedx')

View File

@@ -20,7 +20,7 @@ filterwarnings =
ignore:'etree' is deprecated. Use 'xml.etree.ElementTree' instead.:DeprecationWarning:wiki
junit_family = xunit2
norecursedirs = .* *.egg build conf dist node_modules test_root cms/envs lms/envs
norecursedirs = .* *.egg build conf dist node_modules test_root cms/envs lms/envs openedx/envs
python_classes =
python_files = tests.py test_*.py tests_*.py *_tests.py __init__.py