oauth

package
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: Sep 21, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrDisabled is returned when the OAuth service is disabled.
	ErrDisabled = errors.New("oauth service disabled")

	// ErrTokenIssueFailed is returned when the Bitbucket OAuth token
	// endpoint rejects an authorization code or refresh token grant.
	ErrTokenIssueFailed = errors.New("oauth token issue failed")

	// ErrNotFound is returned when a token is not found.
	ErrNotFound = errors.New("token not found")

	// ErrStateNotFound is returned when an OAuth CSRF state is missing,
	// expired, or already consumed.
	ErrStateNotFound = errors.New("oauth state not found")
)
View Source
var ErrInvalidCiphertext = errors.New("invalid oauth token ciphertext")

ErrInvalidCiphertext indicates stored token ciphertext could not be authenticated or decoded.

View Source
var ErrInvalidKey = errors.New("invalid oauth token encryption key")

ErrInvalidKey indicates the configured OAuth token encryption key is missing or has an unsupported length.

Functions

func Module

func Module() fx.Option

Types

type Config

type Config struct {
	// ClientID is the Bitbucket OAuth app consumer key.
	ClientID string
	// ClientSecret is the Bitbucket OAuth app consumer secret. Never logged.
	ClientSecret string
	// TokenEncryptionKey is the AES key (hex or base64, 16/24/32 bytes) used to
	// encrypt the stored OAuth access and refresh tokens at rest. Required.
	TokenEncryptionKey string
}

Config holds OAuth service tunables.

type EncryptedToken

type EncryptedToken struct {
	Token

	Fingerprint string
}

func NewEncryptedToken

func NewEncryptedToken(enc *Encryptor, token Token) (*EncryptedToken, error)

type Encryptor

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

Encryptor performs authenticated encryption (AES-GCM) of OAuth tokens at rest. A random 12-byte nonce is prepended to the sealed payload; the combined bytes are base64-encoded for storage in a text column. Decryption fails closed (returns an error) when the ciphertext is tampered with.

func NewEncryptor

func NewEncryptor(key []byte) (*Encryptor, error)

NewEncryptor builds an Encryptor from a raw AES key. The key must be 16, 24, or 32 bytes (AES-128/192/256).

func NewEncryptorFromConfig

func NewEncryptorFromConfig(encoded string) (*Encryptor, error)

NewEncryptorFromConfig decodes a key from configuration. Both hex and base64 (standard) encodings are accepted; the decoded key must be a valid AES length. An empty key is rejected so tokens are never persisted plaintext.

func (*Encryptor) Decrypt

func (e *Encryptor) Decrypt(ciphertext string) (string, error)

Decrypt reverses Encrypt, failing closed on any authentication or decode error so a tampered or unreadable token is never returned as plaintext.

func (*Encryptor) Encrypt

func (e *Encryptor) Encrypt(plaintext string) (string, error)

Encrypt seals plaintext with AES-GCM and returns base64(nonce || ciphertext). Empty input round-trips to an empty string (no nonce is generated).

type Repository

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

Repository persists the per-user OAuth token row. Access and refresh tokens are encrypted at rest via enc before being written, and decrypted on read.

func NewRepository

func NewRepository(db *bun.DB) *Repository

func (*Repository) Delete

func (r *Repository) Delete(ctx context.Context, userID int64) error

func (*Repository) Get

func (r *Repository) Get(ctx context.Context, userID int64) (*EncryptedToken, error)

func (*Repository) Update

func (r *Repository) Update(
	ctx context.Context,
	userID int64,
	currentFingerprint string,
	token EncryptedToken,
) (bool, error)

Update persists a refreshed token only if the credential loaded before the refresh still exists and matches currentFingerprint. It returns false when no row matched, which happens if the token was deleted (or replaced) while the refresh request was in flight.

func (*Repository) Upsert

func (r *Repository) Upsert(ctx context.Context, userID int64, token EncryptedToken) error

type Service

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

Service stores the per-user Bitbucket OAuth credential and manages the connection flow. CSRF states are persisted in a cache-backed store.

func NewService

func NewService(
	cfg Config,
	tokens *Repository,
	backend cache.Cache,

	logger *zap.Logger,
) (*Service, error)

func (*Service) AuthorizeURL

func (s *Service) AuthorizeURL(ctx context.Context, userID int64) (string, error)

func (*Service) DeleteToken

func (s *Service) DeleteToken(ctx context.Context, userID int64) error

func (*Service) Exchange

func (s *Service) Exchange(ctx context.Context, state, code string) error

func (*Service) GetToken

func (s *Service) GetToken(ctx context.Context, userID int64) (*Token, error)

type Token

type Token struct {
	AccessToken  string
	RefreshToken string
	Scopes       string
	ExpiresAt    time.Time

	CreatedAt time.Time
	UpdatedAt time.Time
}

Token is the domain representation of the stored Bitbucket OAuth credential. The AccessToken and RefreshToken here are always the decrypted plaintext; they are encrypted at rest by the repository before persistence.

Jump to

Keyboard shortcuts

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