session

package
v0.15.1-alpha.rc1 Latest Latest
Warning

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

Go to latest
Published: Jul 15, 2025 License: MIT Imports: 43 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DBFilename is the default filename of the session database.
	DBFilename = "session.db"

	// DefaultSessionDBTimeout is the default maximum time we wait for the
	// session bbolt database to be opened. If the database is already
	// opened by another process, the unique lock cannot be obtained. With
	// the timeout we error out after the given time instead of just
	// blocking for forever.
	DefaultSessionDBTimeout = 5 * time.Second
)
View Source
const Subsystem = "SESS"

Variables

View Source
var (
	// ErrSessionNotFound is an error returned when we attempt to retrieve
	// information about a session but it is not found.
	ErrSessionNotFound = errors.New("session not found")

	// ErrUnknownGroup is returned when an attempt is made to insert a
	// session and link it to an existing group where the group is not
	// known.
	ErrUnknownGroup = errors.New("unknown group")

	// ErrSessionsInGroupStillActive is returned when an attempt is made to
	// insert a session and link it to a group that still has other active
	// sessions.
	ErrSessionsInGroupStillActive = errors.New(
		"group has active sessions",
	)
)
View Source
var (

	// ErrDBInitErr is returned when a bucket that we expect to have been
	// set up during DB initialisation is not found.
	ErrDBInitErr = errors.New("db did not initialise properly")
)
View Source
var (

	// ErrDBReversion is returned when detecting an attempt to revert to a
	// prior database version.
	ErrDBReversion = errors.New("cannot revert to prior version")
)
View Source
var (
	// ErrMigrationMismatch is returned when the migrated session does not
	// match the original session.
	ErrMigrationMismatch = fmt.Errorf("migrated session does not match " +
		"original session")
)
View Source
var ErrUnknownPrivacyFlag = errors.New("unknown privacy flag")

ErrUnknownPrivacyFlag is an error that is returned when an unknown privacy flag is used.

Functions

func AddToGRPCMetadata

func AddToGRPCMetadata(md metadata.MD, id ID)

AddToGRPCMetadata adds the session ID to the given gRPC metadata kv pairs. The session ID is encoded as a hex string.

func FromGRPCMetadata

func FromGRPCMetadata(md metadata.MD) (fn.Option[ID], error)

FromGRPCMetadata extracts the session ID from the given gRPC metadata kv pairs if one is found.

func MigrateSessionStoreToSQL

func MigrateSessionStoreToSQL(ctx context.Context, kvStore *bbolt.DB,
	tx SQLQueries) error

MigrateSessionStoreToSQL runs the migration of all sessions from the KV database to the SQL database. The migration is done in a single transaction to ensure that all sessions are migrated or none at all.

NOTE: As sessions may contain linked accounts, the accounts sql migration MUST be run prior to this migration.

func SerializeSession

func SerializeSession(w io.Writer, session *Session) error

SerializeSession binary serializes the given session to the writer using the tlv format.

func UseLogger

func UseLogger(logger btclog.Logger)

UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.

Types

type BatchedSQLQueries

type BatchedSQLQueries interface {
	SQLQueries

	db.BatchedTx[SQLQueries]
}

BatchedSQLQueries is a version of the SQLQueries that's capable of batched database operations.

type BoltStore

type BoltStore struct {
	*bbolt.DB
	// contains filtered or unexported fields
}

BoltStore is a bolt-backed persistent store.

func NewDB

func NewDB(dir, fileName string, clock clock.Clock,
	store accounts.Store) (*BoltStore, error)

NewDB creates a new bolt database that can be found at the given directory.

func (*BoltStore) DeleteReservedSessions

func (db *BoltStore) DeleteReservedSessions(_ context.Context) error

DeleteReservedSessions deletes all sessions that are in the StateReserved state.

NOTE: this is part of the Store interface.

func (*BoltStore) GetGroupID

func (db *BoltStore) GetGroupID(_ context.Context, sessionID ID) (ID, error)

GetGroupID will return the group ID for the given session ID.

