refactor(extension): remove internal package dependencies

This commit is contained in:
shanglei
2026-07-25 16:52:10 +08:00
parent 217f4e5567
commit 8ba2431192
22 changed files with 232 additions and 229 deletions

View File

@@ -14,11 +14,11 @@ import (
"github.com/larksuite/cli/cmd/api"
"github.com/larksuite/cli/cmd/auth"
"github.com/larksuite/cli/cmd/service"
"github.com/larksuite/cli/envnames"
"github.com/larksuite/cli/internal/apicatalog"
"github.com/larksuite/cli/internal/build"
"github.com/larksuite/cli/internal/cmdutil"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/internal/httpmock"
"github.com/larksuite/cli/internal/meta"
"github.com/larksuite/cli/internal/output"
@@ -157,11 +157,11 @@ func strictModeFixtureCatalog() apicatalog.Catalog {
func newStrictModeDefaultFactory(t *testing.T, profile string, mode core.StrictMode) (*cmdutil.Factory, *bytes.Buffer, *bytes.Buffer) {
t.Helper()
t.Setenv(envvars.CliAppID, "")
t.Setenv(envvars.CliAppSecret, "")
t.Setenv(envvars.CliUserAccessToken, "")
t.Setenv(envvars.CliTenantAccessToken, "")
t.Setenv(envvars.CliDefaultAs, "")
t.Setenv(envnames.CliAppID, "")
t.Setenv(envnames.CliAppSecret, "")
t.Setenv(envnames.CliUserAccessToken, "")
t.Setenv(envnames.CliTenantAccessToken, "")
t.Setenv(envnames.CliDefaultAs, "")
dir := t.TempDir()
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", dir)

View File

@@ -6,8 +6,8 @@ package cmd
import (
"os"
"github.com/larksuite/cli/envnames"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/envvars"
)
// ResolveStartupBrand resolves the brand before the command tree is built, so
@@ -16,7 +16,7 @@ import (
// environment, then the active profile's raw config entry — without touching
// the keychain (no secrets are needed to know the brand).
func ResolveStartupBrand(profile string) core.LarkBrand {
if raw := os.Getenv(envvars.CliBrand); raw != "" {
if raw := os.Getenv(envnames.CliBrand); raw != "" {
return core.ParseBrand(raw)
}
if cfg, err := core.LoadMultiAppConfig(); err == nil {

18
envnames/envnames.go Normal file
View File

@@ -0,0 +1,18 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
// Package envnames defines environment variable names shared by the CLI and
// its public extension packages.
package envnames
const (
CliAppID = "LARKSUITE_CLI_APP_ID"
CliAppSecret = "LARKSUITE_CLI_APP_SECRET"
CliBrand = "LARKSUITE_CLI_BRAND"
CliUserAccessToken = "LARKSUITE_CLI_USER_ACCESS_TOKEN"
CliTenantAccessToken = "LARKSUITE_CLI_TENANT_ACCESS_TOKEN"
CliDefaultAs = "LARKSUITE_CLI_DEFAULT_AS"
CliStrictMode = "LARKSUITE_CLI_STRICT_MODE"
CliAuthProxy = "LARKSUITE_CLI_AUTH_PROXY"
CliProxyKey = "LARKSUITE_CLI_PROXY_KEY"
)

View File

@@ -7,10 +7,10 @@ import (
"context"
"fmt"
"os"
"strings"
"github.com/larksuite/cli/envnames"
"github.com/larksuite/cli/extension/credential"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/envvars"
)
// Provider resolves credentials from environment variables.
@@ -19,33 +19,33 @@ type Provider struct{}
func (p *Provider) Name() string { return "env" }
func (p *Provider) ResolveAccount(ctx context.Context) (*credential.Account, error) {
appID := os.Getenv(envvars.CliAppID)
appSecret := os.Getenv(envvars.CliAppSecret)
hasUAT := os.Getenv(envvars.CliUserAccessToken) != ""
hasTAT := os.Getenv(envvars.CliTenantAccessToken) != ""
appID := os.Getenv(envnames.CliAppID)
appSecret := os.Getenv(envnames.CliAppSecret)
hasUAT := os.Getenv(envnames.CliUserAccessToken) != ""
hasTAT := os.Getenv(envnames.CliTenantAccessToken) != ""
if appID == "" && appSecret == "" {
switch {
case hasUAT:
return nil, &credential.BlockError{Provider: "env", Reason: envvars.CliUserAccessToken + " is set but " + envvars.CliAppID + " is missing"}
return nil, &credential.BlockError{Provider: "env", Reason: envnames.CliUserAccessToken + " is set but " + envnames.CliAppID + " is missing"}
case hasTAT:
return nil, &credential.BlockError{Provider: "env", Reason: envvars.CliTenantAccessToken + " is set but " + envvars.CliAppID + " is missing"}
return nil, &credential.BlockError{Provider: "env", Reason: envnames.CliTenantAccessToken + " is set but " + envnames.CliAppID + " is missing"}
default:
return nil, nil
}
}
if appID == "" {
return nil, &credential.BlockError{Provider: "env", Reason: envvars.CliAppSecret + " is set but " + envvars.CliAppID + " is missing"}
return nil, &credential.BlockError{Provider: "env", Reason: envnames.CliAppSecret + " is set but " + envnames.CliAppID + " is missing"}
}
if appSecret == "" && !hasUAT && !hasTAT {
return nil, &credential.BlockError{
Provider: "env",
Reason: envvars.CliAppID + " is set but no app secret or access token is available",
Reason: envnames.CliAppID + " is set but no app secret or access token is available",
}
}
brand := credential.Brand(core.ParseBrand(os.Getenv(envvars.CliBrand)))
brand := parseBrand(os.Getenv(envnames.CliBrand))
acct := &credential.Account{AppID: appID, AppSecret: appSecret, Brand: brand}
switch id := credential.Identity(os.Getenv(envvars.CliDefaultAs)); id {
switch id := credential.Identity(os.Getenv(envnames.CliDefaultAs)); id {
case "", credential.IdentityAuto:
acct.DefaultAs = id
case credential.IdentityUser, credential.IdentityBot:
@@ -53,12 +53,12 @@ func (p *Provider) ResolveAccount(ctx context.Context) (*credential.Account, err
default:
return nil, &credential.BlockError{
Provider: "env",
Reason: fmt.Sprintf("invalid %s %q (want user, bot, or auto)", envvars.CliDefaultAs, id),
Reason: fmt.Sprintf("invalid %s %q (want user, bot, or auto)", envnames.CliDefaultAs, id),
}
}
// Explicit strict mode policy takes priority
switch strictMode := os.Getenv(envvars.CliStrictMode); strictMode {
switch strictMode := os.Getenv(envnames.CliStrictMode); strictMode {
case "bot":
acct.SupportedIdentities = credential.SupportsBot
case "user":
@@ -76,7 +76,7 @@ func (p *Provider) ResolveAccount(ctx context.Context) (*credential.Account, err
default:
return nil, &credential.BlockError{
Provider: "env",
Reason: fmt.Sprintf("invalid %s %q (want bot, user, or off)", envvars.CliStrictMode, strictMode),
Reason: fmt.Sprintf("invalid %s %q (want bot, user, or off)", envnames.CliStrictMode, strictMode),
}
}
@@ -96,9 +96,9 @@ func (p *Provider) ResolveToken(ctx context.Context, req credential.TokenSpec) (
var envKey string
switch req.Type {
case credential.TokenTypeUAT:
envKey = envvars.CliUserAccessToken
envKey = envnames.CliUserAccessToken
case credential.TokenTypeTAT:
envKey = envvars.CliTenantAccessToken
envKey = envnames.CliTenantAccessToken
default:
return nil, nil
}
@@ -109,6 +109,13 @@ func (p *Provider) ResolveToken(ctx context.Context, req credential.TokenSpec) (
return &credential.Token{Value: token, Source: "env:" + envKey}, nil
}
func parseBrand(value string) credential.Brand {
if strings.ToLower(strings.TrimSpace(value)) == "lark" {
return credential.BrandLark
}
return credential.BrandFeishu
}
func init() {
credential.Register(&Provider{})
}

View File

@@ -9,8 +9,8 @@ import (
"strings"
"testing"
"github.com/larksuite/cli/envnames"
"github.com/larksuite/cli/extension/credential"
"github.com/larksuite/cli/internal/envvars"
)
func TestProvider_Name(t *testing.T) {
@@ -20,9 +20,9 @@ func TestProvider_Name(t *testing.T) {
}
func TestResolveAccount_BothSet(t *testing.T) {
t.Setenv(envvars.CliAppID, "cli_test")
t.Setenv(envvars.CliAppSecret, "secret_test")
t.Setenv(envvars.CliBrand, " LARK ")
t.Setenv(envnames.CliAppID, "cli_test")
t.Setenv(envnames.CliAppSecret, "secret_test")
t.Setenv(envnames.CliBrand, " LARK ")
acct, err := (&Provider{}).ResolveAccount(context.Background())
if err != nil {
@@ -41,7 +41,7 @@ func TestResolveAccount_NeitherSet(t *testing.T) {
}
func TestResolveAccount_OnlyIDSet(t *testing.T) {
t.Setenv(envvars.CliAppID, "cli_test")
t.Setenv(envnames.CliAppID, "cli_test")
_, err := (&Provider{}).ResolveAccount(context.Background())
var blockErr *credential.BlockError
if !errors.As(err, &blockErr) {
@@ -50,8 +50,8 @@ func TestResolveAccount_OnlyIDSet(t *testing.T) {
}
func TestResolveAccount_AppIDAndUserTokenWithoutSecret(t *testing.T) {
t.Setenv(envvars.CliAppID, "cli_test")
t.Setenv(envvars.CliUserAccessToken, "uat_test")
t.Setenv(envnames.CliAppID, "cli_test")
t.Setenv(envnames.CliUserAccessToken, "uat_test")
acct, err := (&Provider{}).ResolveAccount(context.Background())
if err != nil {
@@ -69,7 +69,7 @@ func TestResolveAccount_AppIDAndUserTokenWithoutSecret(t *testing.T) {
}
func TestResolveAccount_OnlySecretSet(t *testing.T) {
t.Setenv(envvars.CliAppSecret, "secret_test")
t.Setenv(envnames.CliAppSecret, "secret_test")
_, err := (&Provider{}).ResolveAccount(context.Background())
var blockErr *credential.BlockError
if !errors.As(err, &blockErr) {
@@ -78,21 +78,21 @@ func TestResolveAccount_OnlySecretSet(t *testing.T) {
}
func TestResolveAccount_OnlyTokenSetWithoutAppID(t *testing.T) {
t.Setenv(envvars.CliUserAccessToken, "uat_test")
t.Setenv(envnames.CliUserAccessToken, "uat_test")
_, err := (&Provider{}).ResolveAccount(context.Background())
var blockErr *credential.BlockError
if !errors.As(err, &blockErr) {
t.Fatalf("expected BlockError, got %v", err)
}
if !strings.Contains(err.Error(), envvars.CliAppID) {
t.Fatalf("error = %v, want mention of %s", err, envvars.CliAppID)
if !strings.Contains(err.Error(), envnames.CliAppID) {
t.Fatalf("error = %v, want mention of %s", err, envnames.CliAppID)
}
}
func TestResolveAccount_DefaultBrand(t *testing.T) {
t.Setenv(envvars.CliAppID, "cli_test")
t.Setenv(envvars.CliAppSecret, "secret_test")
t.Setenv(envnames.CliAppID, "cli_test")
t.Setenv(envnames.CliAppSecret, "secret_test")
acct, _ := (&Provider{}).ResolveAccount(context.Background())
if acct.Brand != "feishu" {
t.Errorf("expected 'feishu', got %q", acct.Brand)
@@ -100,9 +100,9 @@ func TestResolveAccount_DefaultBrand(t *testing.T) {
}
func TestResolveAccount_DefaultAsFromEnv(t *testing.T) {
t.Setenv(envvars.CliAppID, "cli_test")
t.Setenv(envvars.CliAppSecret, "secret_test")
t.Setenv(envvars.CliDefaultAs, "user")
t.Setenv(envnames.CliAppID, "cli_test")
t.Setenv(envnames.CliAppSecret, "secret_test")
t.Setenv(envnames.CliDefaultAs, "user")
acct, err := (&Provider{}).ResolveAccount(context.Background())
if err != nil {
@@ -114,23 +114,23 @@ func TestResolveAccount_DefaultAsFromEnv(t *testing.T) {
}
func TestResolveToken_UATSet(t *testing.T) {
t.Setenv(envvars.CliUserAccessToken, "u-env")
t.Setenv(envnames.CliUserAccessToken, "u-env")
tok, err := (&Provider{}).ResolveToken(context.Background(), credential.TokenSpec{Type: credential.TokenTypeUAT})
if err != nil {
t.Fatal(err)
}
if tok.Value != "u-env" || tok.Source != "env:"+envvars.CliUserAccessToken {
if tok.Value != "u-env" || tok.Source != "env:"+envnames.CliUserAccessToken {
t.Errorf("unexpected: %+v", tok)
}
}
func TestResolveToken_TATSet(t *testing.T) {
t.Setenv(envvars.CliTenantAccessToken, "t-env")
t.Setenv(envnames.CliTenantAccessToken, "t-env")
tok, err := (&Provider{}).ResolveToken(context.Background(), credential.TokenSpec{Type: credential.TokenTypeTAT})
if err != nil {
t.Fatal(err)
}
if tok.Value != "t-env" || tok.Source != "env:"+envvars.CliTenantAccessToken {
if tok.Value != "t-env" || tok.Source != "env:"+envnames.CliTenantAccessToken {
t.Errorf("unexpected: %+v", tok)
}
}
@@ -143,9 +143,9 @@ func TestResolveToken_NotSet(t *testing.T) {
}
func TestResolveAccount_StrictModeBot(t *testing.T) {
t.Setenv(envvars.CliAppID, "app")
t.Setenv(envvars.CliAppSecret, "secret")
t.Setenv(envvars.CliStrictMode, "bot")
t.Setenv(envnames.CliAppID, "app")
t.Setenv(envnames.CliAppSecret, "secret")
t.Setenv(envnames.CliStrictMode, "bot")
acct, err := (&Provider{}).ResolveAccount(context.Background())
if err != nil {
t.Fatal(err)
@@ -156,9 +156,9 @@ func TestResolveAccount_StrictModeBot(t *testing.T) {
}
func TestResolveAccount_StrictModeUser(t *testing.T) {
t.Setenv(envvars.CliAppID, "app")
t.Setenv(envvars.CliAppSecret, "secret")
t.Setenv(envvars.CliStrictMode, "user")
t.Setenv(envnames.CliAppID, "app")
t.Setenv(envnames.CliAppSecret, "secret")
t.Setenv(envnames.CliStrictMode, "user")
acct, err := (&Provider{}).ResolveAccount(context.Background())
if err != nil {
t.Fatal(err)
@@ -169,9 +169,9 @@ func TestResolveAccount_StrictModeUser(t *testing.T) {
}
func TestResolveAccount_StrictModeOff(t *testing.T) {
t.Setenv(envvars.CliAppID, "app")
t.Setenv(envvars.CliAppSecret, "secret")
t.Setenv(envvars.CliStrictMode, "off")
t.Setenv(envnames.CliAppID, "app")
t.Setenv(envnames.CliAppSecret, "secret")
t.Setenv(envnames.CliStrictMode, "off")
acct, err := (&Provider{}).ResolveAccount(context.Background())
if err != nil {
t.Fatal(err)
@@ -182,9 +182,9 @@ func TestResolveAccount_StrictModeOff(t *testing.T) {
}
func TestResolveAccount_InferFromUATOnly(t *testing.T) {
t.Setenv(envvars.CliAppID, "app")
t.Setenv(envvars.CliAppSecret, "secret")
t.Setenv(envvars.CliUserAccessToken, "u-tok")
t.Setenv(envnames.CliAppID, "app")
t.Setenv(envnames.CliAppSecret, "secret")
t.Setenv(envnames.CliUserAccessToken, "u-tok")
acct, err := (&Provider{}).ResolveAccount(context.Background())
if err != nil {
t.Fatal(err)
@@ -198,9 +198,9 @@ func TestResolveAccount_InferFromUATOnly(t *testing.T) {
}
func TestResolveAccount_InferFromTATOnly(t *testing.T) {
t.Setenv(envvars.CliAppID, "app")
t.Setenv(envvars.CliAppSecret, "secret")
t.Setenv(envvars.CliTenantAccessToken, "t-tok")
t.Setenv(envnames.CliAppID, "app")
t.Setenv(envnames.CliAppSecret, "secret")
t.Setenv(envnames.CliTenantAccessToken, "t-tok")
acct, err := (&Provider{}).ResolveAccount(context.Background())
if err != nil {
t.Fatal(err)
@@ -214,10 +214,10 @@ func TestResolveAccount_InferFromTATOnly(t *testing.T) {
}
func TestResolveAccount_InferBothTokens(t *testing.T) {
t.Setenv(envvars.CliAppID, "app")
t.Setenv(envvars.CliAppSecret, "secret")
t.Setenv(envvars.CliUserAccessToken, "u-tok")
t.Setenv(envvars.CliTenantAccessToken, "t-tok")
t.Setenv(envnames.CliAppID, "app")
t.Setenv(envnames.CliAppSecret, "secret")
t.Setenv(envnames.CliUserAccessToken, "u-tok")
t.Setenv(envnames.CliTenantAccessToken, "t-tok")
acct, err := (&Provider{}).ResolveAccount(context.Background())
if err != nil {
t.Fatal(err)
@@ -231,11 +231,11 @@ func TestResolveAccount_InferBothTokens(t *testing.T) {
}
func TestResolveAccount_StrictModeOverridesTokenInference(t *testing.T) {
t.Setenv(envvars.CliAppID, "app")
t.Setenv(envvars.CliAppSecret, "secret")
t.Setenv(envvars.CliUserAccessToken, "u-tok")
t.Setenv(envvars.CliTenantAccessToken, "t-tok")
t.Setenv(envvars.CliStrictMode, "bot")
t.Setenv(envnames.CliAppID, "app")
t.Setenv(envnames.CliAppSecret, "secret")
t.Setenv(envnames.CliUserAccessToken, "u-tok")
t.Setenv(envnames.CliTenantAccessToken, "t-tok")
t.Setenv(envnames.CliStrictMode, "bot")
acct, err := (&Provider{}).ResolveAccount(context.Background())
if err != nil {
t.Fatal(err)
@@ -246,9 +246,9 @@ func TestResolveAccount_StrictModeOverridesTokenInference(t *testing.T) {
}
func TestResolveAccount_InvalidStrictModeRejected(t *testing.T) {
t.Setenv(envvars.CliAppID, "app")
t.Setenv(envvars.CliAppSecret, "secret")
t.Setenv(envvars.CliStrictMode, "invalid")
t.Setenv(envnames.CliAppID, "app")
t.Setenv(envnames.CliAppSecret, "secret")
t.Setenv(envnames.CliStrictMode, "invalid")
_, err := (&Provider{}).ResolveAccount(context.Background())
if err == nil {
@@ -258,15 +258,15 @@ func TestResolveAccount_InvalidStrictModeRejected(t *testing.T) {
if !errors.As(err, &blockErr) {
t.Fatalf("expected BlockError, got %T", err)
}
if !strings.Contains(err.Error(), envvars.CliStrictMode) {
t.Fatalf("error = %v, want mention of %s", err, envvars.CliStrictMode)
if !strings.Contains(err.Error(), envnames.CliStrictMode) {
t.Fatalf("error = %v, want mention of %s", err, envnames.CliStrictMode)
}
}
func TestResolveAccount_InvalidDefaultAsRejected(t *testing.T) {
t.Setenv(envvars.CliAppID, "app")
t.Setenv(envvars.CliAppSecret, "secret")
t.Setenv(envvars.CliDefaultAs, "invalid")
t.Setenv(envnames.CliAppID, "app")
t.Setenv(envnames.CliAppSecret, "secret")
t.Setenv(envnames.CliDefaultAs, "invalid")
_, err := (&Provider{}).ResolveAccount(context.Background())
if err == nil {
@@ -276,7 +276,7 @@ func TestResolveAccount_InvalidDefaultAsRejected(t *testing.T) {
if !errors.As(err, &blockErr) {
t.Fatalf("expected BlockError, got %T", err)
}
if !strings.Contains(err.Error(), envvars.CliDefaultAs) {
t.Fatalf("error = %v, want mention of %s", err, envvars.CliDefaultAs)
if !strings.Contains(err.Error(), envnames.CliDefaultAs) {
t.Fatalf("error = %v, want mention of %s", err, envnames.CliDefaultAs)
}
}

View File

@@ -14,10 +14,10 @@ import (
"context"
"fmt"
"os"
"strings"
"github.com/larksuite/cli/envnames"
"github.com/larksuite/cli/extension/credential"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/sidecar"
)
@@ -32,7 +32,7 @@ func (p *Provider) Priority() int { return 0 }
// placeholder secret, and SupportedIdentities derived from STRICT_MODE.
// Returns nil, nil when sidecar mode is not active (AUTH_PROXY not set).
func (p *Provider) ResolveAccount(ctx context.Context) (*credential.Account, error) {
proxyAddr := os.Getenv(envvars.CliAuthProxy)
proxyAddr := os.Getenv(envnames.CliAuthProxy)
if proxyAddr == "" {
return nil, nil // not in sidecar mode, skip
}
@@ -40,26 +40,26 @@ func (p *Provider) ResolveAccount(ctx context.Context) (*credential.Account, err
if err := sidecar.ValidateProxyAddr(proxyAddr); err != nil {
return nil, &credential.BlockError{
Provider: "sidecar",
Reason: fmt.Sprintf("invalid %s %q: %v", envvars.CliAuthProxy, proxyAddr, err),
Reason: fmt.Sprintf("invalid %s %q: %v", envnames.CliAuthProxy, proxyAddr, err),
}
}
appID := os.Getenv(envvars.CliAppID)
appID := os.Getenv(envnames.CliAppID)
if appID == "" {
return nil, &credential.BlockError{
Provider: "sidecar",
Reason: envvars.CliAuthProxy + " is set but " + envvars.CliAppID + " is missing",
Reason: envnames.CliAuthProxy + " is set but " + envnames.CliAppID + " is missing",
}
}
if os.Getenv(envvars.CliProxyKey) == "" {
if os.Getenv(envnames.CliProxyKey) == "" {
return nil, &credential.BlockError{
Provider: "sidecar",
Reason: envvars.CliAuthProxy + " is set but " + envvars.CliProxyKey + " is missing",
Reason: envnames.CliAuthProxy + " is set but " + envnames.CliProxyKey + " is missing",
}
}
brand := credential.Brand(core.ParseBrand(os.Getenv(envvars.CliBrand)))
brand := parseBrand(os.Getenv(envnames.CliBrand))
acct := &credential.Account{
AppID: appID,
@@ -68,7 +68,7 @@ func (p *Provider) ResolveAccount(ctx context.Context) (*credential.Account, err
}
// Parse DefaultAs
switch id := credential.Identity(os.Getenv(envvars.CliDefaultAs)); id {
switch id := credential.Identity(os.Getenv(envnames.CliDefaultAs)); id {
case "", credential.IdentityAuto:
acct.DefaultAs = id
case credential.IdentityUser, credential.IdentityBot:
@@ -76,12 +76,12 @@ func (p *Provider) ResolveAccount(ctx context.Context) (*credential.Account, err
default:
return nil, &credential.BlockError{
Provider: "sidecar",
Reason: fmt.Sprintf("invalid %s %q (want user, bot, or auto)", envvars.CliDefaultAs, id),
Reason: fmt.Sprintf("invalid %s %q (want user, bot, or auto)", envnames.CliDefaultAs, id),
}
}
// Parse SupportedIdentities from STRICT_MODE, default to SupportsAll.
switch strictMode := os.Getenv(envvars.CliStrictMode); strictMode {
switch strictMode := os.Getenv(envnames.CliStrictMode); strictMode {
case "bot":
acct.SupportedIdentities = credential.SupportsBot
case "user":
@@ -91,7 +91,7 @@ func (p *Provider) ResolveAccount(ctx context.Context) (*credential.Account, err
default:
return nil, &credential.BlockError{
Provider: "sidecar",
Reason: fmt.Sprintf("invalid %s %q (want bot, user, or off)", envvars.CliStrictMode, strictMode),
Reason: fmt.Sprintf("invalid %s %q (want bot, user, or off)", envnames.CliStrictMode, strictMode),
}
}
@@ -103,7 +103,7 @@ func (p *Provider) ResolveAccount(ctx context.Context) (*credential.Account, err
// (user vs bot), strips it, and the sidecar injects the real token.
// Returns nil, nil when sidecar mode is not active.
func (p *Provider) ResolveToken(ctx context.Context, req credential.TokenSpec) (*credential.Token, error) {
if os.Getenv(envvars.CliAuthProxy) == "" {
if os.Getenv(envnames.CliAuthProxy) == "" {
return nil, nil
}
@@ -124,6 +124,13 @@ func (p *Provider) ResolveToken(ctx context.Context, req credential.TokenSpec) (
}, nil
}
func parseBrand(value string) credential.Brand {
if strings.ToLower(strings.TrimSpace(value)) == "lark" {
return credential.BrandLark
}
return credential.BrandFeishu
}
func init() {
credential.Register(&Provider{})
}

View File

@@ -10,8 +10,8 @@ import (
"os"
"testing"
"github.com/larksuite/cli/envnames"
"github.com/larksuite/cli/extension/credential"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/sidecar"
)
@@ -40,7 +40,7 @@ func unsetEnv(t *testing.T, key string) {
}
func TestResolveAccount_NotActive(t *testing.T) {
unsetEnv(t, envvars.CliAuthProxy)
unsetEnv(t, envnames.CliAuthProxy)
p := &Provider{}
acct, err := p.ResolveAccount(context.Background())
@@ -53,12 +53,12 @@ func TestResolveAccount_NotActive(t *testing.T) {
}
func TestResolveAccount_Active(t *testing.T) {
setEnv(t, envvars.CliAuthProxy, "http://127.0.0.1:16384")
setEnv(t, envvars.CliProxyKey, "test-key")
setEnv(t, envvars.CliAppID, "cli_test123")
setEnv(t, envvars.CliBrand, " LARK ")
unsetEnv(t, envvars.CliDefaultAs)
unsetEnv(t, envvars.CliStrictMode)
setEnv(t, envnames.CliAuthProxy, "http://127.0.0.1:16384")
setEnv(t, envnames.CliProxyKey, "test-key")
setEnv(t, envnames.CliAppID, "cli_test123")
setEnv(t, envnames.CliBrand, " LARK ")
unsetEnv(t, envnames.CliDefaultAs)
unsetEnv(t, envnames.CliStrictMode)
p := &Provider{}
acct, err := p.ResolveAccount(context.Background())
@@ -83,9 +83,9 @@ func TestResolveAccount_Active(t *testing.T) {
}
func TestResolveAccount_MissingProxyKey(t *testing.T) {
setEnv(t, envvars.CliAuthProxy, "http://127.0.0.1:16384")
unsetEnv(t, envvars.CliProxyKey)
setEnv(t, envvars.CliAppID, "cli_test")
setEnv(t, envnames.CliAuthProxy, "http://127.0.0.1:16384")
unsetEnv(t, envnames.CliProxyKey)
setEnv(t, envnames.CliAppID, "cli_test")
p := &Provider{}
_, err := p.ResolveAccount(context.Background())
@@ -98,9 +98,9 @@ func TestResolveAccount_MissingProxyKey(t *testing.T) {
}
func TestResolveAccount_MissingAppID(t *testing.T) {
setEnv(t, envvars.CliAuthProxy, "http://127.0.0.1:16384")
setEnv(t, envvars.CliProxyKey, "test-key")
unsetEnv(t, envvars.CliAppID)
setEnv(t, envnames.CliAuthProxy, "http://127.0.0.1:16384")
setEnv(t, envnames.CliProxyKey, "test-key")
unsetEnv(t, envnames.CliAppID)
p := &Provider{}
_, err := p.ResolveAccount(context.Background())
@@ -113,9 +113,9 @@ func TestResolveAccount_MissingAppID(t *testing.T) {
}
func TestResolveAccount_StrictMode(t *testing.T) {
setEnv(t, envvars.CliAuthProxy, "http://127.0.0.1:16384")
setEnv(t, envvars.CliProxyKey, "test-key")
setEnv(t, envvars.CliAppID, "cli_test")
setEnv(t, envnames.CliAuthProxy, "http://127.0.0.1:16384")
setEnv(t, envnames.CliProxyKey, "test-key")
setEnv(t, envnames.CliAppID, "cli_test")
tests := []struct {
mode string
@@ -131,9 +131,9 @@ func TestResolveAccount_StrictMode(t *testing.T) {
for _, tt := range tests {
t.Run("strict_"+tt.mode, func(t *testing.T) {
if tt.mode == "" {
unsetEnv(t, envvars.CliStrictMode)
unsetEnv(t, envnames.CliStrictMode)
} else {
setEnv(t, envvars.CliStrictMode, tt.mode)
setEnv(t, envnames.CliStrictMode, tt.mode)
}
acct, err := p.ResolveAccount(context.Background())
if err != nil {
@@ -147,7 +147,7 @@ func TestResolveAccount_StrictMode(t *testing.T) {
}
func TestResolveToken_NotActive(t *testing.T) {
unsetEnv(t, envvars.CliAuthProxy)
unsetEnv(t, envnames.CliAuthProxy)
p := &Provider{}
tok, err := p.ResolveToken(context.Background(), credential.TokenSpec{Type: credential.TokenTypeUAT})
@@ -160,8 +160,8 @@ func TestResolveToken_NotActive(t *testing.T) {
}
func TestResolveToken_Sentinels(t *testing.T) {
setEnv(t, envvars.CliAuthProxy, "http://127.0.0.1:16384")
setEnv(t, envvars.CliProxyKey, "test-key")
setEnv(t, envnames.CliAuthProxy, "http://127.0.0.1:16384")
setEnv(t, envnames.CliProxyKey, "test-key")
p := &Provider{}

View File

@@ -20,8 +20,8 @@ import (
"os"
"strings"
"github.com/larksuite/cli/envnames"
"github.com/larksuite/cli/extension/transport"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/sidecar"
)
@@ -36,15 +36,15 @@ func (p *Provider) Name() string { return "sidecar" }
// the non-sidecar transport path (where the credential layer will typically
// block them for lack of a valid account).
func (p *Provider) ResolveInterceptor(ctx context.Context) transport.Interceptor {
proxyAddr := os.Getenv(envvars.CliAuthProxy)
proxyAddr := os.Getenv(envnames.CliAuthProxy)
if proxyAddr == "" {
return nil
}
if err := sidecar.ValidateProxyAddr(proxyAddr); err != nil {
fmt.Fprintf(os.Stderr, "WARNING: invalid %s, sidecar interceptor disabled: %v\n", envvars.CliAuthProxy, err)
fmt.Fprintf(os.Stderr, "WARNING: invalid %s, sidecar interceptor disabled: %v\n", envnames.CliAuthProxy, err)
return nil
}
key := os.Getenv(envvars.CliProxyKey)
key := os.Getenv(envnames.CliProxyKey)
return &Interceptor{
key: []byte(key),
sidecarHost: sidecar.ProxyHost(proxyAddr),
@@ -166,12 +166,12 @@ func detectSentinel(req *http.Request) (identity, authHeader string) {
}
func init() {
proxyAddr := os.Getenv(envvars.CliAuthProxy)
proxyAddr := os.Getenv(envnames.CliAuthProxy)
if proxyAddr == "" {
return
}
if err := sidecar.ValidateProxyAddr(proxyAddr); err != nil {
fmt.Fprintf(os.Stderr, "WARNING: ignoring invalid %s: %v\n", envvars.CliAuthProxy, err)
fmt.Fprintf(os.Stderr, "WARNING: ignoring invalid %s: %v\n", envnames.CliAuthProxy, err)
return
}
transport.Register(&Provider{})

View File

@@ -8,12 +8,12 @@ import (
"errors"
"testing"
"github.com/larksuite/cli/envnames"
"github.com/larksuite/cli/errs"
_ "github.com/larksuite/cli/extension/credential/env"
"github.com/larksuite/cli/extension/fileio"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/credential"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/internal/vfs/localfileio"
)
@@ -29,10 +29,10 @@ func (p *countingFileIOProvider) ResolveFileIO(context.Context) fileio.FileIO {
}
func TestNewDefault_InvocationProfileUsedByStrictModeAndConfig(t *testing.T) {
t.Setenv(envvars.CliAppID, "")
t.Setenv(envvars.CliAppSecret, "")
t.Setenv(envvars.CliUserAccessToken, "")
t.Setenv(envvars.CliTenantAccessToken, "")
t.Setenv(envnames.CliAppID, "")
t.Setenv(envnames.CliAppSecret, "")
t.Setenv(envnames.CliUserAccessToken, "")
t.Setenv(envnames.CliTenantAccessToken, "")
dir := t.TempDir()
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", dir)
@@ -77,10 +77,10 @@ func TestNewDefault_InvocationProfileUsedByStrictModeAndConfig(t *testing.T) {
}
func TestNewDefault_InvocationProfileMissingSticksAcrossEarlyStrictMode(t *testing.T) {
t.Setenv(envvars.CliAppID, "")
t.Setenv(envvars.CliAppSecret, "")
t.Setenv(envvars.CliUserAccessToken, "")
t.Setenv(envvars.CliTenantAccessToken, "")
t.Setenv(envnames.CliAppID, "")
t.Setenv(envnames.CliAppSecret, "")
t.Setenv(envnames.CliUserAccessToken, "")
t.Setenv(envnames.CliTenantAccessToken, "")
dir := t.TempDir()
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", dir)
@@ -118,11 +118,11 @@ func TestNewDefault_InvocationProfileMissingSticksAcrossEarlyStrictMode(t *testi
}
func TestNewDefault_ResolveAs_UsesDefaultAsFromEnvAccount(t *testing.T) {
t.Setenv(envvars.CliAppID, "env-app")
t.Setenv(envvars.CliAppSecret, "env-secret")
t.Setenv(envvars.CliDefaultAs, "user")
t.Setenv(envvars.CliUserAccessToken, "")
t.Setenv(envvars.CliTenantAccessToken, "")
t.Setenv(envnames.CliAppID, "env-app")
t.Setenv(envnames.CliAppSecret, "env-secret")
t.Setenv(envnames.CliDefaultAs, "user")
t.Setenv(envnames.CliUserAccessToken, "")
t.Setenv(envnames.CliTenantAccessToken, "")
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir())
f := NewDefault(nil, InvocationContext{})
@@ -138,11 +138,11 @@ func TestNewDefault_ResolveAs_UsesDefaultAsFromEnvAccount(t *testing.T) {
}
func TestNewDefault_ConfigReturnsCliConfigCopyOfCredentialAccount(t *testing.T) {
t.Setenv(envvars.CliAppID, "env-app")
t.Setenv(envvars.CliAppSecret, "env-secret")
t.Setenv(envvars.CliDefaultAs, "")
t.Setenv(envvars.CliUserAccessToken, "uat-token")
t.Setenv(envvars.CliTenantAccessToken, "")
t.Setenv(envnames.CliAppID, "env-app")
t.Setenv(envnames.CliAppSecret, "env-secret")
t.Setenv(envnames.CliDefaultAs, "")
t.Setenv(envnames.CliUserAccessToken, "uat-token")
t.Setenv(envnames.CliTenantAccessToken, "")
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir())
f := NewDefault(nil, InvocationContext{})
@@ -163,11 +163,11 @@ func TestNewDefault_ConfigReturnsCliConfigCopyOfCredentialAccount(t *testing.T)
}
func TestNewDefault_ConfigUsesRuntimePlaceholderForTokenOnlyEnvAccount(t *testing.T) {
t.Setenv(envvars.CliAppID, "env-app")
t.Setenv(envvars.CliAppSecret, "")
t.Setenv(envvars.CliDefaultAs, "")
t.Setenv(envvars.CliUserAccessToken, "uat-token")
t.Setenv(envvars.CliTenantAccessToken, "")
t.Setenv(envnames.CliAppID, "env-app")
t.Setenv(envnames.CliAppSecret, "")
t.Setenv(envnames.CliDefaultAs, "")
t.Setenv(envnames.CliUserAccessToken, "uat-token")
t.Setenv(envnames.CliTenantAccessToken, "")
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir())
f := NewDefault(nil, InvocationContext{})

View File

@@ -7,8 +7,8 @@ import (
"io"
"testing"
"github.com/larksuite/cli/envnames"
_ "github.com/larksuite/cli/extension/credential/env" // registers the env-backed account provider
"github.com/larksuite/cli/internal/envvars"
)
// installProxyWarnSpy replaces warnIfProxied with a counter for one test and
@@ -61,11 +61,11 @@ func TestCachedHttpClientFunc_ProxyWarnGate(t *testing.T) {
func TestCachedLarkClientFunc_ProxyWarnGate(t *testing.T) {
for _, tc := range proxyWarnGateCases {
t.Run(tc.name, func(t *testing.T) {
t.Setenv(envvars.CliAppID, "env-app")
t.Setenv(envvars.CliAppSecret, "env-secret")
t.Setenv(envvars.CliDefaultAs, "")
t.Setenv(envvars.CliUserAccessToken, "")
t.Setenv(envvars.CliTenantAccessToken, "")
t.Setenv(envnames.CliAppID, "env-app")
t.Setenv(envnames.CliAppSecret, "env-secret")
t.Setenv(envnames.CliDefaultAs, "")
t.Setenv(envnames.CliUserAccessToken, "")
t.Setenv(envnames.CliTenantAccessToken, "")
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir())
calls := installProxyWarnSpy(t)

View File

@@ -11,11 +11,11 @@ import (
"github.com/spf13/cobra"
"github.com/larksuite/cli/envnames"
"github.com/larksuite/cli/errs"
extcred "github.com/larksuite/cli/extension/credential"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/credential"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/internal/output"
)
@@ -92,7 +92,7 @@ func TestResolveAs_DefaultAs_FromConfig(t *testing.T) {
}
func TestResolveAs_DefaultAs_EnvDoesNotBypassConfigSource(t *testing.T) {
t.Setenv(envvars.CliDefaultAs, "user")
t.Setenv(envnames.CliDefaultAs, "user")
f, _, _, _ := TestFactory(t, &core.CliConfig{AppID: "a", AppSecret: "s"})
cmd := newCmdWithAsFlag("auto", false)

View File

@@ -7,11 +7,11 @@ import (
"context"
"testing"
"github.com/larksuite/cli/envnames"
extcred "github.com/larksuite/cli/extension/credential"
envprovider "github.com/larksuite/cli/extension/credential/env"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/credential"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/internal/i18n"
"github.com/larksuite/cli/internal/keychain"
)
@@ -23,9 +23,9 @@ func (n *noopKC) Set(service, account, value string) error { return nil }
func (n *noopKC) Remove(service, account string) error { return nil }
func TestFullChain_EnvWins(t *testing.T) {
t.Setenv(envvars.CliAppID, "env_app")
t.Setenv(envvars.CliAppSecret, "env_secret")
t.Setenv(envvars.CliUserAccessToken, "env_uat")
t.Setenv(envnames.CliAppID, "env_app")
t.Setenv(envnames.CliAppSecret, "env_secret")
t.Setenv(envnames.CliUserAccessToken, "env_uat")
ep := &envprovider.Provider{}
cp := credential.NewCredentialProvider(
@@ -82,8 +82,8 @@ func (m *mockDefaultTokenProvider) ResolveToken(ctx context.Context, req credent
}
func TestFullChain_ConfigStrictMode(t *testing.T) {
t.Setenv(envvars.CliAppID, "")
t.Setenv(envvars.CliAppSecret, "")
t.Setenv(envnames.CliAppID, "")
t.Setenv(envnames.CliAppSecret, "")
dir := t.TempDir()
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", dir)
@@ -125,8 +125,8 @@ func TestFullChain_ConfigStrictMode(t *testing.T) {
// consumers (mail signature, etc.) silently fall back to defaults — defeating
// the whole point of persisting --lang.
func TestFullChain_LangSurvivesProductionPath(t *testing.T) {
t.Setenv(envvars.CliAppID, "")
t.Setenv(envvars.CliAppSecret, "")
t.Setenv(envnames.CliAppID, "")
t.Setenv(envnames.CliAppSecret, "")
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir())
multi := &core.MultiAppConfig{

View File

@@ -4,22 +4,9 @@
package envvars
const (
CliAppID = "LARKSUITE_CLI_APP_ID"
CliAppSecret = "LARKSUITE_CLI_APP_SECRET"
CliBrand = "LARKSUITE_CLI_BRAND"
CliUserAccessToken = "LARKSUITE_CLI_USER_ACCESS_TOKEN"
CliTenantAccessToken = "LARKSUITE_CLI_TENANT_ACCESS_TOKEN"
CliDefaultAs = "LARKSUITE_CLI_DEFAULT_AS"
CliStrictMode = "LARKSUITE_CLI_STRICT_MODE"
// Sidecar proxy (auth proxy mode)
CliAuthProxy = "LARKSUITE_CLI_AUTH_PROXY" // sidecar HTTP address, e.g. "http://127.0.0.1:16384"
CliProxyKey = "LARKSUITE_CLI_PROXY_KEY" // HMAC signing key shared with sidecar
// Content safety scanning mode
CliContentSafetyMode = "LARKSUITE_CLI_CONTENT_SAFETY_MODE"
CliAgentName = "LARKSUITE_CLI_AGENT_NAME"
CliAgentTrace = "LARKSUITE_CLI_AGENT_TRACE"
CliProxyEnable = "LARKSUITE_CLI_PROXY_ENABLE"

View File

@@ -10,12 +10,13 @@ import (
)
const (
agentNameEnv = "LARKSUITE_CLI_AGENT_NAME"
agentNameMaxLen = 128
agentTraceMaxLen = 1024
)
func AgentName() string {
return sanitizeSingleLine(os.Getenv(CliAgentName), agentNameMaxLen)
return sanitizeSingleLine(os.Getenv(agentNameEnv), agentNameMaxLen)
}
func AgentTrace() string {

View File

@@ -9,35 +9,35 @@ import (
)
func TestAgentName_EmptyWhenEnvUnset(t *testing.T) {
t.Setenv(CliAgentName, "")
t.Setenv(agentNameEnv, "")
if got := AgentName(); got != "" {
t.Fatalf("AgentName() = %q, want empty when env unset", got)
}
}
func TestAgentName_ReturnsCleanValue(t *testing.T) {
t.Setenv(CliAgentName, "claude-code")
t.Setenv(agentNameEnv, "claude-code")
if got := AgentName(); got != "claude-code" {
t.Fatalf("AgentName() = %q, want %q", got, "claude-code")
}
}
func TestAgentName_TrimsWhitespace(t *testing.T) {
t.Setenv(CliAgentName, " cursor ")
t.Setenv(agentNameEnv, " cursor ")
if got := AgentName(); got != "cursor" {
t.Fatalf("AgentName() = %q, want %q (whitespace trimmed)", got, "cursor")
}
}
func TestAgentName_RejectsCRLFInjection(t *testing.T) {
t.Setenv(CliAgentName, "agent\r\nX-Evil: attack")
t.Setenv(agentNameEnv, "agent\r\nX-Evil: attack")
if got := AgentName(); got != "" {
t.Fatalf("AgentName() = %q, want empty for CR/LF value", got)
}
}
func TestAgentName_RejectsControlChar(t *testing.T) {
t.Setenv(CliAgentName, "agent\x01injected")
t.Setenv(agentNameEnv, "agent\x01injected")
if got := AgentName(); got != "" {
t.Fatalf("AgentName() = %q, want empty for control char value", got)
}
@@ -45,7 +45,7 @@ func TestAgentName_RejectsControlChar(t *testing.T) {
func TestAgentName_RejectsOverlongValue(t *testing.T) {
longVal := strings.Repeat("a", agentNameMaxLen+1)
t.Setenv(CliAgentName, longVal)
t.Setenv(agentNameEnv, longVal)
if got := AgentName(); got != "" {
t.Fatalf("AgentName() returned non-empty for %d-byte value (max %d)", len(longVal), agentNameMaxLen)
}

View File

@@ -1,21 +1,4 @@
# from denied owner reason added_at
github.com/larksuite/cli/extension/credential/env github.com/larksuite/cli/internal/charcheck arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/env github.com/larksuite/cli/internal/core arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/env github.com/larksuite/cli/internal/envvars arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/env github.com/larksuite/cli/internal/i18n arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/env github.com/larksuite/cli/internal/keychain arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/env github.com/larksuite/cli/internal/validate arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/env github.com/larksuite/cli/internal/vfs arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/env github.com/larksuite/cli/internal/vfs/localfileio arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/sidecar github.com/larksuite/cli/internal/charcheck arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/sidecar github.com/larksuite/cli/internal/core arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/sidecar github.com/larksuite/cli/internal/envvars arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/sidecar github.com/larksuite/cli/internal/i18n arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/sidecar github.com/larksuite/cli/internal/keychain arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/sidecar github.com/larksuite/cli/internal/validate arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/sidecar github.com/larksuite/cli/internal/vfs arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/credential/sidecar github.com/larksuite/cli/internal/vfs/localfileio arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/extension/transport/sidecar github.com/larksuite/cli/internal/envvars arch-migration extension pre-module-split (via core/envvars) 2026-07-24
github.com/larksuite/cli/events github.com/larksuite/cli/shortcuts/im/convert_lib arch-migration events root aggregates the existing im conversion dependency 2026-07-24
github.com/larksuite/cli/events github.com/larksuite/cli/shortcuts/common arch-migration events root aggregates the existing im conversion dependency 2026-07-24
github.com/larksuite/cli/events/im github.com/larksuite/cli/shortcuts/im/convert_lib arch-migration events->shortcuts inversion via convert_lib 2026-07-24

View File

@@ -21,7 +21,7 @@ import (
"io"
"os"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/envnames"
)
func init() {
@@ -35,7 +35,7 @@ func init() {
// isolation that this binary cannot provide. Factored out from init() so
// tests can exercise the decision without actually calling os.Exit.
func checkNoAuthsidecarBuild(getenv func(string) string, stderr io.Writer) int {
v := getenv(envvars.CliAuthProxy)
v := getenv(envnames.CliAuthProxy)
if v == "" {
return 0
}
@@ -49,6 +49,6 @@ func checkNoAuthsidecarBuild(getenv func(string) string, stderr io.Writer) int {
"To fix, either:\n"+
" - rebuild the CLI with: go build -tags authsidecar\n"+
" - or unset %s if sidecar isolation is not required\n",
envvars.CliAuthProxy, envvars.CliAuthProxy)
envnames.CliAuthProxy, envnames.CliAuthProxy)
return 2
}

View File

@@ -10,7 +10,7 @@ import (
"strings"
"testing"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/envnames"
)
func TestCheckNoAuthsidecarBuild_Unset(t *testing.T) {
@@ -30,7 +30,7 @@ func TestCheckNoAuthsidecarBuild_Unset(t *testing.T) {
func TestCheckNoAuthsidecarBuild_Set(t *testing.T) {
var stderr bytes.Buffer
env := func(k string) string {
if k == envvars.CliAuthProxy {
if k == envnames.CliAuthProxy {
return "http://127.0.0.1:16384"
}
return ""
@@ -41,7 +41,7 @@ func TestCheckNoAuthsidecarBuild_Set(t *testing.T) {
}
msg := stderr.String()
for _, want := range []string{
envvars.CliAuthProxy,
envnames.CliAuthProxy,
"authsidecar", // build-tag name must appear so operators can act on it
"rebuild",
} {

View File

@@ -17,10 +17,10 @@ import (
"strings"
"testing"
"github.com/larksuite/cli/envnames"
extcred "github.com/larksuite/cli/extension/credential"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/credential"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/sidecar"
)
@@ -410,13 +410,13 @@ func TestProxyHandler_AcceptsAllowedAuthHeaders(t *testing.T) {
}
func TestRun_RejectsSelfProxy(t *testing.T) {
old, had := os.LookupEnv(envvars.CliAuthProxy)
os.Setenv(envvars.CliAuthProxy, "http://127.0.0.1:16384")
old, had := os.LookupEnv(envnames.CliAuthProxy)
os.Setenv(envnames.CliAuthProxy, "http://127.0.0.1:16384")
defer func() {
if had {
os.Setenv(envvars.CliAuthProxy, old)
os.Setenv(envnames.CliAuthProxy, old)
} else {
os.Unsetenv(envvars.CliAuthProxy)
os.Unsetenv(envnames.CliAuthProxy)
}
}()
@@ -424,8 +424,8 @@ func TestRun_RejectsSelfProxy(t *testing.T) {
if err == nil {
t.Fatal("expected error when AUTH_PROXY is set")
}
if !strings.Contains(err.Error(), envvars.CliAuthProxy) {
t.Errorf("error should mention %s, got: %v", envvars.CliAuthProxy, err)
if !strings.Contains(err.Error(), envnames.CliAuthProxy) {
t.Errorf("error should mention %s, got: %v", envnames.CliAuthProxy, err)
}
}

View File

@@ -28,9 +28,9 @@ import (
"syscall"
"time"
"github.com/larksuite/cli/envnames"
"github.com/larksuite/cli/internal/cmdutil"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/internal/vfs"
"github.com/larksuite/cli/sidecar"
)
@@ -62,8 +62,8 @@ func run(ctx context.Context, listen, keyFile, logFile, profile string) error {
// Reject self-proxy: if this process inherited AUTH_PROXY, the sidecar
// credential provider would activate and return sentinel tokens instead
// of real ones, breaking the "trusted side holds real credentials" premise.
if v := os.Getenv(envvars.CliAuthProxy); v != "" {
return fmt.Errorf("%s is set in this environment (%s); unset it before starting the sidecar server", envvars.CliAuthProxy, v)
if v := os.Getenv(envnames.CliAuthProxy); v != "" {
return fmt.Errorf("%s is set in this environment (%s); unset it before starting the sidecar server", envnames.CliAuthProxy, v)
}
if listen == "" {
return fmt.Errorf("invalid --listen address: empty")
@@ -155,10 +155,10 @@ func run(ctx context.Context, listen, keyFile, logFile, profile string) error {
fmt.Fprintf(os.Stderr, "HMAC key prefix: %s\n", keyPrefix)
fmt.Fprintf(os.Stderr, "Full key written to %s (mode 0600)\n", keyFile)
fmt.Fprintf(os.Stderr, "\nSet in sandbox:\n")
fmt.Fprintf(os.Stderr, " export %s=%q\n", envvars.CliAuthProxy, proxyURL)
fmt.Fprintf(os.Stderr, " export %s=\"<read from %s>\"\n", envvars.CliProxyKey, keyFile)
fmt.Fprintf(os.Stderr, " export %s=%q\n", envvars.CliAppID, cfg.AppID)
fmt.Fprintf(os.Stderr, " export %s=%q\n", envvars.CliBrand, string(cfg.Brand))
fmt.Fprintf(os.Stderr, " export %s=%q\n", envnames.CliAuthProxy, proxyURL)
fmt.Fprintf(os.Stderr, " export %s=\"<read from %s>\"\n", envnames.CliProxyKey, keyFile)
fmt.Fprintf(os.Stderr, " export %s=%q\n", envnames.CliAppID, cfg.AppID)
fmt.Fprintf(os.Stderr, " export %s=%q\n", envnames.CliBrand, string(cfg.Brand))
if err := server.Serve(listener); err != nil && err != http.ErrServerClosed {
return fmt.Errorf("sidecar server exited unexpectedly: %v", err)

View File

@@ -19,10 +19,10 @@ import (
"strings"
"testing"
"github.com/larksuite/cli/envnames"
extcred "github.com/larksuite/cli/extension/credential"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/credential"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/sidecar"
)
@@ -412,7 +412,7 @@ func TestProxyHandler_AcceptsAllowedAuthHeaders(t *testing.T) {
}
func TestRun_RejectsSelfProxy(t *testing.T) {
t.Setenv(envvars.CliAuthProxy, "http://127.0.0.1:16384")
t.Setenv(envnames.CliAuthProxy, "http://127.0.0.1:16384")
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir())
keyPath := filepath.Join(t.TempDir(), "proxy.key")
@@ -420,8 +420,8 @@ func TestRun_RejectsSelfProxy(t *testing.T) {
if err == nil {
t.Fatal("expected error when AUTH_PROXY is set")
}
if !strings.Contains(err.Error(), envvars.CliAuthProxy) {
t.Errorf("error should mention %s, got: %v", envvars.CliAuthProxy, err)
if !strings.Contains(err.Error(), envnames.CliAuthProxy) {
t.Errorf("error should mention %s, got: %v", envnames.CliAuthProxy, err)
}
}

View File

@@ -29,9 +29,9 @@ import (
"syscall"
"time"
"github.com/larksuite/cli/envnames"
"github.com/larksuite/cli/internal/cmdutil"
"github.com/larksuite/cli/internal/core"
"github.com/larksuite/cli/internal/envvars"
"github.com/larksuite/cli/internal/validate"
"github.com/larksuite/cli/internal/vfs"
"github.com/larksuite/cli/sidecar"
@@ -62,8 +62,8 @@ func defaultKeyFile() string {
}
func run(ctx context.Context, listen, keyFile, keysDir, logFile, profile string) error {
if v := os.Getenv(envvars.CliAuthProxy); v != "" {
return fmt.Errorf("%s is set in this environment (%s); unset it before starting the sidecar server", envvars.CliAuthProxy, v)
if v := os.Getenv(envnames.CliAuthProxy); v != "" {
return fmt.Errorf("%s is set in this environment (%s); unset it before starting the sidecar server", envnames.CliAuthProxy, v)
}
if listen == "" {
return fmt.Errorf("invalid --listen address: empty")
@@ -183,10 +183,10 @@ func run(ctx context.Context, listen, keyFile, keysDir, logFile, profile string)
fmt.Fprintf(os.Stderr, "Full key written to %s (mode 0600)\n", keyFile)
fmt.Fprintf(os.Stderr, "Client keys dir: %s\n", keysDir)
fmt.Fprintf(os.Stderr, "\nSet in sandbox:\n")
fmt.Fprintf(os.Stderr, " export %s=%q\n", envvars.CliAuthProxy, proxyURL)
fmt.Fprintf(os.Stderr, " export %s=\"<read from %s>\"\n", envvars.CliProxyKey, keyFile)
fmt.Fprintf(os.Stderr, " export %s=%q\n", envvars.CliAppID, cfg.AppID)
fmt.Fprintf(os.Stderr, " export %s=%q\n", envvars.CliBrand, string(cfg.Brand))
fmt.Fprintf(os.Stderr, " export %s=%q\n", envnames.CliAuthProxy, proxyURL)
fmt.Fprintf(os.Stderr, " export %s=\"<read from %s>\"\n", envnames.CliProxyKey, keyFile)
fmt.Fprintf(os.Stderr, " export %s=%q\n", envnames.CliAppID, cfg.AppID)
fmt.Fprintf(os.Stderr, " export %s=%q\n", envnames.CliBrand, string(cfg.Brand))
if err := server.Serve(listener); err != nil && err != http.ErrServerClosed {
return fmt.Errorf("sidecar server exited unexpectedly: %v", err)