Skip to content

feat: replace enterprise logistration logic with openedx-filters hooks - #407

Open
pwnage101 wants to merge 1 commit into
release-ulmofrom
pwnage101/ENT-11568-edx
Open

feat: replace enterprise logistration logic with openedx-filters hooks#407
pwnage101 wants to merge 1 commit into
release-ulmofrom
pwnage101/ENT-11568-edx

Conversation

@pwnage101

@pwnage101 pwnage101 commented Jul 28, 2026

Copy link
Copy Markdown
Member

Copilot AI lite review requested due to automatic review settings July 28, 2026 21:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes enterprise-specific logic from the user_authn logistration/login/registration flow and replaces it with Open edX Filters hooks so downstream plugins can customize behavior without importing enterprise_support.

Changes:

  • Removed enterprise-specific redirect and context/cookie logic from legacy logistration and post-login redirect handling.
  • Introduced/used six generic Open edX Filters hook points for logistration context/response, MFE redirect veto, post-login redirect, and TPA form overrides.
  • Updated and expanded test coverage to validate the new filter hook behavior and removed enterprise-specific test cases.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
openedx/core/djangoapps/user_authn/views/utils.py Removes enterprise URL regex constants that are no longer needed.
openedx/core/djangoapps/user_authn/views/login_form.py Replaces enterprise logistration branching with filter hooks (context, response, MFE redirect veto, login-form TPA overrides).
openedx/core/djangoapps/user_authn/views/registration_form.py Adds registration-form TPA override filter hook and returns the modified form_desc.
openedx/core/djangoapps/user_authn/views/login.py Replaces enterprise multi-enterprise redirect logic with a post-login redirect filter hook.
openedx/core/djangoapps/user_authn/views/tests/test_logistration.py Removes enterprise-specific logistration assertions and related SAML/enterprise tests.
openedx/core/djangoapps/user_authn/views/tests/test_login.py Removes enterprise multi-enterprise redirect tests tied to the deleted logic.
openedx/core/djangoapps/user_authn/views/tests/test_filters.py Adds new filter tests for logistration/login/registration/post-login redirect hooks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread openedx/core/djangoapps/user_authn/views/tests/test_filters.py
Comment thread openedx/core/djangoapps/user_authn/views/login_form.py Outdated
Comment thread openedx/core/djangoapps/user_authn/views/login.py Outdated
Copilot AI review requested due to automatic review settings July 28, 2026 21:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

openedx/core/djangoapps/user_authn/views/login_form.py:225

  • The PR description lists a new LogistrationMFERedirectRequested hook, but the logistration view still redirects to the Authn MFE directly when should_redirect_to_authn_microfrontend() is true (no filter invocation or tests for that hook). Either wire in the LogistrationMFERedirectRequested filter at this decision point (so plugins can override/suppress the redirect), or update the PR description to reflect the actual set of filters implemented.
    # Redirect to the authn MFE when it is enabled, unless auth is provided externally
    # (SAML/TPA users must remain on the legacy login/registration page).
    has_external_provider = bool(tpa_hint_provider or saml_provider)

    if should_redirect_to_authn_microfrontend() and not has_external_provider:
        query_params = request.GET.urlencode()
        url_path = '/{}{}'.format(
            initial_mode,
            '?' + query_params if query_params else ''
        )
        return redirect(settings.AUTHN_MICROFRONTEND_URL + url_path)

openedx/core/djangoapps/user_authn/views/utils.py:25

  • The PR description says this change “remov[es] all enterprise_support imports”, but this file still imports enterprise_support in get_mfe_context() (openedx/core/djangoapps/user_authn/views/utils.py:117-118). If the intent is only to remove enterprise logic from the legacy logistration views, the PR description should be narrowed; otherwise these remaining imports should be removed/refactored as well.
API_V1 = 'v1'

Comment thread openedx/core/djangoapps/user_authn/config/waffle.py
Copilot AI review requested due to automatic review settings July 29, 2026 19:54
@pwnage101
pwnage101 force-pushed the pwnage101/ENT-11568-edx branch from 3858d01 to c50f851 Compare July 29, 2026 19:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

openedx/core/djangoapps/user_authn/views/tests/test_filters.py:3

  • Docstring typo: “vies” should be “views”.
"""
Test that various filters are fired for the vies in the user_authn app.
"""

Copilot AI review requested due to automatic review settings August 4, 2026 21:05
@pwnage101
pwnage101 force-pushed the pwnage101/ENT-11568-edx branch from c50f851 to 979ef58 Compare August 4, 2026 21:05

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (2)

openedx/core/djangoapps/user_authn/views/login.py:625

  • LoginAltRedirectURLRequested is passed the same value for both redirect_url and next_url. When third_party_auth_requested is true, finish_auth_url may be non-empty while next_url still represents the user’s intended destination; passing finish_auth_url as next_url can prevent filter implementations from making decisions based on the real next URL.
            alt_redirect_url, __, __ = LoginAltRedirectURLRequested.run_filter(
                redirect_url=finish_auth_url or next_url,
                user=possibly_authenticated_user,
                next_url=finish_auth_url or next_url,
            )

openedx/core/djangoapps/user_authn/serializers.py:74

  • Merging extra_context into the serialized output with dict.update() allows plugin-provided keys to overwrite declared serializer fields (e.g., platformName, countryCode). That undermines the serializer’s control of the response schema and can cause hard-to-debug collisions.
        representation = super().to_representation(instance)
        representation.update(instance.get('extra_context') or {})
        return representation

Copilot AI review requested due to automatic review settings August 4, 2026 22:18
@pwnage101
pwnage101 force-pushed the pwnage101/ENT-11568-edx branch from 979ef58 to a9d783d Compare August 4, 2026 22:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (3)

openedx/core/djangoapps/user_authn/views/tests/test_filters.py:2

  • Typo in module docstring: "vies" should be "views".
Test that various filters are fired for the vies in the user_authn app.

openedx/core/djangoapps/user_authn/serializers.py:74

  • extra_context is merged into the serialized payload with representation.update(...), which allows plugin-provided keys to overwrite declared/validated fields (e.g., platformName, providers) and can also raise if extra_context is not a dict. It’s safer to only merge non-colliding keys and ignore/guard invalid types so the serializer retains control of its declared fields.
        representation = super().to_representation(instance)
        representation.update(instance.get('extra_context') or {})
        return representation

openedx/core/djangoapps/user_authn/views/login_form.py:20

  • The PR description says logistration logic is replaced with 5 filters named LogistrationContextRequested, LoginFormTPAOverridesRequested, RegistrationFormTPAOverridesRequested, LogistrationResponseRendered, and PostLoginRedirectURLRequested, but this change set introduces/uses different filter names/types (e.g., LoginFormGenerated, LogistrationViewContextGenerated, LogistrationViewRenderCompleted, LoginAltRedirectURLRequested, AuthnMFEContextGenerated). Please align the PR description (and any referenced integration/testing instructions) with the actual filter contract being implemented, or rename the filters here if the listed names are the intended public API.
from openedx_filters.authentication.filters import (
    LoginFormGenerated,
    LogistrationViewContextGenerated,
    LogistrationViewRenderCompleted,
)

Copilot AI review requested due to automatic review settings August 5, 2026 00:37
@pwnage101
pwnage101 force-pushed the pwnage101/ENT-11568-edx branch from a9d783d to 42cb4a3 Compare August 5, 2026 00:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Suppressed comments (3)

openedx/core/djangoapps/user_authn/views/tests/test_filters.py:3

  • Typo in module docstring: “vies” → “views”.
"""
Test that various filters are fired for the vies in the user_authn app.
"""

openedx/core/djangoapps/user_authn/serializers.py:74

  • to_representation merges extra_context via dict.update, which will overwrite declared fields if a plugin uses a colliding key (and can also raise if extra_context is not a mapping). If the intent is to add plugin-provided keys alongside declared fields, avoid overwriting existing keys and guard for non-dict values.
        representation = super().to_representation(instance)
        representation.update(instance.get('extra_context') or {})
        return representation

openedx/core/djangoapps/user_authn/views/login_form.py:20

  • PR description lists 5 filter hooks with different names (e.g., LogistrationContextRequested, PostLoginRedirectURLRequested), but this change introduces/uses a different set of filters (e.g., LoginFormGenerated, LogistrationViewContextGenerated, LoginAltRedirectURLRequested, AuthnMFEContextGenerated) and appears to add 6 hooks. Please align the PR description (and any linked acceptance criteria) with the actual filter types/names implemented here to avoid confusion for integrators.
from openedx_filters.authentication.filters import (
    LoginFormGenerated,
    LogistrationViewContextGenerated,
    LogistrationViewRenderCompleted,
)

Comment thread openedx/core/djangoapps/user_authn/views/login.py Outdated
Copilot AI review requested due to automatic review settings August 5, 2026 01:23
@pwnage101
pwnage101 force-pushed the pwnage101/ENT-11568-edx branch from 42cb4a3 to 3882714 Compare August 5, 2026 01:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

Suppressed comments (3)

openedx/core/djangoapps/user_authn/views/tests/test_filters.py:3

  • Typo in the module docstring: “vies” should be “views”.
"""
Test that various filters are fired for the vies in the user_authn app.
"""

openedx/core/djangoapps/user_authn/serializers.py:74

  • ContextDataSerializer.to_representation blindly merges extra_context into the serialized output, which can accidentally (or intentionally) overwrite declared fields (e.g., platformName, countryCode) and bypass the serializer’s shape/validation guarantees. Since declared fields are already overridable by modifying context before serialization, extra_context should only add new keys (or explicitly guard against collisions).
    def to_representation(self, instance):
        """
        Serialize the declared fields, then merge in the context's ``extra_context`` entries.

        ``extra_context`` holds entries contributed by plugins, which this serializer cannot
        declare fields for. They are merged as-is: the contributor owns their shape, and no
        coercion is applied.
        """
        representation = super().to_representation(instance)
        representation.update(instance.get('extra_context') or {})
        return representation

