Documentation
¶
Overview ¶
Package settings is each user's own GitHub/Forgejo credentials — saved through the Settings page, encrypted at rest, and what dashboard.Manager builds that user's forge sources from. Replaces v1's GITHUB_TOKEN/FORGEJO_* environment variables, which configured one dashboard for everyone rather than one per signed-in user.
Index ¶
- Variables
- type Cipher
- type Credentials
- type Store
- func (s *Store) Delete(ctx context.Context, userID []byte) error
- func (s *Store) EnsureWebhookCredentials(ctx context.Context, userID []byte) (token, secret string, err error)
- func (s *Store) FindByWebhookToken(ctx context.Context, token string) (userID []byte, secret string, err error)
- func (s *Store) Get(ctx context.Context, userID []byte) (Credentials, error)
- func (s *Store) Init(ctx context.Context) error
- func (s *Store) Set(ctx context.Context, userID []byte, c Credentials) error
Constants ¶
This section is empty.
Variables ¶
var ErrNoEncryptionKey = errors.New("settings: ENCRYPTION_KEY must decode to 32 bytes")
ErrNoEncryptionKey is returned by NewCipher when key isn't valid AES-256 key material — a service holding real credentials has to fail loudly at startup rather than silently store them in the clear.
var ErrNotFound = errors.New("settings: not found")
ErrNotFound is returned when a user has never saved any credentials.
Functions ¶
This section is empty.
Types ¶
type Cipher ¶
type Cipher struct {
// contains filtered or unexported fields
}
Cipher encrypts and decrypts credential fields with AES-256-GCM.
func NewCipher ¶
NewCipher builds a Cipher from base64Key, the raw form of ENCRYPTION_KEY. Generate one with `openssl rand -base64 32`.
type Credentials ¶
type Credentials struct {
GitHubToken string
GitHubUsername string
ForgejoURL string
ForgejoToken string
ForgejoUsername string
// WebhookToken identifies this user in a webhook URL
// (/api/webhooks/{provider}/{token}); WebhookSecret is what's pasted
// into the forge's own webhook "Secret" field and never appears in
// the URL, so a leaked log line alone can't forge a valid signature.
// Neither is a third-party credential the way the forge tokens above
// are, so neither is encrypted at rest — see EnsureWebhookCredentials.
WebhookToken string
WebhookSecret string
UpdatedAt time.Time
}
Credentials is one user's forge configuration, decrypted and ready to use — never itself serialized back to a client once saved; see internal/api's settings handlers for what does reach the browser.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store persists Credentials, encrypted at rest, one row per user.
func NewStore ¶
NewStore wraps db, encrypting and decrypting every token field through cipher. Init must be called once before any other method.
func (*Store) Delete ¶ added in v0.9.0
Delete removes userID's saved credentials — a no-op, not an error, if they never saved any. Used when an admin removes the account outright.
func (*Store) EnsureWebhookCredentials ¶ added in v0.24.0
func (s *Store) EnsureWebhookCredentials(ctx context.Context, userID []byte) (token, secret string, err error)
EnsureWebhookCredentials returns userID's webhook token and secret, generating and persisting them on first call — a user who never opens Settings never gets a row touched for this, and a repeat call always returns the same values (a webhook already configured on a forge points at a URL built from the token; it can't change underneath it). Doesn't touch any other field, including on a user who has no saved row at all yet.
func (*Store) FindByWebhookToken ¶ added in v0.25.0
func (s *Store) FindByWebhookToken(ctx context.Context, token string) (userID []byte, secret string, err error)
FindByWebhookToken looks up which user a webhook token belongs to and their signing secret, for verifying an inbound webhook delivery. Returns ErrNotFound for any token with no match — including the empty string, which every row that's never called EnsureWebhookCredentials shares as its default, and which would otherwise resolve to whichever of them the query happened to return first.