Documentation
¶
Overview ¶
Package credentials provides a secure storage and management system for user credentials. The service uses the "go-keyring" library to interact with the system's native keyring service. For systems that do not support a native keyring service, an alternative using a file at ~/.connect-credentials to persist credentials is implemented.
This package is not thread safe! Manipulation of credentials from multiple threads can result in data loss. A distributed write lock is required to ensure threads do not overwrite the credential store.
Support for breaking changes to the Credentials schema is supported via version system. The current implementation supports a single version (Version 0), but is designed to be extendable to future versions. For example, adding a new field to Credential.
Migration instructions: - Modify the current version to retain the current Credential structure (i.e., copy the struct of Credential to CredentialV0) - Modify Credential to include required changes. - Create a new version (e.g., CredentialV1) and assign Credential to it (.e.g, CredentialV1 = Credential) - Increment CurrentVersion to match the new version (e.g., CredentialVersion = 1) - Add a case statement for the new version to ToCredential. - Modify the existing ToCredential implementation to accommodate changes to Credential.
Key components include: - Credential: The main structure representing a single credential. - CredentialRecord: A structure for storing credential data along with its version for future compatibility. - CredentialsService (interface): A service that provides methods for managing credentials.
- keyringCredentialsService: The service using the system's native keyring.
- fileCredentialsService: Fallback service for persising credentials in file when keyring is not available.
Author: Posit Software, PBC Copyright (C) 2024 by Posit Software, PBC.
Index ¶
- Constants
- Variables
- func NewBackupFileAgentError(filename string, err error) *types.AgentError
- func NewFileCredentialsService(log logging.Logger) (*fileCredentialsService, error)
- func NewKeyringCredentialsService(log logging.Logger) *keyringCredentialsService
- func NewLegacyKeyringCredentialsService(log logging.Logger) *legacyKeyringCredentialsService
- type CorruptedError
- type CreateCredentialDetails
- type CredServiceFactory
- type Credential
- type CredentialIdentityCollision
- type CredentialRecord
- type CredentialTable
- type CredentialV0
- type CredentialV1
- type CredentialV2
- type CredentialV3
- type CredentialsService
- type IncompleteCredentialError
- type LoadError
- type MockCredentialsService
- func (m *MockCredentialsService) ClearDefaultServer() error
- func (m *MockCredentialsService) Delete(id string) error
- func (m *MockCredentialsService) ForceSet(details CreateCredentialDetails) (*Credential, error)
- func (m *MockCredentialsService) Get(id string) (*Credential, error)
- func (m *MockCredentialsService) GetDefaultCloudServer() (*Credential, error)
- func (m *MockCredentialsService) GetDefaultServer() (*Credential, error)
- func (m *MockCredentialsService) List() ([]Credential, error)
- func (m *MockCredentialsService) Reset() (string, error)
- func (m *MockCredentialsService) Set(details CreateCredentialDetails) (*Credential, error)
- func (m *MockCredentialsService) SetDefaultServer(id string) error
- type NameCollisionError
- type NotFoundError
- type VersionError
Constants ¶
const ( CredentialKeyPrefix = "credential_" LegacyKey = "credentials" )
const CurrentVersion = 3
const ServiceName = "Posit Publisher Safe Storage"
Variables ¶
var UseKeychain bool = true
Functions ¶
func NewBackupFileAgentError ¶ added in v1.8.0
func NewBackupFileAgentError(filename string, err error) *types.AgentError
func NewFileCredentialsService ¶ added in v1.1.7
func NewKeyringCredentialsService ¶ added in v1.1.7
func NewLegacyKeyringCredentialsService ¶ added in v1.19.0
NewLegacyKeyringCredentialsService creates a new instance of legacyKeyringCredentialsService
Types ¶
type CorruptedError ¶
type CorruptedError struct {
GUID string
}
func NewCorruptedError ¶ added in v1.1.7
func NewCorruptedError(guid string) *CorruptedError
func (*CorruptedError) Error ¶
func (e *CorruptedError) Error() string
func (*CorruptedError) Is ¶ added in v1.8.0
func (e *CorruptedError) Is(target error) bool
type CreateCredentialDetails ¶ added in v1.18.0
type CreateCredentialDetails struct {
GUID string // Optional, used for migration to preserve original GUID
Name string
URL string
ServerType server_type.ServerType
// Connect fields
ApiKey string
// Snowflake fields
SnowflakeConnection string
// Connect Cloud fields
AccountID string
AccountName string
RefreshToken string
AccessToken types.CloudAuthToken
CloudEnvironment types.CloudEnvironment
// Token authentication fields
Token string
PrivateKey string
}
func (CreateCredentialDetails) ToCredential ¶ added in v1.18.0
func (details CreateCredentialDetails) ToCredential() (*Credential, error)
type CredServiceFactory ¶ added in v1.8.0
type CredServiceFactory = func(log logging.Logger) (CredentialsService, error)
type Credential ¶
type Credential struct {
GUID string `json:"guid"`
Name string `json:"name"`
ServerType server_type.ServerType `json:"serverType"`
URL string `json:"url"`
// Connect fields
ApiKey string `json:"apiKey"`
// Snowflake fields
SnowflakeConnection string `json:"snowflakeConnection"`
// Connect Cloud fields
AccountID string `json:"accountId"`
AccountName string `json:"accountName"`
RefreshToken string `json:"refreshToken"`
AccessToken types.CloudAuthToken `json:"accessToken"`
CloudEnvironment types.CloudEnvironment `json:"cloudEnvironment"`
// Token authentication fields
Token string `json:"token"`
PrivateKey string `json:"privateKey"`
}
func (*Credential) ConflictCheck ¶ added in v1.1.7
func (c *Credential) ConflictCheck(newCred Credential) error
type CredentialIdentityCollision ¶ added in v1.18.1
Credential has already been defined
func NewIdentityCollisionError ¶ added in v1.18.1
func NewIdentityCollisionError(name, url, accountName string) *CredentialIdentityCollision
func (*CredentialIdentityCollision) Error ¶ added in v1.18.1
func (e *CredentialIdentityCollision) Error() string
type CredentialRecord ¶
type CredentialRecord struct {
GUID string `json:"guid"`
Version uint `json:"version"`
Data json.RawMessage `json:"data"`
}
func (*CredentialRecord) ToCredential ¶
func (cr *CredentialRecord) ToCredential() (*Credential, error)
ToCredential converts a CredentialRecord to a Credential based on its version.
type CredentialTable ¶
type CredentialTable = map[string]CredentialRecord
type CredentialV0 ¶
type CredentialV1 ¶ added in v1.16.0
type CredentialV2 ¶ added in v1.18.0
type CredentialV2 struct {
GUID string `json:"guid"`
Name string `json:"name"`
ServerType server_type.ServerType `json:"serverType"`
URL string `json:"url"`
// Connect fields
ApiKey string `json:"apiKey"`
// Snowflake fields
SnowflakeConnection string `json:"snowflakeConnection"`
// Connect Cloud fields
AccountID string `json:"accountId"`
AccountName string `json:"accountName"`
RefreshToken string `json:"refreshToken"`
AccessToken types.CloudAuthToken `json:"accessToken"`
CloudEnvironment types.CloudEnvironment `json:"cloudEnvironment"`
}
type CredentialV3 ¶ added in v1.19.0
type CredentialV3 = Credential
type CredentialsService ¶
type CredentialsService interface {
// Delete removes a Credential by its guid.
// If lookup by guid fails, a NotFoundError is returned.
Delete(guid string) error
// Get retrieves a Credential by its guid.
Get(guid string) (*Credential, error)
// List retrieves all Credentials.
List() ([]Credential, error)
// Set creates a Credential.
// A guid is assigned to the Credential using the UUIDv4 specification.
Set(details CreateCredentialDetails) (*Credential, error)
// ForceSet is like Set but doesn't check for conflicts with existing credentials.
ForceSet(details CreateCredentialDetails) (*Credential, error)
// Reset Reset the CredentialTable from keyring
// It is a last resort in case the data turns out to be unrecognizable.
// There is no backup for keyring data due to encryption, always returns empty string.
Reset() (string, error)
}
func NewCredentialsService ¶ added in v1.1.7
func NewCredentialsService(log logging.Logger) (CredentialsService, error)
The main credentials service constructor that determines if the system's keyring is available to be used, if not, returns a file based credentials service.
type IncompleteCredentialError ¶ added in v1.1.7
type IncompleteCredentialError struct{}
func NewIncompleteCredentialError ¶ added in v1.1.7
func NewIncompleteCredentialError() *IncompleteCredentialError
func (*IncompleteCredentialError) Error ¶ added in v1.1.7
func (e *IncompleteCredentialError) Error() string
type MockCredentialsService ¶ added in v1.19.0
MockCredentialsService is a mock implementation of the CredentialsService interface
func (*MockCredentialsService) ClearDefaultServer ¶ added in v1.19.0
func (m *MockCredentialsService) ClearDefaultServer() error
func (*MockCredentialsService) Delete ¶ added in v1.19.0
func (m *MockCredentialsService) Delete(id string) error
func (*MockCredentialsService) ForceSet ¶ added in v1.19.0
func (m *MockCredentialsService) ForceSet(details CreateCredentialDetails) (*Credential, error)
func (*MockCredentialsService) Get ¶ added in v1.19.0
func (m *MockCredentialsService) Get(id string) (*Credential, error)
func (*MockCredentialsService) GetDefaultCloudServer ¶ added in v1.19.0
func (m *MockCredentialsService) GetDefaultCloudServer() (*Credential, error)
func (*MockCredentialsService) GetDefaultServer ¶ added in v1.19.0
func (m *MockCredentialsService) GetDefaultServer() (*Credential, error)
func (*MockCredentialsService) List ¶ added in v1.19.0
func (m *MockCredentialsService) List() ([]Credential, error)
func (*MockCredentialsService) Reset ¶ added in v1.19.0
func (m *MockCredentialsService) Reset() (string, error)
func (*MockCredentialsService) Set ¶ added in v1.19.0
func (m *MockCredentialsService) Set(details CreateCredentialDetails) (*Credential, error)
func (*MockCredentialsService) SetDefaultServer ¶ added in v1.19.0
func (m *MockCredentialsService) SetDefaultServer(id string) error
type NameCollisionError ¶ added in v1.1.5
Name is used by another credential
func NewNameCollisionError ¶ added in v1.1.7
func NewNameCollisionError(name, url string) *NameCollisionError
func (*NameCollisionError) Error ¶ added in v1.1.5
func (e *NameCollisionError) Error() string
type NotFoundError ¶
type NotFoundError struct {
GUID string
}
func NewNotFoundError ¶ added in v1.1.7
func NewNotFoundError(guid string) *NotFoundError
func (*NotFoundError) Error ¶
func (e *NotFoundError) Error() string
type VersionError ¶
type VersionError struct {
Version uint
}
func NewVersionError ¶ added in v1.1.7
func NewVersionError(v uint) *VersionError
func (*VersionError) Error ¶
func (e *VersionError) Error() string