auth: remove unused RemoveAllContexts · Entire
auth: remove unused RemoveAllContexts
d3427dd→main·
toothbrush·1mo ago·2 files·+0 added/-80 removed
Dead since logout --all was redefined to revoke server-side sessions rather than nuke all local contexts. Nothing else references it.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
7dc263eaaac8View transcript
[?
Refactor Auth Commands for Session ManagementClaude Code·Opus 4.8[1m]·1 step](/content/gh/entireio/cli/session/d51ce65e-9ad9-4c0d-b6af-911eed02c1ee#timeline-7dc263eaaac8/index.html)
Changes
2
cmd/entire/cli/auth
Mcontext_store.go-29
Mcontexts_test.go-51
61 unmodified lines
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
65
66
67
61 unmodified lines
return nil
}
// RemoveAllContexts deletes every stored context and its keyring token — a
// full local logout. Returns the number of contexts removed. Best-effort on
// the keyring deletes; the contexts.json clear is what makes the CLI fully
// logged out.
func RemoveAllContexts() (int, error) {
var removed int
if err := contexts.Modify(contexts.DefaultConfigDir(), func(f *contexts.File) (bool, error) {
if len(f.Contexts) == 0 && f.CurrentContext == "" {
return false, nil
}
for _, c := range f.Contexts {
if c.KeychainService != "" && c.Handle != "" {
// Delete both slots: the access token and its paired refresh
// token. Dropping the refresh slot is what actually scrubs the
// machine — otherwise a leftover refresh token outlives logout.
_ = tokenstore.Delete(c.KeychainService, c.Handle) //nolint:errcheck // best-effort; the contexts.json clear below is authoritative
_ = tokenstore.Delete(tokenstore.RefreshService(c.KeychainService), c.Handle) //nolint:errcheck // best-effort; absent refresh slot is fine
}
removed++
}
f.Contexts = nil
f.CurrentContext = ""
return true, nil
}); err != nil {
return 0, fmt.Errorf("remove all contexts: %w", err)
}
return removed, nil
}
// SetCurrentContext makes name the active context. Returns an error when
// no context with that name exists (a stale current pointer is a foot-gun).
func SetCurrentContext(name string) error {
Mcmd/entire/cli/auth/context_store.go-29
268 unmodified lines
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
272
273
274
268 unmodified lines
}
}
func TestRemoveAllContexts(t *testing.T) {
cfgDir := t.TempDir()
t.Setenv("ENTIRE_CONFIG_DIR", cfgDir)
restore := tokenstore.UseFileBackendForTesting(filepath.Join(t.TempDir(), "tokens.json"))
t.Cleanup(restore)
exp := time.Now().Add(time.Hour).Unix()
if _, err := RecordLoginContext(makeJWT(t, fmt.Sprintf(`{"iss":"https://a.example.com","handle":"alice","exp":%d}`, exp)), "entr_a", true); err != nil {
t.Fatalf("record a: %v", err)
}
if _, err := RecordLoginContext(makeJWT(t, fmt.Sprintf(`{"iss":"https://b.example.com","handle":"bob","exp":%d}`, exp)), "entr_b", true); err != nil {
t.Fatalf("record b: %v", err)
}
n, err := RemoveAllContexts()
if err != nil {
t.Fatalf("RemoveAllContexts: %v", err)
}
if n != 2 {
t.Fatalf("removed %d, want 2", n)
}
f, err := contexts.Load(cfgDir)
if err != nil {
t.Fatalf("load: %v", err)
}
if len(f.Contexts) != 0 || f.CurrentContext != "" {
t.Fatalf("expected fully cleared, got contexts=%d current=%q", len(f.Contexts), f.CurrentContext)
}
// Every refresh slot must be gone too, for both removed contexts.
for _, tc := range []struct{ iss, handle string }{
{"https://a.example.com", "alice"},
{"https://b.example.com", "bob"},
} {
svc := tokenstore.CoreKeyringService(tc.iss)
if v, err := tokenstore.Get(svc, tc.handle); !errors.Is(err, tokenstore.ErrNotFound) {
t.Fatalf("access slot for %s survived: value=%q err=%v", tc.handle, v, err)
}
if v, err := tokenstore.Get(tokenstore.RefreshService(svc), tc.handle); !errors.Is(err, tokenstore.ErrNotFound) {
t.Fatalf("refresh slot for %s survived: value=%q err=%v", tc.handle, v, err)
}
}
// Idempotent.
n2, err := RemoveAllContexts()
if err != nil {
t.Fatalf("second RemoveAllContexts: %v", err)
}
if n2 != 0 {
t.Fatalf("second call removed %d, want 0", n2)
}
}
func TestRemoveCurrentContext_DoesNotSwitchToAnother(t *testing.T) {
cfgDir := t.TempDir()
t.Setenv("ENTIRE_CONFIG_DIR", cfgDir)