Act immediately on flagged signups Mastodon already auto-approved
account.approved never fires for a signup that went through open registration without ever being queued (no prior block on that address). process_signup was waiting on that event forever, so the first flagged signup on any new bad IP/email domain never got welcomed or watched by the suspicious-sweep. Now checks Admin::Account.approved from the account.created payload and acts immediately if it's already true.
This commit is contained in:
+19
-6
@@ -547,7 +547,8 @@ def register_email_domain_block(domain: str, acct: str) -> None:
|
|||||||
log.error("failed to register email_domain_block for %s (acct=%s): %s", domain, acct, exc)
|
log.error("failed to register email_domain_block for %s (acct=%s): %s", domain, acct, exc)
|
||||||
|
|
||||||
|
|
||||||
def process_signup(account_id: str, acct: str, ip: str, email: str = "") -> None:
|
def process_signup(account_id: str, acct: str, ip: str, email: str = "",
|
||||||
|
approved: bool = False) -> None:
|
||||||
"""Classify a new signup's IP and email domain, and act on account.created.
|
"""Classify a new signup's IP and email domain, and act on account.created.
|
||||||
|
|
||||||
Non-flagged (or both signals disabled/unavailable) signups are welcomed
|
Non-flagged (or both signals disabled/unavailable) signups are welcomed
|
||||||
@@ -555,7 +556,10 @@ def process_signup(account_id: str, acct: str, ip: str, email: str = "") -> None
|
|||||||
either signal (datacenter IP and/or high-risk email domain) gets a
|
either signal (datacenter IP and/or high-risk email domain) gets a
|
||||||
moderator DM, the matching auto-block(s) (ip_block / email_domain_block),
|
moderator DM, the matching auto-block(s) (ip_block / email_domain_block),
|
||||||
and — unless dry-run — has its welcome held until account.approved fires
|
and — unless dry-run — has its welcome held until account.approved fires
|
||||||
(see _handle_account_created).
|
(see _handle_account_created). `approved` is the account's *current*
|
||||||
|
Admin::Account.approved state at signup time: if it's already true (open
|
||||||
|
registration, never queued), account.approved will never be delivered for
|
||||||
|
it, so the hold is lifted immediately instead of waiting forever.
|
||||||
"""
|
"""
|
||||||
reasons: list[str] = []
|
reasons: list[str] = []
|
||||||
hold = False
|
hold = False
|
||||||
@@ -599,11 +603,15 @@ def process_signup(account_id: str, acct: str, ip: str, email: str = "") -> None
|
|||||||
+ (" Welcome DM held pending approval." if hold else "")
|
+ (" Welcome DM held pending approval." if hold else "")
|
||||||
)
|
)
|
||||||
|
|
||||||
if not hold:
|
if not hold or approved:
|
||||||
|
# Either never held, or held but Mastodon already auto-approved this
|
||||||
|
# signup (open registration, no moderator queue) — account.approved
|
||||||
|
# is not coming, so act now instead of waiting for it.
|
||||||
send_welcome(account_id, acct)
|
send_welcome(account_id, acct)
|
||||||
maybe_start_suspicious_watch(account_id, acct)
|
maybe_start_suspicious_watch(account_id, acct)
|
||||||
# else: held — sent later if/when account.approved fires (human review),
|
# else: genuinely queued for a moderator's decision — sent later if/when
|
||||||
# which is also where maybe_start_suspicious_watch gets called.
|
# account.approved fires (human review), which is also where
|
||||||
|
# maybe_start_suspicious_watch gets called.
|
||||||
|
|
||||||
|
|
||||||
def maybe_start_suspicious_watch(account_id: str, acct: str) -> None:
|
def maybe_start_suspicious_watch(account_id: str, acct: str) -> None:
|
||||||
@@ -1063,7 +1071,12 @@ def _handle_account_created(obj: dict, background: BackgroundTasks, event: str):
|
|||||||
# decide whether to welcome now or hold for account.approved.
|
# decide whether to welcome now or hold for account.approved.
|
||||||
ip = obj.get("ip") or ""
|
ip = obj.get("ip") or ""
|
||||||
email = obj.get("email") or ""
|
email = obj.get("email") or ""
|
||||||
background.add_task(process_signup, account_id, acct, ip, email)
|
# Admin::Account.approved is already true here for any signup that
|
||||||
|
# Mastodon auto-approved as part of open registration (no moderator
|
||||||
|
# queue involved) — account.approved never fires for those, so
|
||||||
|
# process_signup must act now instead of waiting for it.
|
||||||
|
approved = bool(obj.get("approved"))
|
||||||
|
background.add_task(process_signup, account_id, acct, ip, email, approved)
|
||||||
else:
|
else:
|
||||||
# account.approved: a human has cleared the approval-required
|
# account.approved: a human has cleared the approval-required
|
||||||
# registration gate. Always welcome (dedup makes this safe) — this is
|
# registration gate. Always welcome (dedup makes this safe) — this is
|
||||||
|
|||||||
@@ -263,6 +263,17 @@ def ip_scrutiny_tests():
|
|||||||
main.send_welcome("102", "dc1") # simulate account.approved's unconditional welcome
|
main.send_welcome("102", "dc1") # simulate account.approved's unconditional welcome
|
||||||
assert ("102", "dc1") in sent, sent
|
assert ("102", "dc1") in sent, sent
|
||||||
|
|
||||||
|
# B2. datacenter IP, held, but Mastodon already auto-approved the signup
|
||||||
|
# (open registration, never queued) -> account.approved will never
|
||||||
|
# fire, so process_signup must welcome + start the watch immediately
|
||||||
|
# instead of waiting for an event that isn't coming.
|
||||||
|
sent.clear(); dms.clear(); ipblocks.clear()
|
||||||
|
classifications["198.51.100.22"] = ("datacenter", "Example Cloud Hosting Inc", True)
|
||||||
|
main.process_signup("104", "dc3", "198.51.100.22", "", True)
|
||||||
|
assert ("104", "dc3") in sent, "already-approved flagged signup must be welcomed immediately"
|
||||||
|
assert main.get_signup_flag("104") is True
|
||||||
|
assert main.already_watched_suspicious("104"), "already-approved flagged signup must start its watch immediately"
|
||||||
|
|
||||||
# C. same datacenter IP, but IP_SCRUTINY_DRY_RUN -> welcomed immediately
|
# C. same datacenter IP, but IP_SCRUTINY_DRY_RUN -> welcomed immediately
|
||||||
# (no hold), no ip-block write, DM carries the dry-run prefix.
|
# (no hold), no ip-block write, DM carries the dry-run prefix.
|
||||||
sent.clear(); dms.clear(); ipblocks.clear()
|
sent.clear(); dms.clear(); ipblocks.clear()
|
||||||
|
|||||||
Reference in New Issue
Block a user