feat(auto-ban): add immediate unban and list_bans to AutoBanService #328

Merged
Claude-Run merged 1 commit from feat/BUNYIP-318-autoban-unban-list into main 2026-07-04 00:09:11 +02:00
Member

Adds AutoBanService::unban(ip), which lifts a still-valid ban in one call by removing the IP from the in-memory banned map (the map the request path checks in is_banned), clearing any accumulated strikes, and deleting the persisted ip_bans row so the ban does not reappear on the next restart. The in-memory removals run before the awaited DELETE, so the enforcement effect holds even if the database delete errors; the error is then propagated. It returns whether a ban was actually present (in memory or in the ip_bans table).

Adds AutoBanService::list_bans(), which merges the persisted ip_bans rows (source of strikes and banned_at) with the in-memory map (authoritative for enforcement) and returns the active bans as BanInfo { ip, reason, strikes, banned_at, expires_at } for reuse by the admin API in BUNYIP-319. IpBanRow and the load_active_bans SELECT are extended with the strikes and banned_at columns to carry the full metadata; BanInfo is re-exported from the middleware module.

Tests: in-memory tests prove is_banned returns false after unban and that strikes reset; DB-gated tests (skipped when DATABASE_URL is unset, per the repo convention) prove unban returns presence and deletes the row, and that list_bans surfaces a persisted ban with its reason and strikes.

#BUNYIP-318

Adds AutoBanService::unban(ip), which lifts a still-valid ban in one call by removing the IP from the in-memory `banned` map (the map the request path checks in is_banned), clearing any accumulated strikes, and deleting the persisted ip_bans row so the ban does not reappear on the next restart. The in-memory removals run before the awaited DELETE, so the enforcement effect holds even if the database delete errors; the error is then propagated. It returns whether a ban was actually present (in memory or in the ip_bans table). Adds AutoBanService::list_bans(), which merges the persisted ip_bans rows (source of strikes and banned_at) with the in-memory map (authoritative for enforcement) and returns the active bans as BanInfo { ip, reason, strikes, banned_at, expires_at } for reuse by the admin API in BUNYIP-319. IpBanRow and the load_active_bans SELECT are extended with the strikes and banned_at columns to carry the full metadata; BanInfo is re-exported from the middleware module. Tests: in-memory tests prove is_banned returns false after unban and that strikes reset; DB-gated tests (skipped when DATABASE_URL is unset, per the repo convention) prove unban returns presence and deletes the row, and that list_bans surfaces a persisted ban with its reason and strikes. #BUNYIP-318
feat(auto-ban): add immediate unban and list_bans to AutoBanService
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 23s
Check / fmt + clippy + build + tests (pull_request) Successful in 8m45s
Create release / Create release from merged PR (pull_request) Has been skipped
b2ffecb87d
Adds AutoBanService::unban(ip), which lifts a still-valid ban in one call by removing the IP from the in-memory `banned` map (the map the request path checks in is_banned), clearing any accumulated strikes, and deleting the persisted ip_bans row so the ban does not reappear on the next restart. The in-memory removals run before the awaited DELETE, so the enforcement effect holds even if the database delete errors; the error is then propagated. It returns whether a ban was actually present (in memory or in the ip_bans table).

Adds AutoBanService::list_bans(), which merges the persisted ip_bans rows (source of strikes and banned_at) with the in-memory map (authoritative for enforcement) and returns the active bans as BanInfo { ip, reason, strikes, banned_at, expires_at } for reuse by the admin API in BUNYIP-319. IpBanRow and the load_active_bans SELECT are extended with the strikes and banned_at columns to carry the full metadata; BanInfo is re-exported from the middleware module.

Tests: in-memory tests prove is_banned returns false after unban and that strikes reset; DB-gated tests (skipped when DATABASE_URL is unset, per the repo convention) prove unban returns presence and deletes the row, and that list_bans surfaces a persisted ban with its reason and strikes.

#BUNYIP-318
Claude-Run deleted branch feat/BUNYIP-318-autoban-unban-list 2026-07-04 00:09:11 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!328
No description provided.