oauth

package
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 22, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Index

Constants

View Source
const (
	VaultKeyGitHub = "GH_OAUTH"
	VaultKeyLark   = "LARK_CLI_OAUTH"
)

Vault key names for the two supported providers.

Variables

This section is empty.

Functions

func DeleteBundle

func DeleteBundle(ctx context.Context, vs VaultStore, userID int64, key string) error

DeleteBundle removes the vault entry identified by key for userID.

func SaveGHBundle

func SaveGHBundle(ctx context.Context, vs VaultStore, userID int64, bundle GHOAuthBundle) error

SaveGHBundle serializes bundle to JSON and stores it under VaultKeyGitHub.

func SaveLarkBundle

func SaveLarkBundle(ctx context.Context, vs VaultStore, userID int64, bundle LarkOAuthBundle) error

SaveLarkBundle serializes bundle to JSON and stores it under VaultKeyLark.

Types

type FlowState

type FlowState string

FlowState is the lifecycle state of a device-flow authorization.

const (
	FlowStatePending    FlowState = "pending"
	FlowStateAuthorized FlowState = "authorized"
	FlowStateFailed     FlowState = "failed"
	FlowStateExpired    FlowState = "expired"
)

type FlowStatus

type FlowStatus struct {
	Provider        Provider
	FlowID          string
	UserID          int64
	VerificationURI string
	UserCode        string
	ExpiresAt       time.Time
	State           FlowState
}

FlowStatus is the public view of an in-flight device-flow session.

type FlowStore

type FlowStore struct {
	// contains filtered or unexported fields
}

FlowStore is an in-memory store of in-flight device-flow sessions. Known limitation: a process restart loses all pending flows.

func NewFlowStore

func NewFlowStore() *FlowStore

NewFlowStore returns an empty FlowStore.

func (*FlowStore) Create

func (s *FlowStore) Create(status FlowStatus)

Create stores a new FlowStatus keyed by its FlowID.

func (*FlowStore) Delete

func (s *FlowStore) Delete(flowID string)

Delete removes the flow with the given ID from the store.

func (*FlowStore) Get

func (s *FlowStore) Get(flowID string) (FlowStatus, bool)

Get returns the FlowStatus for flowID, or false if not found.

func (*FlowStore) Update

func (s *FlowStore) Update(flowID string, state FlowState, update func(*FlowStatus))

Update sets state on the named flow and then calls update (if non-nil) to allow further mutation. The state is applied first so callers can inspect or override it inside update.

type GHOAuthBundle

type GHOAuthBundle struct {
	Version      int        `json:"version"`
	AccessToken  string     `json:"access_token"`
	TokenType    string     `json:"token_type"`
	Scope        string     `json:"scope"`
	ExpiresAt    *time.Time `json:"expires_at,omitempty"`
	RefreshToken string     `json:"refresh_token,omitempty"`
}

GHOAuthBundle is the versioned vault payload for GitHub. GitHub personal access tokens from device flow don't expire by default, but we carry optional refresh fields for future fine-grained tokens.

func LoadGHBundle

func LoadGHBundle(ctx context.Context, vs VaultStore, userID int64) (*GHOAuthBundle, error)

LoadGHBundle retrieves and deserializes the GitHub token bundle for userID. Returns nil, nil if no entry exists yet.

type GitHubBroker

type GitHubBroker struct {
	// contains filtered or unexported fields
}

GitHubBroker manages GitHub device-flow sessions.

func NewGitHubBroker

func NewGitHubBroker(cfg GitHubConfig, store *FlowStore) *GitHubBroker

NewGitHubBroker constructs a GitHubBroker.

func (*GitHubBroker) Complete

func (b *GitHubBroker) Complete(ctx context.Context, vs VaultStore, userID int64, flowID string) error

Complete persists the token bundle to vault. Must be called only after Poll returns State == FlowStateAuthorized.

func (*GitHubBroker) Poll

func (b *GitHubBroker) Poll(ctx context.Context, flowID string) (FlowStatus, error)

Poll checks whether the user has completed authorization for flowID. It reads from the store — the background goroutine updates it when done.

func (*GitHubBroker) StartDeviceFlow

func (b *GitHubBroker) StartDeviceFlow(ctx context.Context, userID int64) (FlowStatus, error)

StartDeviceFlow requests a device code from GitHub, stores pending state, and returns the FlowStatus the caller should display to the user. A background goroutine polls GitHub until the user authorizes or the flow expires.

func (*GitHubBroker) WithRedirectURI

func (b *GitHubBroker) WithRedirectURI(uri string) *GitHubBroker

WithRedirectURI returns a new broker with the given redirect URI.

