####### Settings common to LMS and CMS import json import os from xmodule.modulestore.modulestore_settings import update_module_store_settings # Mongodb connection parameters: simply modify `mongodb_parameters` to affect all connections to MongoDb. mongodb_parameters = { "db": "{{ MONGODB_DATABASE }}", "host": "{{ MONGODB_HOST }}", "port": {{ MONGODB_PORT }}, "user": {% if MONGODB_USERNAME %}"{{ MONGODB_USERNAME }}"{% else %}None{% endif %}, "password": {% if MONGODB_PASSWORD %}"{{ MONGODB_PASSWORD }}"{% else %}None{% endif %}, # Connection/Authentication "connect": False, "ssl": {{ MONGODB_USE_SSL }}, "authsource": "{{ MONGODB_AUTH_SOURCE }}", "replicaSet": {% if MONGODB_REPLICA_SET %}"{{ MONGODB_REPLICA_SET }}"{% else %}None{% endif %}, {% if MONGODB_AUTH_MECHANISM %}"authMechanism": "{{ MONGODB_AUTH_MECHANISM }}",{% endif %} } DOC_STORE_CONFIG = mongodb_parameters CONTENTSTORE = { "ENGINE": "xmodule.contentstore.mongo.MongoContentStore", "ADDITIONAL_OPTIONS": {}, "DOC_STORE_CONFIG": DOC_STORE_CONFIG } # Load module store settings from config files update_module_store_settings(MODULESTORE, doc_store_settings=DOC_STORE_CONFIG) DATA_DIR = "/openedx/data/modulestore" for store in MODULESTORE["default"]["OPTIONS"]["stores"]: store["OPTIONS"]["fs_root"] = DATA_DIR # Behave like memcache when it comes to connection errors DJANGO_REDIS_IGNORE_EXCEPTIONS = True # Elasticsearch connection parameters ELASTIC_SEARCH_CONFIG = [{ {% if ELASTICSEARCH_SCHEME == "https" %}"use_ssl": True,{% endif %} "host": "{{ ELASTICSEARCH_HOST }}", "port": {{ ELASTICSEARCH_PORT }}, }] # Common cache config CACHES = { "default": { "KEY_PREFIX": "default", "VERSION": "1", "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://{% if REDIS_USERNAME and REDIS_PASSWORD %}{{ REDIS_USERNAME }}:{{ REDIS_PASSWORD }}{% endif %}@{{ REDIS_HOST }}:{{ REDIS_PORT }}/{{ OPENEDX_CACHE_REDIS_DB }}", }, "general": { "KEY_PREFIX": "general", "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://{% if REDIS_USERNAME and REDIS_PASSWORD %}{{ REDIS_USERNAME }}:{{ REDIS_PASSWORD }}{% endif %}@{{ REDIS_HOST }}:{{ REDIS_PORT }}/{{ OPENEDX_CACHE_REDIS_DB }}", }, "mongo_metadata_inheritance": { "KEY_PREFIX": "mongo_metadata_inheritance", "TIMEOUT": 300, "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://{% if REDIS_USERNAME and REDIS_PASSWORD %}{{ REDIS_USERNAME }}:{{ REDIS_PASSWORD }}{% endif %}@{{ REDIS_HOST }}:{{ REDIS_PORT }}/{{ OPENEDX_CACHE_REDIS_DB }}", }, "configuration": { "KEY_PREFIX": "configuration", "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://{% if REDIS_USERNAME and REDIS_PASSWORD %}{{ REDIS_USERNAME }}:{{ REDIS_PASSWORD }}{% endif %}@{{ REDIS_HOST }}:{{ REDIS_PORT }}/{{ OPENEDX_CACHE_REDIS_DB }}", }, "celery": { "KEY_PREFIX": "celery", "TIMEOUT": 7200, "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://{% if REDIS_USERNAME and REDIS_PASSWORD %}{{ REDIS_USERNAME }}:{{ REDIS_PASSWORD }}{% endif %}@{{ REDIS_HOST }}:{{ REDIS_PORT }}/{{ OPENEDX_CACHE_REDIS_DB }}", }, "course_structure_cache": { "KEY_PREFIX": "course_structure", "TIMEOUT": 7200, "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://{% if REDIS_USERNAME and REDIS_PASSWORD %}{{ REDIS_USERNAME }}:{{ REDIS_PASSWORD }}{% endif %}@{{ REDIS_HOST }}:{{ REDIS_PORT }}/{{ OPENEDX_CACHE_REDIS_DB }}", }, "ora2-storage": { "KEY_PREFIX": "ora2-storage", "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://{% if REDIS_USERNAME and REDIS_PASSWORD %}{{ REDIS_USERNAME }}:{{ REDIS_PASSWORD }}{% endif %}@{{ REDIS_HOST }}:{{ REDIS_PORT }}/{{ OPENEDX_CACHE_REDIS_DB }}", } } # The default Django contrib site is the one associated to the LMS domain name. 1 is # usually "example.com", so it's the next available integer. SITE_ID = 2 # Contact addresses CONTACT_MAILING_ADDRESS = "{{ PLATFORM_NAME }} - {% if ENABLE_HTTPS %}https{% else %}http{% endif %}://{{ LMS_HOST }}" DEFAULT_FROM_EMAIL = ENV_TOKENS.get("DEFAULT_FROM_EMAIL", ENV_TOKENS["CONTACT_EMAIL"]) DEFAULT_FEEDBACK_EMAIL = ENV_TOKENS.get("DEFAULT_FEEDBACK_EMAIL", ENV_TOKENS["CONTACT_EMAIL"]) SERVER_EMAIL = ENV_TOKENS.get("SERVER_EMAIL", ENV_TOKENS["CONTACT_EMAIL"]) TECH_SUPPORT_EMAIL = ENV_TOKENS.get("TECH_SUPPORT_EMAIL", ENV_TOKENS["CONTACT_EMAIL"]) CONTACT_EMAIL = ENV_TOKENS.get("CONTACT_EMAIL", ENV_TOKENS["CONTACT_EMAIL"]) BUGS_EMAIL = ENV_TOKENS.get("BUGS_EMAIL", ENV_TOKENS["CONTACT_EMAIL"]) UNIVERSITY_EMAIL = ENV_TOKENS.get("UNIVERSITY_EMAIL", ENV_TOKENS["CONTACT_EMAIL"]) PRESS_EMAIL = ENV_TOKENS.get("PRESS_EMAIL", ENV_TOKENS["CONTACT_EMAIL"]) PAYMENT_SUPPORT_EMAIL = ENV_TOKENS.get("PAYMENT_SUPPORT_EMAIL", ENV_TOKENS["CONTACT_EMAIL"]) BULK_EMAIL_DEFAULT_FROM_EMAIL = ENV_TOKENS.get("BULK_EMAIL_DEFAULT_FROM_EMAIL", ENV_TOKENS["CONTACT_EMAIL"]) API_ACCESS_MANAGER_EMAIL = ENV_TOKENS.get("API_ACCESS_MANAGER_EMAIL", ENV_TOKENS["CONTACT_EMAIL"]) API_ACCESS_FROM_EMAIL = ENV_TOKENS.get("API_ACCESS_FROM_EMAIL", ENV_TOKENS["CONTACT_EMAIL"]) # Get rid completely of coursewarehistoryextended, as we do not use the CSMH database INSTALLED_APPS.remove("lms.djangoapps.coursewarehistoryextended") DATABASE_ROUTERS.remove( "openedx.core.lib.django_courseware_routers.StudentModuleHistoryExtendedRouter" ) # Set uploaded media file path MEDIA_ROOT = "/openedx/media/" # Video settings VIDEO_IMAGE_SETTINGS["STORAGE_KWARGS"]["location"] = MEDIA_ROOT VIDEO_TRANSCRIPTS_SETTINGS["STORAGE_KWARGS"]["location"] = MEDIA_ROOT GRADES_DOWNLOAD = { "STORAGE_TYPE": "", "STORAGE_KWARGS": { "base_url": "/media/grades/", "location": "/openedx/media/grades", }, } # ORA2 ORA2_FILEUPLOAD_BACKEND = "filesystem" ORA2_FILEUPLOAD_ROOT = "/openedx/data/ora2" FILE_UPLOAD_STORAGE_BUCKET_NAME = "openedxuploads" ORA2_FILEUPLOAD_CACHE_NAME = "ora2-storage" # Change syslog-based loggers which don't work inside docker containers LOGGING["handlers"]["local"] = { "class": "logging.handlers.WatchedFileHandler", "filename": os.path.join(LOG_DIR, "all.log"), "formatter": "standard", } LOGGING["handlers"]["tracking"] = { "level": "DEBUG", "class": "logging.handlers.WatchedFileHandler", "filename": os.path.join(LOG_DIR, "tracking.log"), "formatter": "standard", } LOGGING["loggers"]["tracking"]["handlers"] = ["console", "local", "tracking"] # Silence some loggers (note: we must attempt to get rid of these when upgrading from one release to the next) LOGGING["loggers"]["blockstore.apps.bundles.storage"] = {"handlers": ["console"], "level": "WARNING"} # These warnings are visible in simple commands and init tasks import warnings from django.utils.deprecation import RemovedInDjango40Warning, RemovedInDjango41Warning warnings.filterwarnings("ignore", category=RemovedInDjango40Warning) warnings.filterwarnings("ignore", category=RemovedInDjango41Warning) warnings.filterwarnings("ignore", category=DeprecationWarning, module="wiki.plugins.links.wiki_plugin") warnings.filterwarnings("ignore", category=DeprecationWarning, module="boto.plugin") warnings.filterwarnings("ignore", category=DeprecationWarning, module="botocore.vendored.requests.packages.urllib3._collections") warnings.filterwarnings("ignore", category=DeprecationWarning, module="pkg_resources") warnings.filterwarnings("ignore", category=DeprecationWarning, module="fs") warnings.filterwarnings("ignore", category=DeprecationWarning, module="fs.opener") SILENCED_SYSTEM_CHECKS = ["2_0.W001", "fields.W903"] # Email EMAIL_USE_SSL = {{ SMTP_USE_SSL }} # Forward all emails from edX's Automated Communication Engine (ACE) to django. ACE_ENABLED_CHANNELS = ["django_email"] ACE_CHANNEL_DEFAULT_EMAIL = "django_email" ACE_CHANNEL_TRANSACTIONAL_EMAIL = "django_email" EMAIL_FILE_PATH = "/tmp/openedx/emails" # Language/locales LOCALE_PATHS.append("/openedx/locale/contrib/locale") LOCALE_PATHS.append("/openedx/locale/user/locale") LANGUAGE_COOKIE_NAME = "openedx-language-preference" # Allow the platform to include itself in an iframe X_FRAME_OPTIONS = "SAMEORIGIN" {% set jwt_rsa_key | rsa_import_key %}{{ JWT_RSA_PRIVATE_KEY }}{% endset %} JWT_AUTH["JWT_ISSUER"] = "{{ JWT_COMMON_ISSUER }}" JWT_AUTH["JWT_AUDIENCE"] = "{{ JWT_COMMON_AUDIENCE }}" JWT_AUTH["JWT_SECRET_KEY"] = "{{ JWT_COMMON_SECRET_KEY }}" JWT_AUTH["JWT_PRIVATE_SIGNING_JWK"] = json.dumps( { "kid": "openedx", "kty": "RSA", "e": "{{ jwt_rsa_key.e|long_to_base64 }}", "d": "{{ jwt_rsa_key.d|long_to_base64 }}", "n": "{{ jwt_rsa_key.n|long_to_base64 }}", "p": "{{ jwt_rsa_key.p|long_to_base64 }}", "q": "{{ jwt_rsa_key.q|long_to_base64 }}", "dq": "{{ jwt_rsa_key.dq|long_to_base64 }}", "dp": "{{ jwt_rsa_key.dp|long_to_base64 }}", "qi": "{{ jwt_rsa_key.invq|long_to_base64 }}", } ) JWT_AUTH["JWT_PUBLIC_SIGNING_JWK_SET"] = json.dumps( { "keys": [ { "kid": "openedx", "kty": "RSA", "e": "{{ jwt_rsa_key.e|long_to_base64 }}", "n": "{{ jwt_rsa_key.n|long_to_base64 }}", } ] } ) JWT_AUTH["JWT_ISSUERS"] = [ { "ISSUER": "{{ JWT_COMMON_ISSUER }}", "AUDIENCE": "{{ JWT_COMMON_AUDIENCE }}", "SECRET_KEY": "{{ OPENEDX_SECRET_KEY }}" } ] # Enable/Disable some features globally FEATURES["ENABLE_DISCUSSION_SERVICE"] = False FEATURES["PREVENT_CONCURRENT_LOGINS"] = False FEATURES["ENABLE_CORS_HEADERS"] = True # CORS CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_ALLOW_ALL = False CORS_ALLOW_INSECURE = {% if ENABLE_HTTPS %}False{% else %}True{% endif %} CORS_ALLOW_HEADERS = corsheaders_default_headers + ('use-jwt-cookie',) # Add your MFE and third-party app domains here CORS_ORIGIN_WHITELIST = [] # Disable codejail support # explicitely configuring python is necessary to prevent unsafe calls import codejail.jail_code codejail.jail_code.configure("python", "nonexistingpythonbinary", user=None) # another configuration entry is required to override prod/dev settings CODE_JAIL = { "python_bin": "nonexistingpythonbinary", "user": None, } {{ patch("openedx-common-settings") }} ######## End of settings common to LMS and CMS