fix(auth): keep the admin notice unconditional on the register path
Round 4 showed the `inv is not None` gate added in b5a1002 removed a signal that
matters: for an address the admin had already approved, that email is their only
notice that someone has now created an account on it — the invite is not pending
so nothing lands in the Access-requests queue either. Suppressing it left the
registrant at "awaiting admin approval" with the admin unaware they existed. The
duplicate it avoided (Request access, then sign up) is mild noise by comparison.
The production change is now one db.commit(), which is all the reported bug ever
needed. Release notes corrected again: a previously-denied address was also
unaffected, the pending-request case never lost its queue entry (only the
account behind it), and the test inventory was missing a guard.
This commit is contained in:
@@ -636,7 +636,7 @@ def _register_account(email: str, password: str) -> None:
|
||||
# no-op as the pre-check hit — roll back and stop.
|
||||
db.rollback()
|
||||
return
|
||||
inv = upsert_pending_invite(db, email) # admin-approval gate
|
||||
upsert_pending_invite(db, email) # admin-approval gate
|
||||
# Persist the account ourselves. upsert_pending_invite commits only when it actually writes an
|
||||
# invite row — not when this address already has a pending or approved one — and _issue_token
|
||||
# below only runs with SMTP on. So for an address the admin had already approved (or one whose
|
||||
@@ -650,10 +650,10 @@ def _register_account(email: str, password: str) -> None:
|
||||
# Fragment (#), not a query token: keeps the token out of proxy/access logs + Referer (SB3).
|
||||
email_mod.send_verify_email(email, f"{_app_base()}/#verify={raw}")
|
||||
admins = admin_notify_emails(db)
|
||||
# Only when there is a fresh decision to make, matching the other two call sites. Otherwise
|
||||
# someone who used Request access and then registered sent admins a second copy of the same
|
||||
# request, and an already-approved address produced a notice pointing at an empty queue.
|
||||
if inv is not None and admins:
|
||||
# Unconditional, unlike the other two callers which gate on a fresh invite row: for an
|
||||
# address the admin already approved this notice is the ONLY signal that someone has now
|
||||
# created an account on it, and that account is inactive until the admin acts.
|
||||
if admins:
|
||||
email_mod.send_admin_new_request(admins, email)
|
||||
|
||||
|
||||
|
||||
@@ -183,8 +183,9 @@ def test_registration_of_a_pre_approved_email_persists_the_account_without_smtp(
|
||||
# so their Google sign-in keeps working and an anonymous sign-up cannot revoke access.
|
||||
assert invite.status == "approved"
|
||||
assert invite.decided_by == "admin@example.com"
|
||||
# …and no "new access request" notice, because there is no fresh decision to make.
|
||||
assert notified == []
|
||||
# The admin is still told: for an already-approved address this notice is their only signal
|
||||
# that an account now exists on it, and it is inactive until they act.
|
||||
assert notified == ["roland@example.com"]
|
||||
|
||||
|
||||
def test_registration_with_an_already_pending_request_persists_the_account(
|
||||
@@ -204,7 +205,7 @@ def test_registration_with_an_already_pending_request_persists_the_account(
|
||||
assert user is not None, "registration was rolled back — the account is gone"
|
||||
assert user.is_active is False
|
||||
assert invite.status == "pending"
|
||||
assert notified == [] # the admin already has this request; don't send a second copy
|
||||
assert notified == ["pia@example.com"]
|
||||
|
||||
|
||||
def test_an_admin_can_activate_a_pre_approved_registrant(db, make_user, monkeypatch):
|
||||
|
||||
Reference in New Issue
Block a user