Diff
checker
टेक्स्ट
टेक्स्ट
छवियां
दस्तावेज़
Excel
फ़ोल्डर्स
Legal
Enterprise
डेस्कटॉप
मूल्य
साइन इन करें
Diffchecker डेस्कटॉप डाउनलोड करें
टेक्स्ट की तुलना करें
दो टेक्स्ट फ़ाइलों के बीच अंतर ढूंढें
उपकरण
इतिहास
रियल-टाइम एडिटर
अपरिवर्तित संक्षिप्त करें
लाइन रैप बंद
लेआउट
विभाजित
संयुक्त
परिवर्तन हाइलाइट करें
स्मार्ट
शब्द
अक्षर
सिंटैक्स हाइलाइटिंग
सिंटैक्स चुनें
अनदेखा करें
टेक्स्ट बदलें
पहले अंतर पर जाएँ
इनपुट संपादित करें
Diffchecker Desktop
Diffchecker चलाने का सबसे सुरक्षित तरीका। Diffchecker Desktop ऐप पाएं: आपके diffs कभी आपके कंप्यूटर से बाहर नहीं जाते!
Desktop पाएं
Doppler Open edX integration
बनाया गया
5 वर्ष पहले
Diff कभी समाप्त नहीं होता
साफ़
निर्यात करें
शेयर करें
समझाएं
16 हटाए गए
लाइनें
कुल
हटाया गया
अक्षर
कुल
हटाया गया
इस सुविधा का उपयोग जारी रखने के लिए, अपग्रेड करें
Diff
checker
Pro
मूल्य देखें
586 लाइनें
सभी को कॉपी करें
17 जोड़े गए
लाइनें
कुल
जोड़ा गया
अक्षर
कुल
जोड़ा गया
इस सुविधा का उपयोग जारी रखने के लिए, अपग्रेड करें
Diff
checker
Pro
मूल्य देखें
588 लाइनें
सभी को कॉपी करें
"""
"""
This is the default template for our main set of AWS servers.
This is the default template for our main set of AWS servers.
Common traits:
Common traits:
* Use memcached, and cache-backed sessions
* Use memcached, and cache-backed sessions
* Use a MySQL 5.1 database
* Use a MySQL 5.1 database
"""
"""
# We intentionally define lots of variables that aren't used, and
# We intentionally define lots of variables that aren't used, and
# want to import all variables from base settings files
# want to import all variables from base settings files
# pylint: disable=wildcard-import, unused-wildcard-import
# pylint: disable=wildcard-import, unused-wildcard-import
# Pylint gets confused by path.py instances, which report themselves as class
# Pylint gets confused by path.py instances, which report themselves as class
# objects. As a result, pylint applies the wrong regex in validating names,
# objects. As a result, pylint applies the wrong regex in validating names,
# and throws spurious errors. Therefore, we disable invalid-name checking.
# and throws spurious errors. Therefore, we disable invalid-name checking.
# pylint: disable=invalid-name
# pylint: disable=invalid-name
import codecs
import codecs
import copy
import copy
import datetime
import datetime
import os
import os
कॉपी
कॉपी हुआ
कॉपी
कॉपी हुआ
import requests
import dateutil
import dateutil
import yaml
import yaml
from corsheaders.defaults import default_headers as corsheaders_default_headers
from corsheaders.defaults import default_headers as corsheaders_default_headers
from django.core.exceptions import ImproperlyConfigured
from django.core.exceptions import ImproperlyConfigured
from edx_django_utils.plugins import add_plugins
from edx_django_utils.plugins import add_plugins
from path import Path as path
from path import Path as path
from openedx.core.djangoapps.plugins.constants import ProjectType, SettingsType
from openedx.core.djangoapps.plugins.constants import ProjectType, SettingsType
from openedx.core.lib.derived import derive_settings
from openedx.core.lib.derived import derive_settings
from openedx.core.lib.logsettings import get_logger_config
from openedx.core.lib.logsettings import get_logger_config
from xmodule.modulestore.modulestore_settings import convert_module_store_setting_if_needed
from xmodule.modulestore.modulestore_settings import convert_module_store_setting_if_needed
from .common import *
from .common import *
def get_env_setting(setting):
def get_env_setting(setting):
""" Get the environment setting or return exception """
""" Get the environment setting or return exception """
try:
try:
return os.environ[setting]
return os.environ[setting]
except KeyError:
except KeyError:
error_msg = "Set the %s env variable" % setting
error_msg = "Set the %s env variable" % setting
raise ImproperlyConfigured(error_msg) # lint-amnesty, pylint: disable=raise-missing-from
raise ImproperlyConfigured(error_msg) # lint-amnesty, pylint: disable=raise-missing-from
################################ ALWAYS THE SAME ##############################
################################ ALWAYS THE SAME ##############################
DEBUG = False
DEBUG = False
DEFAULT_TEMPLATE_ENGINE['OPTIONS']['debug'] = False
DEFAULT_TEMPLATE_ENGINE['OPTIONS']['debug'] = False
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
# IMPORTANT: With this enabled, the server must always be behind a proxy that
# IMPORTANT: With this enabled, the server must always be behind a proxy that
# strips the header HTTP_X_FORWARDED_PROTO from client requests. Otherwise,
# strips the header HTTP_X_FORWARDED_PROTO from client requests. Otherwise,
# a user can fool our server into thinking it was an https connection.
# a user can fool our server into thinking it was an https connection.
# See
# See
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header
# for other warnings.
# for other warnings.
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
################################ END ALWAYS THE SAME ##############################
################################ END ALWAYS THE SAME ##############################
कॉपी
कॉपी हुआ
कॉपी
कॉपी हुआ
################################### Getting Environment Variables From Doppler ###################################
url = "https://api.doppler.com/v3/configs/config/secrets"
querystring = {"project": "openedx", "config": "dev"}
DOPPLER_TOKEN = AUTH_TOKENS.get('DOPPLER_TOKEN', '')
Authorization = "Basic {DOPPLER_TOKEN}".format(DOPPLER_TOKEN=DOPPLER_TOKEN)
headers = {
"Accept": "application/json",
"accepts": "application/json",
"Authorization": Authorization
}
doppler_response = requests.request("GET", url, headers=headers, params=querystring)
EMAIL_HOST_PASSWORD = doppler_response.json()['secrets']['EMAIL_HOST_PASSWORD']['raw']
################################### END Getting Environment Variables From Doppler ###############################
# A file path to a YAML file from which to load all the configuration for the edx platform
# A file path to a YAML file from which to load all the configuration for the edx platform
CONFIG_FILE = get_env_setting('LMS_CFG')
CONFIG_FILE = get_env_setting('LMS_CFG')
with codecs.open(CONFIG_FILE, encoding='utf-8') as f:
with codecs.open(CONFIG_FILE, encoding='utf-8') as f:
__config__ = yaml.safe_load(f)
__config__ = yaml.safe_load(f)
# ENV_TOKENS and AUTH_TOKENS are included for reverse compatibility.
# ENV_TOKENS and AUTH_TOKENS are included for reverse compatibility.
# Removing them may break plugins that rely on them.
# Removing them may break plugins that rely on them.
ENV_TOKENS = __config__
ENV_TOKENS = __config__
AUTH_TOKENS = __config__
AUTH_TOKENS = __config__
# Add the key/values from config into the global namespace of this module.
# Add the key/values from config into the global namespace of this module.
# But don't override the FEATURES dict because we do that in an additive way.
# But don't override the FEATURES dict because we do that in an additive way.
__config_copy__ = copy.deepcopy(__config__)
__config_copy__ = copy.deepcopy(__config__)
KEYS_WITH_MERGED_VALUES = [
KEYS_WITH_MERGED_VALUES = [
'FEATURES',
'FEATURES',
'TRACKING_BACKENDS',
'TRACKING_BACKENDS',
'EVENT_TRACKING_BACKENDS',
'EVENT_TRACKING_BACKENDS',
'JWT_AUTH',
'JWT_AUTH',
'CELERY_QUEUES',
'CELERY_QUEUES',
'MKTG_URL_LINK_MAP',
'MKTG_URL_LINK_MAP',
'MKTG_URL_OVERRIDES',
'MKTG_URL_OVERRIDES',
]
]
for key in KEYS_WITH_MERGED_VALUES:
for key in KEYS_WITH_MERGED_VALUES:
if key in __config_copy__:
if key in __config_copy__:
del __config_copy__[key]
del __config_copy__[key]
vars().update(__config_copy__)
vars().update(__config_copy__)
try:
try:
# A file path to a YAML file from which to load all the code revisions currently deployed
# A file path to a YAML file from which to load all the code revisions currently deployed
REVISION_CONFIG_FILE = get_env_setting('REVISION_CFG')
REVISION_CONFIG_FILE = get_env_setting('REVISION_CFG')
with codecs.open(REVISION_CONFIG_FILE, encoding='utf-8') as f:
with codecs.open(REVISION_CONFIG_FILE, encoding='utf-8') as f:
REVISION_CONFIG = yaml.safe_load(f)
REVISION_CONFIG = yaml.safe_load(f)
except Exception: # pylint: disable=broad-except
except Exception: # pylint: disable=broad-except
REVISION_CONFIG = {}
REVISION_CONFIG = {}
# Do NOT calculate this dynamically at startup with git because it's *slow*.
# Do NOT calculate this dynamically at startup with git because it's *slow*.
EDX_PLATFORM_REVISION = REVISION_CONFIG.get('EDX_PLATFORM_REVISION', EDX_PLATFORM_REVISION)
EDX_PLATFORM_REVISION = REVISION_CONFIG.get('EDX_PLATFORM_REVISION', EDX_PLATFORM_REVISION)
###################################### CELERY ################################
###################################### CELERY ################################
# Don't use a connection pool, since connections are dropped by ELB.
# Don't use a connection pool, since connections are dropped by ELB.
BROKER_POOL_LIMIT = 0
BROKER_POOL_LIMIT = 0
BROKER_CONNECTION_TIMEOUT = 1
BROKER_CONNECTION_TIMEOUT = 1
# For the Result Store, use the django cache named 'celery'
# For the Result Store, use the django cache named 'celery'
CELERY_RESULT_BACKEND = 'django-cache'
CELERY_RESULT_BACKEND = 'django-cache'
# When the broker is behind an ELB, use a heartbeat to refresh the
# When the broker is behind an ELB, use a heartbeat to refresh the
# connection and to detect if it has been dropped.
# connection and to detect if it has been dropped.
BROKER_HEARTBEAT = ENV_TOKENS.get('BROKER_HEARTBEAT', 60.0)
BROKER_HEARTBEAT = ENV_TOKENS.get('BROKER_HEARTBEAT', 60.0)
BROKER_HEARTBEAT_CHECKRATE = ENV_TOKENS.get('BROKER_HEARTBEAT_CHECKRATE', 2)
BROKER_HEARTBEAT_CHECKRATE = ENV_TOKENS.get('BROKER_HEARTBEAT_CHECKRATE', 2)
# Each worker should only fetch one message at a time
# Each worker should only fetch one message at a time
CELERYD_PREFETCH_MULTIPLIER = 1
CELERYD_PREFETCH_MULTIPLIER = 1
# STATIC_ROOT specifies the directory where static files are
# STATIC_ROOT specifies the directory where static files are
# collected
# collected
STATIC_ROOT_BASE = ENV_TOKENS.get('STATIC_ROOT_BASE', None)
STATIC_ROOT_BASE = ENV_TOKENS.get('STATIC_ROOT_BASE', None)
if STATIC_ROOT_BASE:
if STATIC_ROOT_BASE:
STATIC_ROOT = path(STATIC_ROOT_BASE)
STATIC_ROOT = path(STATIC_ROOT_BASE)
WEBPACK_LOADER['DEFAULT']['STATS_FILE'] = STATIC_ROOT / "webpack-stats.json"
WEBPACK_LOADER['DEFAULT']['STATS_FILE'] = STATIC_ROOT / "webpack-stats.json"
WEBPACK_LOADER['WORKERS']['STATS_FILE'] = STATIC_ROOT / "webpack-worker-stats.json"
WEBPACK_LOADER['WORKERS']['STATS_FILE'] = STATIC_ROOT / "webpack-worker-stats.json"
# STATIC_URL_BASE specifies the base url to use for static files
# STATIC_URL_BASE specifies the base url to use for static files
STATIC_URL_BASE = ENV_TOKENS.get('STATIC_URL_BASE', None)
STATIC_URL_BASE = ENV_TOKENS.get('STATIC_URL_BASE', None)
if STATIC_URL_BASE:
if STATIC_URL_BASE:
STATIC_URL = STATIC_URL_BASE
STATIC_URL = STATIC_URL_BASE
if not STATIC_URL.endswith("/"):
if not STATIC_URL.endswith("/"):
STATIC_URL += "/"
STATIC_URL += "/"
# Allow overriding build profile used by RequireJS with one
# Allow overriding build profile used by RequireJS with one
# contained on a custom theme
# contained on a custom theme
REQUIRE_BUILD_PROFILE = ENV_TOKENS.get('REQUIRE_BUILD_PROFILE', REQUIRE_BUILD_PROFILE)
REQUIRE_BUILD_PROFILE = ENV_TOKENS.get('REQUIRE_BUILD_PROFILE', REQUIRE_BUILD_PROFILE)
# The following variables use (or) instead of the default value inside (get). This is to enforce using the Lazy Text
# The following variables use (or) instead of the default value inside (get). This is to enforce using the Lazy Text
# values when the varibale is an empty string. Therefore, setting these variable as empty text in related
# values when the varibale is an empty string. Therefore, setting these variable as empty text in related
# json files will make the system reads thier values from django translation files
# json files will make the system reads thier values from django translation files
PLATFORM_NAME = ENV_TOKENS.get('PLATFORM_NAME') or PLATFORM_NAME
PLATFORM_NAME = ENV_TOKENS.get('PLATFORM_NAME') or PLATFORM_NAME
PLATFORM_DESCRIPTION = ENV_TOKENS.get('PLATFORM_DESCRIPTION') or PLATFORM_DESCRIPTION
PLATFORM_DESCRIPTION = ENV_TOKENS.get('PLATFORM_DESCRIPTION') or PLATFORM_DESCRIPTION
CC_MERCHANT_NAME = ENV_TOKENS.get('CC_MERCHANT_NAME', PLATFORM_NAME)
CC_MERCHANT_NAME = ENV_TOKENS.get('CC_MERCHANT_NAME', PLATFORM_NAME)
EMAIL_FILE_PATH = ENV_TOKENS.get('EMAIL_FILE_PATH', None)
EMAIL_FILE_PATH = ENV_TOKENS.get('EMAIL_FILE_PATH', None)
EMAIL_HOST = ENV_TOKENS.get('EMAIL_HOST', 'localhost') # django default is localhost
EMAIL_HOST = ENV_TOKENS.get('EMAIL_HOST', 'localhost') # django default is localhost
EMAIL_PORT = ENV_TOKENS.get('EMAIL_PORT', 25) # django default is 25
EMAIL_PORT = ENV_TOKENS.get('EMAIL_PORT', 25) # django default is 25
EMAIL_USE_TLS = ENV_TOKENS.get('EMAIL_USE_TLS', False) # django default is False
EMAIL_USE_TLS = ENV_TOKENS.get('EMAIL_USE_TLS', False) # django default is False
SITE_NAME = ENV_TOKENS['SITE_NAME']
SITE_NAME = ENV_TOKENS['SITE_NAME']
SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN')
SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN')
SESSION_COOKIE_HTTPONLY = ENV_TOKENS.get('SESSION_COOKIE_HTTPONLY', True)
SESSION_COOKIE_HTTPONLY = ENV_TOKENS.get('SESSION_COOKIE_HTTPONLY', True)
DCS_SESSION_COOKIE_SAMESITE = ENV_TOKENS.get('DCS_SESSION_COOKIE_SAMESITE', DCS_SESSION_COOKIE_SAMESITE)
DCS_SESSION_COOKIE_SAMESITE = ENV_TOKENS.get('DCS_SESSION_COOKIE_SAMESITE', DCS_SESSION_COOKIE_SAMESITE)
DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL = ENV_TOKENS.get('DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL', DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL) # lint-amnesty, pylint: disable=line-too-long
DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL = ENV_TOKENS.get('DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL', DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL) # lint-amnesty, pylint: disable=line-too-long
AWS_SES_REGION_NAME = ENV_TOKENS.get('AWS_SES_REGION_NAME', 'us-east-1')
AWS_SES_REGION_NAME = ENV_TOKENS.get('AWS_SES_REGION_NAME', 'us-east-1')
AWS_SES_REGION_ENDPOINT = ENV_TOKENS.get('AWS_SES_REGION_ENDPOINT', 'email.us-east-1.amazonaws.com')
AWS_SES_REGION_ENDPOINT = ENV_TOKENS.get('AWS_SES_REGION_ENDPOINT', 'email.us-east-1.amazonaws.com')
REGISTRATION_EMAIL_PATTERNS_ALLOWED = ENV_TOKENS.get('REGISTRATION_EMAIL_PATTERNS_ALLOWED')
REGISTRATION_EMAIL_PATTERNS_ALLOWED = ENV_TOKENS.get('REGISTRATION_EMAIL_PATTERNS_ALLOWED')
LMS_ROOT_URL = ENV_TOKENS.get('LMS_ROOT_URL')
LMS_ROOT_URL = ENV_TOKENS.get('LMS_ROOT_URL')
LMS_INTERNAL_ROOT_URL = ENV_TOKENS.get('LMS_INTERNAL_ROOT_URL', LMS_ROOT_URL)
LMS_INTERNAL_ROOT_URL = ENV_TOKENS.get('LMS_INTERNAL_ROOT_URL', LMS_ROOT_URL)
# List of logout URIs for each IDA that the learner should be logged out of when they logout of the LMS. Only applies to
# List of logout URIs for each IDA that the learner should be logged out of when they logout of the LMS. Only applies to
# IDA for which the social auth flow uses DOT (Django OAuth Toolkit).
# IDA for which the social auth flow uses DOT (Django OAuth Toolkit).
IDA_LOGOUT_URI_LIST = ENV_TOKENS.get('IDA_LOGOUT_URI_LIST', [])
IDA_LOGOUT_URI_LIST = ENV_TOKENS.get('IDA_LOGOUT_URI_LIST', [])
ENV_FEATURES = ENV_TOKENS.get('FEATURES', {})
ENV_FEATURES = ENV_TOKENS.get('FEATURES', {})
for feature, value in ENV_FEATURES.items():
for feature, value in ENV_FEATURES.items():
FEATURES[feature] = value
FEATURES[feature] = value
CMS_BASE = ENV_TOKENS.get('CMS_BASE', 'studio.edx.org')
CMS_BASE = ENV_TOKENS.get('CMS_BASE', 'studio.edx.org')
ALLOWED_HOSTS = [
ALLOWED_HOSTS = [
# TODO: bbeggs remove this before prod, temp fix to get load testing running
# TODO: bbeggs remove this before prod, temp fix to get load testing running
"*",
"*",
ENV_TOKENS.get('LMS_BASE'),
ENV_TOKENS.get('LMS_BASE'),
FEATURES['PREVIEW_LMS_BASE'],
FEATURES['PREVIEW_LMS_BASE'],
]
]
# allow for environments to specify what cookie name our login subsystem should use
# allow for environments to specify what cookie name our login subsystem should use
# this is to fix a bug regarding simultaneous logins between edx.org and edge.edx.org which can
# this is to fix a bug regarding simultaneous logins between edx.org and edge.edx.org which can
# happen with some browsers (e.g. Firefox)
# happen with some browsers (e.g. Firefox)
if ENV_TOKENS.get('SESSION_COOKIE_NAME', None):
if ENV_TOKENS.get('SESSION_COOKIE_NAME', None):
# NOTE, there's a bug in Django (http://bugs.python.org/issue18012) which necessitates this being a str()
# NOTE, there's a bug in Django (http://bugs.python.org/issue18012) which necessitates this being a str()
SESSION_COOKIE_NAME = str(ENV_TOKENS.get('SESSION_COOKIE_NAME'))
SESSION_COOKIE_NAME = str(ENV_TOKENS.get('SESSION_COOKIE_NAME'))
CACHES = ENV_TOKENS['CACHES']
CACHES = ENV_TOKENS['CACHES']
# Cache used for location mapping -- called many times with the same key/value
# Cache used for location mapping -- called many times with the same key/value
# in a given request.
# in a given request.
if 'loc_cache' not in CACHES:
if 'loc_cache' not in CACHES:
CACHES['loc_cache'] = {
CACHES['loc_cache'] = {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'edx_location_mem_cache',
'LOCATION': 'edx_location_mem_cache',
}
}
if 'staticfiles' in CACHES:
if 'staticfiles' in CACHES:
CACHES['staticfiles']['KEY_PREFIX'] = EDX_PLATFORM_REVISION
CACHES['staticfiles']['KEY_PREFIX'] = EDX_PLATFORM_REVISION
# In order to transition from local disk asset storage to S3 backed asset storage,
# In order to transition from local disk asset storage to S3 backed asset storage,
# we need to run asset collection twice, once for local disk and once for S3.
# we need to run asset collection twice, once for local disk and once for S3.
# Once we have migrated to service assets off S3, then we can convert this back to
# Once we have migrated to service assets off S3, then we can convert this back to
# managed by the yaml file contents
# managed by the yaml file contents
STATICFILES_STORAGE = os.environ.get('STATICFILES_STORAGE', ENV_TOKENS.get('STATICFILES_STORAGE', STATICFILES_STORAGE))
STATICFILES_STORAGE = os.environ.get('STATICFILES_STORAGE', ENV_TOKENS.get('STATICFILES_STORAGE', STATICFILES_STORAGE))
# Load all AWS_ prefixed variables to allow an S3Boto3Storage to be configured
# Load all AWS_ prefixed variables to allow an S3Boto3Storage to be configured
_locals = locals()
_locals = locals()
for key, value in ENV_TOKENS.items():
for key, value in ENV_TOKENS.items():
if key.startswith('AWS_'):
if key.startswith('AWS_'):
_locals[key] = value
_locals[key] = value
# Currency
# Currency
PAID_COURSE_REGISTRATION_CURRENCY = ENV_TOKENS.get('PAID_COURSE_REGISTRATION_CURRENCY',
PAID_COURSE_REGISTRATION_CURRENCY = ENV_TOKENS.get('PAID_COURSE_REGISTRATION_CURRENCY',
PAID_COURSE_REGISTRATION_CURRENCY)
PAID_COURSE_REGISTRATION_CURRENCY)
# We want Bulk Email running on the high-priority queue, so we define the
# We want Bulk Email running on the high-priority queue, so we define the
# routing key that points to it. At the moment, the name is the same.
# routing key that points to it. At the moment, the name is the same.
# We have to reset the value here, since we have changed the value of the queue name.
# We have to reset the value here, since we have changed the value of the queue name.
BULK_EMAIL_ROUTING_KEY = ENV_TOKENS.get('BULK_EMAIL_ROUTING_KEY', HIGH_PRIORITY_QUEUE)
BULK_EMAIL_ROUTING_KEY = ENV_TOKENS.get('BULK_EMAIL_ROUTING_KEY', HIGH_PRIORITY_QUEUE)
# We can run smaller jobs on the low priority queue. See note above for why
# We can run smaller jobs on the low priority queue. See note above for why
# we have to reset the value here.
# we have to reset the value here.
BULK_EMAIL_ROUTING_KEY_SMALL_JOBS = ENV_TOKENS.get('BULK_EMAIL_ROUTING_KEY_SMALL_JOBS', DEFAULT_PRIORITY_QUEUE)
BULK_EMAIL_ROUTING_KEY_SMALL_JOBS = ENV_TOKENS.get('BULK_EMAIL_ROUTING_KEY_SMALL_JOBS', DEFAULT_PRIORITY_QUEUE)
# Queue to use for expiring old entitlements
# Queue to use for expiring old entitlements
ENTITLEMENTS_EXPIRATION_ROUTING_KEY = ENV_TOKENS.get('ENTITLEMENTS_EXPIRATION_ROUTING_KEY', DEFAULT_PRIORITY_QUEUE)
ENTITLEMENTS_EXPIRATION_ROUTING_KEY = ENV_TOKENS.get('ENTITLEMENTS_EXPIRATION_ROUTING_KEY', DEFAULT_PRIORITY_QUEUE)
# Message expiry time in seconds
# Message expiry time in seconds
CELERY_EVENT_QUEUE_TTL = ENV_TOKENS.get('CELERY_EVENT_QUEUE_TTL', None)
CELERY_EVENT_QUEUE_TTL = ENV_TOKENS.get('CELERY_EVENT_QUEUE_TTL', None)
# Allow CELERY_QUEUES to be overwritten by ENV_TOKENS,
# Allow CELERY_QUEUES to be overwritten by ENV_TOKENS,
ENV_CELERY_QUEUES = ENV_TOKENS.get('CELERY_QUEUES', None)
ENV_CELERY_QUEUES = ENV_TOKENS.get('CELERY_QUEUES', None)
if ENV_CELERY_QUEUES:
if ENV_CELERY_QUEUES:
CELERY_QUEUES = {queue: {} for queue in ENV_CELERY_QUEUES}
CELERY_QUEUES = {queue: {} for queue in ENV_CELERY_QUEUES}
# Then add alternate environment queues
# Then add alternate environment queues
ALTERNATE_QUEUE_ENVS = ENV_TOKENS.get('ALTERNATE_WORKER_QUEUES', '').split()
ALTERNATE_QUEUE_ENVS = ENV_TOKENS.get('ALTERNATE_WORKER_QUEUES', '').split()
ALTERNATE_QUEUES = [
ALTERNATE_QUEUES = [
DEFAULT_PRIORITY_QUEUE.replace(QUEUE_VARIANT, alternate + '.')
DEFAULT_PRIORITY_QUEUE.replace(QUEUE_VARIANT, alternate + '.')
for alternate in ALTERNATE_QUEUE_ENVS
for alternate in ALTERNATE_QUEUE_ENVS
]
]
CELERY_QUEUES.update(
CELERY_QUEUES.update(
{
{
alternate: {}
alternate: {}
for alternate in ALTERNATE_QUEUES
for alternate in ALTERNATE_QUEUES
if alternate not in list(CELERY_QUEUES.keys())
if alternate not in list(CELERY_QUEUES.keys())
}
}
)
)
# following setting is for backward compatibility
# following setting is for backward compatibility
if ENV_TOKENS.get('COMPREHENSIVE_THEME_DIR', None):
if ENV_TOKENS.get('COMPREHENSIVE_THEME_DIR', None):
COMPREHENSIVE_THEME_DIR = ENV_TOKENS.get('COMPREHENSIVE_THEME_DIR')
COMPREHENSIVE_THEME_DIR = ENV_TOKENS.get('COMPREHENSIVE_THEME_DIR')
# COMPREHENSIVE_THEME_LOCALE_PATHS contain the paths to themes locale directories e.g.
# COMPREHENSIVE_THEME_LOCALE_PATHS contain the paths to themes locale directories e.g.
# "COMPREHENSIVE_THEME_LOCALE_PATHS" : [
# "COMPREHENSIVE_THEME_LOCALE_PATHS" : [
# "/edx/src/edx-themes/conf/locale"
# "/edx/src/edx-themes/conf/locale"
# ],
# ],
COMPREHENSIVE_THEME_LOCALE_PATHS = ENV_TOKENS.get('COMPREHENSIVE_THEME_LOCALE_PATHS', [])
COMPREHENSIVE_THEME_LOCALE_PATHS = ENV_TOKENS.get('COMPREHENSIVE_THEME_LOCALE_PATHS', [])
MKTG_URL_LINK_MAP.update(ENV_TOKENS.get('MKTG_URL_LINK_MAP', {}))
MKTG_URL_LINK_MAP.update(ENV_TOKENS.get('MKTG_URL_LINK_MAP', {}))
ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS = ENV_TOKENS.get(
ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS = ENV_TOKENS.get(
'ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS',
'ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS',
ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS
ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS
)
)
# Marketing link overrides
# Marketing link overrides
MKTG_URL_OVERRIDES.update(ENV_TOKENS.get('MKTG_URL_OVERRIDES', MKTG_URL_OVERRIDES))
MKTG_URL_OVERRIDES.update(ENV_TOKENS.get('MKTG_URL_OVERRIDES', MKTG_URL_OVERRIDES))
# Intentional defaults.
# Intentional defaults.
ID_VERIFICATION_SUPPORT_LINK = ENV_TOKENS.get('ID_VERIFICATION_SUPPORT_LINK', SUPPORT_SITE_LINK)
ID_VERIFICATION_SUPPORT_LINK = ENV_TOKENS.get('ID_VERIFICATION_SUPPORT_LINK', SUPPORT_SITE_LINK)
PASSWORD_RESET_SUPPORT_LINK = ENV_TOKENS.get('PASSWORD_RESET_SUPPORT_LINK', SUPPORT_SITE_LINK)
PASSWORD_RESET_SUPPORT_LINK = ENV_TOKENS.get('PASSWORD_RESET_SUPPORT_LINK', SUPPORT_SITE_LINK)
ACTIVATION_EMAIL_SUPPORT_LINK = ENV_TOKENS.get('ACTIVATION_EMAIL_SUPPORT_LINK', SUPPORT_SITE_LINK)
ACTIVATION_EMAIL_SUPPORT_LINK = ENV_TOKENS.get('ACTIVATION_EMAIL_SUPPORT_LINK', SUPPORT_SITE_LINK)
LOGIN_ISSUE_SUPPORT_LINK = ENV_TOKENS.get('LOGIN_ISSUE_SUPPORT_LINK', SUPPORT_SITE_LINK)
LOGIN_ISSUE_SUPPORT_LINK = ENV_TOKENS.get('LOGIN_ISSUE_SUPPORT_LINK', SUPPORT_SITE_LINK)
# Timezone overrides
# Timezone overrides
TIME_ZONE = ENV_TOKENS.get('CELERY_TIMEZONE', CELERY_TIMEZONE)
TIME_ZONE = ENV_TOKENS.get('CELERY_TIMEZONE', CELERY_TIMEZONE)
# Translation overrides
# Translation overrides
LANGUAGE_DICT = dict(LANGUAGES)
LANGUAGE_DICT = dict(LANGUAGES)
# Additional installed apps
# Additional installed apps
for app in ENV_TOKENS.get('ADDL_INSTALLED_APPS', []):
for app in ENV_TOKENS.get('ADDL_INSTALLED_APPS', []):
INSTALLED_APPS.append(app)
INSTALLED_APPS.append(app)
local_loglevel = ENV_TOKENS.get('LOCAL_LOGLEVEL', 'INFO')
local_loglevel = ENV_TOKENS.get('LOCAL_LOGLEVEL', 'INFO')
LOG_DIR = ENV_TOKENS['LOG_DIR']
LOG_DIR = ENV_TOKENS['LOG_DIR']
DATA_DIR = path(ENV_TOKENS.get('DATA_DIR', DATA_DIR))
DATA_DIR = path(ENV_TOKENS.get('DATA_DIR', DATA_DIR))
LOGGING = get_logger_config(LOG_DIR,
LOGGING = get_logger_config(LOG_DIR,
logging_env=ENV_TOKENS['LOGGING_ENV'],
logging_env=ENV_TOKENS['LOGGING_ENV'],
local_loglevel=local_loglevel,
local_loglevel=local_loglevel,
service_variant=SERVICE_VARIANT)
service_variant=SERVICE_VARIANT)
COURSE_LISTINGS = ENV_TOKENS.get('COURSE_LISTINGS', {})
COURSE_LISTINGS = ENV_TOKENS.get('COURSE_LISTINGS', {})
COMMENTS_SERVICE_URL = ENV_TOKENS.get("COMMENTS_SERVICE_URL", '')
COMMENTS_SERVICE_URL = ENV_TOKENS.get("COMMENTS_SERVICE_URL", '')
COMMENTS_SERVICE_KEY = ENV_TOKENS.get("COMMENTS_SERVICE_KEY", '')
COMMENTS_SERVICE_KEY = ENV_TOKENS.get("COMMENTS_SERVICE_KEY", '')
CERT_QUEUE = ENV_TOKENS.get("CERT_QUEUE", 'test-pull')
CERT_QUEUE = ENV_TOKENS.get("CERT_QUEUE", 'test-pull')
# Python lib settings
# Python lib settings
PYTHON_LIB_FILENAME = ENV_TOKENS.get('PYTHON_LIB_FILENAME', 'python_lib.zip')
PYTHON_LIB_FILENAME = ENV_TOKENS.get('PYTHON_LIB_FILENAME', 'python_lib.zip')
# Code jail settings
# Code jail settings
for name, value in ENV_TOKENS.get("CODE_JAIL", {}).items():
for name, value in ENV_TOKENS.get("CODE_JAIL", {}).items():
oldvalue = CODE_JAIL.get(name)
oldvalue = CODE_JAIL.get(name)
if isinstance(oldvalue, dict):
if isinstance(oldvalue, dict):
for subname, subvalue in value.items():
for subname, subvalue in value.items():
oldvalue[subname] = subvalue
oldvalue[subname] = subvalue
else:
else:
CODE_JAIL[name] = value
CODE_JAIL[name] = value
COURSES_WITH_UNSAFE_CODE = ENV_TOKENS.get("COURSES_WITH_UNSAFE_CODE", [])
COURSES_WITH_UNSAFE_CODE = ENV_TOKENS.get("COURSES_WITH_UNSAFE_CODE", [])
# Event Tracking
# Event Tracking
if "TRACKING_IGNORE_URL_PATTERNS" in ENV_TOKENS:
if "TRACKING_IGNORE_URL_PATTERNS" in ENV_TOKENS:
TRACKING_IGNORE_URL_PATTERNS = ENV_TOKENS.get("TRACKING_IGNORE_URL_PATTERNS")
TRACKING_IGNORE_URL_PATTERNS = ENV_TOKENS.get("TRACKING_IGNORE_URL_PATTERNS")
# SSL external authentication settings
# SSL external authentication settings
SSL_AUTH_EMAIL_DOMAIN = ENV_TOKENS.get("SSL_AUTH_EMAIL_DOMAIN", "MIT.EDU")
SSL_AUTH_EMAIL_DOMAIN = ENV_TOKENS.get("SSL_AUTH_EMAIL_DOMAIN", "MIT.EDU")
SSL_AUTH_DN_FORMAT_STRING = ENV_TOKENS.get(
SSL_AUTH_DN_FORMAT_STRING = ENV_TOKENS.get(
"SSL_AUTH_DN_FORMAT_STRING",
"SSL_AUTH_DN_FORMAT_STRING",
"/C=US/ST=Massachusetts/O=Massachusetts Institute of Technology/OU=Client CA v1/CN={0}/emailAddress={1}"
"/C=US/ST=Massachusetts/O=Massachusetts Institute of Technology/OU=Client CA v1/CN={0}/emailAddress={1}"
)
)
# Video Caching. Pairing country codes with CDN URLs.
# Video Caching. Pairing country codes with CDN URLs.
# Example: {'CN': 'http://api.xuetangx.com/edx/video?s3_url='}
# Example: {'CN': 'http://api.xuetangx.com/edx/video?s3_url='}
VIDEO_CDN_URL = ENV_TOKENS.get('VIDEO_CDN_URL', {})
VIDEO_CDN_URL = ENV_TOKENS.get('VIDEO_CDN_URL', {})
# Determines whether the CSRF token can be transported on
# Determines whether the CSRF token can be transported on
# unencrypted channels. It is set to False here for backward compatibility,
# unencrypted channels. It is set to False here for backward compatibility,
# but it is highly recommended that this is True for enviroments accessed
# but it is highly recommended that this is True for enviroments accessed
# by end users.
# by end users.
CSRF_COOKIE_SECURE = ENV_TOKENS.get('CSRF_COOKIE_SECURE', False)
CSRF_COOKIE_SECURE = ENV_TOKENS.get('CSRF_COOKIE_SECURE', False)
# Determines which origins are trusted for unsafe requests eg. POST requests.
# Determines which origins are trusted for unsafe requests eg. POST requests.
CSRF_TRUSTED_ORIGINS = ENV_TOKENS.get('CSRF_TRUSTED_ORIGINS', [])
CSRF_TRUSTED_ORIGINS = ENV_TOKENS.get('CSRF_TRUSTED_ORIGINS', [])
############# CORS headers for cross-domain requests #################
############# CORS headers for cross-domain requests #################
if FEATURES.get('ENABLE_CORS_HEADERS') or FEATURES.get('ENABLE_CROSS_DOMAIN_CSRF_COOKIE'):
if FEATURES.get('ENABLE_CORS_HEADERS') or FEATURES.get('ENABLE_CROSS_DOMAIN_CSRF_COOKIE'):
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = ENV_TOKENS.get('CORS_ORIGIN_WHITELIST', ())
CORS_ORIGIN_WHITELIST = ENV_TOKENS.get('CORS_ORIGIN_WHITELIST', ())
CORS_ORIGIN_ALLOW_ALL = ENV_TOKENS.get('CORS_ORIGIN_ALLOW_ALL', False)
CORS_ORIGIN_ALLOW_ALL = ENV_TOKENS.get('CORS_ORIGIN_ALLOW_ALL', False)
CORS_ALLOW_INSECURE = ENV_TOKENS.get('CORS_ALLOW_INSECURE', False)
CORS_ALLOW_INSECURE = ENV_TOKENS.get('CORS_ALLOW_INSECURE', False)
CORS_ALLOW_HEADERS = corsheaders_default_headers + (
CORS_ALLOW_HEADERS = corsheaders_default_headers + (
'use-jwt-cookie',
'use-jwt-cookie',
)
)
# If setting a cross-domain cookie, it's really important to choose
# If setting a cross-domain cookie, it's really important to choose
# a name for the cookie that is DIFFERENT than the cookies used
# a name for the cookie that is DIFFERENT than the cookies used
# by each subdomain. For example, suppose the applications
# by each subdomain. For example, suppose the applications
# at these subdomains are configured to use the following cookie names:
# at these subdomains are configured to use the following cookie names:
#
#
# 1) foo.example.com --> "csrftoken"
# 1) foo.example.com --> "csrftoken"
# 2) baz.example.com --> "csrftoken"
# 2) baz.example.com --> "csrftoken"
# 3) bar.example.com --> "csrftoken"
# 3) bar.example.com --> "csrftoken"
#
#
# For the cross-domain version of the CSRF cookie, you need to choose
# For the cross-domain version of the CSRF cookie, you need to choose
# a name DIFFERENT than "csrftoken"; otherwise, the new token configured
# a name DIFFERENT than "csrftoken"; otherwise, the new token configured
# for ".example.com" could conflict with the other cookies,
# for ".example.com" could conflict with the other cookies,
# non-deterministically causing 403 responses.
# non-deterministically causing 403 responses.
#
#
# Because of the way Django stores cookies, the cookie name MUST
# Because of the way Django stores cookies, the cookie name MUST
# be a `str`, not unicode. Otherwise there will `TypeError`s will be raised
# be a `str`, not unicode. Otherwise there will `TypeError`s will be raised
# when Django tries to call the unicode `translate()` method with the wrong
# when Django tries to call the unicode `translate()` method with the wrong
# number of parameters.
# number of parameters.
CROSS_DOMAIN_CSRF_COOKIE_NAME = str(ENV_TOKENS.get('CROSS_DOMAIN_CSRF_COOKIE_NAME'))
CROSS_DOMAIN_CSRF_COOKIE_NAME = str(ENV_TOKENS.get('CROSS_DOMAIN_CSRF_COOKIE_NAME'))
# When setting the domain for the "cross-domain" version of the CSRF
# When setting the domain for the "cross-domain" version of the CSRF
# cookie, you should choose something like: ".example.com"
# cookie, you should choose something like: ".example.com"
# (note the leading dot), where both the referer and the host
# (note the leading dot), where both the referer and the host
# are subdomains of "example.com".
# are subdomains of "example.com".
#
#
# Browser security rules require that
# Browser security rules require that
# the cookie domain matches the domain of the server; otherwise
# the cookie domain matches the domain of the server; otherwise
# the cookie won't get set. And once the cookie gets set, the client
# the cookie won't get set. And once the cookie gets set, the client
# needs to be on a domain that matches the cookie domain, otherwise
# needs to be on a domain that matches the cookie domain, otherwise
# the client won't be able to read the cookie.
# the client won't be able to read the cookie.
CROSS_DOMAIN_CSRF_COOKIE_DOMAIN = ENV_TOKENS.get('CROSS_DOMAIN_CSRF_COOKIE_DOMAIN')
CROSS_DOMAIN_CSRF_COOKIE_DOMAIN = ENV_TOKENS.get('CROSS_DOMAIN_CSRF_COOKIE_DOMAIN')
# Field overrides. To use the IDDE feature, add
# Field overrides. To use the IDDE feature, add
# 'courseware.student_field_overrides.IndividualStudentOverrideProvider'.
# 'courseware.student_field_overrides.IndividualStudentOverrideProvider'.
FIELD_OVERRIDE_PROVIDERS = tuple(ENV_TOKENS.get('FIELD_OVERRIDE_PROVIDERS', []))
FIELD_OVERRIDE_PROVIDERS = tuple(ENV_TOKENS.get('FIELD_OVERRIDE_PROVIDERS', []))
############### XBlock filesystem field config ##########
############### XBlock filesystem field config ##########
if 'DJFS' in AUTH_TOKENS and AUTH_TOKENS['DJFS'] is not None:
if 'DJFS' in AUTH_TOKENS and AUTH_TOKENS['DJFS'] is not None:
DJFS = AUTH_TOKENS['DJFS']
DJFS = AUTH_TOKENS['DJFS']
############### Module Store Items ##########
############### Module Store Items ##########
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS = ENV_TOKENS.get('HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS', {})
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS = ENV_TOKENS.get('HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS', {})
# PREVIEW DOMAIN must be present in HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS for the preview to show draft changes
# PREVIEW DOMAIN must be present in HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS for the preview to show draft changes
if 'PREVIEW_LMS_BASE' in FEATURES and FEATURES['PREVIEW_LMS_BASE'] != '':
if 'PREVIEW_LMS_BASE' in FEATURES and FEATURES['PREVIEW_LMS_BASE'] != '':
PREVIEW_DOMAIN = FEATURES['PREVIEW_LMS_BASE'].split(':')[0]
PREVIEW_DOMAIN = FEATURES['PREVIEW_LMS_BASE'].split(':')[0]
# update dictionary with preview domain regex
# update dictionary with preview domain regex
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS.update({
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS.update({
PREVIEW_DOMAIN: 'draft-preferred'
PREVIEW_DOMAIN: 'draft-preferred'
})
})
MODULESTORE_FIELD_OVERRIDE_PROVIDERS = ENV_TOKENS.get(
MODULESTORE_FIELD_OVERRIDE_PROVIDERS = ENV_TOKENS.get(
'MODULESTORE_FIELD_OVERRIDE_PROVIDERS',
'MODULESTORE_FIELD_OVERRIDE_PROVIDERS',
MODULESTORE_FIELD_OVERRIDE_PROVIDERS
MODULESTORE_FIELD_OVERRIDE_PROVIDERS
)
)
XBLOCK_FIELD_DATA_WRAPPERS = ENV_TOKENS.get(
XBLOCK_FIELD_DATA_WRAPPERS = ENV_TOKENS.get(
'XBLOCK_FIELD_DATA_WRAPPERS',
'XBLOCK_FIELD_DATA_WRAPPERS',
XBLOCK_FIELD_DATA_WRAPPERS
XBLOCK_FIELD_DATA_WRAPPERS
)
)
############### Mixed Related(Secure/Not-Secure) Items ##########
############### Mixed Related(Secure/Not-Secure) Items ##########
LMS_SEGMENT_KEY = AUTH_TOKENS.get('SEGMENT_KEY')
LMS_SEGMENT_KEY = AUTH_TOKENS.get('SEGMENT_KEY')
SECRET_KEY = AUTH_TOKENS['SECRET_KEY']
SECRET_KEY = AUTH_TOKENS['SECRET_KEY']
AWS_ACCESS_KEY_ID = AUTH_TOKENS["AWS_ACCESS_KEY_ID"]
AWS_ACCESS_KEY_ID = AUTH_TOKENS["AWS_ACCESS_KEY_ID"]
if AWS_ACCESS_KEY_ID == "":
if AWS_ACCESS_KEY_ID == "":
AWS_ACCESS_KEY_ID = None
AWS_ACCESS_KEY_ID = None
AWS_SECRET_ACCESS_KEY = AUTH_TOKENS["AWS_SECRET_ACCESS_KEY"]
AWS_SECRET_ACCESS_KEY = AUTH_TOKENS["AWS_SECRET_ACCESS_KEY"]
if AWS_SECRET_ACCESS_KEY == "":
if AWS_SECRET_ACCESS_KEY == "":
AWS_SECRET_ACCESS_KEY = None
AWS_SECRET_ACCESS_KEY = None
AWS_STORAGE_BUCKET_NAME = AUTH_TOKENS.get('AWS_STORAGE_BUCKET_NAME', 'edxuploads')
AWS_STORAGE_BUCKET_NAME = AUTH_TOKENS.get('AWS_STORAGE_BUCKET_NAME', 'edxuploads')
# Disabling querystring auth instructs Boto to exclude the querystring parameters (e.g. signature, access key) it
# Disabling querystring auth instructs Boto to exclude the querystring parameters (e.g. signature, access key) it
# normally appends to every returned URL.
# normally appends to every returned URL.
AWS_QUERYSTRING_AUTH = AUTH_TOKENS.get('AWS_QUERYSTRING_AUTH', True)
AWS_QUERYSTRING_AUTH = AUTH_TOKENS.get('AWS_QUERYSTRING_AUTH', True)
AWS_S3_CUSTOM_DOMAIN = AUTH_TOKENS.get('AWS_S3_CUSTOM_DOMAIN', 'edxuploads.s3.amazonaws.com')
AWS_S3_CUSTOM_DOMAIN = AUTH_TOKENS.get('AWS_S3_CUSTOM_DOMAIN', 'edxuploads.s3.amazonaws.com')
if AUTH_TOKENS.get('DEFAULT_FILE_STORAGE'):
if AUTH_TOKENS.get('DEFAULT_FILE_STORAGE'):
DEFAULT_FILE_STORAGE = AUTH_TOKENS.get('DEFAULT_FILE_STORAGE')
DEFAULT_FILE_STORAGE = AUTH_TOKENS.get('DEFAULT_FILE_STORAGE')
elif AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY:
elif AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY:
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
else:
else:
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
# If there is a database called 'read_replica', you can use the use_read_replica_if_available
# If there is a database called 'read_replica', you can use the use_read_replica_if_available
# function in util/query.py, which is useful for very large database reads
# function in util/query.py, which is useful for very large database reads
DATABASES = AUTH_TOKENS['DATABASES']
DATABASES = AUTH_TOKENS['DATABASES']
# The normal database user does not have enough permissions to run migrations.
# The normal database user does not have enough permissions to run migrations.
# Migrations are run with separate credentials, given as DB_MIGRATION_*
# Migrations are run with separate credentials, given as DB_MIGRATION_*
# environment variables
# environment variables
for name, database in DATABASES.items():
for name, database in DATABASES.items():
if name != 'read_replica':
if name != 'read_replica':
database.update({
database.update({
'ENGINE': os.environ.get('DB_MIGRATION_ENGINE', database['ENGINE']),
'ENGINE': os.environ.get('DB_MIGRATION_ENGINE', database['ENGINE']),
'USER': os.environ.get('DB_MIGRATION_USER', database['USER']),
'USER': os.environ.get('DB_MIGRATION_USER', database['USER']),
'PASSWORD': os.environ.get('DB_MIGRATION_PASS', database['PASSWORD']),
'PASSWORD': os.environ.get('DB_MIGRATION_PASS', database['PASSWORD']),
'NAME': os.environ.get('DB_MIGRATION_NAME', database['NAME']),
'NAME': os.environ.get('DB_MIGRATION_NAME', database['NAME']),
'HOST': os.environ.get('DB_MIGRATION_HOST', database['HOST']),
'HOST': os.environ.get('DB_MIGRATION_HOST', database['HOST']),
'PORT': os.environ.get('DB_MIGRATION_PORT', database['PORT']),
'PORT': os.environ.get('DB_MIGRATION_PORT', database['PORT']),
})
})
XQUEUE_INTERFACE = AUTH_TOKENS['XQUEUE_INTERFACE']
XQUEUE_INTERFACE = AUTH_TOKENS['XQUEUE_INTERFACE']
# Get the MODULESTORE from auth.json, but if it doesn't exist,
# Get the MODULESTORE from auth.json, but if it doesn't exist,
# use the one from common.py
# use the one from common.py
MODULESTORE = convert_module_store_setting_if_needed(AUTH_TOKENS.get('MODULESTORE', MODULESTORE))
MODULESTORE = convert_module_store_setting_if_needed(AUTH_TOKENS.get('MODULESTORE', MODULESTORE))
MONGODB_LOG = AUTH_TOKENS.get('MONGODB_LOG', {})
MONGODB_LOG = AUTH_TOKENS.get('MONGODB_LOG', {})
EMAIL_HOST_USER = AUTH_TOKENS.get('EMAIL_HOST_USER', '') # django default is ''
EMAIL_HOST_USER = AUTH_TOKENS.get('EMAIL_HOST_USER', '') # django default is ''
कॉपी
कॉपी हुआ
कॉपी
कॉपी हुआ
EMAIL_HOST_PASSWORD = AUTH_TOKENS.get('EMAIL_HOST_PASSWORD', '') # django default is ''
############################### BLOCKSTORE #####################################
############################### BLOCKSTORE #####################################
BLOCKSTORE_API_URL = ENV_TOKENS.get('BLOCKSTORE_API_URL', None) # e.g. "https://blockstore.example.com/api/v1/"
BLOCKSTORE_API_URL = ENV_TOKENS.get('BLOCKSTORE_API_URL', None) # e.g. "https://blockstore.example.com/api/v1/"
# Configure an API auth token at (blockstore URL)/admin/authtoken/token/
# Configure an API auth token at (blockstore URL)/admin/authtoken/token/
BLOCKSTORE_API_AUTH_TOKEN = AUTH_TOKENS.get('BLOCKSTORE_API_AUTH_TOKEN', None)
BLOCKSTORE_API_AUTH_TOKEN = AUTH_TOKENS.get('BLOCKSTORE_API_AUTH_TOKEN', None)
# Datadog for events!
# Datadog for events!
DATADOG = AUTH_TOKENS.get("DATADOG", {})
DATADOG = AUTH_TOKENS.get("DATADOG", {})
DATADOG.update(ENV_TOKENS.get("DATADOG", {}))
DATADOG.update(ENV_TOKENS.get("DATADOG", {}))
# TODO: deprecated (compatibility with previous settings)
# TODO: deprecated (compatibility with previous settings)
if 'DATADOG_API' in AUTH_TOKENS:
if 'DATADOG_API' in AUTH_TOKENS:
DATADOG['api_key'] = AUTH_TOKENS['DATADOG_API']
DATADOG['api_key'] = AUTH_TOKENS['DATADOG_API']
# Analytics API
# Analytics API
ANALYTICS_API_KEY = AUTH_TOKENS.get("ANALYTICS_API_KEY", ANALYTICS_API_KEY)
ANALYTICS_API_KEY = AUTH_TOKENS.get("ANALYTICS_API_KEY", ANALYTICS_API_KEY)
ANALYTICS_API_URL = ENV_TOKENS.get("ANALYTICS_API_URL", ANALYTICS_API_URL)
ANALYTICS_API_URL = ENV_TOKENS.get("ANALYTICS_API_URL", ANALYTICS_API_URL)
# Zendesk
# Zendesk
ZENDESK_USER = AUTH_TOKENS.get("ZENDESK_USER")
ZENDESK_USER = AUTH_TOKENS.get("ZENDESK_USER")
ZENDESK_API_KEY = AUTH_TOKENS.get("ZENDESK_API_KEY")
ZENDESK_API_KEY = AUTH_TOKENS.get("ZENDESK_API_KEY")
# API Key for inbound requests from Notifier service
# API Key for inbound requests from Notifier service
EDX_API_KEY = AUTH_TOKENS.get("EDX_API_KEY")
EDX_API_KEY = AUTH_TOKENS.get("EDX_API_KEY")
# Celery Broker
# Celery Broker
CELERY_BROKER_TRANSPORT = ENV_TOKENS.get("CELERY_BROKER_TRANSPORT", "")
CELERY_BROKER_TRANSPORT = ENV_TOKENS.get("CELERY_BROKER_TRANSPORT", "")
CELERY_BROKER_HOSTNAME = ENV_TOKENS.get("CELERY_BROKER_HOSTNAME", "")
CELERY_BROKER_HOSTNAME = ENV_TOKENS.get("CELERY_BROKER_HOSTNAME", "")
CELERY_BROKER_VHOST = ENV_TOKENS.get("CELERY_BROKER_VHOST", "")
CELERY_BROKER_VHOST = ENV_TOKENS.get("CELERY_BROKER_VHOST", "")
CELERY_BROKER_USER = AUTH_TOKENS.get("CELERY_BROKER_USER", "")
CELERY_BROKER_USER = AUTH_TOKENS.get("CELERY_BROKER_USER", "")
CELERY_BROKER_PASSWORD = AUTH_TOKENS.get("CELERY_BROKER_PASSWORD", "")
CELERY_BROKER_PASSWORD = AUTH_TOKENS.get("CELERY_BROKER_PASSWORD", "")
BROKER_URL = "{}://{}:{}@{}/{}".format(CELERY_BROKER_TRANSPORT,
BROKER_URL = "{}://{}:{}@{}/{}".format(CELERY_BROKER_TRANSPORT,
CELERY_BROKER_USER,
CELERY_BROKER_USER,
CELERY_BROKER_PASSWORD,
CELERY_BROKER_PASSWORD,
CELERY_BROKER_HOSTNAME,
CELERY_BROKER_HOSTNAME,
CELERY_BROKER_VHOST)
CELERY_BROKER_VHOST)
BROKER_USE_SSL = ENV_TOKENS.get('CELERY_BROKER_USE_SSL', False)
BROKER_USE_SSL = ENV_TOKENS.get('CELERY_BROKER_USE_SSL', False)
BROKER_TRANSPORT_OPTIONS = {
BROKER_TRANSPORT_OPTIONS = {
'fanout_patterns': True,
'fanout_patterns': True,
'fanout_prefix': True,
'fanout_prefix': True,
}
}
# Block Structures
# Block Structures
# upload limits
# upload limits
STUDENT_FILEUPLOAD_MAX_SIZE = ENV_TOKENS.get("STUDENT_FILEUPLOAD_MAX_SIZE", STUDENT_FILEUPLOAD_MAX_SIZE)
STUDENT_FILEUPLOAD_MAX_SIZE = ENV_TOKENS.get("STUDENT_FILEUPLOAD_MAX_SIZE", STUDENT_FILEUPLOAD_MAX_SIZE)
# Event tracking
# Event tracking
TRACKING_BACKENDS.update(AUTH_TOKENS.get("TRACKING_BACKENDS", {}))
TRACKING_BACKENDS.update(AUTH_TOKENS.get("TRACKING_BACKENDS", {}))
EVENT_TRACKING_BACKENDS['tracking_logs']['OPTIONS']['backends'].update(AUTH_TOKENS.get("EVENT_TRACKING_BACKENDS", {}))
EVENT_TRACKING_BACKENDS['tracking_logs']['OPTIONS']['backends'].update(AUTH_TOKENS.get("EVENT_TRACKING_BACKENDS", {}))
EVENT_TRACKING_BACKENDS['segmentio']['OPTIONS']['processors'][0]['OPTIONS']['whitelist'].extend(
EVENT_TRACKING_BACKENDS['segmentio']['OPTIONS']['processors'][0]['OPTIONS']['whitelist'].extend(
AUTH_TOKENS.get("EVENT_TRACKING_SEGMENTIO_EMIT_WHITELIST", []))
AUTH_TOKENS.get("EVENT_TRACKING_SEGMENTIO_EMIT_WHITELIST", []))
TRACKING_SEGMENTIO_WEBHOOK_SECRET = AUTH_TOKENS.get(
TRACKING_SEGMENTIO_WEBHOOK_SECRET = AUTH_TOKENS.get(
"TRACKING_SEGMENTIO_WEBHOOK_SECRET",
"TRACKING_SEGMENTIO_WEBHOOK_SECRET",
TRACKING_SEGMENTIO_WEBHOOK_SECRET
TRACKING_SEGMENTIO_WEBHOOK_SECRET
)
)
TRACKING_SEGMENTIO_ALLOWED_TYPES = ENV_TOKENS.get("TRACKING_SEGMENTIO_ALLOWED_TYPES", TRACKING_SEGMENTIO_ALLOWED_TYPES)
TRACKING_SEGMENTIO_ALLOWED_TYPES = ENV_TOKENS.get("TRACKING_SEGMENTIO_ALLOWED_TYPES", TRACKING_SEGMENTIO_ALLOWED_TYPES)
TRACKING_SEGMENTIO_DISALLOWED_SUBSTRING_NAMES = ENV_TOKENS.get(
TRACKING_SEGMENTIO_DISALLOWED_SUBSTRING_NAMES = ENV_TOKENS.get(
"TRACKING_SEGMENTIO_DISALLOWED_SUBSTRING_NAMES",
"TRACKING_SEGMENTIO_DISALLOWED_SUBSTRING_NAMES",
TRACKING_SEGMENTIO_DISALLOWED_SUBSTRING_NAMES
TRACKING_SEGMENTIO_DISALLOWED_SUBSTRING_NAMES
)
)
TRACKING_SEGMENTIO_SOURCE_MAP = ENV_TOKENS.get("TRACKING_SEGMENTIO_SOURCE_MAP", TRACKING_SEGMENTIO_SOURCE_MAP)
TRACKING_SEGMENTIO_SOURCE_MAP = ENV_TOKENS.get("TRACKING_SEGMENTIO_SOURCE_MAP", TRACKING_SEGMENTIO_SOURCE_MAP)
# Heartbeat
# Heartbeat
HEARTBEAT_CELERY_ROUTING_KEY = ENV_TOKENS.get('HEARTBEAT_CELERY_ROUTING_KEY', HEARTBEAT_CELERY_ROUTING_KEY)
HEARTBEAT_CELERY_ROUTING_KEY = ENV_TOKENS.get('HEARTBEAT_CELERY_ROUTING_KEY', HEARTBEAT_CELERY_ROUTING_KEY)
# Student identity verification settings
# Student identity verification settings
VERIFY_STUDENT = AUTH_TOKENS.get("VERIFY_STUDENT", VERIFY_STUDENT)
VERIFY_STUDENT = AUTH_TOKENS.get("VERIFY_STUDENT", VERIFY_STUDENT)
DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH = ENV_TOKENS.get(
DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH = ENV_TOKENS.get(
"DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH",
"DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH",
DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH
DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH
)
)
# Grades download
# Grades download
GRADES_DOWNLOAD_ROUTING_KEY = ENV_TOKENS.get('GRADES_DOWNLOAD_ROUTING_KEY', HIGH_MEM_QUEUE)
GRADES_DOWNLOAD_ROUTING_KEY = ENV_TOKENS.get('GRADES_DOWNLOAD_ROUTING_KEY', HIGH_MEM_QUEUE)
GRADES_DOWNLOAD = ENV_TOKENS.get("GRADES_DOWNLOAD", GRADES_DOWNLOAD)
GRADES_DOWNLOAD = ENV_TOKENS.get("GRADES_DOWNLOAD", GRADES_DOWNLOAD)
# Rate limit for regrading tasks that a grading policy change can kick off
# Rate limit for regrading tasks that a grading policy change can kick off
# financial reports
# financial reports
FINANCIAL_REPORTS = ENV_TOKENS.get("FINANCIAL_REPORTS", FINANCIAL_REPORTS)
FINANCIAL_REPORTS = ENV_TOKENS.get("FINANCIAL_REPORTS", FINANCIAL_REPORTS)
##### ORA2 ######
##### ORA2 ######
# Prefix for uploads of example-based assessment AI classifiers
# Prefix for uploads of example-based assessment AI classifiers
# This can be used to separate uploads for different environments
# This can be used to separate uploads for different environments
# within the same S3 bucket.
# within the same S3 bucket.
ORA2_FILE_PREFIX = ENV_TOKENS.get("ORA2_FILE_PREFIX", ORA2_FILE_PREFIX)
ORA2_FILE_PREFIX = ENV_TOKENS.get("ORA2_FILE_PREFIX", ORA2_FILE_PREFIX)
##### ACCOUNT LOCKOUT DEFAULT PARAMETERS #####
##### ACCOUNT LOCKOUT DEFAULT PARAMETERS #####
MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED = ENV_TOKENS.get(
MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED = ENV_TOKENS.get(
"MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED", MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED
"MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED", MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED
)
)
MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS = ENV_TOKENS.get(
MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS = ENV_TOKENS.get(
"MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS", MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS
"MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS", MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS
)
)
##### LOGISTRATION RATE LIMIT SETTINGS #####
##### LOGISTRATION RATE LIMIT SETTINGS #####
LOGISTRATION_RATELIMIT_RATE = ENV_TOKENS.get('LOGISTRATION_RATELIMIT_RATE', LOGISTRATION_RATELIMIT_RATE)
LOGISTRATION_RATELIMIT_RATE = ENV_TOKENS.get('LOGISTRATION_RATELIMIT_RATE', LOGISTRATION_RATELIMIT_RATE)
कॉपी
कॉपी हुआ
कॉपी
कॉपी हुआ
LOGISTRATION_API_RATELIMIT = ENV_TOKENS.get('
LOGISTRATION_API_RATELIMIT', LOGISTRATION_API_RATELIMIT)
LOGISTRATION_API_RATELIMIT = ENV_TOKENS.get('
RESET_PASSWORD_TOKEN_VALIDATE_API_RATELIMIT = ENV_TOKENS.get(
'RESET_PASSWORD_TOKEN_VALIDATE_API_RATELIMIT', RESET_PASSWORD_TOKEN_VALIDATE_API_RATELIMIT
)
RESET_PASSWORD_API_RATELIMIT = ENV_TOKENS.get('RESET_PASSWORD_API_RATELIMIT', RESET_PASSWORD_API_RATELIMIT)
##### REGISTRATION RATE LIMIT SETTINGS #####
REGISTRATION_VALIDATION_RATELIMIT = ENV_TOKENS.get(
'REGISTRATION_VALIDATION_RATELIMIT', REGISTRATION_VALIDATION_RATELIMIT
)
REGISTRATION_RATELIMIT = ENV_TOKENS.get('REGISTRATION_RATELIMIT', REGISTRATION_RATELIMIT)
#### PASSWORD POLICY SETTINGS #####
AUTH_PASSWORD_VALIDATORS = ENV_TOKENS.get("AUTH_PASSWORD_VALIDAT
सेव किए गए Diffs
ऑरिजनल टेक्स्ट
फ़ाइल खोलें
""" This is the default template for our main set of AWS servers. Common traits: * Use memcached, and cache-backed sessions * Use a MySQL 5.1 database """ # We intentionally define lots of variables that aren't used, and # want to import all variables from base settings files # pylint: disable=wildcard-import, unused-wildcard-import # Pylint gets confused by path.py instances, which report themselves as class # objects. As a result, pylint applies the wrong regex in validating names, # and throws spurious errors. Therefore, we disable invalid-name checking. # pylint: disable=invalid-name import codecs import copy import datetime import os import dateutil import yaml from corsheaders.defaults import default_headers as corsheaders_default_headers from django.core.exceptions import ImproperlyConfigured from edx_django_utils.plugins import add_plugins from path import Path as path from openedx.core.djangoapps.plugins.constants import ProjectType, SettingsType from openedx.core.lib.derived import derive_settings from openedx.core.lib.logsettings import get_logger_config from xmodule.modulestore.modulestore_settings import convert_module_store_setting_if_needed from .common import * def get_env_setting(setting): """ Get the environment setting or return exception """ try: return os.environ[setting] except KeyError: error_msg = "Set the %s env variable" % setting raise ImproperlyConfigured(error_msg) # lint-amnesty, pylint: disable=raise-missing-from ################################ ALWAYS THE SAME ############################## DEBUG = False DEFAULT_TEMPLATE_ENGINE['OPTIONS']['debug'] = False SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # IMPORTANT: With this enabled, the server must always be behind a proxy that # strips the header HTTP_X_FORWARDED_PROTO from client requests. Otherwise, # a user can fool our server into thinking it was an https connection. # See # https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header # for other warnings. SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') ################################ END ALWAYS THE SAME ############################## # A file path to a YAML file from which to load all the configuration for the edx platform CONFIG_FILE = get_env_setting('LMS_CFG') with codecs.open(CONFIG_FILE, encoding='utf-8') as f: __config__ = yaml.safe_load(f) # ENV_TOKENS and AUTH_TOKENS are included for reverse compatibility. # Removing them may break plugins that rely on them. ENV_TOKENS = __config__ AUTH_TOKENS = __config__ # Add the key/values from config into the global namespace of this module. # But don't override the FEATURES dict because we do that in an additive way. __config_copy__ = copy.deepcopy(__config__) KEYS_WITH_MERGED_VALUES = [ 'FEATURES', 'TRACKING_BACKENDS', 'EVENT_TRACKING_BACKENDS', 'JWT_AUTH', 'CELERY_QUEUES', 'MKTG_URL_LINK_MAP', 'MKTG_URL_OVERRIDES', ] for key in KEYS_WITH_MERGED_VALUES: if key in __config_copy__: del __config_copy__[key] vars().update(__config_copy__) try: # A file path to a YAML file from which to load all the code revisions currently deployed REVISION_CONFIG_FILE = get_env_setting('REVISION_CFG') with codecs.open(REVISION_CONFIG_FILE, encoding='utf-8') as f: REVISION_CONFIG = yaml.safe_load(f) except Exception: # pylint: disable=broad-except REVISION_CONFIG = {} # Do NOT calculate this dynamically at startup with git because it's *slow*. EDX_PLATFORM_REVISION = REVISION_CONFIG.get('EDX_PLATFORM_REVISION', EDX_PLATFORM_REVISION) ###################################### CELERY ################################ # Don't use a connection pool, since connections are dropped by ELB. BROKER_POOL_LIMIT = 0 BROKER_CONNECTION_TIMEOUT = 1 # For the Result Store, use the django cache named 'celery' CELERY_RESULT_BACKEND = 'django-cache' # When the broker is behind an ELB, use a heartbeat to refresh the # connection and to detect if it has been dropped. BROKER_HEARTBEAT = ENV_TOKENS.get('BROKER_HEARTBEAT', 60.0) BROKER_HEARTBEAT_CHECKRATE = ENV_TOKENS.get('BROKER_HEARTBEAT_CHECKRATE', 2) # Each worker should only fetch one message at a time CELERYD_PREFETCH_MULTIPLIER = 1 # STATIC_ROOT specifies the directory where static files are # collected STATIC_ROOT_BASE = ENV_TOKENS.get('STATIC_ROOT_BASE', None) if STATIC_ROOT_BASE: STATIC_ROOT = path(STATIC_ROOT_BASE) WEBPACK_LOADER['DEFAULT']['STATS_FILE'] = STATIC_ROOT / "webpack-stats.json" WEBPACK_LOADER['WORKERS']['STATS_FILE'] = STATIC_ROOT / "webpack-worker-stats.json" # STATIC_URL_BASE specifies the base url to use for static files STATIC_URL_BASE = ENV_TOKENS.get('STATIC_URL_BASE', None) if STATIC_URL_BASE: STATIC_URL = STATIC_URL_BASE if not STATIC_URL.endswith("/"): STATIC_URL += "/" # Allow overriding build profile used by RequireJS with one # contained on a custom theme REQUIRE_BUILD_PROFILE = ENV_TOKENS.get('REQUIRE_BUILD_PROFILE', REQUIRE_BUILD_PROFILE) # The following variables use (or) instead of the default value inside (get). This is to enforce using the Lazy Text # values when the varibale is an empty string. Therefore, setting these variable as empty text in related # json files will make the system reads thier values from django translation files PLATFORM_NAME = ENV_TOKENS.get('PLATFORM_NAME') or PLATFORM_NAME PLATFORM_DESCRIPTION = ENV_TOKENS.get('PLATFORM_DESCRIPTION') or PLATFORM_DESCRIPTION CC_MERCHANT_NAME = ENV_TOKENS.get('CC_MERCHANT_NAME', PLATFORM_NAME) EMAIL_FILE_PATH = ENV_TOKENS.get('EMAIL_FILE_PATH', None) EMAIL_HOST = ENV_TOKENS.get('EMAIL_HOST', 'localhost') # django default is localhost EMAIL_PORT = ENV_TOKENS.get('EMAIL_PORT', 25) # django default is 25 EMAIL_USE_TLS = ENV_TOKENS.get('EMAIL_USE_TLS', False) # django default is False SITE_NAME = ENV_TOKENS['SITE_NAME'] SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN') SESSION_COOKIE_HTTPONLY = ENV_TOKENS.get('SESSION_COOKIE_HTTPONLY', True) DCS_SESSION_COOKIE_SAMESITE = ENV_TOKENS.get('DCS_SESSION_COOKIE_SAMESITE', DCS_SESSION_COOKIE_SAMESITE) DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL = ENV_TOKENS.get('DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL', DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL) # lint-amnesty, pylint: disable=line-too-long AWS_SES_REGION_NAME = ENV_TOKENS.get('AWS_SES_REGION_NAME', 'us-east-1') AWS_SES_REGION_ENDPOINT = ENV_TOKENS.get('AWS_SES_REGION_ENDPOINT', 'email.us-east-1.amazonaws.com') REGISTRATION_EMAIL_PATTERNS_ALLOWED = ENV_TOKENS.get('REGISTRATION_EMAIL_PATTERNS_ALLOWED') LMS_ROOT_URL = ENV_TOKENS.get('LMS_ROOT_URL') LMS_INTERNAL_ROOT_URL = ENV_TOKENS.get('LMS_INTERNAL_ROOT_URL', LMS_ROOT_URL) # List of logout URIs for each IDA that the learner should be logged out of when they logout of the LMS. Only applies to # IDA for which the social auth flow uses DOT (Django OAuth Toolkit). IDA_LOGOUT_URI_LIST = ENV_TOKENS.get('IDA_LOGOUT_URI_LIST', []) ENV_FEATURES = ENV_TOKENS.get('FEATURES', {}) for feature, value in ENV_FEATURES.items(): FEATURES[feature] = value CMS_BASE = ENV_TOKENS.get('CMS_BASE', 'studio.edx.org') ALLOWED_HOSTS = [ # TODO: bbeggs remove this before prod, temp fix to get load testing running "*", ENV_TOKENS.get('LMS_BASE'), FEATURES['PREVIEW_LMS_BASE'], ] # allow for environments to specify what cookie name our login subsystem should use # this is to fix a bug regarding simultaneous logins between edx.org and edge.edx.org which can # happen with some browsers (e.g. Firefox) if ENV_TOKENS.get('SESSION_COOKIE_NAME', None): # NOTE, there's a bug in Django (http://bugs.python.org/issue18012) which necessitates this being a str() SESSION_COOKIE_NAME = str(ENV_TOKENS.get('SESSION_COOKIE_NAME')) CACHES = ENV_TOKENS['CACHES'] # Cache used for location mapping -- called many times with the same key/value # in a given request. if 'loc_cache' not in CACHES: CACHES['loc_cache'] = { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'edx_location_mem_cache', } if 'staticfiles' in CACHES: CACHES['staticfiles']['KEY_PREFIX'] = EDX_PLATFORM_REVISION # In order to transition from local disk asset storage to S3 backed asset storage, # we need to run asset collection twice, once for local disk and once for S3. # Once we have migrated to service assets off S3, then we can convert this back to # managed by the yaml file contents STATICFILES_STORAGE = os.environ.get('STATICFILES_STORAGE', ENV_TOKENS.get('STATICFILES_STORAGE', STATICFILES_STORAGE)) # Load all AWS_ prefixed variables to allow an S3Boto3Storage to be configured _locals = locals() for key, value in ENV_TOKENS.items(): if key.startswith('AWS_'): _locals[key] = value # Currency PAID_COURSE_REGISTRATION_CURRENCY = ENV_TOKENS.get('PAID_COURSE_REGISTRATION_CURRENCY', PAID_COURSE_REGISTRATION_CURRENCY) # We want Bulk Email running on the high-priority queue, so we define the # routing key that points to it. At the moment, the name is the same. # We have to reset the value here, since we have changed the value of the queue name. BULK_EMAIL_ROUTING_KEY = ENV_TOKENS.get('BULK_EMAIL_ROUTING_KEY', HIGH_PRIORITY_QUEUE) # We can run smaller jobs on the low priority queue. See note above for why # we have to reset the value here. BULK_EMAIL_ROUTING_KEY_SMALL_JOBS = ENV_TOKENS.get('BULK_EMAIL_ROUTING_KEY_SMALL_JOBS', DEFAULT_PRIORITY_QUEUE) # Queue to use for expiring old entitlements ENTITLEMENTS_EXPIRATION_ROUTING_KEY = ENV_TOKENS.get('ENTITLEMENTS_EXPIRATION_ROUTING_KEY', DEFAULT_PRIORITY_QUEUE) # Message expiry time in seconds CELERY_EVENT_QUEUE_TTL = ENV_TOKENS.get('CELERY_EVENT_QUEUE_TTL', None) # Allow CELERY_QUEUES to be overwritten by ENV_TOKENS, ENV_CELERY_QUEUES = ENV_TOKENS.get('CELERY_QUEUES', None) if ENV_CELERY_QUEUES: CELERY_QUEUES = {queue: {} for queue in ENV_CELERY_QUEUES} # Then add alternate environment queues ALTERNATE_QUEUE_ENVS = ENV_TOKENS.get('ALTERNATE_WORKER_QUEUES', '').split() ALTERNATE_QUEUES = [ DEFAULT_PRIORITY_QUEUE.replace(QUEUE_VARIANT, alternate + '.') for alternate in ALTERNATE_QUEUE_ENVS ] CELERY_QUEUES.update( { alternate: {} for alternate in ALTERNATE_QUEUES if alternate not in list(CELERY_QUEUES.keys()) } ) # following setting is for backward compatibility if ENV_TOKENS.get('COMPREHENSIVE_THEME_DIR', None): COMPREHENSIVE_THEME_DIR = ENV_TOKENS.get('COMPREHENSIVE_THEME_DIR') # COMPREHENSIVE_THEME_LOCALE_PATHS contain the paths to themes locale directories e.g. # "COMPREHENSIVE_THEME_LOCALE_PATHS" : [ # "/edx/src/edx-themes/conf/locale" # ], COMPREHENSIVE_THEME_LOCALE_PATHS = ENV_TOKENS.get('COMPREHENSIVE_THEME_LOCALE_PATHS', []) MKTG_URL_LINK_MAP.update(ENV_TOKENS.get('MKTG_URL_LINK_MAP', {})) ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS = ENV_TOKENS.get( 'ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS', ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS ) # Marketing link overrides MKTG_URL_OVERRIDES.update(ENV_TOKENS.get('MKTG_URL_OVERRIDES', MKTG_URL_OVERRIDES)) # Intentional defaults. ID_VERIFICATION_SUPPORT_LINK = ENV_TOKENS.get('ID_VERIFICATION_SUPPORT_LINK', SUPPORT_SITE_LINK) PASSWORD_RESET_SUPPORT_LINK = ENV_TOKENS.get('PASSWORD_RESET_SUPPORT_LINK', SUPPORT_SITE_LINK) ACTIVATION_EMAIL_SUPPORT_LINK = ENV_TOKENS.get('ACTIVATION_EMAIL_SUPPORT_LINK', SUPPORT_SITE_LINK) LOGIN_ISSUE_SUPPORT_LINK = ENV_TOKENS.get('LOGIN_ISSUE_SUPPORT_LINK', SUPPORT_SITE_LINK) # Timezone overrides TIME_ZONE = ENV_TOKENS.get('CELERY_TIMEZONE', CELERY_TIMEZONE) # Translation overrides LANGUAGE_DICT = dict(LANGUAGES) # Additional installed apps for app in ENV_TOKENS.get('ADDL_INSTALLED_APPS', []): INSTALLED_APPS.append(app) local_loglevel = ENV_TOKENS.get('LOCAL_LOGLEVEL', 'INFO') LOG_DIR = ENV_TOKENS['LOG_DIR'] DATA_DIR = path(ENV_TOKENS.get('DATA_DIR', DATA_DIR)) LOGGING = get_logger_config(LOG_DIR, logging_env=ENV_TOKENS['LOGGING_ENV'], local_loglevel=local_loglevel, service_variant=SERVICE_VARIANT) COURSE_LISTINGS = ENV_TOKENS.get('COURSE_LISTINGS', {}) COMMENTS_SERVICE_URL = ENV_TOKENS.get("COMMENTS_SERVICE_URL", '') COMMENTS_SERVICE_KEY = ENV_TOKENS.get("COMMENTS_SERVICE_KEY", '') CERT_QUEUE = ENV_TOKENS.get("CERT_QUEUE", 'test-pull') # Python lib settings PYTHON_LIB_FILENAME = ENV_TOKENS.get('PYTHON_LIB_FILENAME', 'python_lib.zip') # Code jail settings for name, value in ENV_TOKENS.get("CODE_JAIL", {}).items(): oldvalue = CODE_JAIL.get(name) if isinstance(oldvalue, dict): for subname, subvalue in value.items(): oldvalue[subname] = subvalue else: CODE_JAIL[name] = value COURSES_WITH_UNSAFE_CODE = ENV_TOKENS.get("COURSES_WITH_UNSAFE_CODE", []) # Event Tracking if "TRACKING_IGNORE_URL_PATTERNS" in ENV_TOKENS: TRACKING_IGNORE_URL_PATTERNS = ENV_TOKENS.get("TRACKING_IGNORE_URL_PATTERNS") # SSL external authentication settings SSL_AUTH_EMAIL_DOMAIN = ENV_TOKENS.get("SSL_AUTH_EMAIL_DOMAIN", "MIT.EDU") SSL_AUTH_DN_FORMAT_STRING = ENV_TOKENS.get( "SSL_AUTH_DN_FORMAT_STRING", "/C=US/ST=Massachusetts/O=Massachusetts Institute of Technology/OU=Client CA v1/CN={0}/emailAddress={1}" ) # Video Caching. Pairing country codes with CDN URLs. # Example: {'CN': 'http://api.xuetangx.com/edx/video?s3_url='} VIDEO_CDN_URL = ENV_TOKENS.get('VIDEO_CDN_URL', {}) # Determines whether the CSRF token can be transported on # unencrypted channels. It is set to False here for backward compatibility, # but it is highly recommended that this is True for enviroments accessed # by end users. CSRF_COOKIE_SECURE = ENV_TOKENS.get('CSRF_COOKIE_SECURE', False) # Determines which origins are trusted for unsafe requests eg. POST requests. CSRF_TRUSTED_ORIGINS = ENV_TOKENS.get('CSRF_TRUSTED_ORIGINS', []) ############# CORS headers for cross-domain requests ################# if FEATURES.get('ENABLE_CORS_HEADERS') or FEATURES.get('ENABLE_CROSS_DOMAIN_CSRF_COOKIE'): CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_WHITELIST = ENV_TOKENS.get('CORS_ORIGIN_WHITELIST', ()) CORS_ORIGIN_ALLOW_ALL = ENV_TOKENS.get('CORS_ORIGIN_ALLOW_ALL', False) CORS_ALLOW_INSECURE = ENV_TOKENS.get('CORS_ALLOW_INSECURE', False) CORS_ALLOW_HEADERS = corsheaders_default_headers + ( 'use-jwt-cookie', ) # If setting a cross-domain cookie, it's really important to choose # a name for the cookie that is DIFFERENT than the cookies used # by each subdomain. For example, suppose the applications # at these subdomains are configured to use the following cookie names: # # 1) foo.example.com --> "csrftoken" # 2) baz.example.com --> "csrftoken" # 3) bar.example.com --> "csrftoken" # # For the cross-domain version of the CSRF cookie, you need to choose # a name DIFFERENT than "csrftoken"; otherwise, the new token configured # for ".example.com" could conflict with the other cookies, # non-deterministically causing 403 responses. # # Because of the way Django stores cookies, the cookie name MUST # be a `str`, not unicode. Otherwise there will `TypeError`s will be raised # when Django tries to call the unicode `translate()` method with the wrong # number of parameters. CROSS_DOMAIN_CSRF_COOKIE_NAME = str(ENV_TOKENS.get('CROSS_DOMAIN_CSRF_COOKIE_NAME')) # When setting the domain for the "cross-domain" version of the CSRF # cookie, you should choose something like: ".example.com" # (note the leading dot), where both the referer and the host # are subdomains of "example.com". # # Browser security rules require that # the cookie domain matches the domain of the server; otherwise # the cookie won't get set. And once the cookie gets set, the client # needs to be on a domain that matches the cookie domain, otherwise # the client won't be able to read the cookie. CROSS_DOMAIN_CSRF_COOKIE_DOMAIN = ENV_TOKENS.get('CROSS_DOMAIN_CSRF_COOKIE_DOMAIN') # Field overrides. To use the IDDE feature, add # 'courseware.student_field_overrides.IndividualStudentOverrideProvider'. FIELD_OVERRIDE_PROVIDERS = tuple(ENV_TOKENS.get('FIELD_OVERRIDE_PROVIDERS', [])) ############### XBlock filesystem field config ########## if 'DJFS' in AUTH_TOKENS and AUTH_TOKENS['DJFS'] is not None: DJFS = AUTH_TOKENS['DJFS'] ############### Module Store Items ########## HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS = ENV_TOKENS.get('HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS', {}) # PREVIEW DOMAIN must be present in HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS for the preview to show draft changes if 'PREVIEW_LMS_BASE' in FEATURES and FEATURES['PREVIEW_LMS_BASE'] != '': PREVIEW_DOMAIN = FEATURES['PREVIEW_LMS_BASE'].split(':')[0] # update dictionary with preview domain regex HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS.update({ PREVIEW_DOMAIN: 'draft-preferred' }) MODULESTORE_FIELD_OVERRIDE_PROVIDERS = ENV_TOKENS.get( 'MODULESTORE_FIELD_OVERRIDE_PROVIDERS', MODULESTORE_FIELD_OVERRIDE_PROVIDERS ) XBLOCK_FIELD_DATA_WRAPPERS = ENV_TOKENS.get( 'XBLOCK_FIELD_DATA_WRAPPERS', XBLOCK_FIELD_DATA_WRAPPERS ) ############### Mixed Related(Secure/Not-Secure) Items ########## LMS_SEGMENT_KEY = AUTH_TOKENS.get('SEGMENT_KEY') SECRET_KEY = AUTH_TOKENS['SECRET_KEY'] AWS_ACCESS_KEY_ID = AUTH_TOKENS["AWS_ACCESS_KEY_ID"] if AWS_ACCESS_KEY_ID == "": AWS_ACCESS_KEY_ID = None AWS_SECRET_ACCESS_KEY = AUTH_TOKENS["AWS_SECRET_ACCESS_KEY"] if AWS_SECRET_ACCESS_KEY == "": AWS_SECRET_ACCESS_KEY = None AWS_STORAGE_BUCKET_NAME = AUTH_TOKENS.get('AWS_STORAGE_BUCKET_NAME', 'edxuploads') # Disabling querystring auth instructs Boto to exclude the querystring parameters (e.g. signature, access key) it # normally appends to every returned URL. AWS_QUERYSTRING_AUTH = AUTH_TOKENS.get('AWS_QUERYSTRING_AUTH', True) AWS_S3_CUSTOM_DOMAIN = AUTH_TOKENS.get('AWS_S3_CUSTOM_DOMAIN', 'edxuploads.s3.amazonaws.com') if AUTH_TOKENS.get('DEFAULT_FILE_STORAGE'): DEFAULT_FILE_STORAGE = AUTH_TOKENS.get('DEFAULT_FILE_STORAGE') elif AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY: DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' else: DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' # If there is a database called 'read_replica', you can use the use_read_replica_if_available # function in util/query.py, which is useful for very large database reads DATABASES = AUTH_TOKENS['DATABASES'] # The normal database user does not have enough permissions to run migrations. # Migrations are run with separate credentials, given as DB_MIGRATION_* # environment variables for name, database in DATABASES.items(): if name != 'read_replica': database.update({ 'ENGINE': os.environ.get('DB_MIGRATION_ENGINE', database['ENGINE']), 'USER': os.environ.get('DB_MIGRATION_USER', database['USER']), 'PASSWORD': os.environ.get('DB_MIGRATION_PASS', database['PASSWORD']), 'NAME': os.environ.get('DB_MIGRATION_NAME', database['NAME']), 'HOST': os.environ.get('DB_MIGRATION_HOST', database['HOST']), 'PORT': os.environ.get('DB_MIGRATION_PORT', database['PORT']), }) XQUEUE_INTERFACE = AUTH_TOKENS['XQUEUE_INTERFACE'] # Get the MODULESTORE from auth.json, but if it doesn't exist, # use the one from common.py MODULESTORE = convert_module_store_setting_if_needed(AUTH_TOKENS.get('MODULESTORE', MODULESTORE)) MONGODB_LOG = AUTH_TOKENS.get('MONGODB_LOG', {}) EMAIL_HOST_USER = AUTH_TOKENS.get('EMAIL_HOST_USER', '') # django default is '' EMAIL_HOST_PASSWORD = AUTH_TOKENS.get('EMAIL_HOST_PASSWORD', '') # django default is '' ############################### BLOCKSTORE ##################################### BLOCKSTORE_API_URL = ENV_TOKENS.get('BLOCKSTORE_API_URL', None) # e.g. "https://blockstore.example.com/api/v1/" # Configure an API auth token at (blockstore URL)/admin/authtoken/token/ BLOCKSTORE_API_AUTH_TOKEN = AUTH_TOKENS.get('BLOCKSTORE_API_AUTH_TOKEN', None) # Datadog for events! DATADOG = AUTH_TOKENS.get("DATADOG", {}) DATADOG.update(ENV_TOKENS.get("DATADOG", {})) # TODO: deprecated (compatibility with previous settings) if 'DATADOG_API' in AUTH_TOKENS: DATADOG['api_key'] = AUTH_TOKENS['DATADOG_API'] # Analytics API ANALYTICS_API_KEY = AUTH_TOKENS.get("ANALYTICS_API_KEY", ANALYTICS_API_KEY) ANALYTICS_API_URL = ENV_TOKENS.get("ANALYTICS_API_URL", ANALYTICS_API_URL) # Zendesk ZENDESK_USER = AUTH_TOKENS.get("ZENDESK_USER") ZENDESK_API_KEY = AUTH_TOKENS.get("ZENDESK_API_KEY") # API Key for inbound requests from Notifier service EDX_API_KEY = AUTH_TOKENS.get("EDX_API_KEY") # Celery Broker CELERY_BROKER_TRANSPORT = ENV_TOKENS.get("CELERY_BROKER_TRANSPORT", "") CELERY_BROKER_HOSTNAME = ENV_TOKENS.get("CELERY_BROKER_HOSTNAME", "") CELERY_BROKER_VHOST = ENV_TOKENS.get("CELERY_BROKER_VHOST", "") CELERY_BROKER_USER = AUTH_TOKENS.get("CELERY_BROKER_USER", "") CELERY_BROKER_PASSWORD = AUTH_TOKENS.get("CELERY_BROKER_PASSWORD", "") BROKER_URL = "{}://{}:{}@{}/{}".format(CELERY_BROKER_TRANSPORT, CELERY_BROKER_USER, CELERY_BROKER_PASSWORD, CELERY_BROKER_HOSTNAME, CELERY_BROKER_VHOST) BROKER_USE_SSL = ENV_TOKENS.get('CELERY_BROKER_USE_SSL', False) BROKER_TRANSPORT_OPTIONS = { 'fanout_patterns': True, 'fanout_prefix': True, } # Block Structures # upload limits STUDENT_FILEUPLOAD_MAX_SIZE = ENV_TOKENS.get("STUDENT_FILEUPLOAD_MAX_SIZE", STUDENT_FILEUPLOAD_MAX_SIZE) # Event tracking TRACKING_BACKENDS.update(AUTH_TOKENS.get("TRACKING_BACKENDS", {})) EVENT_TRACKING_BACKENDS['tracking_logs']['OPTIONS']['backends'].update(AUTH_TOKENS.get("EVENT_TRACKING_BACKENDS", {})) EVENT_TRACKING_BACKENDS['segmentio']['OPTIONS']['processors'][0]['OPTIONS']['whitelist'].extend( AUTH_TOKENS.get("EVENT_TRACKING_SEGMENTIO_EMIT_WHITELIST", [])) TRACKING_SEGMENTIO_WEBHOOK_SECRET = AUTH_TOKENS.get( "TRACKING_SEGMENTIO_WEBHOOK_SECRET", TRACKING_SEGMENTIO_WEBHOOK_SECRET ) TRACKING_SEGMENTIO_ALLOWED_TYPES = ENV_TOKENS.get("TRACKING_SEGMENTIO_ALLOWED_TYPES", TRACKING_SEGMENTIO_ALLOWED_TYPES) TRACKING_SEGMENTIO_DISALLOWED_SUBSTRING_NAMES = ENV_TOKENS.get( "TRACKING_SEGMENTIO_DISALLOWED_SUBSTRING_NAMES", TRACKING_SEGMENTIO_DISALLOWED_SUBSTRING_NAMES ) TRACKING_SEGMENTIO_SOURCE_MAP = ENV_TOKENS.get("TRACKING_SEGMENTIO_SOURCE_MAP", TRACKING_SEGMENTIO_SOURCE_MAP) # Heartbeat HEARTBEAT_CELERY_ROUTING_KEY = ENV_TOKENS.get('HEARTBEAT_CELERY_ROUTING_KEY', HEARTBEAT_CELERY_ROUTING_KEY) # Student identity verification settings VERIFY_STUDENT = AUTH_TOKENS.get("VERIFY_STUDENT", VERIFY_STUDENT) DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH = ENV_TOKENS.get( "DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH", DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH ) # Grades download GRADES_DOWNLOAD_ROUTING_KEY = ENV_TOKENS.get('GRADES_DOWNLOAD_ROUTING_KEY', HIGH_MEM_QUEUE) GRADES_DOWNLOAD = ENV_TOKENS.get("GRADES_DOWNLOAD", GRADES_DOWNLOAD) # Rate limit for regrading tasks that a grading policy change can kick off # financial reports FINANCIAL_REPORTS = ENV_TOKENS.get("FINANCIAL_REPORTS", FINANCIAL_REPORTS) ##### ORA2 ###### # Prefix for uploads of example-based assessment AI classifiers # This can be used to separate uploads for different environments # within the same S3 bucket. ORA2_FILE_PREFIX = ENV_TOKENS.get("ORA2_FILE_PREFIX", ORA2_FILE_PREFIX) ##### ACCOUNT LOCKOUT DEFAULT PARAMETERS ##### MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED = ENV_TOKENS.get( "MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED", MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED ) MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS = ENV_TOKENS.get( "MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS", MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS ) ##### LOGISTRATION RATE LIMIT SETTINGS ##### LOGISTRATION_RATELIMIT_RATE = ENV_TOKENS.get('LOGISTRATION_RATELIMIT_RATE', LOGISTRATION_RATELIMIT_RATE) LOGISTRATION_API_RATELIMIT = ENV_TOKENS.get('LOGISTRATION_API_RATELIMIT', LOGISTRATION_API_RATELIMIT) RESET_PASSWORD_TOKEN_VALIDATE_API_RATELIMIT = ENV_TOKENS.get( 'RESET_PASSWORD_TOKEN_VALIDATE_API_RATELIMIT', RESET_PASSWORD_TOKEN_VALIDATE_API_RATELIMIT ) RESET_PASSWORD_API_RATELIMIT = ENV_TOKENS.get('RESET_PASSWORD_API_RATELIMIT', RESET_PASSWORD_API_RATELIMIT) ##### REGISTRATION RATE LIMIT SETTINGS ##### REGISTRATION_VALIDATION_RATELIMIT = ENV_TOKENS.get( 'REGISTRATION_VALIDATION_RATELIMIT', REGISTRATION_VALIDATION_RATELIMIT ) REGISTRATION_RATELIMIT = ENV_TOKENS.get('REGISTRATION_RATELIMIT', REGISTRATION_RATELIMIT) #### PASSWORD POLICY SETTINGS ##### AUTH_PASSWORD_VALIDATORS = ENV_TOKENS.get("AUTH_PASSWORD_VALIDATORS", AUTH_PASSWORD_VALIDATORS) ### INACTIVITY SETTINGS #### SESSION_INACTIVITY_TIMEOUT_IN_SECONDS = AUTH_TOKENS.get("SESSION_INACTIVITY_TIMEOUT_IN_SECONDS") ##### LMS DEADLINE DISPLAY TIME_ZONE ####### TIME_ZONE_DISPLAYED_FOR_DEADLINES = ENV_TOKENS.get("TIME_ZONE_DISPLAYED_FOR_DEADLINES", TIME_ZONE_DISPLAYED_FOR_DEADLINES) ##### Third-party auth options ################################################ ENABLE_REQUIRE_THIRD_PARTY_AUTH = ENV_TOKENS.get('ENABLE_REQUIRE_THIRD_PARTY_AUTH', False) if FEATURES.get('ENABLE_THIRD_PARTY_AUTH'): tmp_backends = ENV_TOKENS.get('THIRD_PARTY_AUTH_BACKENDS', [ 'social_core.backends.google.GoogleOAuth2', 'social_core.backends.linkedin.LinkedinOAuth2', 'social_core.backends.facebook.FacebookOAuth2', 'social_core.backends.azuread.AzureADOAuth2', 'common.djangoapps.third_party_auth.appleid.AppleIdAuth', # vendored 'social_core.backends.apple.AppleIdAuth' 'common.djangoapps.third_party_auth.identityserver3.IdentityServer3', 'common.djangoapps.third_party_auth.saml.SAMLAuthBackend', 'common.djangoapps.third_party_auth.lti.LTIAuthBackend', ]) AUTHENTICATION_BACKENDS = list(tmp_backends) + list(AUTHENTICATION_BACKENDS) del tmp_backends # The reduced session expiry time during the third party login pipeline. (Value in seconds) SOCIAL_AUTH_PIPELINE_TIMEOUT = ENV_TOKENS.get('SOCIAL_AUTH_PIPELINE_TIMEOUT', 600) # Most provider configuration is done via ConfigurationModels but for a few sensitive values # we allow configuration via AUTH_TOKENS instead (optionally). # The SAML private/public key values do not need the delimiter lines (such as # "-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----" etc.) but they may be included # if you want (though it's easier to format the key values as JSON without the delimiters). SOCIAL_AUTH_SAML_SP_PRIVATE_KEY = AUTH_TOKENS.get('SOCIAL_AUTH_SAML_SP_PRIVATE_KEY', '') SOCIAL_AUTH_SAML_SP_PUBLIC_CERT = AUTH_TOKENS.get('SOCIAL_AUTH_SAML_SP_PUBLIC_CERT', '') SOCIAL_AUTH_SAML_SP_PRIVATE_KEY_DICT = AUTH_TOKENS.get('SOCIAL_AUTH_SAML_SP_PRIVATE_KEY_DICT', {}) SOCIAL_AUTH_SAML_SP_PUBLIC_CERT_DICT = AUTH_TOKENS.get('SOCIAL_AUTH_SAML_SP_PUBLIC_CERT_DICT', {}) SOCIAL_AUTH_OAUTH_SECRETS = AUTH_TOKENS.get('SOCIAL_AUTH_OAUTH_SECRETS', {}) SOCIAL_AUTH_LTI_CONSUMER_SECRETS = AUTH_TOKENS.get('SOCIAL_AUTH_LTI_CONSUMER_SECRETS', {}) # third_party_auth config moved to ConfigurationModels. This is for data migration only: THIRD_PARTY_AUTH_OLD_CONFIG = AUTH_TOKENS.get('THIRD_PARTY_AUTH', None) if ENV_TOKENS.get('THIRD_PARTY_AUTH_SAML_FETCH_PERIOD_HOURS', 24) is not None: CELERYBEAT_SCHEDULE['refresh-saml-metadata'] = { 'task': 'common.djangoapps.third_party_auth.fetch_saml_metadata', 'schedule': datetime.timedelta(hours=ENV_TOKENS.get('THIRD_PARTY_AUTH_SAML_FETCH_PERIOD_HOURS', 24)), } # The following can be used to integrate a custom login form with third_party_auth. # It should be a dict where the key is a word passed via ?auth_entry=, and the value is a # dict with an arbitrary 'secret_key' and a 'url'. THIRD_PARTY_AUTH_CUSTOM_AUTH_FORMS = AUTH_TOKENS.get('THIRD_PARTY_AUTH_CUSTOM_AUTH_FORMS', {}) ##### OAUTH2 Provider ############## if FEATURES.get('ENABLE_OAUTH2_PROVIDER'): OAUTH_ENFORCE_SECURE = ENV_TOKENS.get('OAUTH_ENFORCE_SECURE', True) OAUTH_ENFORCE_CLIENT_SECURE = ENV_TOKENS.get('OAUTH_ENFORCE_CLIENT_SECURE', True) # Defaults for the following are defined in lms.envs.common OAUTH_EXPIRE_DELTA = datetime.timedelta( days=ENV_TOKENS.get('OAUTH_EXPIRE_CONFIDENTIAL_CLIENT_DAYS', OAUTH_EXPIRE_CONFIDENTIAL_CLIENT_DAYS) ) OAUTH_EXPIRE_DELTA_PUBLIC = datetime.timedelta( days=ENV_TOKENS.get('OAUTH_EXPIRE_PUBLIC_CLIENT_DAYS', OAUTH_EXPIRE_PUBLIC_CLIENT_DAYS) ) ##### GOOGLE ANALYTICS IDS ##### GOOGLE_ANALYTICS_ACCOUNT = AUTH_TOKENS.get('GOOGLE_ANALYTICS_ACCOUNT') GOOGLE_ANALYTICS_TRACKING_ID = AUTH_TOKENS.get('GOOGLE_ANALYTICS_TRACKING_ID') GOOGLE_ANALYTICS_LINKEDIN = AUTH_TOKENS.get('GOOGLE_ANALYTICS_LINKEDIN') GOOGLE_SITE_VERIFICATION_ID = ENV_TOKENS.get('GOOGLE_SITE_VERIFICATION_ID') ##### BRANCH.IO KEY ##### BRANCH_IO_KEY = AUTH_TOKENS.get('BRANCH_IO_KEY') #### Course Registration Code length #### REGISTRATION_CODE_LENGTH = ENV_TOKENS.get('REGISTRATION_CODE_LENGTH', 8) # Which access.py permission names to check; # We default this to the legacy permission 'see_exists'. COURSE_CATALOG_VISIBILITY_PERMISSION = ENV_TOKENS.get( 'COURSE_CATALOG_VISIBILITY_PERMISSION', COURSE_CATALOG_VISIBILITY_PERMISSION ) COURSE_ABOUT_VISIBILITY_PERMISSION = ENV_TOKENS.get( 'COURSE_ABOUT_VISIBILITY_PERMISSION', COURSE_ABOUT_VISIBILITY_PERMISSION ) DEFAULT_COURSE_VISIBILITY_IN_CATALOG = ENV_TOKENS.get( 'DEFAULT_COURSE_VISIBILITY_IN_CATALOG', DEFAULT_COURSE_VISIBILITY_IN_CATALOG ) DEFAULT_MOBILE_AVAILABLE = ENV_TOKENS.get( 'DEFAULT_MOBILE_AVAILABLE', DEFAULT_MOBILE_AVAILABLE ) # Enrollment API Cache Timeout ENROLLMENT_COURSE_DETAILS_CACHE_TIMEOUT = ENV_TOKENS.get('ENROLLMENT_COURSE_DETAILS_CACHE_TIMEOUT', 60) if FEATURES.get('ENABLE_COURSEWARE_SEARCH') or \ FEATURES.get('ENABLE_DASHBOARD_SEARCH') or \ FEATURES.get('ENABLE_COURSE_DISCOVERY') or \ FEATURES.get('ENABLE_TEAMS'): # Use ElasticSearch as the search engine herein SEARCH_ENGINE = "search.elastic.ElasticSearchEngine" SEARCH_FILTER_GENERATOR = ENV_TOKENS.get('SEARCH_FILTER_GENERATOR', SEARCH_FILTER_GENERATOR) # TODO: Once we have successfully upgraded to ES7, switch this back to ELASTIC_SEARCH_CONFIG. ELASTIC_SEARCH_CONFIG = ENV_TOKENS.get('ELASTIC_SEARCH_CONFIG_ES7', [{}]) # Facebook app FACEBOOK_API_VERSION = AUTH_TOKENS.get("FACEBOOK_API_VERSION") FACEBOOK_APP_SECRET = AUTH_TOKENS.get("FACEBOOK_APP_SECRET") FACEBOOK_APP_ID = AUTH_TOKENS.get("FACEBOOK_APP_ID") XBLOCK_SETTINGS = ENV_TOKENS.get('XBLOCK_SETTINGS', {}) XBLOCK_SETTINGS.setdefault("VideoBlock", {})["licensing_enabled"] = FEATURES.get("LICENSING", False) XBLOCK_SETTINGS.setdefault("VideoBlock", {})['YOUTUBE_API_KEY'] = AUTH_TOKENS.get('YOUTUBE_API_KEY', YOUTUBE_API_KEY) ##### Custom Courses for EdX ##### if FEATURES.get('CUSTOM_COURSES_EDX'): INSTALLED_APPS += ['lms.djangoapps.ccx', 'openedx.core.djangoapps.ccxcon.apps.CCXConnectorConfig'] MODULESTORE_FIELD_OVERRIDE_PROVIDERS += ( 'lms.djangoapps.ccx.overrides.CustomCoursesForEdxOverrideProvider', ) ##### Individual Due Date Extensions ##### if FEATURES.get('INDIVIDUAL_DUE_DATES'): FIELD_OVERRIDE_PROVIDERS += ( 'courseware.student_field_overrides.IndividualStudentOverrideProvider', ) ##### Show Answer Override for Self-Paced Courses ##### FIELD_OVERRIDE_PROVIDERS += ( 'openedx.features.personalized_learner_schedules.show_answer.show_answer_field_override.ShowAnswerFieldOverride', ) ##### Self-Paced Course Due Dates ##### XBLOCK_FIELD_DATA_WRAPPERS += ( 'lms.djangoapps.courseware.field_overrides:OverrideModulestoreFieldData.wrap', ) MODULESTORE_FIELD_OVERRIDE_PROVIDERS += ( 'lms.djangoapps.courseware.self_paced_overrides.SelfPacedDateOverrideProvider', ) # PROFILE IMAGE CONFIG PROFILE_IMAGE_DEFAULT_FILENAME = 'images/profiles/default' PROFILE_IMAGE_SIZES_MAP = ENV_TOKENS.get( 'PROFILE_IMAGE_SIZES_MAP', PROFILE_IMAGE_SIZES_MAP ) ##### Credit Provider Integration ##### CREDIT_PROVIDER_SECRET_KEYS = AUTH_TOKENS.get("CREDIT_PROVIDER_SECRET_KEYS", {}) ##################### LTI Provider ##################### if FEATURES.get('ENABLE_LTI_PROVIDER'): INSTALLED_APPS.append('lms.djangoapps.lti_provider.apps.LtiProviderConfig') AUTHENTICATION_BACKENDS.append('lms.djangoapps.lti_provider.users.LtiBackend') LTI_USER_EMAIL_DOMAIN = ENV_TOKENS.get('LTI_USER_EMAIL_DOMAIN', 'lti.example.com') # For more info on this, see the notes in common.py LTI_AGGREGATE_SCORE_PASSBACK_DELAY = ENV_TOKENS.get( 'LTI_AGGREGATE_SCORE_PASSBACK_DELAY', LTI_AGGREGATE_SCORE_PASSBACK_DELAY ) ##################### Credit Provider help link #################### #### JWT configuration #### JWT_AUTH.update(ENV_TOKENS.get('JWT_AUTH', {})) JWT_AUTH.update(AUTH_TOKENS.get('JWT_AUTH', {})) # Offset for pk of courseware.StudentModuleHistoryExtended STUDENTMODULEHISTORYEXTENDED_OFFSET = ENV_TOKENS.get( 'STUDENTMODULEHISTORYEXTENDED_OFFSET', STUDENTMODULEHISTORYEXTENDED_OFFSET ) # Cutoff date for granting audit certificates if ENV_TOKENS.get('AUDIT_CERT_CUTOFF_DATE', None): AUDIT_CERT_CUTOFF_DATE = dateutil.parser.parse(ENV_TOKENS.get('AUDIT_CERT_CUTOFF_DATE')) ################################ Settings for Credentials Service ################################ CREDENTIALS_GENERATION_ROUTING_KEY = ENV_TOKENS.get('CREDENTIALS_GENERATION_ROUTING_KEY', DEFAULT_PRIORITY_QUEUE) # Queue to use for award program certificates PROGRAM_CERTIFICATES_ROUTING_KEY = ENV_TOKENS.get('PROGRAM_CERTIFICATES_ROUTING_KEY', DEFAULT_PRIORITY_QUEUE) SOFTWARE_SECURE_VERIFICATION_ROUTING_KEY = ENV_TOKENS.get( 'SOFTWARE_SECURE_VERIFICATION_ROUTING_KEY', HIGH_PRIORITY_QUEUE ) API_ACCESS_MANAGER_EMAIL = ENV_TOKENS.get('API_ACCESS_MANAGER_EMAIL') API_ACCESS_FROM_EMAIL = ENV_TOKENS.get('API_ACCESS_FROM_EMAIL') ############## OPEN EDX ENTERPRISE SERVICE CONFIGURATION ###################### # The Open edX Enterprise service is currently hosted via the LMS container/process. # However, for all intents and purposes this service is treated as a standalone IDA. # These configuration settings are specific to the Enterprise service and you should # not find references to them within the edx-platform project. # Publicly-accessible enrollment URL, for use on the client side. ENTERPRISE_PUBLIC_ENROLLMENT_API_URL = ENV_TOKENS.get( 'ENTERPRISE_PUBLIC_ENROLLMENT_API_URL', (LMS_ROOT_URL or '') + LMS_ENROLLMENT_API_PATH ) # Enrollment URL used on the server-side. ENTERPRISE_ENROLLMENT_API_URL = ENV_TOKENS.get( 'ENTERPRISE_ENROLLMENT_API_URL', (LMS_INTERNAL_ROOT_URL or '') + LMS_ENROLLMENT_API_PATH ) # Enterprise logo image size limit in KB's ENTERPRISE_CUSTOMER_LOGO_IMAGE_SIZE = ENV_TOKENS.get( 'ENTERPRISE_CUSTOMER_LOGO_IMAGE_SIZE', ENTERPRISE_CUSTOMER_LOGO_IMAGE_SIZE ) # Course enrollment modes to be hidden in the Enterprise enrollment page # if the "Hide audit track" flag is enabled for an EnterpriseCustomer ENTERPRISE_COURSE_ENROLLMENT_AUDIT_MODES = ENV_TOKENS.get( 'ENTERPRISE_COURSE_ENROLLMENT_AUDIT_MODES', ENTERPRISE_COURSE_ENROLLMENT_AUDIT_MODES ) # A support URL used on Enterprise landing pages for when a warning # message goes off. ENTERPRISE_SUPPORT_URL = ENV_TOKENS.get( 'ENTERPRISE_SUPPORT_URL', ENTERPRISE_SUPPORT_URL ) # A default dictionary to be used for filtering out enterprise customer catalog. ENTERPRISE_CUSTOMER_CATALOG_DEFAULT_CONTENT_FILTER = ENV_TOKENS.get( 'ENTERPRISE_CUSTOMER_CATALOG_DEFAULT_CONTENT_FILTER', ENTERPRISE_CUSTOMER_CATALOG_DEFAULT_CONTENT_FILTER ) INTEGRATED_CHANNELS_API_CHUNK_TRANSMISSION_LIMIT = ENV_TOKENS.get( 'INTEGRATED_CHANNELS_API_CHUNK_TRANSMISSION_LIMIT', INTEGRATED_CHANNELS_API_CHUNK_TRANSMISSION_LIMIT ) ############## ENTERPRISE SERVICE API CLIENT CONFIGURATION ###################### # The LMS communicates with the Enterprise service via the EdxRestApiClient class # The below environmental settings are utilized by the LMS when interacting with # the service, and override the default parameters which are defined in common.py DEFAULT_ENTERPRISE_API_URL = None if LMS_INTERNAL_ROOT_URL is not None: DEFAULT_ENTERPRISE_API_URL = LMS_INTERNAL_ROOT_URL + '/enterprise/api/v1/' ENTERPRISE_API_URL = ENV_TOKENS.get('ENTERPRISE_API_URL', DEFAULT_ENTERPRISE_API_URL) DEFAULT_ENTERPRISE_CONSENT_API_URL = None if LMS_INTERNAL_ROOT_URL is not None: DEFAULT_ENTERPRISE_CONSENT_API_URL = LMS_INTERNAL_ROOT_URL + '/consent/api/v1/' ENTERPRISE_CONSENT_API_URL = ENV_TOKENS.get('ENTERPRISE_CONSENT_API_URL', DEFAULT_ENTERPRISE_CONSENT_API_URL) ENTERPRISE_SERVICE_WORKER_USERNAME = ENV_TOKENS.get( 'ENTERPRISE_SERVICE_WORKER_USERNAME', ENTERPRISE_SERVICE_WORKER_USERNAME ) ENTERPRISE_API_CACHE_TIMEOUT = ENV_TOKENS.get( 'ENTERPRISE_API_CACHE_TIMEOUT', ENTERPRISE_API_CACHE_TIMEOUT ) ENTERPRISE_CATALOG_INTERNAL_ROOT_URL = ENV_TOKENS.get( 'ENTERPRISE_CATALOG_INTERNAL_ROOT_URL', ENTERPRISE_CATALOG_INTERNAL_ROOT_URL ) ############## ENTERPRISE SERVICE LMS CONFIGURATION ################################## # The LMS has some features embedded that are related to the Enterprise service, but # which are not provided by the Enterprise service. These settings override the # base values for the parameters as defined in common.py ENTERPRISE_PLATFORM_WELCOME_TEMPLATE = ENV_TOKENS.get( 'ENTERPRISE_PLATFORM_WELCOME_TEMPLATE', ENTERPRISE_PLATFORM_WELCOME_TEMPLATE ) ENTERPRISE_SPECIFIC_BRANDED_WELCOME_TEMPLATE = ENV_TOKENS.get( 'ENTERPRISE_SPECIFIC_BRANDED_WELCOME_TEMPLATE', ENTERPRISE_SPECIFIC_BRANDED_WELCOME_TEMPLATE ) ENTERPRISE_TAGLINE = ENV_TOKENS.get( 'ENTERPRISE_TAGLINE', ENTERPRISE_TAGLINE ) ENTERPRISE_EXCLUDED_REGISTRATION_FIELDS = set( ENV_TOKENS.get( 'ENTERPRISE_EXCLUDED_REGISTRATION_FIELDS', ENTERPRISE_EXCLUDED_REGISTRATION_FIELDS ) ) BASE_COOKIE_DOMAIN = ENV_TOKENS.get( 'BASE_COOKIE_DOMAIN', BASE_COOKIE_DOMAIN ) SYSTEM_TO_FEATURE_ROLE_MAPPING = ENV_TOKENS.get( 'SYSTEM_TO_FEATURE_ROLE_MAPPING', SYSTEM_TO_FEATURE_ROLE_MAPPING ) # Add an ICP license for serving content in China if your organization is registered to do so ICP_LICENSE = ENV_TOKENS.get('ICP_LICENSE', None) ICP_LICENSE_INFO = ENV_TOKENS.get('ICP_LICENSE_INFO', {}) ############## Settings for CourseGraph ############################ COURSEGRAPH_JOB_QUEUE = ENV_TOKENS.get('COURSEGRAPH_JOB_QUEUE', DEFAULT_PRIORITY_QUEUE) # How long to cache OpenAPI schemas and UI, in seconds. OPENAPI_CACHE_TIMEOUT = ENV_TOKENS.get('OPENAPI_CACHE_TIMEOUT', 60 * 60) ########################## 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 = ENV_TOKENS.get( 'PARENTAL_CONSENT_AGE_LIMIT', PARENTAL_CONSENT_AGE_LIMIT ) ########################## Extra middleware classes ####################### # Allow extra middleware classes to be added to the app through configuration. MIDDLEWARE.extend(ENV_TOKENS.get('EXTRA_MIDDLEWARE_CLASSES', [])) ################# Settings for the maintenance banner ################# MAINTENANCE_BANNER_TEXT = ENV_TOKENS.get('MAINTENANCE_BANNER_TEXT', None) ########################## limiting dashboard courses ###################### DASHBOARD_COURSE_LIMIT = ENV_TOKENS.get('DASHBOARD_COURSE_LIMIT', None) ######################## Setting for content libraries ######################## MAX_BLOCKS_PER_CONTENT_LIBRARY = ENV_TOKENS.get('MAX_BLOCKS_PER_CONTENT_LIBRARY', MAX_BLOCKS_PER_CONTENT_LIBRARY) ############################### Plugin Settings ############################### # This is at the bottom because it is going to load more settings after base settings are loaded # Load production.py in plugins add_plugins(__name__, ProjectType.LMS, SettingsType.PRODUCTION) ########################## Derive Any Derived Settings ####################### derive_settings(__name__) ############## Settings for Completion API ######################### # Once a user has watched this percentage of a video, mark it as complete: # (0.0 = 0%, 1.0 = 100%) COMPLETION_VIDEO_COMPLETE_PERCENTAGE = ENV_TOKENS.get('COMPLETION_VIDEO_COMPLETE_PERCENTAGE', COMPLETION_VIDEO_COMPLETE_PERCENTAGE) COMPLETION_BY_VIEWING_DELAY_MS = ENV_TOKENS.get('COMPLETION_BY_VIEWING_DELAY_MS', COMPLETION_BY_VIEWING_DELAY_MS) ################# Settings for brand logos. ################# LOGO_URL = ENV_TOKENS.get('LOGO_URL', LOGO_URL) LOGO_URL_PNG = ENV_TOKENS.get('LOGO_URL_PNG', LOGO_URL_PNG) LOGO_TRADEMARK_URL = ENV_TOKENS.get('LOGO_TRADEMARK_URL', LOGO_TRADEMARK_URL) FAVICON_URL = ENV_TOKENS.get('FAVICON_URL', FAVICON_URL) ######################## CELERY ROUTING ######################## # Defines alternate environment tasks, as a dict of form { task_name: alternate_queue } ALTERNATE_ENV_TASKS = {} # Defines the task -> alternate worker queue to be used when routing. EXPLICIT_QUEUES = { 'openedx.core.djangoapps.content.course_overviews.tasks.async_course_overview_update': { 'queue': GRADES_DOWNLOAD_ROUTING_KEY}, 'lms.djangoapps.bulk_email.tasks.send_course_email': { 'queue': BULK_EMAIL_ROUTING_KEY}, 'openedx.core.djangoapps.heartbeat.tasks.sample_task': { 'queue': HEARTBEAT_CELERY_ROUTING_KEY}, 'lms.djangoapps.instructor_task.tasks.calculate_grades_csv': { 'queue': GRADES_DOWNLOAD_ROUTING_KEY}, 'lms.djangoapps.instructor_task.tasks.calculate_problem_grade_report': { 'queue': GRADES_DOWNLOAD_ROUTING_KEY}, 'lms.djangoapps.instructor_task.tasks.generate_certificates': { 'queue': GRADES_DOWNLOAD_ROUTING_KEY}, 'lms.djangoapps.email_marketing.tasks.get_email_cookies_via_sailthru': { 'queue': ACE_ROUTING_KEY}, 'lms.djangoapps.email_marketing.tasks.update_user': { 'queue': ACE_ROUTING_KEY}, 'lms.djangoapps.email_marketing.tasks.update_user_email': { 'queue': ACE_ROUTING_KEY}, 'lms.djangoapps.email_marketing.tasks.update_course_enrollment': { 'queue': ACE_ROUTING_KEY}, 'lms.djangoapps.verify_student.tasks.send_verification_status_email': { 'queue': ACE_ROUTING_KEY}, 'lms.djangoapps.verify_student.tasks.send_ace_message': { 'queue': ACE_ROUTING_KEY}, 'lms.djangoapps.verify_student.tasks.send_request_to_ss_for_user': { 'queue': SOFTWARE_SECURE_VERIFICATION_ROUTING_KEY}, 'openedx.core.djangoapps.schedules.tasks._recurring_nudge_schedule_send': { 'queue': ACE_ROUTING_KEY}, 'openedx.core.djangoapps.schedules.tasks._upgrade_reminder_schedule_send': { 'queue': ACE_ROUTING_KEY}, 'openedx.core.djangoapps.schedules.tasks._course_update_schedule_send': { 'queue': ACE_ROUTING_KEY}, 'openedx.core.djangoapps.schedules.tasks.v1.tasks.send_grade_to_credentials': { 'queue': CREDENTIALS_GENERATION_ROUTING_KEY}, 'common.djangoapps.entitlements.tasks.expire_old_entitlements': { 'queue': ENTITLEMENTS_EXPIRATION_ROUTING_KEY}, 'lms.djangoapps.grades.tasks.recalculate_course_and_subsection_grades_for_user': { 'queue': POLICY_CHANGE_GRADES_ROUTING_KEY}, 'lms.djangoapps.grades.tasks.recalculate_subsection_grade_v3': { 'queue': RECALCULATE_GRADES_ROUTING_KEY}, 'openedx.core.djangoapps.programs.tasks.v1.tasks.award_program_certificates': { 'queue': PROGRAM_CERTIFICATES_ROUTING_KEY}, 'openedx.core.djangoapps.programs.tasks.v1.tasks.revoke_program_certificates': { 'queue': PROGRAM_CERTIFICATES_ROUTING_KEY}, 'openedx.core.djangoapps.programs.tasks.v1.tasks.update_certificate_visible_date_on_course_update': { 'queue': PROGRAM_CERTIFICATES_ROUTING_KEY}, 'openedx.core.djangoapps.programs.tasks.v1.tasks.award_course_certificate': { 'queue': PROGRAM_CERTIFICATES_ROUTING_KEY}, 'openedx.core.djangoapps.coursegraph.dump_course_to_neo4j': { 'queue': COURSEGRAPH_JOB_QUEUE}, } LOGO_IMAGE_EXTRA_TEXT = ENV_TOKENS.get('LOGO_IMAGE_EXTRA_TEXT', '') ############## XBlock extra mixins ############################ XBLOCK_MIXINS += tuple(XBLOCK_EXTRA_MIXINS) ################# Settings for Chrome-specific origin trials ######## # Token for "Disable Different Origin Subframe Dialog Suppression" Chrome Origin Trial, which must be origin-specific. CHROME_DISABLE_SUBFRAME_DIALOG_SUPPRESSION_TOKEN = ENV_TOKENS.get( 'CHROME_DISABLE_SUBFRAME_DIALOG_SUPPRESSION_TOKEN', CHROME_DISABLE_SUBFRAME_DIALOG_SUPPRESSION_TOKEN )
परिवर्तित टेक्स्ट
फ़ाइल खोलें
""" This is the default template for our main set of AWS servers. Common traits: * Use memcached, and cache-backed sessions * Use a MySQL 5.1 database """ # We intentionally define lots of variables that aren't used, and # want to import all variables from base settings files # pylint: disable=wildcard-import, unused-wildcard-import # Pylint gets confused by path.py instances, which report themselves as class # objects. As a result, pylint applies the wrong regex in validating names, # and throws spurious errors. Therefore, we disable invalid-name checking. # pylint: disable=invalid-name import codecs import copy import datetime import os import requests import dateutil import yaml from corsheaders.defaults import default_headers as corsheaders_default_headers from django.core.exceptions import ImproperlyConfigured from edx_django_utils.plugins import add_plugins from path import Path as path from openedx.core.djangoapps.plugins.constants import ProjectType, SettingsType from openedx.core.lib.derived import derive_settings from openedx.core.lib.logsettings import get_logger_config from xmodule.modulestore.modulestore_settings import convert_module_store_setting_if_needed from .common import * def get_env_setting(setting): """ Get the environment setting or return exception """ try: return os.environ[setting] except KeyError: error_msg = "Set the %s env variable" % setting raise ImproperlyConfigured(error_msg) # lint-amnesty, pylint: disable=raise-missing-from ################################ ALWAYS THE SAME ############################## DEBUG = False DEFAULT_TEMPLATE_ENGINE['OPTIONS']['debug'] = False SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # IMPORTANT: With this enabled, the server must always be behind a proxy that # strips the header HTTP_X_FORWARDED_PROTO from client requests. Otherwise, # a user can fool our server into thinking it was an https connection. # See # https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header # for other warnings. SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') ################################ END ALWAYS THE SAME ############################## ################################### Getting Environment Variables From Doppler ################################### url = "https://api.doppler.com/v3/configs/config/secrets" querystring = {"project": "openedx", "config": "dev"} DOPPLER_TOKEN = AUTH_TOKENS.get('DOPPLER_TOKEN', '') Authorization = "Basic {DOPPLER_TOKEN}".format(DOPPLER_TOKEN=DOPPLER_TOKEN) headers = { "Accept": "application/json", "accepts": "application/json", "Authorization": Authorization } doppler_response = requests.request("GET", url, headers=headers, params=querystring) EMAIL_HOST_PASSWORD = doppler_response.json()['secrets']['EMAIL_HOST_PASSWORD']['raw'] ################################### END Getting Environment Variables From Doppler ############################### # A file path to a YAML file from which to load all the configuration for the edx platform CONFIG_FILE = get_env_setting('LMS_CFG') with codecs.open(CONFIG_FILE, encoding='utf-8') as f: __config__ = yaml.safe_load(f) # ENV_TOKENS and AUTH_TOKENS are included for reverse compatibility. # Removing them may break plugins that rely on them. ENV_TOKENS = __config__ AUTH_TOKENS = __config__ # Add the key/values from config into the global namespace of this module. # But don't override the FEATURES dict because we do that in an additive way. __config_copy__ = copy.deepcopy(__config__) KEYS_WITH_MERGED_VALUES = [ 'FEATURES', 'TRACKING_BACKENDS', 'EVENT_TRACKING_BACKENDS', 'JWT_AUTH', 'CELERY_QUEUES', 'MKTG_URL_LINK_MAP', 'MKTG_URL_OVERRIDES', ] for key in KEYS_WITH_MERGED_VALUES: if key in __config_copy__: del __config_copy__[key] vars().update(__config_copy__) try: # A file path to a YAML file from which to load all the code revisions currently deployed REVISION_CONFIG_FILE = get_env_setting('REVISION_CFG') with codecs.open(REVISION_CONFIG_FILE, encoding='utf-8') as f: REVISION_CONFIG = yaml.safe_load(f) except Exception: # pylint: disable=broad-except REVISION_CONFIG = {} # Do NOT calculate this dynamically at startup with git because it's *slow*. EDX_PLATFORM_REVISION = REVISION_CONFIG.get('EDX_PLATFORM_REVISION', EDX_PLATFORM_REVISION) ###################################### CELERY ################################ # Don't use a connection pool, since connections are dropped by ELB. BROKER_POOL_LIMIT = 0 BROKER_CONNECTION_TIMEOUT = 1 # For the Result Store, use the django cache named 'celery' CELERY_RESULT_BACKEND = 'django-cache' # When the broker is behind an ELB, use a heartbeat to refresh the # connection and to detect if it has been dropped. BROKER_HEARTBEAT = ENV_TOKENS.get('BROKER_HEARTBEAT', 60.0) BROKER_HEARTBEAT_CHECKRATE = ENV_TOKENS.get('BROKER_HEARTBEAT_CHECKRATE', 2) # Each worker should only fetch one message at a time CELERYD_PREFETCH_MULTIPLIER = 1 # STATIC_ROOT specifies the directory where static files are # collected STATIC_ROOT_BASE = ENV_TOKENS.get('STATIC_ROOT_BASE', None) if STATIC_ROOT_BASE: STATIC_ROOT = path(STATIC_ROOT_BASE) WEBPACK_LOADER['DEFAULT']['STATS_FILE'] = STATIC_ROOT / "webpack-stats.json" WEBPACK_LOADER['WORKERS']['STATS_FILE'] = STATIC_ROOT / "webpack-worker-stats.json" # STATIC_URL_BASE specifies the base url to use for static files STATIC_URL_BASE = ENV_TOKENS.get('STATIC_URL_BASE', None) if STATIC_URL_BASE: STATIC_URL = STATIC_URL_BASE if not STATIC_URL.endswith("/"): STATIC_URL += "/" # Allow overriding build profile used by RequireJS with one # contained on a custom theme REQUIRE_BUILD_PROFILE = ENV_TOKENS.get('REQUIRE_BUILD_PROFILE', REQUIRE_BUILD_PROFILE) # The following variables use (or) instead of the default value inside (get). This is to enforce using the Lazy Text # values when the varibale is an empty string. Therefore, setting these variable as empty text in related # json files will make the system reads thier values from django translation files PLATFORM_NAME = ENV_TOKENS.get('PLATFORM_NAME') or PLATFORM_NAME PLATFORM_DESCRIPTION = ENV_TOKENS.get('PLATFORM_DESCRIPTION') or PLATFORM_DESCRIPTION CC_MERCHANT_NAME = ENV_TOKENS.get('CC_MERCHANT_NAME', PLATFORM_NAME) EMAIL_FILE_PATH = ENV_TOKENS.get('EMAIL_FILE_PATH', None) EMAIL_HOST = ENV_TOKENS.get('EMAIL_HOST', 'localhost') # django default is localhost EMAIL_PORT = ENV_TOKENS.get('EMAIL_PORT', 25) # django default is 25 EMAIL_USE_TLS = ENV_TOKENS.get('EMAIL_USE_TLS', False) # django default is False SITE_NAME = ENV_TOKENS['SITE_NAME'] SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN') SESSION_COOKIE_HTTPONLY = ENV_TOKENS.get('SESSION_COOKIE_HTTPONLY', True) DCS_SESSION_COOKIE_SAMESITE = ENV_TOKENS.get('DCS_SESSION_COOKIE_SAMESITE', DCS_SESSION_COOKIE_SAMESITE) DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL = ENV_TOKENS.get('DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL', DCS_SESSION_COOKIE_SAMESITE_FORCE_ALL) # lint-amnesty, pylint: disable=line-too-long AWS_SES_REGION_NAME = ENV_TOKENS.get('AWS_SES_REGION_NAME', 'us-east-1') AWS_SES_REGION_ENDPOINT = ENV_TOKENS.get('AWS_SES_REGION_ENDPOINT', 'email.us-east-1.amazonaws.com') REGISTRATION_EMAIL_PATTERNS_ALLOWED = ENV_TOKENS.get('REGISTRATION_EMAIL_PATTERNS_ALLOWED') LMS_ROOT_URL = ENV_TOKENS.get('LMS_ROOT_URL') LMS_INTERNAL_ROOT_URL = ENV_TOKENS.get('LMS_INTERNAL_ROOT_URL', LMS_ROOT_URL) # List of logout URIs for each IDA that the learner should be logged out of when they logout of the LMS. Only applies to # IDA for which the social auth flow uses DOT (Django OAuth Toolkit). IDA_LOGOUT_URI_LIST = ENV_TOKENS.get('IDA_LOGOUT_URI_LIST', []) ENV_FEATURES = ENV_TOKENS.get('FEATURES', {}) for feature, value in ENV_FEATURES.items(): FEATURES[feature] = value CMS_BASE = ENV_TOKENS.get('CMS_BASE', 'studio.edx.org') ALLOWED_HOSTS = [ # TODO: bbeggs remove this before prod, temp fix to get load testing running "*", ENV_TOKENS.get('LMS_BASE'), FEATURES['PREVIEW_LMS_BASE'], ] # allow for environments to specify what cookie name our login subsystem should use # this is to fix a bug regarding simultaneous logins between edx.org and edge.edx.org which can # happen with some browsers (e.g. Firefox) if ENV_TOKENS.get('SESSION_COOKIE_NAME', None): # NOTE, there's a bug in Django (http://bugs.python.org/issue18012) which necessitates this being a str() SESSION_COOKIE_NAME = str(ENV_TOKENS.get('SESSION_COOKIE_NAME')) CACHES = ENV_TOKENS['CACHES'] # Cache used for location mapping -- called many times with the same key/value # in a given request. if 'loc_cache' not in CACHES: CACHES['loc_cache'] = { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'edx_location_mem_cache', } if 'staticfiles' in CACHES: CACHES['staticfiles']['KEY_PREFIX'] = EDX_PLATFORM_REVISION # In order to transition from local disk asset storage to S3 backed asset storage, # we need to run asset collection twice, once for local disk and once for S3. # Once we have migrated to service assets off S3, then we can convert this back to # managed by the yaml file contents STATICFILES_STORAGE = os.environ.get('STATICFILES_STORAGE', ENV_TOKENS.get('STATICFILES_STORAGE', STATICFILES_STORAGE)) # Load all AWS_ prefixed variables to allow an S3Boto3Storage to be configured _locals = locals() for key, value in ENV_TOKENS.items(): if key.startswith('AWS_'): _locals[key] = value # Currency PAID_COURSE_REGISTRATION_CURRENCY = ENV_TOKENS.get('PAID_COURSE_REGISTRATION_CURRENCY', PAID_COURSE_REGISTRATION_CURRENCY) # We want Bulk Email running on the high-priority queue, so we define the # routing key that points to it. At the moment, the name is the same. # We have to reset the value here, since we have changed the value of the queue name. BULK_EMAIL_ROUTING_KEY = ENV_TOKENS.get('BULK_EMAIL_ROUTING_KEY', HIGH_PRIORITY_QUEUE) # We can run smaller jobs on the low priority queue. See note above for why # we have to reset the value here. BULK_EMAIL_ROUTING_KEY_SMALL_JOBS = ENV_TOKENS.get('BULK_EMAIL_ROUTING_KEY_SMALL_JOBS', DEFAULT_PRIORITY_QUEUE) # Queue to use for expiring old entitlements ENTITLEMENTS_EXPIRATION_ROUTING_KEY = ENV_TOKENS.get('ENTITLEMENTS_EXPIRATION_ROUTING_KEY', DEFAULT_PRIORITY_QUEUE) # Message expiry time in seconds CELERY_EVENT_QUEUE_TTL = ENV_TOKENS.get('CELERY_EVENT_QUEUE_TTL', None) # Allow CELERY_QUEUES to be overwritten by ENV_TOKENS, ENV_CELERY_QUEUES = ENV_TOKENS.get('CELERY_QUEUES', None) if ENV_CELERY_QUEUES: CELERY_QUEUES = {queue: {} for queue in ENV_CELERY_QUEUES} # Then add alternate environment queues ALTERNATE_QUEUE_ENVS = ENV_TOKENS.get('ALTERNATE_WORKER_QUEUES', '').split() ALTERNATE_QUEUES = [ DEFAULT_PRIORITY_QUEUE.replace(QUEUE_VARIANT, alternate + '.') for alternate in ALTERNATE_QUEUE_ENVS ] CELERY_QUEUES.update( { alternate: {} for alternate in ALTERNATE_QUEUES if alternate not in list(CELERY_QUEUES.keys()) } ) # following setting is for backward compatibility if ENV_TOKENS.get('COMPREHENSIVE_THEME_DIR', None): COMPREHENSIVE_THEME_DIR = ENV_TOKENS.get('COMPREHENSIVE_THEME_DIR') # COMPREHENSIVE_THEME_LOCALE_PATHS contain the paths to themes locale directories e.g. # "COMPREHENSIVE_THEME_LOCALE_PATHS" : [ # "/edx/src/edx-themes/conf/locale" # ], COMPREHENSIVE_THEME_LOCALE_PATHS = ENV_TOKENS.get('COMPREHENSIVE_THEME_LOCALE_PATHS', []) MKTG_URL_LINK_MAP.update(ENV_TOKENS.get('MKTG_URL_LINK_MAP', {})) ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS = ENV_TOKENS.get( 'ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS', ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS ) # Marketing link overrides MKTG_URL_OVERRIDES.update(ENV_TOKENS.get('MKTG_URL_OVERRIDES', MKTG_URL_OVERRIDES)) # Intentional defaults. ID_VERIFICATION_SUPPORT_LINK = ENV_TOKENS.get('ID_VERIFICATION_SUPPORT_LINK', SUPPORT_SITE_LINK) PASSWORD_RESET_SUPPORT_LINK = ENV_TOKENS.get('PASSWORD_RESET_SUPPORT_LINK', SUPPORT_SITE_LINK) ACTIVATION_EMAIL_SUPPORT_LINK = ENV_TOKENS.get('ACTIVATION_EMAIL_SUPPORT_LINK', SUPPORT_SITE_LINK) LOGIN_ISSUE_SUPPORT_LINK = ENV_TOKENS.get('LOGIN_ISSUE_SUPPORT_LINK', SUPPORT_SITE_LINK) # Timezone overrides TIME_ZONE = ENV_TOKENS.get('CELERY_TIMEZONE', CELERY_TIMEZONE) # Translation overrides LANGUAGE_DICT = dict(LANGUAGES) # Additional installed apps for app in ENV_TOKENS.get('ADDL_INSTALLED_APPS', []): INSTALLED_APPS.append(app) local_loglevel = ENV_TOKENS.get('LOCAL_LOGLEVEL', 'INFO') LOG_DIR = ENV_TOKENS['LOG_DIR'] DATA_DIR = path(ENV_TOKENS.get('DATA_DIR', DATA_DIR)) LOGGING = get_logger_config(LOG_DIR, logging_env=ENV_TOKENS['LOGGING_ENV'], local_loglevel=local_loglevel, service_variant=SERVICE_VARIANT) COURSE_LISTINGS = ENV_TOKENS.get('COURSE_LISTINGS', {}) COMMENTS_SERVICE_URL = ENV_TOKENS.get("COMMENTS_SERVICE_URL", '') COMMENTS_SERVICE_KEY = ENV_TOKENS.get("COMMENTS_SERVICE_KEY", '') CERT_QUEUE = ENV_TOKENS.get("CERT_QUEUE", 'test-pull') # Python lib settings PYTHON_LIB_FILENAME = ENV_TOKENS.get('PYTHON_LIB_FILENAME', 'python_lib.zip') # Code jail settings for name, value in ENV_TOKENS.get("CODE_JAIL", {}).items(): oldvalue = CODE_JAIL.get(name) if isinstance(oldvalue, dict): for subname, subvalue in value.items(): oldvalue[subname] = subvalue else: CODE_JAIL[name] = value COURSES_WITH_UNSAFE_CODE = ENV_TOKENS.get("COURSES_WITH_UNSAFE_CODE", []) # Event Tracking if "TRACKING_IGNORE_URL_PATTERNS" in ENV_TOKENS: TRACKING_IGNORE_URL_PATTERNS = ENV_TOKENS.get("TRACKING_IGNORE_URL_PATTERNS") # SSL external authentication settings SSL_AUTH_EMAIL_DOMAIN = ENV_TOKENS.get("SSL_AUTH_EMAIL_DOMAIN", "MIT.EDU") SSL_AUTH_DN_FORMAT_STRING = ENV_TOKENS.get( "SSL_AUTH_DN_FORMAT_STRING", "/C=US/ST=Massachusetts/O=Massachusetts Institute of Technology/OU=Client CA v1/CN={0}/emailAddress={1}" ) # Video Caching. Pairing country codes with CDN URLs. # Example: {'CN': 'http://api.xuetangx.com/edx/video?s3_url='} VIDEO_CDN_URL = ENV_TOKENS.get('VIDEO_CDN_URL', {}) # Determines whether the CSRF token can be transported on # unencrypted channels. It is set to False here for backward compatibility, # but it is highly recommended that this is True for enviroments accessed # by end users. CSRF_COOKIE_SECURE = ENV_TOKENS.get('CSRF_COOKIE_SECURE', False) # Determines which origins are trusted for unsafe requests eg. POST requests. CSRF_TRUSTED_ORIGINS = ENV_TOKENS.get('CSRF_TRUSTED_ORIGINS', []) ############# CORS headers for cross-domain requests ################# if FEATURES.get('ENABLE_CORS_HEADERS') or FEATURES.get('ENABLE_CROSS_DOMAIN_CSRF_COOKIE'): CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_WHITELIST = ENV_TOKENS.get('CORS_ORIGIN_WHITELIST', ()) CORS_ORIGIN_ALLOW_ALL = ENV_TOKENS.get('CORS_ORIGIN_ALLOW_ALL', False) CORS_ALLOW_INSECURE = ENV_TOKENS.get('CORS_ALLOW_INSECURE', False) CORS_ALLOW_HEADERS = corsheaders_default_headers + ( 'use-jwt-cookie', ) # If setting a cross-domain cookie, it's really important to choose # a name for the cookie that is DIFFERENT than the cookies used # by each subdomain. For example, suppose the applications # at these subdomains are configured to use the following cookie names: # # 1) foo.example.com --> "csrftoken" # 2) baz.example.com --> "csrftoken" # 3) bar.example.com --> "csrftoken" # # For the cross-domain version of the CSRF cookie, you need to choose # a name DIFFERENT than "csrftoken"; otherwise, the new token configured # for ".example.com" could conflict with the other cookies, # non-deterministically causing 403 responses. # # Because of the way Django stores cookies, the cookie name MUST # be a `str`, not unicode. Otherwise there will `TypeError`s will be raised # when Django tries to call the unicode `translate()` method with the wrong # number of parameters. CROSS_DOMAIN_CSRF_COOKIE_NAME = str(ENV_TOKENS.get('CROSS_DOMAIN_CSRF_COOKIE_NAME')) # When setting the domain for the "cross-domain" version of the CSRF # cookie, you should choose something like: ".example.com" # (note the leading dot), where both the referer and the host # are subdomains of "example.com". # # Browser security rules require that # the cookie domain matches the domain of the server; otherwise # the cookie won't get set. And once the cookie gets set, the client # needs to be on a domain that matches the cookie domain, otherwise # the client won't be able to read the cookie. CROSS_DOMAIN_CSRF_COOKIE_DOMAIN = ENV_TOKENS.get('CROSS_DOMAIN_CSRF_COOKIE_DOMAIN') # Field overrides. To use the IDDE feature, add # 'courseware.student_field_overrides.IndividualStudentOverrideProvider'. FIELD_OVERRIDE_PROVIDERS = tuple(ENV_TOKENS.get('FIELD_OVERRIDE_PROVIDERS', [])) ############### XBlock filesystem field config ########## if 'DJFS' in AUTH_TOKENS and AUTH_TOKENS['DJFS'] is not None: DJFS = AUTH_TOKENS['DJFS'] ############### Module Store Items ########## HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS = ENV_TOKENS.get('HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS', {}) # PREVIEW DOMAIN must be present in HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS for the preview to show draft changes if 'PREVIEW_LMS_BASE' in FEATURES and FEATURES['PREVIEW_LMS_BASE'] != '': PREVIEW_DOMAIN = FEATURES['PREVIEW_LMS_BASE'].split(':')[0] # update dictionary with preview domain regex HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS.update({ PREVIEW_DOMAIN: 'draft-preferred' }) MODULESTORE_FIELD_OVERRIDE_PROVIDERS = ENV_TOKENS.get( 'MODULESTORE_FIELD_OVERRIDE_PROVIDERS', MODULESTORE_FIELD_OVERRIDE_PROVIDERS ) XBLOCK_FIELD_DATA_WRAPPERS = ENV_TOKENS.get( 'XBLOCK_FIELD_DATA_WRAPPERS', XBLOCK_FIELD_DATA_WRAPPERS ) ############### Mixed Related(Secure/Not-Secure) Items ########## LMS_SEGMENT_KEY = AUTH_TOKENS.get('SEGMENT_KEY') SECRET_KEY = AUTH_TOKENS['SECRET_KEY'] AWS_ACCESS_KEY_ID = AUTH_TOKENS["AWS_ACCESS_KEY_ID"] if AWS_ACCESS_KEY_ID == "": AWS_ACCESS_KEY_ID = None AWS_SECRET_ACCESS_KEY = AUTH_TOKENS["AWS_SECRET_ACCESS_KEY"] if AWS_SECRET_ACCESS_KEY == "": AWS_SECRET_ACCESS_KEY = None AWS_STORAGE_BUCKET_NAME = AUTH_TOKENS.get('AWS_STORAGE_BUCKET_NAME', 'edxuploads') # Disabling querystring auth instructs Boto to exclude the querystring parameters (e.g. signature, access key) it # normally appends to every returned URL. AWS_QUERYSTRING_AUTH = AUTH_TOKENS.get('AWS_QUERYSTRING_AUTH', True) AWS_S3_CUSTOM_DOMAIN = AUTH_TOKENS.get('AWS_S3_CUSTOM_DOMAIN', 'edxuploads.s3.amazonaws.com') if AUTH_TOKENS.get('DEFAULT_FILE_STORAGE'): DEFAULT_FILE_STORAGE = AUTH_TOKENS.get('DEFAULT_FILE_STORAGE') elif AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY: DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' else: DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' # If there is a database called 'read_replica', you can use the use_read_replica_if_available # function in util/query.py, which is useful for very large database reads DATABASES = AUTH_TOKENS['DATABASES'] # The normal database user does not have enough permissions to run migrations. # Migrations are run with separate credentials, given as DB_MIGRATION_* # environment variables for name, database in DATABASES.items(): if name != 'read_replica': database.update({ 'ENGINE': os.environ.get('DB_MIGRATION_ENGINE', database['ENGINE']), 'USER': os.environ.get('DB_MIGRATION_USER', database['USER']), 'PASSWORD': os.environ.get('DB_MIGRATION_PASS', database['PASSWORD']), 'NAME': os.environ.get('DB_MIGRATION_NAME', database['NAME']), 'HOST': os.environ.get('DB_MIGRATION_HOST', database['HOST']), 'PORT': os.environ.get('DB_MIGRATION_PORT', database['PORT']), }) XQUEUE_INTERFACE = AUTH_TOKENS['XQUEUE_INTERFACE'] # Get the MODULESTORE from auth.json, but if it doesn't exist, # use the one from common.py MODULESTORE = convert_module_store_setting_if_needed(AUTH_TOKENS.get('MODULESTORE', MODULESTORE)) MONGODB_LOG = AUTH_TOKENS.get('MONGODB_LOG', {}) EMAIL_HOST_USER = AUTH_TOKENS.get('EMAIL_HOST_USER', '') # django default is '' ############################### BLOCKSTORE ##################################### BLOCKSTORE_API_URL = ENV_TOKENS.get('BLOCKSTORE_API_URL', None) # e.g. "https://blockstore.example.com/api/v1/" # Configure an API auth token at (blockstore URL)/admin/authtoken/token/ BLOCKSTORE_API_AUTH_TOKEN = AUTH_TOKENS.get('BLOCKSTORE_API_AUTH_TOKEN', None) # Datadog for events! DATADOG = AUTH_TOKENS.get("DATADOG", {}) DATADOG.update(ENV_TOKENS.get("DATADOG", {})) # TODO: deprecated (compatibility with previous settings) if 'DATADOG_API' in AUTH_TOKENS: DATADOG['api_key'] = AUTH_TOKENS['DATADOG_API'] # Analytics API ANALYTICS_API_KEY = AUTH_TOKENS.get("ANALYTICS_API_KEY", ANALYTICS_API_KEY) ANALYTICS_API_URL = ENV_TOKENS.get("ANALYTICS_API_URL", ANALYTICS_API_URL) # Zendesk ZENDESK_USER = AUTH_TOKENS.get("ZENDESK_USER") ZENDESK_API_KEY = AUTH_TOKENS.get("ZENDESK_API_KEY") # API Key for inbound requests from Notifier service EDX_API_KEY = AUTH_TOKENS.get("EDX_API_KEY") # Celery Broker CELERY_BROKER_TRANSPORT = ENV_TOKENS.get("CELERY_BROKER_TRANSPORT", "") CELERY_BROKER_HOSTNAME = ENV_TOKENS.get("CELERY_BROKER_HOSTNAME", "") CELERY_BROKER_VHOST = ENV_TOKENS.get("CELERY_BROKER_VHOST", "") CELERY_BROKER_USER = AUTH_TOKENS.get("CELERY_BROKER_USER", "") CELERY_BROKER_PASSWORD = AUTH_TOKENS.get("CELERY_BROKER_PASSWORD", "") BROKER_URL = "{}://{}:{}@{}/{}".format(CELERY_BROKER_TRANSPORT, CELERY_BROKER_USER, CELERY_BROKER_PASSWORD, CELERY_BROKER_HOSTNAME, CELERY_BROKER_VHOST) BROKER_USE_SSL = ENV_TOKENS.get('CELERY_BROKER_USE_SSL', False) BROKER_TRANSPORT_OPTIONS = { 'fanout_patterns': True, 'fanout_prefix': True, } # Block Structures # upload limits STUDENT_FILEUPLOAD_MAX_SIZE = ENV_TOKENS.get("STUDENT_FILEUPLOAD_MAX_SIZE", STUDENT_FILEUPLOAD_MAX_SIZE) # Event tracking TRACKING_BACKENDS.update(AUTH_TOKENS.get("TRACKING_BACKENDS", {})) EVENT_TRACKING_BACKENDS['tracking_logs']['OPTIONS']['backends'].update(AUTH_TOKENS.get("EVENT_TRACKING_BACKENDS", {})) EVENT_TRACKING_BACKENDS['segmentio']['OPTIONS']['processors'][0]['OPTIONS']['whitelist'].extend( AUTH_TOKENS.get("EVENT_TRACKING_SEGMENTIO_EMIT_WHITELIST", [])) TRACKING_SEGMENTIO_WEBHOOK_SECRET = AUTH_TOKENS.get( "TRACKING_SEGMENTIO_WEBHOOK_SECRET", TRACKING_SEGMENTIO_WEBHOOK_SECRET ) TRACKING_SEGMENTIO_ALLOWED_TYPES = ENV_TOKENS.get("TRACKING_SEGMENTIO_ALLOWED_TYPES", TRACKING_SEGMENTIO_ALLOWED_TYPES) TRACKING_SEGMENTIO_DISALLOWED_SUBSTRING_NAMES = ENV_TOKENS.get( "TRACKING_SEGMENTIO_DISALLOWED_SUBSTRING_NAMES", TRACKING_SEGMENTIO_DISALLOWED_SUBSTRING_NAMES ) TRACKING_SEGMENTIO_SOURCE_MAP = ENV_TOKENS.get("TRACKING_SEGMENTIO_SOURCE_MAP", TRACKING_SEGMENTIO_SOURCE_MAP) # Heartbeat HEARTBEAT_CELERY_ROUTING_KEY = ENV_TOKENS.get('HEARTBEAT_CELERY_ROUTING_KEY', HEARTBEAT_CELERY_ROUTING_KEY) # Student identity verification settings VERIFY_STUDENT = AUTH_TOKENS.get("VERIFY_STUDENT", VERIFY_STUDENT) DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH = ENV_TOKENS.get( "DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH", DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH ) # Grades download GRADES_DOWNLOAD_ROUTING_KEY = ENV_TOKENS.get('GRADES_DOWNLOAD_ROUTING_KEY', HIGH_MEM_QUEUE) GRADES_DOWNLOAD = ENV_TOKENS.get("GRADES_DOWNLOAD", GRADES_DOWNLOAD) # Rate limit for regrading tasks that a grading policy change can kick off # financial reports FINANCIAL_REPORTS = ENV_TOKENS.get("FINANCIAL_REPORTS", FINANCIAL_REPORTS) ##### ORA2 ###### # Prefix for uploads of example-based assessment AI classifiers # This can be used to separate uploads for different environments # within the same S3 bucket. ORA2_FILE_PREFIX = ENV_TOKENS.get("ORA2_FILE_PREFIX", ORA2_FILE_PREFIX) ##### ACCOUNT LOCKOUT DEFAULT PARAMETERS ##### MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED = ENV_TOKENS.get( "MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED", MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED ) MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS = ENV_TOKENS.get( "MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS", MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS ) ##### LOGISTRATION RATE LIMIT SETTINGS ##### LOGISTRATION_RATELIMIT_RATE = ENV_TOKENS.get('LOGISTRATION_RATELIMIT_RATE', LOGISTRATION_RATELIMIT_RATE) LOGISTRATION_API_RATELIMIT = ENV_TOKENS.get('LOGISTRATION_API_RATELIMIT', LOGISTRATION_API_RATELIMIT) RESET_PASSWORD_TOKEN_VALIDATE_API_RATELIMIT = ENV_TOKENS.get( 'RESET_PASSWORD_TOKEN_VALIDATE_API_RATELIMIT', RESET_PASSWORD_TOKEN_VALIDATE_API_RATELIMIT ) RESET_PASSWORD_API_RATELIMIT = ENV_TOKENS.get('RESET_PASSWORD_API_RATELIMIT', RESET_PASSWORD_API_RATELIMIT) ##### REGISTRATION RATE LIMIT SETTINGS ##### REGISTRATION_VALIDATION_RATELIMIT = ENV_TOKENS.get( 'REGISTRATION_VALIDATION_RATELIMIT', REGISTRATION_VALIDATION_RATELIMIT ) REGISTRATION_RATELIMIT = ENV_TOKENS.get('REGISTRATION_RATELIMIT', REGISTRATION_RATELIMIT) #### PASSWORD POLICY SETTINGS ##### AUTH_PASSWORD_VALIDATORS = ENV_TOKENS.get("AUTH_PASSWORD_VALIDATORS", AUTH_PASSWORD_VALIDATORS) ### INACTIVITY SETTINGS #### SESSION_INACTIVITY_TIMEOUT_IN_SECONDS = AUTH_TOKENS.get("SESSION_INACTIVITY_TIMEOUT_IN_SECONDS") ##### LMS DEADLINE DISPLAY TIME_ZONE ####### TIME_ZONE_DISPLAYED_FOR_DEADLINES = ENV_TOKENS.get("TIME_ZONE_DISPLAYED_FOR_DEADLINES", TIME_ZONE_DISPLAYED_FOR_DEADLINES) ##### Third-party auth options ################################################ ENABLE_REQUIRE_THIRD_PARTY_AUTH = ENV_TOKENS.get('ENABLE_REQUIRE_THIRD_PARTY_AUTH', False) if FEATURES.get('ENABLE_THIRD_PARTY_AUTH'): tmp_backends = ENV_TOKENS.get('THIRD_PARTY_AUTH_BACKENDS', [ 'social_core.backends.google.GoogleOAuth2', 'social_core.backends.linkedin.LinkedinOAuth2', 'social_core.backends.facebook.FacebookOAuth2', 'social_core.backends.azuread.AzureADOAuth2', 'common.djangoapps.third_party_auth.appleid.AppleIdAuth', # vendored 'social_core.backends.apple.AppleIdAuth' 'common.djangoapps.third_party_auth.identityserver3.IdentityServer3', 'common.djangoapps.third_party_auth.saml.SAMLAuthBackend', 'common.djangoapps.third_party_auth.lti.LTIAuthBackend', ]) AUTHENTICATION_BACKENDS = list(tmp_backends) + list(AUTHENTICATION_BACKENDS) del tmp_backends # The reduced session expiry time during the third party login pipeline. (Value in seconds) SOCIAL_AUTH_PIPELINE_TIMEOUT = ENV_TOKENS.get('SOCIAL_AUTH_PIPELINE_TIMEOUT', 600) # Most provider configuration is done via ConfigurationModels but for a few sensitive values # we allow configuration via AUTH_TOKENS instead (optionally). # The SAML private/public key values do not need the delimiter lines (such as # "-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----" etc.) but they may be included # if you want (though it's easier to format the key values as JSON without the delimiters). SOCIAL_AUTH_SAML_SP_PRIVATE_KEY = AUTH_TOKENS.get('SOCIAL_AUTH_SAML_SP_PRIVATE_KEY', '') SOCIAL_AUTH_SAML_SP_PUBLIC_CERT = AUTH_TOKENS.get('SOCIAL_AUTH_SAML_SP_PUBLIC_CERT', '') SOCIAL_AUTH_SAML_SP_PRIVATE_KEY_DICT = AUTH_TOKENS.get('SOCIAL_AUTH_SAML_SP_PRIVATE_KEY_DICT', {}) SOCIAL_AUTH_SAML_SP_PUBLIC_CERT_DICT = AUTH_TOKENS.get('SOCIAL_AUTH_SAML_SP_PUBLIC_CERT_DICT', {}) SOCIAL_AUTH_OAUTH_SECRETS = AUTH_TOKENS.get('SOCIAL_AUTH_OAUTH_SECRETS', {}) SOCIAL_AUTH_LTI_CONSUMER_SECRETS = AUTH_TOKENS.get('SOCIAL_AUTH_LTI_CONSUMER_SECRETS', {}) # third_party_auth config moved to ConfigurationModels. This is for data migration only: THIRD_PARTY_AUTH_OLD_CONFIG = AUTH_TOKENS.get('THIRD_PARTY_AUTH', None) if ENV_TOKENS.get('THIRD_PARTY_AUTH_SAML_FETCH_PERIOD_HOURS', 24) is not None: CELERYBEAT_SCHEDULE['refresh-saml-metadata'] = { 'task': 'common.djangoapps.third_party_auth.fetch_saml_metadata', 'schedule': datetime.timedelta(hours=ENV_TOKENS.get('THIRD_PARTY_AUTH_SAML_FETCH_PERIOD_HOURS', 24)), } # The following can be used to integrate a custom login form with third_party_auth. # It should be a dict where the key is a word passed via ?auth_entry=, and the value is a # dict with an arbitrary 'secret_key' and a 'url'. THIRD_PARTY_AUTH_CUSTOM_AUTH_FORMS = AUTH_TOKENS.get('THIRD_PARTY_AUTH_CUSTOM_AUTH_FORMS', {}) ##### OAUTH2 Provider ############## if FEATURES.get('ENABLE_OAUTH2_PROVIDER'): OAUTH_ENFORCE_SECURE = ENV_TOKENS.get('OAUTH_ENFORCE_SECURE', True) OAUTH_ENFORCE_CLIENT_SECURE = ENV_TOKENS.get('OAUTH_ENFORCE_CLIENT_SECURE', True) # Defaults for the following are defined in lms.envs.common OAUTH_EXPIRE_DELTA = datetime.timedelta( days=ENV_TOKENS.get('OAUTH_EXPIRE_CONFIDENTIAL_CLIENT_DAYS', OAUTH_EXPIRE_CONFIDENTIAL_CLIENT_DAYS) ) OAUTH_EXPIRE_DELTA_PUBLIC = datetime.timedelta( days=ENV_TOKENS.get('OAUTH_EXPIRE_PUBLIC_CLIENT_DAYS', OAUTH_EXPIRE_PUBLIC_CLIENT_DAYS) ) ##### GOOGLE ANALYTICS IDS ##### GOOGLE_ANALYTICS_ACCOUNT = AUTH_TOKENS.get('GOOGLE_ANALYTICS_ACCOUNT') GOOGLE_ANALYTICS_TRACKING_ID = AUTH_TOKENS.get('GOOGLE_ANALYTICS_TRACKING_ID') GOOGLE_ANALYTICS_LINKEDIN = AUTH_TOKENS.get('GOOGLE_ANALYTICS_LINKEDIN') GOOGLE_SITE_VERIFICATION_ID = ENV_TOKENS.get('GOOGLE_SITE_VERIFICATION_ID') ##### BRANCH.IO KEY ##### BRANCH_IO_KEY = AUTH_TOKENS.get('BRANCH_IO_KEY') #### Course Registration Code length #### REGISTRATION_CODE_LENGTH = ENV_TOKENS.get('REGISTRATION_CODE_LENGTH', 8) # Which access.py permission names to check; # We default this to the legacy permission 'see_exists'. COURSE_CATALOG_VISIBILITY_PERMISSION = ENV_TOKENS.get( 'COURSE_CATALOG_VISIBILITY_PERMISSION', COURSE_CATALOG_VISIBILITY_PERMISSION ) COURSE_ABOUT_VISIBILITY_PERMISSION = ENV_TOKENS.get( 'COURSE_ABOUT_VISIBILITY_PERMISSION', COURSE_ABOUT_VISIBILITY_PERMISSION ) DEFAULT_COURSE_VISIBILITY_IN_CATALOG = ENV_TOKENS.get( 'DEFAULT_COURSE_VISIBILITY_IN_CATALOG', DEFAULT_COURSE_VISIBILITY_IN_CATALOG ) DEFAULT_MOBILE_AVAILABLE = ENV_TOKENS.get( 'DEFAULT_MOBILE_AVAILABLE', DEFAULT_MOBILE_AVAILABLE ) # Enrollment API Cache Timeout ENROLLMENT_COURSE_DETAILS_CACHE_TIMEOUT = ENV_TOKENS.get('ENROLLMENT_COURSE_DETAILS_CACHE_TIMEOUT', 60) if FEATURES.get('ENABLE_COURSEWARE_SEARCH') or \ FEATURES.get('ENABLE_DASHBOARD_SEARCH') or \ FEATURES.get('ENABLE_COURSE_DISCOVERY') or \ FEATURES.get('ENABLE_TEAMS'): # Use ElasticSearch as the search engine herein SEARCH_ENGINE = "search.elastic.ElasticSearchEngine" SEARCH_FILTER_GENERATOR = ENV_TOKENS.get('SEARCH_FILTER_GENERATOR', SEARCH_FILTER_GENERATOR) # TODO: Once we have successfully upgraded to ES7, switch this back to ELASTIC_SEARCH_CONFIG. ELASTIC_SEARCH_CONFIG = ENV_TOKENS.get('ELASTIC_SEARCH_CONFIG_ES7', [{}]) # Facebook app FACEBOOK_API_VERSION = AUTH_TOKENS.get("FACEBOOK_API_VERSION") FACEBOOK_APP_SECRET = AUTH_TOKENS.get("FACEBOOK_APP_SECRET") FACEBOOK_APP_ID = AUTH_TOKENS.get("FACEBOOK_APP_ID") XBLOCK_SETTINGS = ENV_TOKENS.get('XBLOCK_SETTINGS', {}) XBLOCK_SETTINGS.setdefault("VideoBlock", {})["licensing_enabled"] = FEATURES.get("LICENSING", False) XBLOCK_SETTINGS.setdefault("VideoBlock", {})['YOUTUBE_API_KEY'] = AUTH_TOKENS.get('YOUTUBE_API_KEY', YOUTUBE_API_KEY) ##### Custom Courses for EdX ##### if FEATURES.get('CUSTOM_COURSES_EDX'): INSTALLED_APPS += ['lms.djangoapps.ccx', 'openedx.core.djangoapps.ccxcon.apps.CCXConnectorConfig'] MODULESTORE_FIELD_OVERRIDE_PROVIDERS += ( 'lms.djangoapps.ccx.overrides.CustomCoursesForEdxOverrideProvider', ) ##### Individual Due Date Extensions ##### if FEATURES.get('INDIVIDUAL_DUE_DATES'): FIELD_OVERRIDE_PROVIDERS += ( 'courseware.student_field_overrides.IndividualStudentOverrideProvider', ) ##### Show Answer Override for Self-Paced Courses ##### FIELD_OVERRIDE_PROVIDERS += ( 'openedx.features.personalized_learner_schedules.show_answer.show_answer_field_override.ShowAnswerFieldOverride', ) ##### Self-Paced Course Due Dates ##### XBLOCK_FIELD_DATA_WRAPPERS += ( 'lms.djangoapps.courseware.field_overrides:OverrideModulestoreFieldData.wrap', ) MODULESTORE_FIELD_OVERRIDE_PROVIDERS += ( 'lms.djangoapps.courseware.self_paced_overrides.SelfPacedDateOverrideProvider', ) # PROFILE IMAGE CONFIG PROFILE_IMAGE_DEFAULT_FILENAME = 'images/profiles/default' PROFILE_IMAGE_SIZES_MAP = ENV_TOKENS.get( 'PROFILE_IMAGE_SIZES_MAP', PROFILE_IMAGE_SIZES_MAP ) ##### Credit Provider Integration ##### CREDIT_PROVIDER_SECRET_KEYS = AUTH_TOKENS.get("CREDIT_PROVIDER_SECRET_KEYS", {}) ##################### LTI Provider ##################### if FEATURES.get('ENABLE_LTI_PROVIDER'): INSTALLED_APPS.append('lms.djangoapps.lti_provider.apps.LtiProviderConfig') AUTHENTICATION_BACKENDS.append('lms.djangoapps.lti_provider.users.LtiBackend') LTI_USER_EMAIL_DOMAIN = ENV_TOKENS.get('LTI_USER_EMAIL_DOMAIN', 'lti.example.com') # For more info on this, see the notes in common.py LTI_AGGREGATE_SCORE_PASSBACK_DELAY = ENV_TOKENS.get( 'LTI_AGGREGATE_SCORE_PASSBACK_DELAY', LTI_AGGREGATE_SCORE_PASSBACK_DELAY ) ##################### Credit Provider help link #################### #### JWT configuration #### JWT_AUTH.update(ENV_TOKENS.get('JWT_AUTH', {})) JWT_AUTH.update(AUTH_TOKENS.get('JWT_AUTH', {})) # Offset for pk of courseware.StudentModuleHistoryExtended STUDENTMODULEHISTORYEXTENDED_OFFSET = ENV_TOKENS.get( 'STUDENTMODULEHISTORYEXTENDED_OFFSET', STUDENTMODULEHISTORYEXTENDED_OFFSET ) # Cutoff date for granting audit certificates if ENV_TOKENS.get('AUDIT_CERT_CUTOFF_DATE', None): AUDIT_CERT_CUTOFF_DATE = dateutil.parser.parse(ENV_TOKENS.get('AUDIT_CERT_CUTOFF_DATE')) ################################ Settings for Credentials Service ################################ CREDENTIALS_GENERATION_ROUTING_KEY = ENV_TOKENS.get('CREDENTIALS_GENERATION_ROUTING_KEY', DEFAULT_PRIORITY_QUEUE) # Queue to use for award program certificates PROGRAM_CERTIFICATES_ROUTING_KEY = ENV_TOKENS.get('PROGRAM_CERTIFICATES_ROUTING_KEY', DEFAULT_PRIORITY_QUEUE) SOFTWARE_SECURE_VERIFICATION_ROUTING_KEY = ENV_TOKENS.get( 'SOFTWARE_SECURE_VERIFICATION_ROUTING_KEY', HIGH_PRIORITY_QUEUE ) API_ACCESS_MANAGER_EMAIL = ENV_TOKENS.get('API_ACCESS_MANAGER_EMAIL') API_ACCESS_FROM_EMAIL = ENV_TOKENS.get('API_ACCESS_FROM_EMAIL') ############## OPEN EDX ENTERPRISE SERVICE CONFIGURATION ###################### # The Open edX Enterprise service is currently hosted via the LMS container/process. # However, for all intents and purposes this service is treated as a standalone IDA. # These configuration settings are specific to the Enterprise service and you should # not find references to them within the edx-platform project. # Publicly-accessible enrollment URL, for use on the client side. ENTERPRISE_PUBLIC_ENROLLMENT_API_URL = ENV_TOKENS.get( 'ENTERPRISE_PUBLIC_ENROLLMENT_API_URL', (LMS_ROOT_URL or '') + LMS_ENROLLMENT_API_PATH ) # Enrollment URL used on the server-side. ENTERPRISE_ENROLLMENT_API_URL = ENV_TOKENS.get( 'ENTERPRISE_ENROLLMENT_API_URL', (LMS_INTERNAL_ROOT_URL or '') + LMS_ENROLLMENT_API_PATH ) # Enterprise logo image size limit in KB's ENTERPRISE_CUSTOMER_LOGO_IMAGE_SIZE = ENV_TOKENS.get( 'ENTERPRISE_CUSTOMER_LOGO_IMAGE_SIZE', ENTERPRISE_CUSTOMER_LOGO_IMAGE_SIZE ) # Course enrollment modes to be hidden in the Enterprise enrollment page # if the "Hide audit track" flag is enabled for an EnterpriseCustomer ENTERPRISE_COURSE_ENROLLMENT_AUDIT_MODES = ENV_TOKENS.get( 'ENTERPRISE_COURSE_ENROLLMENT_AUDIT_MODES', ENTERPRISE_COURSE_ENROLLMENT_AUDIT_MODES ) # A support URL used on Enterprise landing pages for when a warning # message goes off. ENTERPRISE_SUPPORT_URL = ENV_TOKENS.get( 'ENTERPRISE_SUPPORT_URL', ENTERPRISE_SUPPORT_URL ) # A default dictionary to be used for filtering out enterprise customer catalog. ENTERPRISE_CUSTOMER_CATALOG_DEFAULT_CONTENT_FILTER = ENV_TOKENS.get( 'ENTERPRISE_CUSTOMER_CATALOG_DEFAULT_CONTENT_FILTER', ENTERPRISE_CUSTOMER_CATALOG_DEFAULT_CONTENT_FILTER ) INTEGRATED_CHANNELS_API_CHUNK_TRANSMISSION_LIMIT = ENV_TOKENS.get( 'INTEGRATED_CHANNELS_API_CHUNK_TRANSMISSION_LIMIT', INTEGRATED_CHANNELS_API_CHUNK_TRANSMISSION_LIMIT ) ############## ENTERPRISE SERVICE API CLIENT CONFIGURATION ###################### # The LMS communicates with the Enterprise service via the EdxRestApiClient class # The below environmental settings are utilized by the LMS when interacting with # the service, and override the default parameters which are defined in common.py DEFAULT_ENTERPRISE_API_URL = None if LMS_INTERNAL_ROOT_URL is not None: DEFAULT_ENTERPRISE_API_URL = LMS_INTERNAL_ROOT_URL + '/enterprise/api/v1/' ENTERPRISE_API_URL = ENV_TOKENS.get('ENTERPRISE_API_URL', DEFAULT_ENTERPRISE_API_URL) DEFAULT_ENTERPRISE_CONSENT_API_URL = None if LMS_INTERNAL_ROOT_URL is not None: DEFAULT_ENTERPRISE_CONSENT_API_URL = LMS_INTERNAL_ROOT_URL + '/consent/api/v1/' ENTERPRISE_CONSENT_API_URL = ENV_TOKENS.get('ENTERPRISE_CONSENT_API_URL', DEFAULT_ENTERPRISE_CONSENT_API_URL) ENTERPRISE_SERVICE_WORKER_USERNAME = ENV_TOKENS.get( 'ENTERPRISE_SERVICE_WORKER_USERNAME', ENTERPRISE_SERVICE_WORKER_USERNAME ) ENTERPRISE_API_CACHE_TIMEOUT = ENV_TOKENS.get( 'ENTERPRISE_API_CACHE_TIMEOUT', ENTERPRISE_API_CACHE_TIMEOUT ) ENTERPRISE_CATALOG_INTERNAL_ROOT_URL = ENV_TOKENS.get( 'ENTERPRISE_CATALOG_INTERNAL_ROOT_URL', ENTERPRISE_CATALOG_INTERNAL_ROOT_URL ) ############## ENTERPRISE SERVICE LMS CONFIGURATION ################################## # The LMS has some features embedded that are related to the Enterprise service, but # which are not provided by the Enterprise service. These settings override the # base values for the parameters as defined in common.py ENTERPRISE_PLATFORM_WELCOME_TEMPLATE = ENV_TOKENS.get( 'ENTERPRISE_PLATFORM_WELCOME_TEMPLATE', ENTERPRISE_PLATFORM_WELCOME_TEMPLATE ) ENTERPRISE_SPECIFIC_BRANDED_WELCOME_TEMPLATE = ENV_TOKENS.get( 'ENTERPRISE_SPECIFIC_BRANDED_WELCOME_TEMPLATE', ENTERPRISE_SPECIFIC_BRANDED_WELCOME_TEMPLATE ) ENTERPRISE_TAGLINE = ENV_TOKENS.get( 'ENTERPRISE_TAGLINE', ENTERPRISE_TAGLINE ) ENTERPRISE_EXCLUDED_REGISTRATION_FIELDS = set( ENV_TOKENS.get( 'ENTERPRISE_EXCLUDED_REGISTRATION_FIELDS', ENTERPRISE_EXCLUDED_REGISTRATION_FIELDS ) ) BASE_COOKIE_DOMAIN = ENV_TOKENS.get( 'BASE_COOKIE_DOMAIN', BASE_COOKIE_DOMAIN ) SYSTEM_TO_FEATURE_ROLE_MAPPING = ENV_TOKENS.get( 'SYSTEM_TO_FEATURE_ROLE_MAPPING', SYSTEM_TO_FEATURE_ROLE_MAPPING ) # Add an ICP license for serving content in China if your organization is registered to do so ICP_LICENSE = ENV_TOKENS.get('ICP_LICENSE', None) ICP_LICENSE_INFO = ENV_TOKENS.get('ICP_LICENSE_INFO', {}) ############## Settings for CourseGraph ############################ COURSEGRAPH_JOB_QUEUE = ENV_TOKENS.get('COURSEGRAPH_JOB_QUEUE', DEFAULT_PRIORITY_QUEUE) # How long to cache OpenAPI schemas and UI, in seconds. OPENAPI_CACHE_TIMEOUT = ENV_TOKENS.get('OPENAPI_CACHE_TIMEOUT', 60 * 60) ########################## 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 = ENV_TOKENS.get( 'PARENTAL_CONSENT_AGE_LIMIT', PARENTAL_CONSENT_AGE_LIMIT ) ########################## Extra middleware classes ####################### # Allow extra middleware classes to be added to the app through configuration. MIDDLEWARE.extend(ENV_TOKENS.get('EXTRA_MIDDLEWARE_CLASSES', [])) ################# Settings for the maintenance banner ################# MAINTENANCE_BANNER_TEXT = ENV_TOKENS.get('MAINTENANCE_BANNER_TEXT', None) ########################## limiting dashboard courses ###################### DASHBOARD_COURSE_LIMIT = ENV_TOKENS.get('DASHBOARD_COURSE_LIMIT', None) ######################## Setting for content libraries ######################## MAX_BLOCKS_PER_CONTENT_LIBRARY = ENV_TOKENS.get('MAX_BLOCKS_PER_CONTENT_LIBRARY', MAX_BLOCKS_PER_CONTENT_LIBRARY) ############################### Plugin Settings ############################### # This is at the bottom because it is going to load more settings after base settings are loaded # Load production.py in plugins add_plugins(__name__, ProjectType.LMS, SettingsType.PRODUCTION) ########################## Derive Any Derived Settings ####################### derive_settings(__name__) ############## Settings for Completion API ######################### # Once a user has watched this percentage of a video, mark it as complete: # (0.0 = 0%, 1.0 = 100%) COMPLETION_VIDEO_COMPLETE_PERCENTAGE = ENV_TOKENS.get('COMPLETION_VIDEO_COMPLETE_PERCENTAGE', COMPLETION_VIDEO_COMPLETE_PERCENTAGE) COMPLETION_BY_VIEWING_DELAY_MS = ENV_TOKENS.get('COMPLETION_BY_VIEWING_DELAY_MS', COMPLETION_BY_VIEWING_DELAY_MS) ################# Settings for brand logos. ################# LOGO_URL = ENV_TOKENS.get('LOGO_URL', LOGO_URL) LOGO_URL_PNG = ENV_TOKENS.get('LOGO_URL_PNG', LOGO_URL_PNG) LOGO_TRADEMARK_URL = ENV_TOKENS.get('LOGO_TRADEMARK_URL', LOGO_TRADEMARK_URL) FAVICON_URL = ENV_TOKENS.get('FAVICON_URL', FAVICON_URL) ######################## CELERY ROUTING ######################## # Defines alternate environment tasks, as a dict of form { task_name: alternate_queue } ALTERNATE_ENV_TASKS = {} # Defines the task -> alternate worker queue to be used when routing. EXPLICIT_QUEUES = { 'openedx.core.djangoapps.content.course_overviews.tasks.async_course_overview_update': { 'queue': GRADES_DOWNLOAD_ROUTING_KEY}, 'lms.djangoapps.bulk_email.tasks.send_course_email': { 'queue': BULK_EMAIL_ROUTING_KEY}, 'openedx.core.djangoapps.heartbeat.tasks.sample_task': { 'queue': HEARTBEAT_CELERY_ROUTING_KEY}, 'lms.djangoapps.instructor_task.tasks.calculate_grades_csv': { 'queue': GRADES_DOWNLOAD_ROUTING_KEY}, 'lms.djangoapps.instructor_task.tasks.calculate_problem_grade_report': { 'queue': GRADES_DOWNLOAD_ROUTING_KEY}, 'lms.djangoapps.instructor_task.tasks.generate_certificates': { 'queue': GRADES_DOWNLOAD_ROUTING_KEY}, 'lms.djangoapps.email_marketing.tasks.get_email_cookies_via_sailthru': { 'queue': ACE_ROUTING_KEY}, 'lms.djangoapps.email_marketing.tasks.update_user': { 'queue': ACE_ROUTING_KEY}, 'lms.djangoapps.email_marketing.tasks.update_user_email': { 'queue': ACE_ROUTING_KEY}, 'lms.djangoapps.email_marketing.tasks.update_course_enrollment': { 'queue': ACE_ROUTING_KEY}, 'lms.djangoapps.verify_student.tasks.send_verification_status_email': { 'queue': ACE_ROUTING_KEY}, 'lms.djangoapps.verify_student.tasks.send_ace_message': { 'queue': ACE_ROUTING_KEY}, 'lms.djangoapps.verify_student.tasks.send_request_to_ss_for_user': { 'queue': SOFTWARE_SECURE_VERIFICATION_ROUTING_KEY}, 'openedx.core.djangoapps.schedules.tasks._recurring_nudge_schedule_send': { 'queue': ACE_ROUTING_KEY}, 'openedx.core.djangoapps.schedules.tasks._upgrade_reminder_schedule_send': { 'queue': ACE_ROUTING_KEY}, 'openedx.core.djangoapps.schedules.tasks._course_update_schedule_send': { 'queue': ACE_ROUTING_KEY}, 'openedx.core.djangoapps.schedules.tasks.v1.tasks.send_grade_to_credentials': { 'queue': CREDENTIALS_GENERATION_ROUTING_KEY}, 'common.djangoapps.entitlements.tasks.expire_old_entitlements': { 'queue': ENTITLEMENTS_EXPIRATION_ROUTING_KEY}, 'lms.djangoapps.grades.tasks.recalculate_course_and_subsection_grades_for_user': { 'queue': POLICY_CHANGE_GRADES_ROUTING_KEY}, 'lms.djangoapps.grades.tasks.recalculate_subsection_grade_v3': { 'queue': RECALCULATE_GRADES_ROUTING_KEY}, 'openedx.core.djangoapps.programs.tasks.v1.tasks.award_program_certificates': { 'queue': PROGRAM_CERTIFICATES_ROUTING_KEY}, 'openedx.core.djangoapps.programs.tasks.v1.tasks.revoke_program_certificates': { 'queue': PROGRAM_CERTIFICATES_ROUTING_KEY}, 'openedx.core.djangoapps.programs.tasks.v1.tasks.update_certificate_visible_date_on_course_update': { 'queue': PROGRAM_CERTIFICATES_ROUTING_KEY}, 'openedx.core.djangoapps.programs.tasks.v1.tasks.award_course_certificate': { 'queue': PROGRAM_CERTIFICATES_ROUTING_KEY}, 'openedx.core.djangoapps.coursegraph.dump_course_to_neo4j': { 'queue': COURSEGRAPH_JOB_QUEUE}, } LOGO_IMAGE_EXTRA_TEXT = ENV_TOKENS.get('LOGO_IMAGE_EXTRA_TEXT', '') ############## XBlock extra mixins ############################ XBLOCK_MIXINS += tuple(XBLOCK_EXTRA_MIXINS) ################# Settings for Chrome-specific origin trials ######## # Token for "Disable Different Origin Subframe Dialog Suppression" Chrome Origin Trial, which must be origin-specific. CHROME_DISABLE_SUBFRAME_DIALOG_SUPPRESSION_TOKEN = ENV_TOKENS.get( 'CHROME_DISABLE_SUBFRAME_DIALOG_SUPPRESSION_TOKEN', CHROME_DISABLE_SUBFRAME_DIALOG_SUPPRESSION_TOKEN )
अंतर खोजें