refactor(auth): dedup cell login refresh + tidy jurisdiction test per cleanup review · Entire

refactor(auth): dedup cell login refresh + tidy jurisdiction test per cleanup review

5ead384·

jagregory·4d ago·2 files·+30 added/-38 removed

- Extract refreshCellLoginJWT, shared by resolveActiveContextCellSubject and resolveStoredCellSubject (was a duplicated ~12-line build-provider → call → map-ErrNotLoggedIn block). - Use the existing writeActiveContext test helper for the single-context TestJurisdictionToken_StoredContext seed. - Drop the orphaned/stale doc-comment block left stacked above TestJurisdictionToken_StoredContext.

Behavior unchanged; fmt + lint clean, tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

Sessions

01KXDCZ2NFPYHZEFQ56T24GHTYView transcript

Changes

2

16 unmodified lines

17
18
19
20
21
22
23
276 unmodified lines

300
301
302
302
303
304
305
303
304
305
306
309
310
311
312
313
314
315
316
317
307
308
309
33 unmodified lines

343
344
345
357
358
359
360
361
362
346
347
348
349
350
367
368
369
370
371
372
373
374
375
376
351
352
353
2 unmodified lines

356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385

16 unmodified lines

"github.com/entireio/cli/cmd/entire/cli/api"
    "github.com/entireio/cli/internal/entireclient/clusterdiscovery"
    "github.com/entireio/cli/internal/entireclient/contexts"
    "github.com/entireio/cli/internal/entireclient/httputil"
    "github.com/entireio/cli/internal/entireclient/userdirs"
)
276 unmodified lines

return cellSubject{}, fmt.Errorf("not logged in (run 'entire login' first): %w", ErrNotLoggedIn)
    }

// Gate the login provider's HTTPS relaxation on the context's own core plus
    // the explicit --insecure-http-auth opt-in, mirroring resolveStoredCellSubject.
    allowInsecure := insecureHTTPEnabled() || isLoopbackHTTP(c.CoreURL)
    loginProvider, err := NewRefreshingLoginProvider(c, cellExchangeTransportForTest, allowInsecure)
    loginJWT, err := refreshCellLoginJWT(ctx, c)
    if err != nil {
        return cellSubject{}, err
    }
    loginJWT, err := loginProvider(ctx)
    if err != nil {
        if errors.Is(err, ErrNotLoggedIn) {
            return cellSubject{}, fmt.Errorf("not logged in (run 'entire login' first): %w", err)
        }
        // The provider already prefixes "refresh login token:"; return as-is to
        // avoid a doubled prefix.
        return cellSubject{}, err
    }

origin := api.OriginOnly(c.CoreURL)
    return cellSubject{
33 unmodified lines

return cellSubject{}, err
    }

// Gate the login provider's HTTPS relaxation on the core it actually dials
    // (selected.CoreURL) plus the explicit --insecure-http-auth opt-in, matching
    // the sibling ResolveDataAPIToken. A loopback data API must not relax HTTPS
    // for a non-loopback core.
    allowInsecure := insecureHTTPEnabled() || isLoopbackHTTP(selected.CoreURL)
    loginProvider, err := NewRefreshingLoginProvider(selected, cellExchangeTransportForTest, allowInsecure)
    loginJWT, err := refreshCellLoginJWT(ctx, selected)
    if err != nil {
        return cellSubject{}, err
    }

loginJWT, err := loginProvider(ctx)
    if err != nil {
        if errors.Is(err, ErrNotLoggedIn) {
            return cellSubject{}, fmt.Errorf("not logged in (run 'entire login' first): %w", err)
        }
        // The provider already prefixes "refresh login token:"; return as-is to
        // avoid a doubled prefix.
        return cellSubject{}, err
    }

return cellSubject{
        loginJWT:       loginJWT,
        discoveredCore: selected.CoreURL,
2 unmodified lines

}, nil
}

// refreshCellLoginJWT returns c's login JWT, transparently re-minting it from the
// stored refresh token. Shared by the active-context and discovered-context cell
// subject resolvers, which differ only in how they pick c.
func refreshCellLoginJWT(ctx context.Context, c *contexts.Context) (string, error) {
    // Gate the login provider's HTTPS relaxation on the core it actually dials
    // plus the explicit --insecure-http-auth opt-in: a loopback core must not
    // relax HTTPS for a non-loopback one.
    allowInsecure := insecureHTTPEnabled() || isLoopbackHTTP(c.CoreURL)
    loginProvider, err := NewRefreshingLoginProvider(c, cellExchangeTransportForTest, allowInsecure)
    if err != nil {
        return "", err
    }
    loginJWT, err := loginProvider(ctx)
    if err != nil {
        if errors.Is(err, ErrNotLoggedIn) {
            return "", fmt.Errorf("not logged in (run 'entire login' first): %w", err)
        }
        // The provider already prefixes "refresh login token:"; return as-is to
        // avoid a doubled prefix.
        return "", err
    }
    return loginJWT, nil
}

// resolveEnvTokenCellSubject builds the exchange subject from ENTIRE_TOKEN: the
// env token is the subject login JWT and its aud core is the environment signal
// (passed as dataOrigin) so the audience/core templates follow prod/staging/

Mcmd/entire/cli/auth/cell_data_api.go+27/-29

422 unmodified lines

423 424 425 426 427 428 429 426 427 428 429 434 430 431 432 433 434 9 unmodified lines

444 445 446 450 451 452 453 447 448 449 450

422 unmodified lines

} }

// TestJurisdictionToken_StoredContext exercises the exported token-only path off // a stored login context: it must return the exchanged identity token and mint // it with scope=openid, the jurisdiction audience, and the login JWT as // subject_token. Not parallel: manipulates env + token store. // TestJurisdictionToken_StoredContext proves the stored path mints from the // ACTIVE login context (like plain entire auth token), deriving the // environment from that context's core rather than the data host. No // ENTIRE_API_BASE_URL is set, so the default (entire.io) data host must NOT // influence the result — only the active context does. // influence the result — only the active context does. Not parallel: manipulates // env + token store. func TestJurisdictionToken_StoredContext(t *testing.T) { configDir := t.TempDir() t.Setenv("ENTIRE_CONFIG_DIR", configDir) 9 unmodified lines

if err := tokenstore.Set(svc, "me", tokenstore.EncodeTokenWithExpiration(loginJWT, 7200)); err != nil { t.Fatalf("seed token: %v", err) } ctxObj := &contexts.Context{Name: "me@entire", CoreURL: core, Handle: "me", KeychainService: svc} if err := contexts.Save(configDir, &contexts.File{CurrentContext: ctxObj.Name, Contexts: []*contexts.Context{ctxObj}}); err != nil { t.Fatalf("save contexts: %v", err) } writeActiveContext(t, configDir, "me@entire", core, "me", svc)

ct := &captureTransport{token: "cell-identity-token"} t.Cleanup(SetCellExchangeTransportForTest(t, ct))


Mcmd/entire/cli/auth/cell_data_api_test.go+3/-9