From 0c2ae7e28b230c76a4f0458917ad24e042492718 Mon Sep 17 00:00:00 2001 From: subhashree-sahu31 Date: Fri, 20 Feb 2026 15:23:22 +0530 Subject: [PATCH] feat: added enterprise theming changes (#139) * feat: added enterprise theming changes * fix: fixed newline breaking changes * fix: removed the whitespace (cherry picked from commit a681c1f67661374469420542643ff82ea49e34c2) --- .../core/djangoapps/user_authn/serializers.py | 10 ++++ .../core/djangoapps/user_authn/views/utils.py | 17 +++++++ openedx/features/enterprise_support/api.py | 10 ++++ openedx/features/enterprise_support/utils.py | 51 +++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/openedx/core/djangoapps/user_authn/serializers.py b/openedx/core/djangoapps/user_authn/serializers.py index c088b7eda7db..ac41d263e91d 100644 --- a/openedx/core/djangoapps/user_authn/serializers.py +++ b/openedx/core/djangoapps/user_authn/serializers.py @@ -32,6 +32,16 @@ class PipelineUserDetailsSerializer(serializers.Serializer): lastName = serializers.CharField(source='last_name', allow_null=True) +class EnterpriseBrandingSerializer(serializers.Serializer): + """Serializer for enterprise branding data.""" + + enterpriseName = serializers.CharField(allow_null=True, required=False) + enterpriseLogoUrl = serializers.CharField(allow_null=True, required=False) + enterpriseBrandedWelcomeString = serializers.CharField(allow_null=True, required=False) + enterpriseSlug = serializers.CharField(allow_null=True, required=False) + platformWelcomeString = serializers.CharField(allow_null=True, required=False) + + class ContextDataSerializer(serializers.Serializer): """ Context Data Serializers diff --git a/openedx/core/djangoapps/user_authn/views/utils.py b/openedx/core/djangoapps/user_authn/views/utils.py index 4d852114e2a6..1fc4a1dd97b5 100644 --- a/openedx/core/djangoapps/user_authn/views/utils.py +++ b/openedx/core/djangoapps/user_authn/views/utils.py @@ -122,12 +122,29 @@ def get_mfe_context(request, redirect_to, tpa_hint=None): """ Returns Authn MFE context. """ + # Import enterprise functions INSIDE the function to avoid circular import + from openedx.features.enterprise_support.api import enterprise_customer_for_request + from openedx.features.enterprise_support.utils import get_enterprise_sidebar_context ip_address = get_client_ip(request)[0] country_code = country_code_from_ip(ip_address) context = third_party_auth_context(request, redirect_to, tpa_hint) + # Add enterprise branding if enterprise customer is detected + enterprise_customer = enterprise_customer_for_request(request) + enterprise_branding = None + if enterprise_customer: + sidebar_context = get_enterprise_sidebar_context(enterprise_customer, is_proxy_login=False) + if sidebar_context: + enterprise_branding = { + 'enterpriseName': sidebar_context.get('enterprise_name'), + 'enterpriseLogoUrl': sidebar_context.get('enterprise_logo_url'), + 'enterpriseBrandedWelcomeString': str(sidebar_context.get('enterprise_branded_welcome_string', '')), + 'platformWelcomeString': str(sidebar_context.get('platform_welcome_string', '')), + 'enterpriseSlug': sidebar_context.get('enterprise_slug') or enterprise_customer.get('slug'), + } context.update({ 'countryCode': country_code, + 'enterpriseBranding': enterprise_branding, # Add enterprise branding to context }) return context diff --git a/openedx/features/enterprise_support/api.py b/openedx/features/enterprise_support/api.py index 4b6a16435fd3..c6bd91fd7644 100644 --- a/openedx/features/enterprise_support/api.py +++ b/openedx/features/enterprise_support/api.py @@ -298,6 +298,16 @@ def get_enterprise_customer(self, uuid): return enterprise_customer +def fetch_enterprise_branding(self, enterprise_customer_uuid): + """ + Fetch branding configuration for the given enterprise customer UUID. + """ + branding_url = f"{self.base_api_url}/enterprise-customer-branding/{enterprise_customer_uuid}/" + response = self.client.get(branding_url) + response.raise_for_status() + return response.json() + + def activate_learner_enterprise(request, user, enterprise_customer): """ Allow an enterprise learner to activate one of learner's linked enterprises. diff --git a/openedx/features/enterprise_support/utils.py b/openedx/features/enterprise_support/utils.py index cc6402e60492..a2f5b0153080 100644 --- a/openedx/features/enterprise_support/utils.py +++ b/openedx/features/enterprise_support/utils.py @@ -21,9 +21,12 @@ from common.djangoapps import third_party_auth from common.djangoapps.student.helpers import get_next_url_for_login_page from lms.djangoapps.branding.api import get_privacy_url +from openedx.core.djangoapps.geoinfo.api import country_code_from_ip from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers from openedx.core.djangoapps.user_authn.cookies import standard_cookie_settings from openedx.core.djangolib.markup import HTML, Text +from openedx.core.djangoapps.user_authn.views.utils import third_party_auth_context +from ipware import get_client_ip ENTERPRISE_HEADER_LINKS = WaffleFlag('enterprise.enterprise_header_links', __name__) # pylint: disable=toggle-missing-annotation @@ -144,6 +147,7 @@ def get_enterprise_sidebar_context(enterprise_customer, is_proxy_login): 'enterprise_name': enterprise_customer['name'], 'enterprise_logo_url': logo_url, 'enterprise_branded_welcome_string': branded_welcome_string, + 'enterprise_slug': enterprise_customer.get('slug'), 'platform_welcome_string': platform_welcome_string, } @@ -488,3 +492,50 @@ def is_course_accessed(user, course_id): return True except UnavailableCompletionData: return False + + +def get_enterprise_dashboard_url(request, enterprise_customer): + """ + Generate the enterprise-specific dashboard URL. + """ + base_url = settings.ENTERPRISE_LEARNER_PORTAL_BASE_URL + return f"{base_url}/{enterprise_customer['slug']}" + + +def get_mfe_context(request, redirect_to, tpa_hint=None): + """ + Returns Authn MFE context. + """ + # Import enterprise functions INSIDE the function to avoid circular import + from openedx.features.enterprise_support.api import enterprise_customer_for_request + + ip_address = get_client_ip(request)[0] + country_code = country_code_from_ip(ip_address) + context = third_party_auth_context(request, redirect_to, tpa_hint) + + enterprise_customer = enterprise_customer_for_request(request) + enterprise_branding = None + + if enterprise_customer: + sidebar_context = get_enterprise_sidebar_context( + enterprise_customer, + is_proxy_login=False + ) + if sidebar_context: + enterprise_branding = { + 'enterpriseName': sidebar_context.get('enterprise_name'), + 'enterpriseLogoUrl': sidebar_context.get('enterprise_logo_url'), + 'enterpriseBrandedWelcomeString': str( + sidebar_context.get('enterprise_branded_welcome_string', '') + ), + 'platformWelcomeString': str( + sidebar_context.get('platform_welcome_string', '') + ), + } + + context.update({ + 'countryCode': country_code, + 'enterpriseBranding': enterprise_branding, + }) + + return context