type GitHubConfig

type GitHubConfig struct {
	ClientID     string
	ClientSecret string
}

GitHubConfig holds the OAuth app credentials for device flow.

type LarkBroker

type LarkBroker struct {
	// contains filtered or unexported fields
}

LarkBroker manages Lark/Feishu OAuth sessions via the authorization-code flow adapted for device-like use: StartDeviceFlow returns a URL the user visits; Poll checks completion; Complete exchanges the code and saves the bundle to vault.

func NewLarkBroker

func NewLarkBroker(cfg LarkConfig, store *FlowStore) *LarkBroker

NewLarkBroker constructs a LarkBroker. redirectURI is the OAuth callback URL that your HTTP handler will receive and then call Complete on.

func (*LarkBroker) Complete

func (b *LarkBroker) Complete(ctx context.Context, vs VaultStore, userID int64, flowID string, code string) error

Complete exchanges an authorization code for tokens, saves the bundle to vault, and marks the flow as authorized. The code comes from your OAuth callback handler's query parameter.

func (*LarkBroker) Poll

func (b *LarkBroker) Poll(ctx context.Context, flowID string) (FlowStatus, error)

Poll checks whether the flow identified by flowID has been completed. Completion is signaled externally via Complete after the OAuth callback is received.

func (*LarkBroker) StartDeviceFlow

func (b *LarkBroker) StartDeviceFlow(ctx context.Context, userID int64) (FlowStatus, error)

StartDeviceFlow generates a state token, constructs the authorization URL, and stores a pending FlowStatus. The user must navigate to VerificationURI.

func (*LarkBroker) WithRedirectURI

func (b *LarkBroker) WithRedirectURI(uri string) *LarkBroker

WithRedirectURI returns a new broker with the same configuration but the given redirect URI.

type LarkConfig

type LarkConfig struct {
	AppID     string
	AppSecret string
	Brand     string // "lark" or "feishu"
}

LarkConfig holds the OAuth app credentials for Lark/Feishu device-style flow.

type LarkOAuthBundle

type LarkOAuthBundle struct {
	Version          int       `json:"version"`
	AppID            string    `json:"app_id"`
	AppSecret        string    `json:"app_secret"`
	Brand            string    `json:"brand"` // "lark" or "feishu"
	AccessToken      string    `json:"access_token"`
	RefreshToken     string    `json:"refresh_token"`
	AccessExpiresAt  time.Time `json:"access_expires_at"`
	RefreshExpiresAt time.Time `json:"refresh_expires_at"`
}

LarkOAuthBundle is the versioned vault payload for Lark/Feishu. AppSecret is stored here (already encrypted at rest in vault) so the TokenManager can refresh tokens without needing the app credentials passed in at call time.

func LoadLarkBundle

func LoadLarkBundle(ctx context.Context, vs VaultStore, userID int64) (*LarkOAuthBundle, error)

LoadLarkBundle retrieves and deserializes the Lark token bundle for userID. Returns nil, nil if no entry exists yet.

type Provider

type Provider string

Provider identifies an OAuth provider.

const (
	ProviderGitHub Provider = "github"
	ProviderLark   Provider = "lark"
)

type TokenManager

type TokenManager struct {
	// contains filtered or unexported fields
}

TokenManager provides host-side token validation and (for Lark) automatic refresh. It reads from and writes to the vault.

func NewTokenManager

func NewTokenManager(vs VaultStore) *TokenManager

NewTokenManager constructs a TokenManager backed by vs.

func (*TokenManager) GetGHToken

func (m *TokenManager) GetGHToken(ctx context.Context, userID int64) (string, error)

GetGHToken returns a valid GitHub access token for userID. GitHub tokens obtained via device flow do not expire in standard flow, so this simply returns whatever is in the vault bundle.

func (*TokenManager) GetLarkRuntimeEnv

func (m *TokenManager) GetLarkRuntimeEnv(ctx context.Context, userID int64) (map[string]string, error)

GetLarkRuntimeEnv returns the environment variables needed for lark-cli. It loads the Lark bundle, refreshes the access token if expired, and returns a map ready for env injection. Returns an error if the bundle is absent or the refresh token has expired, so callers can skip injection without failing.

Current lark-cli releases read the LARKSUITE_CLI_* variables for configless runtime auth.

type VaultStore

type VaultStore interface {
	Set(ctx context.Context, userID int64, name string, plaintext string) error
	Delete(ctx context.Context, userID int64, name string) error
	LoadEnv(ctx context.Context, userID int64) (map[string]string, error)
}

VaultStore is the narrow interface this package needs from the vault service.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL