refactor(api): drop dead login concurrency limiter and reconcile passwordless comments

The passwordless migration (b330d77) removed the password-login route, leaving
concurrencyLimiter — its bcrypt concurrency cap — with no caller, and scattered
stale "local-password" / "change-password" references through the surviving auth
code's comments.

- Remove the dead concurrencyLimiter (type + newConcurrencyLimiter + acquire):
  no caller, no struct field, no test. Reword the one streamLimiter doc that
  contrasted against it.
- Realign comments in repo.go, pgrepo.go, session.go, util.go to the passwordless
  reality: staff lookups feed email-OTP / passkey / setup redeem, not a password
  compare; RevokeUserSessionsExcept and DeleteAllPasskeyCredentialsForUser are
  retained (uncalled) for the P5 account-remediation path (#78); "local sessions"
  no longer implies a password.

Comments and dead code only; no behavior change. Full WSL test tree green.
This commit is contained in:
flyemoji committed 2026-07-04 21:47:12 +09:00
1 parent 0c1cc598c1
commit 3b43f05a83
5 files changed
+44 -78

No files matched your search

+2 -42
View File
@@ -622,54 +622,14 @@ func (c *cooldownLimiter) release(name string, reservedAt time.Time) {
}
}
// ---- login concurrency cap ----
// concurrencyLimiter bounds how many holders may run a guarded section at once. It
// backs the public login route's bcrypt cap (handleLogin): a buffered channel of n
// tokens; acquire takes one WITHOUT blocking (returning ok=false when the section
// is already full), release returns it. Unlike cooldownLimiter — a per-key time
// window — this bounds simultaneity, not frequency, which is the right shape for a
// CPU-costly section a flood would otherwise pin every core running. A non-positive
// cap disables it (acquire always admits, release is a no-op), mirroring the "zero
// disables" idiom of WakeCooldown and MaxRunningServers.
type concurrencyLimiter struct {
slots chan struct{}
}
// newConcurrencyLimiter builds a limiter admitting at most n concurrent holders. A
// non-positive n yields a disabled limiter (nil slots) that admits everyone.
func newConcurrencyLimiter(n int) *concurrencyLimiter {
if n <= 0 {
return &concurrencyLimiter{}
}
return &concurrencyLimiter{slots: make(chan struct{}, n)}
}
// acquire tries to take a slot without blocking. It returns a release func and true
// on success, or nil and false when the section is already at capacity. The disabled
// limiter (nil slots) always admits and returns a no-op release. release MUST be
// called exactly once on the success path, so it reads naturally as `release, ok :=
// l.acquire(); if !ok { shed }; defer/inline release()`.
func (l *concurrencyLimiter) acquire() (release func(), ok bool) {
if l.slots == nil {
return func() {}, true
}
select {
case l.slots <- struct{}{}:
return func() { <-l.slots }, true
default:
return nil, false
}
}
// ---- per-principal stream cap ----
// streamLimiter bounds how many concurrent guarded sections a single KEY may hold at
// once. It backs the per-principal SSE stream cap (console + build-log relays): each
// relay blocks for the life of a client's attachment and, under a stalled reader,
// pins a goroutine plus a kube-apiserver follow connection, so an unbounded number of
// them from one principal is a control-plane connection-exhaustion vector. Unlike the
// login concurrencyLimiter (a single global semaphore), this counts per key. A
// them from one principal is a control-plane connection-exhaustion vector. Unlike a
// single global semaphore, this counts per key. A
// non-positive max disables it (acquire always admits, release is a no-op), the same
// "zero disables" idiom as the other levers.
type streamLimiter struct {