DataTalksClub / DataTalksClub/website

D3.1 phase 3: Switch identity-window readers to accounts_ext.IdentityState

Open
#392 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

auth courses data-migration enhancement P1
Dominant language
Python
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Part of the D3.1 umbrella (#334): phase 3 of 6. Switches the identity-window and importer reader surface for normalized_email/identity_state to accounts_ext.IdentityState, refreshed against current main. Can run concurrently with phase 2 (#391) — both depend only on phase 1, not on each other.

Normative sources

Source What it governs
community-base repo: docs/plan/phase-3.md D3.1; docs/03-playbooks.md P7 DTC step 3 Reader-migration expectation
Phase 1 issue (#390) accounts_ext.IdentityState model this phase reads/writes
_docs/audits/2026-09-07-backend-security-audit.md (BE-08, REL-04) Quarantine-revocation and claims-store behavior this phase must not regress

Goal

Every read and write of normalized_email/identity_state goes through user.identity_state (the new accounts_ext.IdentityState OneToOne) instead of the CustomUser fields. Both stay in sync until phase 4 removes the CustomUser copy.

Scope: reader surface (verify each by reading current main — this table corrects and extends #334's original inventory)

Area Files Note
Identity core accounts/identity_inventory.py, accounts/identity_resolution.py, accounts/middleware.py, accounts/backends.py, accounts/auth.py, accounts/api.py, accounts/development_owner.py Unchanged from #334
Events events/models.py Unchanged from #334; events/identity.py (originally also listed) was deleted in commit 4c9b5239 ("Retire legacy event redirects, EventAlias, and events/identity.py", 2026-09-11) — its live resolve_*/canonical_*/create_event_identity primitives moved into events/models.py itself
Events (corrected path) scripts/prod/registrant_import.py Was events/registrant_import.py in #334's original table; moved out of the events app to scripts/prod/ in the same 2026-09-11 commit. Update any reference to the old path.
Importers and prod scripts accounts/services/cmp_learner_import.py, courses/services/cmp_learner_history_import.py, scripts/prod/account_reconciliation/, scripts/prod/import_cmp_learners.py, scripts/prod/legacy_zoomcamp/ Unchanged from #334
New quarantine-enforcement call sites (added after #334's grooming; verified read-only, no field-literal change needed) accounts/studio_authorization.py, accounts/studio_sessions.py, management_api/authentication.py These call accounts.identity_resolution.identity_state_eligible(user) rather than reading user.identity_state directly, so once identity_resolution.py itself is switched to user.identity_state (the new relation), no separate edit is needed here — confirm this with a grep in the PR rather than assuming it.

Also required: the identity_inventory.py literal fallout already flagged in #334's own grooming comments (ACCOUNT_MANY_TO_MANY_RELATIONS's owner_model/through_table/user_field, ACCOUNT_RELATIONS's first entry) is a phase 5 (rename) concern, not this phase — do not pre-edit those literals here; they still say accounts.CustomUser correctly until the rename lands.

Non-goals

  • No change to the ten courses.LearnerProfile fields' readers (phase 2, independent).
  • No removal of normalized_email/identity_state/the unique constraint from CustomUser (phase 4).
  • No rename (phase 5), no AISL field additions (phase 6).
  • No behavior change to quarantine enforcement, alias resolution, or the CMP claims store beyond the read/write relocation.

Dependencies

  • Depends on: #390 (accounts_ext.IdentityState must exist and be backfilled).
  • Blocks: #393.

Acceptance criteria

Django and integration
  • make django-check / make migrations-check pass.
  • make test passes, including accounts/tests/test_identity_quarantine_revocation.py and the CMP import/claims tests, unmodified in behavior.
  • A grep-backed inventory in the PR body lists every file that read/wrote normalized_email/identity_state before this change (using the corrected table above) and confirms each now goes through identity_state.
  • Email login still authenticates through the Django test client (login, session, member page 200); quarantined accounts are still denied on session, legacy-token, and management-API paths with the same generic denial.
  • AccountIdentityAlias survivor resolution and the CMP learner import's claims store (CmpLearnerClaim/CmpLearnerImportBinding, added since #334's original grooming) still pass their existing tests unmodified.
Repository and operations
  • Versioned verification plan per _docs/ci/change-selective-ci.md recorded in the engineer handoff.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with phase 1 issue #390 and the listed identity files, especially accounts/identity_resolution.py, accounts/identity_inventory.py, accounts/auth.py, accounts/api.py, and events/models.py. Use a grep-backed inventory to trace normalized_email and identity_state reads and writes, including the corrected importer paths. Run make django-check, make migrations-check, make test, and the named quarantine-revocation and CMP tests; done means all readers use identity_state without changing quarantine, alias, or claims behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
django, python
Domain
authentication, backend, database
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.