openedx/core/djangoapps/user_authn/views/utils.py:129

  • The docstring for get_running_third_party_auth_state says “Both are None … when the provider … could not be determined”, but the implementation returns the running pipeline even if Registry.get_from_pipeline(...) returns None. Either update the behavior to match the docstring, or (preferably) update the docstring/return description to reflect that running_pipeline may be non-None when current_provider is None.
    Returns:
        tuple[dict, ProviderConfig]: the running pipeline and its provider. Both are None
        when third party auth is disabled, when no pipeline is running for the request, or
        when the provider of the running pipeline could not be determined.
    """

Copilot AI review requested due to automatic review settings August 7, 2026 00:22
@pwnage101
pwnage101 force-pushed the pwnage101/ENT-11568-edx branch from 3882714 to 3687447 Compare August 7, 2026 00:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

Suppressed comments (4)

openedx/core/djangoapps/user_authn/serializers.py:74

  • ContextDataSerializer.to_representation merges extra_context via dict.update(), which allows plugin-provided keys to overwrite declared serializer fields (e.g., platformName, countryCode). This contradicts the docstring (“entries the serializer cannot declare fields for”) and can unexpectedly change the response shape/values.
        representation = super().to_representation(instance)
        representation.update(instance.get('extra_context') or {})
        return representation

openedx/core/djangoapps/user_authn/views/login.py:515

  • is_safe_login_or_logout_redirect(...) can raise (e.g., if client_id is present but invalid, Application.objects.get(client_id=...) raises DoesNotExist). That would turn a bad client_id into a 500 during login when an alt redirect is returned.
    if not alt_redirect_url or not is_safe_login_or_logout_redirect(
        redirect_to=alt_redirect_url,
        request_host=request.get_host(),
        dot_client_id=request.POST.get("client_id"),
        require_https=request.is_secure(),

openedx/core/djangoapps/user_authn/views/utils.py:128

  • The get_running_third_party_auth_state docstring return type says tuple[RunningPipeline, ProviderConfig], but the function (and type annotation) can return None for either element. This makes the contract harder to follow for callers.
    Returns:
        tuple[RunningPipeline, ProviderConfig]: the running pipeline and its provider.

openedx/core/djangoapps/user_authn/views/login.py:499

  • The PR description lists a PostLoginRedirectURLRequested hook, but the implementation here uses LoginAltRedirectURLRequested (filter type org.openedx.authentication.login.alt_redirect_url.requested.v1). Please confirm the intended filter name/type and update either the PR description or the code so they match.
    # .. filter_implemented_name: LoginAltRedirectURLRequested
    # .. filter_type: org.openedx.authentication.login.alt_redirect_url.requested.v1
    alt_redirect_url, __ = LoginAltRedirectURLRequested.run_filter(
        redirect_url=redirect_url,
        user=user,

@pwnage101
pwnage101 force-pushed the pwnage101/ENT-11568-edx branch from 3687447 to bdbe952 Compare August 7, 2026 19:53
Copilot AI review requested due to automatic review settings August 7, 2026 19:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated no new comments.

Suppressed comments (3)

openedx/core/djangoapps/user_authn/views/tests/test_filters.py:2

  • Typo in module docstring: "vies" → "views".
Test that various filters are fired for the vies in the user_authn app.

openedx/core/djangoapps/user_authn/serializers.py:74

  • extra_context is described as holding only undeclared keys, but representation.update(extra_context) will silently overwrite declared fields (e.g., platformName) if a plugin returns a colliding key. This makes the response schema less predictable and can mask bugs in filter implementations.
        representation = super().to_representation(instance)
        representation.update(instance.get('extra_context') or {})
        return representation

openedx/core/djangoapps/user_authn/views/utils.py:128

  • The docstring return type says tuple[RunningPipeline, ProviderConfig], but the function can (and does) return (None, None) and (RunningPipeline, None). Updating the signature in the docstring avoids misleading API documentation.
    Returns:
        tuple[RunningPipeline, ProviderConfig]: the running pipeline and its provider.

Replace the enterprise-specific logic in the user_authn logistration
views with six generic filters, removing all enterprise_support
imports and enterprise-specific logic:

- LogistrationViewContextGenerated
- AuthnMFEContextGenerated
- LogistrationViewRenderCompleted
- LoginFormGenerated
- RegistrationFormGenerated
- LoginAltRedirectURLRequested

ENT-11568
@pwnage101
pwnage101 force-pushed the pwnage101/ENT-11568-edx branch from bdbe952 to e24703c Compare August 7, 2026 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants