diff --git a/cmd/whoami/whoami.go b/cmd/whoami/whoami.go index bc4124fa6..e6c31ce16 100644 --- a/cmd/whoami/whoami.go +++ b/cmd/whoami/whoami.go @@ -35,15 +35,14 @@ type whoamiResult struct { OnBehalfOf *delegatedUser `json:"onBehalfOf,omitempty"` Hint string `json:"hint,omitempty"` - // CredentialSource, Explicit, DirectCredentialEnv, and Suggestion surface - // the cached credential.IdentitySelection computed during resolution (not - // re-inferred here). CredentialSource can be empty ("") on the non-env + // CredentialSource, Explicit, and DirectCredentialEnv surface the cached + // credential.IdentitySelection computed during resolution (not re-inferred + // here). CredentialSource can be empty ("") on the non-env // extension-provider path (e.g. sidecar mode), where no selection kind // applies; this is a documented, valid state, not an error. CredentialSource string `json:"credentialSource"` Explicit bool `json:"explicit"` DirectCredentialEnv credential.DirectCredentialEnv `json:"directCredentialEnv"` - Suggestion string `json:"suggestion,omitempty"` } // delegatedUser is the user a user-identity acts on behalf of. @@ -160,7 +159,6 @@ func buildResult(cfg *core.CliConfig, as core.Identity, source string, diag iden CredentialSource: string(selection.Source), Explicit: selection.Explicit(), DirectCredentialEnv: selection.DirectCredentialEnv, - Suggestion: selection.Suggestion, } // Use the diagnosed hint as-is: it is tailored to the credential source, so // it never says "auth login" when that is blocked under an external provider. diff --git a/cmd/whoami/whoami_test.go b/cmd/whoami/whoami_test.go index 3768d3ba0..201a347c9 100644 --- a/cmd/whoami/whoami_test.go +++ b/cmd/whoami/whoami_test.go @@ -375,8 +375,8 @@ func profileSelectionFactory(t *testing.T) (*cmdutil.Factory, *bytes.Buffer) { // TestWhoamiIncludesCredentialSource locks in the diagnostic fields surfaced // from the cached credential.IdentitySelection (Task 6): credentialSource, -// explicit, directCredentialEnv, and suggestion. whoami must read the cached -// selection as-is, not re-infer it. +// explicit, and directCredentialEnv. whoami must read the cached selection +// as-is, not re-infer it. func TestWhoamiIncludesCredentialSource(t *testing.T) { f, out := profileSelectionFactory(t) @@ -404,9 +404,6 @@ func TestWhoamiIncludesCredentialSource(t *testing.T) { if got.DirectCredentialEnv.Present { t.Fatalf("directCredentialEnv.present = true, want false: %#v", got.DirectCredentialEnv) } - if got.Suggestion == "" { - t.Fatalf("suggestion = empty, want non-empty") - } if !strings.Contains(raw, `"credentialSource": "env:LARKSUITE_CLI_PROFILE"`) { t.Fatalf("raw JSON missing credentialSource literal: %s", raw) } diff --git a/internal/credential/credential_provider.go b/internal/credential/credential_provider.go index 856fac22a..4a6bd6e47 100644 --- a/internal/credential/credential_provider.go +++ b/internal/credential/credential_provider.go @@ -310,7 +310,6 @@ func (p *CredentialProvider) doResolveAccount(ctx context.Context) (*Account, er WithAppID(app.AppId). WithHint("verify the profile's app secret or re-add the profile with `lark-cli config`.") } - p.selection.Suggestion = "如需临时覆盖本条命令,使用 --profile。" p.selectedSource = defaultTokenSource{resolver: p.defaultToken} return acct, nil } diff --git a/internal/credential/credential_provider_selection_test.go b/internal/credential/credential_provider_selection_test.go index d0d517874..fec878f3b 100644 --- a/internal/credential/credential_provider_selection_test.go +++ b/internal/credential/credential_provider_selection_test.go @@ -180,7 +180,7 @@ func TestSelection_State4_EnvComplete(t *testing.T) { if !sel.DirectCredentialEnv.Present { t.Errorf("DirectCredentialEnv.Present = false, want true") } - assertNoSecretLeak(t, "state4", string(sel.Source), sel.Suggestion, sel.DirectCredentialEnv.AppID) + assertNoSecretLeak(t, "state4", string(sel.Source), sel.DirectCredentialEnv.AppID) assertNoSecretLeak(t, "state4-keys", sel.DirectCredentialEnv.Keys...) } @@ -201,7 +201,7 @@ func TestSelection_State5_ProfileOnly(t *testing.T) { if sel.DirectCredentialEnv.Present { t.Errorf("DirectCredentialEnv.Present = true, want false") } - assertNoSecretLeak(t, "state5", string(sel.Source), sel.Suggestion) + assertNoSecretLeak(t, "state5", string(sel.Source)) } // State #5b: P valid from env (not flag) -> env:LARKSUITE_CLI_PROFILE source. @@ -325,9 +325,6 @@ func TestSelection_State7_UnderlyingErrorContainingSecret_NotLeaked(t *testing.T if strings.Contains(string(sel.Source), secretMarkerValue) { t.Errorf("Selection.Source leaked secret marker: %q", sel.Source) } - if strings.Contains(sel.Suggestion, secretMarkerValue) { - t.Errorf("Selection.Suggestion leaked secret marker: %q", sel.Suggestion) - } if strings.Contains(sel.DirectCredentialEnv.AppID, secretMarkerValue) { t.Errorf("Selection.DirectCredentialEnv.AppID leaked secret marker: %q", sel.DirectCredentialEnv.AppID) } @@ -340,7 +337,7 @@ func TestSelection_State7_UnderlyingErrorContainingSecret_NotLeaked(t *testing.T // doResolveAccount); assert it is zero-valued, which trivially implies no // marker anywhere in it and guards against a future field being populated // from the failed resolution. - if sel.Source != "" || sel.Suggestion != "" || sel.DirectCredentialEnv.Present || + if sel.Source != "" || sel.DirectCredentialEnv.Present || sel.DirectCredentialEnv.AppID != "" || len(sel.DirectCredentialEnv.Keys) != 0 { t.Errorf("Selection() = %+v, want zero value on profile_secret_invalid", sel) } @@ -366,7 +363,7 @@ func TestSelection_State8_ProfileMatchesEnv(t *testing.T) { if sel.DirectCredentialEnv.AppID != "cli_a" { t.Errorf("DirectCredentialEnv.AppID = %q, want cli_a", sel.DirectCredentialEnv.AppID) } - assertNoSecretLeak(t, "state8", string(sel.Source), sel.Suggestion, sel.DirectCredentialEnv.AppID) + assertNoSecretLeak(t, "state8", string(sel.Source), sel.DirectCredentialEnv.AppID) assertNoSecretLeak(t, "state8-keys", sel.DirectCredentialEnv.Keys...) } @@ -469,7 +466,7 @@ func TestSelection_NonEnvExtensionProviderWinsOverProfile(t *testing.T) { t.Errorf("got profile_app_credential_conflict, want none for non-env provider") } } - assertNoSecretLeak(t, "nonenv-sidecar", string(sel.Source), sel.Suggestion, sel.DirectCredentialEnv.AppID) + assertNoSecretLeak(t, "nonenv-sidecar", string(sel.Source), sel.DirectCredentialEnv.AppID) } // State #1: P none, E none, C present -> config default (currentApp). diff --git a/internal/credential/identity_selection.go b/internal/credential/identity_selection.go index 875c775d7..bc2dadcc7 100644 --- a/internal/credential/identity_selection.go +++ b/internal/credential/identity_selection.go @@ -29,7 +29,6 @@ type DirectCredentialEnv struct { type IdentitySelection struct { Source CredentialSourceKind DirectCredentialEnv DirectCredentialEnv - Suggestion string } // Explicit reports whether the identity was actively specified by the