bf9395e022
CI / license-header (push) Has been skipped
CI / e2e-dry-run (push) Has been skipped
CI / fast-gate (push) Failing after 0s
Test PR Label Logic / test-pr-labels (push) Failing after 1s
Skill Format Check / check-format (push) Failing after 2s
CI / security (push) Failing after 5s
CI / unit-test (push) Has been skipped
CI / lint (push) Has been skipped
CI / script-test (push) Has been skipped
CI / deterministic-gate (push) Has been skipped
CI / coverage (push) Has been skipped
CI / results (push) Has been cancelled
CI / deadcode (push) Has been cancelled
CI / e2e-live (push) Has been cancelled
101 lines
2.9 KiB
Go
101 lines
2.9 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package credential
|
|
|
|
import "context"
|
|
|
|
// Brand represents the Lark platform brand.
|
|
type Brand string
|
|
|
|
const (
|
|
BrandLark Brand = "lark"
|
|
BrandFeishu Brand = "feishu"
|
|
)
|
|
|
|
// NoAppSecret marks that a credential source does not provide a real app secret.
|
|
// Token-only sources should return this value instead of inventing placeholder text.
|
|
const NoAppSecret = ""
|
|
|
|
// Identity represents the caller identity type.
|
|
type Identity string
|
|
|
|
const (
|
|
IdentityUser Identity = "user"
|
|
IdentityBot Identity = "bot"
|
|
IdentityAuto Identity = "auto"
|
|
)
|
|
|
|
// IdentitySupport declares which identities a credential source can provide.
|
|
type IdentitySupport uint8
|
|
|
|
const (
|
|
SupportsUser IdentitySupport = 1 << iota
|
|
SupportsBot
|
|
SupportsAll = SupportsUser | SupportsBot
|
|
)
|
|
|
|
// Has reports whether s includes the given flag.
|
|
func (s IdentitySupport) Has(flag IdentitySupport) bool { return s&flag != 0 }
|
|
|
|
// UserOnly returns true if only user identity is supported.
|
|
func (s IdentitySupport) UserOnly() bool { return s == SupportsUser }
|
|
|
|
// BotOnly returns true if only bot identity is supported.
|
|
func (s IdentitySupport) BotOnly() bool { return s == SupportsBot }
|
|
|
|
// Account holds resolved app credentials and configuration.
|
|
type Account struct {
|
|
AppID string
|
|
AppSecret string // real app secret; empty or NoAppSecret means unavailable
|
|
Brand Brand // BrandLark or BrandFeishu
|
|
DefaultAs Identity // IdentityUser / IdentityBot / IdentityAuto; empty = not set
|
|
ProfileName string
|
|
OpenID string // optional; if UAT is available, API result takes precedence
|
|
SupportedIdentities IdentitySupport // zero = provider did not declare; treat as no restriction
|
|
}
|
|
|
|
// Token holds a resolved access token and optional metadata.
|
|
type Token struct {
|
|
Value string
|
|
Scopes string // space-separated; empty = skip scope pre-check
|
|
Source string // e.g. "env:LARKSUITE_CLI_USER_ACCESS_TOKEN", "vault:addr"
|
|
}
|
|
|
|
// TokenType represents the kind of access token.
|
|
type TokenType string
|
|
|
|
const (
|
|
TokenTypeUAT TokenType = "uat"
|
|
TokenTypeTAT TokenType = "tat"
|
|
)
|
|
|
|
// TokenSpec describes what token is needed.
|
|
type TokenSpec struct {
|
|
Type TokenType
|
|
AppID string
|
|
}
|
|
|
|
// BlockError is returned by a Provider to actively reject a request
|
|
// and prevent subsequent providers in the chain from being consulted.
|
|
type BlockError struct {
|
|
Provider string
|
|
Reason string
|
|
}
|
|
|
|
func (e *BlockError) Error() string {
|
|
return "blocked by " + e.Provider + ": " + e.Reason
|
|
}
|
|
|
|
// Provider is the unified interface for credential resolution.
|
|
//
|
|
// Flow control uses Go's native mechanisms:
|
|
// - Handle: return &Account{...}, nil or return &Token{...}, nil
|
|
// - Skip: return nil, nil
|
|
// - Block: return nil, &BlockError{...}
|
|
type Provider interface {
|
|
Name() string
|
|
ResolveAccount(ctx context.Context) (*Account, error)
|
|
ResolveToken(ctx context.Context, req TokenSpec) (*Token, error)
|
|
}
|