fix: honor runtime credential sources in config views

Change-Id: I40b2ffedc5c1db5e08e86b9472ea2b84fa02bb29
This commit is contained in:
梁硕
2026-04-06 00:23:01 +08:00
parent faea09d15e
commit b3bfd526c5
5 changed files with 125 additions and 12 deletions
+18 -6
View File
@@ -31,12 +31,7 @@ func NewCmdConfigDefaultAs(f *cmdutil.Factory) *cobra.Command {
}
if len(args) == 0 {
current := app.DefaultAs
if current == "" {
current = "auto"
}
fmt.Fprintf(f.IOStreams.Out, "default-as: %s\n", current)
return nil
return showDefaultAs(f, app)
}
value := args[0]
@@ -54,3 +49,20 @@ func NewCmdConfigDefaultAs(f *cmdutil.Factory) *cobra.Command {
}
return cmd
}
func showDefaultAs(f *cmdutil.Factory, app *core.AppConfig) error {
current := ""
if f != nil && f.Config != nil {
if cfg, err := f.Config(); err == nil && cfg != nil {
current = cfg.DefaultAs
}
}
if current == "" && app != nil {
current = app.DefaultAs
}
if current == "" {
current = "auto"
}
fmt.Fprintf(f.IOStreams.Out, "default-as: %s\n", current)
return nil
}
+17 -6
View File
@@ -4,8 +4,8 @@
package config
import (
"context"
"fmt"
"os"
"github.com/larksuite/cli/internal/cmdutil"
"github.com/larksuite/cli/internal/core"
@@ -81,19 +81,30 @@ func showStrictMode(f *cmdutil.Factory, multi *core.MultiAppConfig, app *core.Ap
// Runtime effective mode from credential provider chain is the source of truth.
runtime := f.ResolveStrictMode()
configMode, configSource := resolveStrictModeStatus(multi, app)
if source := resolveRuntimeStrictModeSource(f); source != "" {
fmt.Fprintf(f.IOStreams.Out, "strict-mode: %s (source: %s)\n", runtime, source)
return nil
}
if runtime != configMode {
source := "credential provider"
if os.Getenv("LARKSUITE_CLI_STRICT_MODE") != "" {
source = "env LARKSUITE_CLI_STRICT_MODE"
}
fmt.Fprintf(f.IOStreams.Out, "strict-mode: %s (source: %s)\n", runtime, source)
fmt.Fprintf(f.IOStreams.Out, "strict-mode: %s (source: credential provider)\n", runtime)
return nil
}
fmt.Fprintf(f.IOStreams.Out, "strict-mode: %s (source: %s)\n", configMode, configSource)
return nil
}
func resolveRuntimeStrictModeSource(f *cmdutil.Factory) string {
if f == nil || f.Credential == nil {
return ""
}
name, err := f.Credential.ResolveSourceName(context.Background())
if err != nil || name == "" || name == "default" {
return ""
}
return fmt.Sprintf("credential provider %q", name)
}
func setStrictMode(f *cmdutil.Factory, multi *core.MultiAppConfig, app *core.AppConfig, value string, global bool) error {
mode := core.StrictMode(value)
switch mode {
+57
View File
@@ -4,13 +4,29 @@
package config
import (
"context"
"strings"
"testing"
extcred "github.com/larksuite/cli/extension/credential"
"github.com/larksuite/cli/internal/cmdutil"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/credential"
)
type stubStrictModeProvider struct {
name string
account *extcred.Account
}
func (p *stubStrictModeProvider) Name() string { return p.name }
func (p *stubStrictModeProvider) ResolveAccount(ctx context.Context) (*extcred.Account, error) {
return p.account, nil
}
func (p *stubStrictModeProvider) ResolveToken(ctx context.Context, req extcred.TokenSpec) (*extcred.Token, error) {
return nil, nil
}
func setupStrictModeTestConfig(t *testing.T) {
t.Helper()
dir := t.TempDir()
@@ -130,3 +146,44 @@ func TestStrictMode_InvalidValue(t *testing.T) {
t.Error("expected error for invalid value 'on'")
}
}
func TestStrictMode_Show_PrefersExternalCredentialSourceEvenWhenValueMatchesConfig(t *testing.T) {
setupStrictModeTestConfig(t)
multi, err := core.LoadMultiAppConfig()
if err != nil {
t.Fatal(err)
}
mode := core.StrictModeBot
multi.Apps[0].StrictMode = &mode
if err := core.SaveMultiAppConfig(multi); err != nil {
t.Fatal(err)
}
f, stdout, _, _ := cmdutil.TestFactory(t, &core.CliConfig{AppID: "test-app", AppSecret: "secret"})
f.Credential = credential.NewCredentialProvider(
[]extcred.Provider{&stubStrictModeProvider{
name: "env",
account: &extcred.Account{
AppID: "env-app",
AppSecret: "env-secret",
Brand: string(core.BrandFeishu),
SupportedIdentities: extcred.SupportsBot,
},
}},
nil,
nil,
nil,
)
cmd := NewCmdConfigStrictMode(f)
cmd.SetArgs([]string{})
if err := cmd.Execute(); err != nil {
t.Fatal(err)
}
want := `strict-mode: bot (source: credential provider "env")`
if !strings.Contains(stdout.String(), want) {
t.Fatalf("output = %q, want substring %q", stdout.String(), want)
}
}
@@ -254,6 +254,19 @@ func (p *CredentialProvider) selectedCredentialSource(ctx context.Context) (cred
return p.selectedSource, nil
}
func (p *CredentialProvider) ResolveSourceName(ctx context.Context) (string, error) {
if p.selectedSource == nil {
if _, err := p.ResolveAccount(ctx); err != nil {
return "", err
}
}
source := p.selectedSource
if source == nil {
return "", nil
}
return source.Name(), nil
}
func resolveTokenFromSource(ctx context.Context, source credentialSource, req TokenSpec) (*TokenResult, error) {
result, found, err := source.TryResolveToken(ctx, req)
if err != nil {
@@ -320,6 +320,26 @@ func TestCredentialProvider_ResolveTokenTreatsEmptyDefaultTokenAsMalformed(t *te
}
}
func TestCredentialProvider_ResolveSourceName_SelectedExtensionSource(t *testing.T) {
cp := NewCredentialProvider(
[]extcred.Provider{&mockExtProvider{
name: "env",
account: &extcred.Account{AppID: "ext_app", Brand: "feishu"},
}},
nil,
nil,
nil,
)
name, err := cp.ResolveSourceName(context.Background())
if err != nil {
t.Fatalf("ResolveSourceName() error = %v", err)
}
if name != "env" {
t.Fatalf("ResolveSourceName() = %q, want %q", name, "env")
}
}
func TestCredentialProvider_ResolveAccountDoesNotEnrichWithTokenFromDifferentProvider(t *testing.T) {
httpClientCalls := 0
cp := NewCredentialProvider(