NOTE: this is part of the IDToGroupIndex interface.

func (*BoltStore) GetSession

func (db *BoltStore) GetSession(_ context.Context, id ID) (*Session, error)

GetSession fetches the session with the given ID.

NOTE: this is part of the Store interface.

func (*BoltStore) GetSessionByLocalPub

func (db *BoltStore) GetSessionByLocalPub(_ context.Context,
	key *btcec.PublicKey) (*Session, error)

GetSessionByLocalPub fetches the session with the given local pub key.

NOTE: this is part of the Store interface.

func (*BoltStore) GetSessionIDs

func (db *BoltStore) GetSessionIDs(_ context.Context, groupID ID) ([]ID,
	error)

GetSessionIDs will return the set of session IDs that are in the group with the given ID.

NOTE: this is part of the IDToGroupIndex interface.

func (*BoltStore) ListAllSessions

func (db *BoltStore) ListAllSessions(_ context.Context) ([]*Session, error)

ListAllSessions returns all sessions currently known to the store.

NOTE: this is part of the Store interface.

func (*BoltStore) ListSessionsByState

func (db *BoltStore) ListSessionsByState(_ context.Context, state State) (
	[]*Session, error)

ListSessionsByState returns all sessions currently known to the store that are in the given state.

NOTE: this is part of the Store interface.

func (*BoltStore) ListSessionsByType

func (db *BoltStore) ListSessionsByType(_ context.Context, t Type) ([]*Session,
	error)

ListSessionsByType returns all sessions currently known to the store that have the given type.

NOTE: this is part of the Store interface.

func (*BoltStore) NewSession

func (db *BoltStore) NewSession(ctx context.Context, label string, typ Type,
	expiry time.Time, serverAddr string, opts ...Option) (*Session, error)

NewSession creates and persists a new session with the given user-defined parameters. The initial state of the session will be Reserved until ShiftState is called with StateCreated.

NOTE: this is part of the Store interface.

func (*BoltStore) ShiftState

func (db *BoltStore) ShiftState(_ context.Context, id ID, dest State) error

ShiftState updates the state of the session with the given ID to the "dest" state.

NOTE: this is part of the Store interface.

func (*BoltStore) UpdateSessionRemotePubKey

func (db *BoltStore) UpdateSessionRemotePubKey(_ context.Context, id ID,
	remotePubKey *btcec.PublicKey) error

UpdateSessionRemotePubKey can be used to add the given remote pub key to the session with the given ID.

NOTE: this is part of the Store interface.

type FeaturesConfig

type FeaturesConfig map[string][]byte

FeaturesConfig is a map from feature name to a raw byte array which stores any config feature config options.

type GRPCServerCreator

type GRPCServerCreator func(sessionID ID,
	opts ...grpc.ServerOption) *grpc.Server

type ID

type ID [4]byte

ID represents the id of a session.

var EmptyID ID

EmptyID is an empty session ID.

func IDFromBytes

func IDFromBytes(b []byte) (ID, error)

IDFromBytes is a helper function that creates a session ID from a byte slice.

func IDFromMacRootKeyID

func IDFromMacRootKeyID(rootKeyID uint64) ID

IDFromMacRootKeyID converts a macaroon root key ID to a session ID.

func IDFromMacaroon

func IDFromMacaroon(mac *macaroon.Macaroon) (ID, error)

IDFromMacaroon is a helper function that creates a session ID from a macaroon ID.

func NewSessionPrivKeyAndID

func NewSessionPrivKeyAndID() (*btcec.PrivateKey, ID, error)

NewSessionPrivKeyAndID randomly derives a new private key and session ID pair.

type IDToGroupIndex

type IDToGroupIndex interface {
	// GetGroupID will return the group ID for the given session ID.
	GetGroupID(ctx context.Context, sessionID ID) (ID, error)

	// GetSessionIDs will return the set of session IDs that are in the
	// group with the given ID.
	GetSessionIDs(ctx context.Context, groupID ID) ([]ID, error)
}

