Skip to content

feat(user): revoke sessions on user disable#1595

Merged
AmanGIT07 merged 2 commits into
mainfrom
feat/revoke-sessions-on-user-disable
May 11, 2026
Merged

feat(user): revoke sessions on user disable#1595
AmanGIT07 merged 2 commits into
mainfrom
feat/revoke-sessions-on-user-disable

Conversation

@AmanGIT07
Copy link
Copy Markdown
Contributor

@AmanGIT07 AmanGIT07 commented May 11, 2026

Summary

user.Service.Disable now soft-deletes all of the user's active sessions after flipping state. Outstanding session cookies stop authenticating immediately instead of lingering until expires_at. Not a security fix — the existing notDisabledUserExp filter at the user repo already blocks disabled-user auth at lookup time — but a hygiene and pre-disable sessions can no longer silently resume if the user is re-enabled within the validity window. They will need to re-login.

Refs umbrella issue #1585.

Changes

  • core/authenticate/session/service.go — new Service.DeleteByUserID that reuses repo.List + repo.Delete.
  • core/user/service.go — new SessionService interface and field; Disable calls DeleteByUserID after a successful SetState. Invalid-id and not-found paths skip the revocation as before.
  • cmd/serve.go — pass the existing sessionService into user.NewService.
  • Mock: core/user/mocks/session_service.go (regenerated via mockery; core/user is already in .mockery.yaml).

Technical Details

The DRY choice: DeleteByUserID lists the user's active sessions via the existing repo method and calls repo.Delete per session. Each delete goes through the existing TX + createSessionRevokeAuditRecord path, which already emits a SessionRevokedEvent when the actor is different from the session owner (the admin-initiated disable case).

Mirrors what serviceUserService.Delete already does for credentials.

Test Plan

  • go test ./core/user/... ./core/authenticate/session/... passes
  • go build ./... clean
  • New unit tests: 4 TestService_DeleteByUserID subtests (happy, empty, list-error, delete-error); TestService_Disable updated with revoke-on-success, skip-on-failure, and revoke-error-propagation cases
  • Manual: disable a user with an active session cookie, verify subsequent requests with that cookie return Unauthenticated; verify sessions.deleted_at is set

🤖 Generated with Claude Code

When a user is disabled, soft-delete all of their active sessions so
outstanding session cookies stop authenticating immediately rather than
lingering until expires_at (up to 7 days). The lazy notDisabledUserExp
filter at the user repo already blocks disabled-user auth, so this is a
hygiene/audit improvement rather than a security fix: it produces an
explicit revocation trail (per-session SessionRevokedEvent records via
the existing audit hook) and prevents pre-disable sessions from silently
resuming if the user is re-enabled within the validity window.

Reuses repo.List + repo.Delete instead of adding a bulk SQL path, so
each revoked session goes through the same audit pipeline as a manual
admin revoke.

Refs: #1585

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
frontier Ready Ready Preview, Comment May 11, 2026 8:13am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 11, 2026

Review Change Stack

Warning

Rate limit exceeded

@AmanGIT07 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 40 minutes and 48 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a8e28a2f-c395-4465-bafd-a7ac01f844fb

📥 Commits

Reviewing files that changed from the base of the PR and between 0ac2225 and 191225d.

📒 Files selected for processing (2)
  • core/authenticate/session/service.go
  • core/authenticate/session/service_test.go
📝 Walkthrough

Walkthrough

The PR adds automatic session revocation when a user is disabled. It introduces a DeleteByUserID method to the session service, integrates a session service dependency into the user service constructor, calls session deletion from the Disable method after updating user state, and updates all wiring and tests to support this workflow.

Changes

User Session Deletion on Disable

Layer / File(s) Summary
Service Contracts
core/user/service.go
Adds SessionService interface with DeleteByUserID(ctx, userID) error. Updates user.NewService constructor to accept and store a sessionService dependency.
Session Deletion Implementation
core/authenticate/session/service.go
Implements DeleteByUserID(ctx, userID) to list all active sessions for a user and soft-delete each session ID via the repository.
User Disable with Session Revocation
core/user/service.go
Updates Service.Disable to call sessionService.DeleteByUserID(ctx, id) after successfully setting user state to Disabled.
Dependency Wiring
cmd/serve.go
Passes sessionService as an additional argument to user.NewService(...) in buildAPIDependencies.
Session Deletion Tests
core/authenticate/session/service_test.go
Adds TestService_DeleteByUserID with subtests for successful multi-session revocation, no-op on empty session lists, list error propagation, and early termination on deletion failure.
User Service Tests
core/user/service_test.go
Updates mock wiring helper to create sessionService and pass it to user.NewService. Expands TestService_Disable to verify session revocation is called after state change, with additional cases for invalid IDs, user-not-found (no revocation), and session deletion error propagation. Updates all other service method tests to use the new wiring.
Session Service Mock
core/user/mocks/session_service.go
Auto-generates a Mockery mock for SessionService with expecter, DeleteByUserID method, call wrapper with chaining helpers, and test constructor.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • whoAbhishekSah
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
core/authenticate/session/service.go (1)

91-93: ⚡ Quick win

Use the service deletion path inside bulk revoke.

Calling s.Delete(ctx, sess.ID) here avoids behavior drift between single-session and bulk-session revocation paths.

Suggested diff
 	for _, sess := range sessions {
-		if err := s.repo.Delete(ctx, sess.ID); err != nil {
+		if err := s.Delete(ctx, sess.ID); err != nil {
 			return err
 		}
 	}

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 22390923-e1ad-4ce1-b9fd-baa4a4a1163b

📥 Commits

Reviewing files that changed from the base of the PR and between 65953a6 and 0ac2225.

📒 Files selected for processing (6)
  • cmd/serve.go
  • core/authenticate/session/service.go
  • core/authenticate/session/service_test.go
  • core/user/mocks/session_service.go
  • core/user/service.go
  • core/user/service_test.go

Comment thread core/authenticate/session/service_test.go
@coveralls
Copy link
Copy Markdown

coveralls commented May 11, 2026

Coverage Report for CI Build 25658348755

Coverage increased (+0.02%) to 41.985%

Details

  • Coverage increased (+0.02%) from the base build.
  • Patch coverage: 1 uncovered change across 1 file (16 of 17 lines covered, 94.12%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
cmd/serve.go 1 0 0.0%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 37268
Covered Lines: 15647
Line Coverage: 41.99%
Coverage Strength: 11.88 hits per line

💛 - Coveralls

Route bulk session revoke through Service.Delete instead of repo.Delete
so future Delete changes propagate; strengthen early-exit test to assert
the second session's delete is never attempted after the first fails.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread core/user/service.go
@AmanGIT07 AmanGIT07 merged commit 452e047 into main May 11, 2026
8 checks passed
@AmanGIT07 AmanGIT07 deleted the feat/revoke-sessions-on-user-disable branch May 11, 2026 09:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants