From 1bec83447fcacc966e2a12c1b0acbf77294577fb Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Mon, 24 Aug 2026 11:20:53 -0400 Subject: [PATCH 1/2] feat!: remove the ENABLE_MFE_CONFIG_API toggle The LMS setting ENABLE_MFE_CONFIG_API (default False) gated two read-only endpoints used by frontends: GET /api/mfe_config/v1 GET /api/frontend_site_config/v1/ Both return only non-sensitive frontend configuration, and both are empty unless an operator populates MFE_CONFIG, MFE_CONFIG_OVERRIDES, or FRONTEND_SITE_CONFIG. There was no reason to keep them off by default, so the toggle is gone and both endpoints now respond unconditionally. The data settings (MFE_CONFIG, MFE_CONFIG_OVERRIDES, FRONTEND_SITE_CONFIG) are unchanged and remain how operators control what these endpoints return. The toggle was LMS-only; there was no CMS equivalent. Removes: - the toggle definition and annotation in lms/envs/common.py - the `if not settings.ENABLE_MFE_CONFIG_API` guards in MFEConfigView.get and FrontendSiteConfigView.get, plus the HttpResponseNotFound / NotFound imports they were the only users of - the ENABLE_MFE_CONFIG_API overrides in lms/envs/test.py and lms/envs/mock.yml - the two "returns 404 when disabled" tests, which no longer describe any reachable behaviour See DEPR ticket: https://github.com/openedx/openedx-platform/issues/38959 BREAKING CHANGE: Operators who set ENABLE_MFE_CONFIG_API in their LMS_CFG yaml or a private settings module should drop the line; the key is now ignored. If you set it to True, deleting it is all that is needed -- that is the new default. If you set it to False *and* populated MFE_CONFIG, MFE_CONFIG_OVERRIDES, or FRONTEND_SITE_CONFIG, that configuration is now served publicly by the two endpoints above; review or clear it if it should not be public. Co-Authored-By: Claude Opus 5 (1M context) --- .../mfe_config_api/tests/test_views.py | 19 ------------------- lms/djangoapps/mfe_config_api/views.py | 9 +-------- lms/envs/common.py | 12 ------------ lms/envs/mock.yml | 1 - lms/envs/test.py | 1 - 5 files changed, 1 insertion(+), 41 deletions(-) diff --git a/lms/djangoapps/mfe_config_api/tests/test_views.py b/lms/djangoapps/mfe_config_api/tests/test_views.py index 8b508544acc8..2d0020d58b10 100644 --- a/lms/djangoapps/mfe_config_api/tests/test_views.py +++ b/lms/djangoapps/mfe_config_api/tests/test_views.py @@ -182,19 +182,6 @@ def test_get_mfe_config_with_queryparam_from_django_settings(self): expected = default_legacy_config | settings.MFE_CONFIG | settings.MFE_CONFIG_OVERRIDES["mymfe"] self.assertEqual(response.json(), expected) # noqa: PT009 - @patch("lms.djangoapps.mfe_config_api.views.configuration_helpers") - @override_settings(ENABLE_MFE_CONFIG_API=False) - def test_404_get_mfe_config(self, configuration_helpers_mock): - """Test the 404 not found response from get mfe config. - - Expected result: - - The get_value method of configuration_helpers is not called. - - The status of the response of the request is a HTTP_404_NOT_FOUND. - """ - response = self.client.get(self.mfe_config_api_url) - configuration_helpers_mock.get_value.assert_not_called() - self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) # noqa: PT009 - @patch("lms.djangoapps.mfe_config_api.views.configuration_helpers") def test_get_mfe_config_for_catalog(self, configuration_helpers_mock): """Test the mfe config by explicitly using catalog mfe as an example. @@ -488,12 +475,6 @@ def setUp(self): cache.clear() return super().setUp() - @override_settings(ENABLE_MFE_CONFIG_API=False) - def test_404_when_disabled(self): - """API returns 404 when ENABLE_MFE_CONFIG_API is False.""" - response = self.client.get(self.url) - self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) # noqa: PT009 - @patch("lms.djangoapps.mfe_config_api.views.configuration_helpers") def test_site_level_keys_translated(self, configuration_helpers_mock): """Keys that map to RequiredSiteConfig/OptionalSiteConfig appear at the top level in camelCase.""" diff --git a/lms/djangoapps/mfe_config_api/views.py b/lms/djangoapps/mfe_config_api/views.py index 647751730619..eb98b224ed8e 100644 --- a/lms/djangoapps/mfe_config_api/views.py +++ b/lms/djangoapps/mfe_config_api/views.py @@ -6,12 +6,11 @@ import edx_api_doc_tools as apidocs from django.conf import settings -from django.http import HttpResponseNotFound, JsonResponse +from django.http import JsonResponse from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_page from help_tokens.core import HelpUrlExpert from rest_framework import status -from rest_framework.exceptions import NotFound from rest_framework.permissions import AllowAny from rest_framework.response import Response from rest_framework.views import APIView @@ -299,9 +298,6 @@ def get(self, request): ``` """ - if not settings.ENABLE_MFE_CONFIG_API: - return HttpResponseNotFound() - mfe_name = ( str(request.query_params.get("mfe")) if request.query_params.get("mfe") @@ -438,9 +434,6 @@ def get(self, request): } ``` """ - if not settings.ENABLE_MFE_CONFIG_API: - raise NotFound() - # Legacy translation (removable once MFE_CONFIG is deprecated). site_config = translate_legacy_mfe_config() diff --git a/lms/envs/common.py b/lms/envs/common.py index e8a185c1d49c..431a83328263 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -3066,18 +3066,6 @@ FINANCIAL_ASSISTANCE_APPLICATION_STATUS_URL = "/core/api/financial_assistance_application/status/" CREATE_FINANCIAL_ASSISTANCE_APPLICATION_URL = '/core/api/financial_assistance_applications' -# .. toggle_name: ENABLE_MFE_CONFIG_API -# .. toggle_implementation: DjangoSetting -# .. toggle_default: False -# .. toggle_description: Set to True to enable MFE Config API. This is disabled by -# default. -# .. toggle_use_cases: open_edx -# .. toggle_creation_date: 2022-05-20 -# .. toggle_target_removal_date: None -# .. toggle_warnings: None -# .. toggle_tickets: None -ENABLE_MFE_CONFIG_API = False - # .. setting_name: MFE_CONFIG # .. setting_implementation: DjangoSetting # .. setting_default: {} diff --git a/lms/envs/mock.yml b/lms/envs/mock.yml index 47edb551cc16..3c52f27e0209 100644 --- a/lms/envs/mock.yml +++ b/lms/envs/mock.yml @@ -449,7 +449,6 @@ ENABLE_AUTHN_RESET_PASSWORD_HIBP_POLICY: true ENABLE_COMPREHENSIVE_THEMING: true ENABLE_COPPA_COMPLIANCE: true ENABLE_DYNAMIC_REGISTRATION_FIELDS: true -ENABLE_MFE_CONFIG_API: true ENTERPRISE_ADMIN_PORTAL_BASE_URL: hello ENTERPRISE_ADMIN_PORTAL_HOSTNAME: hello ENTERPRISE_ALL_SERVICE_USERNAMES: diff --git a/lms/envs/test.py b/lms/envs/test.py index d9f529e86938..392acc992302 100644 --- a/lms/envs/test.py +++ b/lms/envs/test.py @@ -400,7 +400,6 @@ CORS_ORIGIN_WHITELIST = ['https://sandbox.edx.org'] ################## MFE API #################### -ENABLE_MFE_CONFIG_API = True MFE_CONFIG = { "BASE_URL": "https://name_of_mfe.example.com", "LANGUAGE_PREFERENCE_COOKIE_NAME": "example-language-preference", From 616e94a1351ecb74b06247818231bad424d39840 Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Mon, 24 Aug 2026 11:21:01 -0400 Subject: [PATCH 2/2] docs: record the ENABLE_MFE_CONFIG_API removal in ADR 0001 ADR 0001 recorded the decision to gate the MFE config API behind ENABLE_MFE_CONFIG_API. That decision has been reversed, so replace the bullet with the current state -- the API is always available -- while keeping the history and linking the DEPR ticket that removed the toggle. See DEPR ticket: https://github.com/openedx/openedx-platform/issues/38959 Co-Authored-By: Claude Opus 5 (1M context) --- .../mfe_config_api/docs/decisions/0001-mfe-config-api.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lms/djangoapps/mfe_config_api/docs/decisions/0001-mfe-config-api.rst b/lms/djangoapps/mfe_config_api/docs/decisions/0001-mfe-config-api.rst index 8e298991186d..9760f698ec19 100644 --- a/lms/djangoapps/mfe_config_api/docs/decisions/0001-mfe-config-api.rst +++ b/lms/djangoapps/mfe_config_api/docs/decisions/0001-mfe-config-api.rst @@ -16,7 +16,11 @@ Decision ******** - A lightweight API will be created that returns the mfe configuration variables from the site configuration or django settings. `PR Discussion about django settings`_ -- The API will be enabled or disabled using the setting ``ENABLE_MFE_CONFIG_API``. +- The API will always be available. It was originally gated behind an + ``ENABLE_MFE_CONFIG_API`` toggle that defaulted to ``False``; that toggle was + removed by the `DEPR ticket for ENABLE_MFE_CONFIG_API`_ because the API only exposes + non-sensitive frontend configuration and returns nothing that an operator has + not explicitly configured. - The API will take the mfe configuration in the ``MFE_CONFIG`` keyset in the site configuration (admin > site configuration > your domain) or in django settings. - This API allows to consult the configurations by specific MFE. Making a request like ``/api/mfe_config/v1?mfe=mymfe`` will return the configuration defined in ``MFE_CONFIG_OVERRIDES["mymfe"]`` merged with the ``MFE_CONFIG`` configuration. - The API will have a mechanism to cache the response with ``MFE_CONFIG_API_CACHE_TIMEOUT`` variable. @@ -70,3 +74,5 @@ References .. _Issue MFE runtime configuration in frontend-wg: https://github.com/openedx/frontend-wg/issues/103 .. _PR Discussion about django settings: https://github.com/openedx/edx-platform/pull/30473#discussion_r916263245 + +.. _DEPR ticket for ENABLE_MFE_CONFIG_API: https://github.com/openedx/openedx-platform/issues/38959