IDToGroupIndex defines an interface for the session ID to group ID index.

type MacaroonRecipe

type MacaroonRecipe struct {
	Permissions []bakery.Op
	Caveats     []macaroon.Caveat
}

MacaroonRecipe defines the permissions and caveats that should be used to bake a macaroon.

type Option

type Option func(*sessionOptions)

Option defines the signature of a functional option that can be used to tweak various session creation options.

func WithAccount

func WithAccount(id accounts.AccountID) Option

WithAccount can be used to link the session to an account.

func WithDevServer

func WithDevServer() Option

WithDevServer can be used to set if TLS verification should be skipped when connecting to the mailbox server.

func WithFeatureConfig

func WithFeatureConfig(config FeaturesConfig) Option

WithFeatureConfig can be used to set the feature configuration bytes for this session.

func WithLinkedGroupID

func WithLinkedGroupID(groupID *ID) Option

WithLinkedGroupID can be used to link this session to a previous session.

func WithMacaroonRecipe

func WithMacaroonRecipe(caveats []macaroon.Caveat, perms []bakery.Op) Option

WithMacaroonRecipe can be used to set the permissions and caveats that should be used to bake the macaroon for a session.

func WithPrivacy

func WithPrivacy(flags PrivacyFlags) Option

WithPrivacy can be used to enable the privacy mapper for this session. An optional set of privacy flags can be provided to further customize the privacy mapper.

type PrivacyFlag

type PrivacyFlag uint64

PrivacyFlag is an enum representing privacy flags for obfuscation behavior of feature configuration, feature rules and API calls. Privacy is on by default, by setting a privacy flag one can disable certain obfuscation behavior.

const (

	// ClearPubkeys is a privacy flag that indicates that the public node
	// ids in API should be treated as clear text.
	ClearPubkeys PrivacyFlag = 0

	// ClearAmounts is a privacy flag that indicates that the amounts in the
	// API should not be obfuscated.
	ClearAmounts PrivacyFlag = 1

	// ClearChanIDs is a privacy flag that indicates that the channel id and
	// channel points in API should not be obfuscated.
	ClearChanIDs PrivacyFlag = 2

	// ClearTimeStamps is a privacy flag that indicates that the timestamps
	// in the API should not be obfuscated.
	ClearTimeStamps PrivacyFlag = 3

	// ClearChanInitiator is a privacy flag that indicates that the channel
	// initiator in the API should not be obfuscated.
	ClearChanInitiator PrivacyFlag = 4

	// ClearHTLCs is a privacy flag that indicates that the HTLCs in the API
	// should not be obfuscated.
	ClearHTLCs PrivacyFlag = 5

	// ClearClosingTxIds is a privacy flag that indicates that the channel
	// closing transaction ids in the API should not be obfuscated.
	ClearClosingTxIds PrivacyFlag = 6

	// ClearNetworkAddresses is a privacy flag that indicates that the
	// network addresses in the API should not be obfuscated.
	ClearNetworkAddresses PrivacyFlag = 7
)

func (PrivacyFlag) String

func (f PrivacyFlag) String() string

String returns a string representation of the privacy flag.

func (PrivacyFlag) Validate

func (f PrivacyFlag) Validate() error

Validate returns an error if a privacy flag is unknown.

type PrivacyFlags

type PrivacyFlags []PrivacyFlag

PrivacyFlags is a struct representing a set of privacy flags.

func Deserialize

func Deserialize(serialized uint64) (PrivacyFlags, error)

Deserialize returns a PrivacyFlags struct from a serialized representation.

func Parse

func Parse(flags string) (PrivacyFlags, error)

Parse constructs privacy flags from its string representation.

func (PrivacyFlags) Add

func (f PrivacyFlags) Add(other PrivacyFlags) PrivacyFlags

Add adds a set of privacy flags to another set.

func (PrivacyFlags) Contains

func (f PrivacyFlags) Contains(other PrivacyFlag) bool

Contains checks if a privacy flag is contained in the set.

func (PrivacyFlags) Equal

func (f PrivacyFlags) Equal(other PrivacyFlags) bool

Equal checks if two sets of privacy flags are equal.

func (PrivacyFlags) Serialize

func (f PrivacyFlags) Serialize() uint64

Serialize returns a serialized representation of the privacy flags.

func (PrivacyFlags) String

func (f PrivacyFlags) String() string

String returns a string representation of the privacy flags.

type SQLQueries

type SQLQueries interface {
	GetAliasBySessionID(ctx context.Context, id int64) ([]byte, error)
	GetSessionByID(ctx context.Context, id int64) (sqlc.Session, error)
	GetSessionsInGroup(ctx context.Context, groupID sql.NullInt64) ([]sqlc.Session, error)
	GetSessionAliasesInGroup(ctx context.Context, groupID sql.NullInt64) ([][]byte, error)
	GetSessionByAlias(ctx context.Context, legacyID []byte) (sqlc.Session, error)
	GetSessionByLocalPublicKey(ctx context.Context, localPublicKey []byte) (sqlc.Session, error)
	GetSessionFeatureConfigs(ctx context.Context, sessionID int64) ([]sqlc.SessionFeatureConfig, error)
	GetSessionMacaroonCaveats(ctx context.Context, sessionID int64) ([]sqlc.SessionMacaroonCaveat, error)
	GetSessionIDByAlias(ctx context.Context, legacyID []byte) (int64, error)
	GetSessionMacaroonPermissions(ctx context.Context, sessionID int64) ([]sqlc.SessionMacaroonPermission, error)
	GetSessionPrivacyFlags(ctx context.Context, sessionID int64) ([]sqlc.SessionPrivacyFlag, error)
	InsertSessionFeatureConfig(ctx context.Context, arg sqlc.InsertSessionFeatureConfigParams) error
	SetSessionRevokedAt(ctx context.Context, arg sqlc.SetSessionRevokedAtParams) error
	InsertSessionMacaroonCaveat(ctx context.Context, arg sqlc.InsertSessionMacaroonCaveatParams) error
	InsertSessionMacaroonPermission(ctx context.Context, arg sqlc.InsertSessionMacaroonPermissionParams) error
	InsertSessionPrivacyFlag(ctx context.Context, arg sqlc.InsertSessionPrivacyFlagParams) error
	InsertSession(ctx context.Context, arg sqlc.InsertSessionParams) (int64, error)
	ListSessions(ctx context.Context) ([]sqlc.Session, error)
	ListSessionsByType(ctx context.Context, sessionType int16) ([]sqlc.Session, error)
	ListSessionsByState(ctx context.Context, state int16) ([]sqlc.Session, error)
	SetSessionRemotePublicKey(ctx context.Context, arg sqlc.SetSessionRemotePublicKeyParams) error
	SetSessionGroupID(ctx context.Context, arg sqlc.SetSessionGroupIDParams) error
	UpdateSessionState(ctx context.Context, arg sqlc.UpdateSessionStateParams) error
	DeleteSessionsWithState(ctx context.Context, state int16) error
	GetAccountIDByAlias(ctx context.Context, alias int64) (int64, error)
	GetAccount(ctx context.Context, id int64) (sqlc.Account, error)
}

SQLQueries is a subset of the sqlc.Queries interface that can be used to interact with session related tables.

type SQLStore

type SQLStore struct {

	// BaseDB represents the underlying database connection.
	*db.BaseDB
	// contains filtered or unexported fields
}

SQLStore represents a storage backend.

func NewSQLStore

func NewSQLStore(sqlDB *db.BaseDB, clock clock.Clock) *SQLStore

NewSQLStore creates a new SQLStore instance given an open BatchedSQLQueries storage backend.

func (*SQLStore) DeleteReservedSessions

func (s *SQLStore) DeleteReservedSessions(ctx context.Context) error

DeleteReservedSessions deletes all sessions that are in the StateReserved state.

NOTE: this is part of the Store interface.

func (*SQLStore) GetGroupID

func (s *SQLStore) GetGroupID(ctx context.Context, sessionID ID) (ID, error)

GetGroupID will return the legacy group Alias for the given legacy session Alias.

NOTE: This is part of the AliasToGroupIndex interface.

func (*SQLStore) GetSession

func (s *SQLStore) GetSession(ctx context.Context, alias ID) (*Session, error)

GetSession returns the session with the given legacy Alias.

NOTE: This is part of the Store interface.

func (*SQLStore) GetSessionByLocalPub

func (s *SQLStore) GetSessionByLocalPub(ctx context.Context,
	key *btcec.PublicKey) (*Session, error)

GetSessionByLocalPub fetches the session with the given local pub key.

NOTE: This is part of the Store interface.

func (*SQLStore) GetSessionIDs

func (s *SQLStore) GetSessionIDs(ctx context.Context, legacyGroupID ID) ([]ID,
	error)

GetSessionIDs will return the set of legacy session IDs that are in the group with the given legacy Alias.

NOTE: This is part of the AliasToGroupIndex interface.

func (*SQLStore) ListAllSessions

func (s *SQLStore) ListAllSessions(ctx context.Context) ([]*Session, error)

ListAllSessions returns all sessions currently known to the store.

NOTE: This is part of the Store interface.

func (*SQLStore) ListSessionsByState

func (s *SQLStore) ListSessionsByState(ctx context.Context, state State) (
	[]*Session, error)

ListSessionsByState returns all sessions currently known to the store that are in the given state.

NOTE: this is part of the Store interface.

func (*SQLStore) ListSessionsByType

func (s *SQLStore) ListSessionsByType(ctx context.Context, t Type) ([]*Session,
	error)

ListSessionsByType returns all sessions currently known to the store that have the given type.

NOTE: this is part of the Store interface.

func (*SQLStore) NewSession

func (s *SQLStore) NewSession(ctx context.Context, label string, typ Type,
	expiry time.Time, serverAddr string, opts ...Option) (*Session, error)

NewSession creates and persists a new session with the given user-defined parameters. The initial state of the session will be Reserved until ShiftState is called with StateCreated.

NOTE: this is part of the Store interface.

func (*SQLStore) ShiftState

func (s *SQLStore) ShiftState(ctx context.Context, alias ID, dest State) error

ShiftState updates the state of the session with the given ID to the "dest" state.

NOTE: this is part of the Store interface.

func (*SQLStore) UpdateSessionRemotePubKey

func (s *SQLStore) UpdateSessionRemotePubKey(ctx context.Context, alias ID,
	remotePubKey *btcec.PublicKey) error

UpdateSessionRemotePubKey can be used to add the given remote pub key to the session with the given legacy ID.

NOTE: This is part of the Store interface.

type Server

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

func NewServer

func NewServer(serverCreator GRPCServerCreator) *Server

func (*Server) StartSession

func (s *Server) StartSession(session *Session, authData []byte,
	onUpdate func(ctx context.Context, id ID,
		remote *btcec.PublicKey) error,
	onNewStatus func(s mailbox.ServerStatus)) (chan struct{}, error)

func (*Server) Stop

func (s *Server) Stop()

func (*Server) StopSession

func (s *Server) StopSession(localPublicKey *btcec.PublicKey) error

type Session

type Session struct {
	ID                ID
	Label             string
	State             State
	Type              Type
	Expiry            time.Time
	CreatedAt         time.Time
	RevokedAt         time.Time
	ServerAddr        string
	DevServer         bool
	MacaroonRootKey   uint64
	MacaroonRecipe    *MacaroonRecipe
	PairingSecret     [mailbox.NumPassphraseEntropyBytes]byte
	LocalPrivateKey   *btcec.PrivateKey
	LocalPublicKey    *btcec.PublicKey
	RemotePublicKey   *btcec.PublicKey
	FeatureConfig     *FeaturesConfig
	WithPrivacyMapper bool
	PrivacyFlags      PrivacyFlags

	// GroupID is the Session ID of the very first Session in the linked
	// group of sessions. If this is the very first session in the group
	// then this will be the same as ID.
	GroupID ID

	// AccountID is an optional account that the session has been linked to.
	AccountID fn.Option[accounts.AccountID]
}

Session is a struct representing a long-term Terminal Connect session.

func DeserializeSession

func DeserializeSession(r io.Reader) (*Session, error)

DeserializeSession deserializes a session from the given reader, expecting the data to be encoded in the tlv format.

type State

type State uint8

State represents the state of a session.

const (
	// StateCreated is the state of a session once it has been fully
	// committed to the BoltStore and is ready to be used. This is the
	// first state after StateReserved.
	StateCreated State = 0

	// StateInUse is the state of a session that is currently being used.
	//
	// NOTE: this state is not currently used, but we keep it around for now
	// since old sessions might still have this state persisted.
	StateInUse State = 1

	// StateRevoked is the state of a session that has been revoked before
	// its expiry date.
	StateRevoked State = 2

	// StateExpired is the state of a session that has passed its expiry
	// date.
	StateExpired State = 3

	// StateReserved is a temporary initial state of a session. This is used
	// to reserve a unique ID and private key pair for a session before it
	// is fully created. On start-up, any sessions in this state should be
	// cleaned up.
	StateReserved State = 4
)

func (State) Terminal

func (s State) Terminal() bool

Terminal returns true if the state is a terminal state.

type Store

type Store interface {
	// NewSession creates a new session with the given user-defined
	// parameters. The session will remain in the StateReserved state until
	// ShiftState is called to update the state.
	NewSession(ctx context.Context, label string, typ Type,
		expiry time.Time, serverAddr string, opts ...Option) (*Session,
		error)

	// GetSessionByLocalPub fetches the session with the given local pub
	// key.
	GetSessionByLocalPub(ctx context.Context,
		key *btcec.PublicKey) (*Session, error)

	// ListAllSessions returns all sessions currently known to the store.
	ListAllSessions(ctx context.Context) ([]*Session, error)

	// ListSessionsByType returns all sessions of the given type.
	ListSessionsByType(ctx context.Context, t Type) ([]*Session, error)

	// ListSessionsByState returns all sessions currently known to the store
	// that are in the given state.
	ListSessionsByState(ctx context.Context, state State) ([]*Session,
		error)

	// UpdateSessionRemotePubKey can be used to add the given remote pub key
	// to the session with the given ID.
	UpdateSessionRemotePubKey(ctx context.Context, id ID,
		remotePubKey *btcec.PublicKey) error

	// GetSession fetches the session with the given ID.
	GetSession(ctx context.Context, id ID) (*Session, error)

	// DeleteReservedSessions deletes all sessions that are in the
	// StateReserved state.
	DeleteReservedSessions(ctx context.Context) error

	// ShiftState updates the state of the session with the given ID to the
	// "dest" state.
	ShiftState(ctx context.Context, id ID, dest State) error

	IDToGroupIndex
}

Store is the interface a persistent storage must implement for storing and retrieving Terminal Connect sessions.

func NewTestDB

func NewTestDB(t *testing.T, clock clock.Clock) Store

NewTestDB is a helper function that creates an BBolt database for testing.

func NewTestDBFromPath

func NewTestDBFromPath(t *testing.T, dbPath string,
	clock clock.Clock) Store

NewTestDBFromPath is a helper function that creates a new BoltStore with a connection to an existing BBolt database for testing.

func NewTestDBWithAccounts

func NewTestDBWithAccounts(t *testing.T, clock clock.Clock,
	acctStore accounts.Store) Store

NewTestDBWithAccounts creates a new test session Store with access to an existing accounts DB.

type Type

type Type uint8

Type represents the type of session.

const (
	TypeMacaroonReadonly Type = 0
	TypeMacaroonAdmin    Type = 1
	TypeMacaroonCustom   Type = 2
	TypeUIPassword       Type = 3
	TypeAutopilot        Type = 4
	TypeMacaroonAccount  Type = 5
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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