Skip to content

ref(auth): remove unused code - #121268

Open
nora-shap wants to merge 1 commit into
masterfrom
nora/auth/ID-1752
Open

ref(auth): remove unused code#121268
nora-shap wants to merge 1 commit into
masterfrom
nora/auth/ID-1752

Conversation

@nora-shap

Copy link
Copy Markdown
Member

TL;DR

The ConfirmEmail pipeline view contains a returning-user "email override" and an "enter your email" form (ConfirmEmailForm). Both are vestigial.

The ConfirmEmail form began as "let users type an email when GitHub gives none" idea (2015-07), but the /user/emails fallback (2015-09) covered that case before the form even shipped (2015-10). What remained was a returning-user override that (a) never persisted and (b) fed a login path that ignores the email. It has been effectively inert for its entire ~11-year life, which is why nobody noticed: returning users are matched by GitHub id, so the email value never mattered.

Net: this code does not do the thing its shape implies. Removing the override and the form changes no real behavior. This document traces exactly how it got here.

What the code looks like today

class ConfirmEmail(AuthView):
    def handle(self, request, pipeline):
        user = pipeline.fetch_state("user")
        assert user is not None

        # TODO(dcramer): this isn't ideal, but our current flow doesnt really
        # support this behavior;
        try:
            auth_identity = AuthIdentity.objects.select_related("user").get(
                auth_provider=pipeline.provider_model, ident=user["id"]
            )
        except AuthIdentity.DoesNotExist:
            pass
        else:
            user["email"] = auth_identity.user.email      # (A) local-only mutation, never bind_state'd

        if user.get("email"):
            return pipeline.next_step()

        form = ConfirmEmailForm(request.POST or None)     # (B) reachable only if (A) set email to ""
        if form.is_valid():
            user["email"] = form.cleaned_data["email"]
            pipeline.bind_state("user", user)
            return pipeline.next_step()
        return self.respond("sentry_auth_github/enter-email.html", {"form": form})

Why it doesn't do what it looks like

  1. FetchUser already guarantees an email. The SSO pipeline steps are [OAuth2Login, OAuth2Callback, FetchUser, ConfirmEmail]. The preceding step, FetchUser, returns pipeline.error(...) if it finds 0 or >1 primary emails. So by the time ConfirmEmail runs, user["email"] is never empty.

  2. The override is not persisted. The else branch mutates the local copy but never calls bind_state, so the write never reaches Redis. The next reader (build_identity via finish_pipeline) re-reads the original FetchUser email from the pipeline state.

  3. Even then, the collected email is discarded. A returning user resolves to AuthIdentityHandler.handle_existing_identity, which updates and logs in auth_identity.user by id. It never reads identity["email"] or writes user.email. So the form throws away FetchUser's valid GitHub email, prompts for a replacement, and then that replacement goes nowhere.

How we got here (archaeology)

All original logic predates the sentry monorepo — it was authored in the now-archived getsentry/sentry-auth-github plugin.

  • a454f01 2015-07-20 — Initial commit. FetchUser binds user data; no email logic, no ConfirmEmail.
  • 28c885c 2015-09-20 — "handling hidden emails." Adds the /user/emails primary-email fallback to FetchUser. From here on, FetchUser yields an email or hard-errors.
  • 0e8b604 2015-10-15 — "Handle hidden email addresses / Cleanup forms" Introduces ConfirmEmail exactly as it exists today. Because the /user/emails fallback had shipped 3 weeks earlier, the form was only reachable via the blank-email-returning-user edge, and the override was a non-persisting local mutation.

Why removal is safe

  • New users: never reach the form (FetchUser guarantees an email or errors). Unaffected.
  • Returning users (active): matched by id in handle_existing_identity; identity email ignored. Without the override they keep FetchUser's GitHub email (still ignored) and log in identically.
  • Returning users with blank User.email: today they're shown a pointless form whose result is discarded; after removal they simply log in by id. Strictly no worse.
  • Returning-but-inactive users (the one path where identity email is consumed, via handle_unknown_identity): removal is actually better — resolution uses FetchUser's real GitHub email instead of a form-typed one.

@linear-code

linear-code Bot commented Aug 4, 2026

Copy link
Copy Markdown

ID-1752

@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Aug 4, 2026
@nora-shap

Copy link
Copy Markdown
Member Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 704513e. Configure here.

@nora-shap

Copy link
Copy Markdown
Member Author

@sentry review

@nora-shap
nora-shap marked this pull request as ready for review August 4, 2026 23:41
@nora-shap
nora-shap requested review from a team as code owners August 4, 2026 23:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants