Documentation
¶
Overview ¶
Package identityservice owns remote account and credential policies.
Index ¶
- Constants
- Variables
- type Account
- type AccountSummary
- type CreatedToken
- type GoogleClient
- type GoogleFlow
- type GoogleStore
- type Invite
- type InviteStatus
- type Option
- type PasswordCredential
- type Purpose
- type Service
- func (service *Service) AccountSummaries(ctx context.Context) ([]AccountSummary, error)
- func (service *Service) Accounts(ctx context.Context) ([]Account, error)
- func (service *Service) AuthenticateSession(ctx context.Context, secret string) (Session, error)
- func (service *Service) AuthenticateToken(ctx context.Context, secret string) (TokenIdentity, error)
- func (service *Service) ChangePassword(ctx context.Context, accountID, current, password string) error
- func (service *Service) CompleteGoogle(ctx context.Context, state, binding, code string) (Session, error)
- func (service *Service) CompleteSetup(ctx context.Context, secret, username, password string) (Session, error)
- func (service *Service) CreateInvite(ctx context.Context, email string) (Invite, string, error)
- func (service *Service) CreateToken(ctx context.Context, accountID, name string, purpose Purpose, ...) (CreatedToken, error)
- func (service *Service) DeleteAccount(ctx context.Context, accountID string) error
- func (service *Service) DisableAccount(ctx context.Context, accountID string) error
- func (service *Service) EnableAccount(ctx context.Context, accountID string) error
- func (service *Service) GoogleEmail(ctx context.Context, accountID string) (string, error)
- func (service *Service) GoogleEnabled() bool
- func (service *Service) Invites(ctx context.Context) ([]Invite, error)
- func (service *Service) Login(ctx context.Context, username, password string) (Session, error)
- func (service *Service) Logout(ctx context.Context, secret string) error
- func (service *Service) PendingInvite(ctx context.Context, secret string) (Invite, error)
- func (service *Service) PrepareSetup(ctx context.Context) (string, error)
- func (service *Service) ResetPassword(ctx context.Context, username, password string) error
- func (service *Service) RevokeInvite(ctx context.Context, id string) error
- func (service *Service) RevokeToken(ctx context.Context, accountID, tokenID string) error
- func (service *Service) SetupRequired(ctx context.Context) (bool, error)
- func (service *Service) StartGoogle(ctx context.Context, inviteSecret string) (string, string, error)
- func (service *Service) Tokens(ctx context.Context, accountID string) ([]Token, error)
- type Session
- type Store
- type Token
- type TokenIdentity
Constants ¶
const ( InviteLifetime = 48 * time.Hour GoogleFlowLifetime = 10 * time.Minute )
Variables ¶
var ( // ErrGoogleDisabled reports Google sign-in is not configured. ErrGoogleDisabled = errors.New("google sign-in is not configured") // ErrNoAccount reports a Google account without a diffx account or invite. ErrNoAccount = errors.New("no account for this Google account") // ErrInviteMismatch reports a verified Google email that differs from the invite. ErrInviteMismatch = errors.New("google account does not match the invite") )
var ( ErrAuthentication = errors.New("invalid credentials") ErrInvalidInput = errors.New("invalid identity input") ErrConflict = errors.New("username already exists") ErrNotFound = errors.New("identity not found") // ErrForbidden refuses an administrative action on the admin account itself. ErrForbidden = errors.New("identity operation not permitted") )
Functions ¶
This section is empty.
Types ¶
type Account ¶
Account is an authenticated owner. Admin marks the single account that signs in with a password and manages other accounts.
type AccountSummary ¶ added in v0.2.2
AccountSummary is the administrative view of an account.
type CreatedToken ¶
type GoogleClient ¶ added in v0.2.2
type GoogleClient interface {
AuthorizeURL(state, nonce, verifier string) string
Exchange(ctx context.Context, code, verifier, nonce string) (google.Identity, error)
}
GoogleClient is the Google wire adapter this service drives.
type GoogleFlow ¶ added in v0.2.2
type GoogleFlow struct {
BindingHash string
Nonce string
Verifier string
InviteID string
ExpiresAt time.Time
}
GoogleFlow is one started authorization, bound to the starting browser.
type GoogleStore ¶ added in v0.2.2
type GoogleStore interface {
// CreateInvite revokes the email's pending invites in the same transaction;
// an email linked to an account is ErrConflict.
CreateInvite(ctx context.Context, invite Invite, tokenHash string) error
Invites(context.Context) ([]Invite, error)
Invite(ctx context.Context, id string) (Invite, error)
RevokeInvite(ctx context.Context, id string, at time.Time) error
// PendingInvite resolves an unexpired, unused, unrevoked invite by its secret.
PendingInvite(ctx context.Context, tokenHash string, now time.Time) (Invite, error)
// AcceptInvite creates the account and its Google identity and uses the
// pending invite in one transaction. A taken username is ErrConflict; an
// unavailable invite or an already linked subject is ErrNotFound.
AcceptInvite(ctx context.Context, inviteID string, account Account, identity google.Identity, now time.Time) error
// GoogleAccount resolves a linked subject, recording the latest email.
GoogleAccount(ctx context.Context, identity google.Identity, now time.Time) (account Account, disabled bool, err error)
// GoogleEmail is the latest email Google reported for the account; "" for
// accounts without a Google identity.
GoogleEmail(ctx context.Context, accountID string) (string, error)
PutGoogleFlow(ctx context.Context, stateHash string, flow GoogleFlow) error
// TakeGoogleFlow consumes an unexpired flow exactly once.
TakeGoogleFlow(ctx context.Context, stateHash string, now time.Time) (GoogleFlow, error)
}
GoogleStore persists Google identities, invites and authorization flows.
type Invite ¶ added in v0.2.2
type InviteStatus ¶ added in v0.2.2
type InviteStatus string
const ( InvitePending InviteStatus = "pending" InviteUsed InviteStatus = "used" InviteExpired InviteStatus = "expired" InviteRevoked InviteStatus = "revoked" )
type Option ¶ added in v0.2.2
type Option func(*Service)
func WithGoogle ¶ added in v0.2.2
func WithGoogle(client GoogleClient) Option
WithGoogle enables Google sign-in and invites.
type PasswordCredential ¶
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func (*Service) AccountSummaries ¶ added in v0.2.2
func (service *Service) AccountSummaries(ctx context.Context) ([]AccountSummary, error)
func (*Service) Accounts ¶
Accounts lists enabled accounts, the owners the ingestion worker may serve.
func (*Service) AuthenticateSession ¶
func (*Service) AuthenticateToken ¶
func (*Service) ChangePassword ¶
func (*Service) CompleteGoogle ¶ added in v0.2.2
func (service *Service) CompleteGoogle(ctx context.Context, state, binding, code string) (Session, error)
CompleteGoogle finishes authorization in the browser that started it. A linked Google subject signs in, keeping its account when the email changes. Otherwise an invite flow creates the account when Google verified the invited email.
func (*Service) CompleteSetup ¶ added in v0.2.2
func (service *Service) CompleteSetup(ctx context.Context, secret, username, password string) (Session, error)
CompleteSetup creates the admin from a valid setup secret and signs it in.
func (*Service) CreateInvite ¶ added in v0.2.2
CreateInvite issues a single-use 48 hour invite for one email, replacing any pending invite for it. The secret is returned once and stored hashed.
func (*Service) CreateToken ¶
func (*Service) DeleteAccount ¶ added in v0.2.2
DeleteAccount removes the account and every review, token and integration it owns.
func (*Service) DisableAccount ¶ added in v0.2.2
func (*Service) EnableAccount ¶ added in v0.2.2
func (*Service) GoogleEmail ¶ added in v0.2.2
GoogleEmail is the account's latest Google email, or "" for the admin.
func (*Service) GoogleEnabled ¶ added in v0.2.2
func (*Service) Login ¶
Login accepts passwords only for the admin; every other failure is the same ErrAuthentication, so it never reveals which accounts exist or use Google.
func (*Service) PendingInvite ¶ added in v0.2.2
PendingInvite resolves an invite link for the invite page.
func (*Service) PrepareSetup ¶ added in v0.2.2
PrepareSetup issues a one-time admin setup secret while no admin exists, replacing any earlier one. It returns "" once an admin exists. The secret is stored hashed, so each start issues a new one.
func (*Service) ResetPassword ¶
ResetPassword recovers the admin offline; other accounts have no password.
func (*Service) RevokeInvite ¶ added in v0.2.2
func (*Service) RevokeToken ¶
func (*Service) SetupRequired ¶ added in v0.2.2
type Store ¶
type Store interface {
// PutAdminSetup replaces the pending setup secret while no admin exists and
// reports whether it was stored.
PutAdminSetup(context.Context, string, time.Time) (bool, error)
AdminExists(context.Context) (bool, error)
// CreateAdmin consumes the unexpired setup secret and creates the admin in
// one transaction; a missing, expired or used secret is ErrNotFound.
CreateAdmin(ctx context.Context, account Account, passwordHash, setupHash string, now time.Time) error
AccountSummaries(context.Context) ([]AccountSummary, error)
// SetAccountDisabled revokes sessions and tokens when disabling. Both it and
// DeleteAccount refuse the admin with ErrForbidden.
SetAccountDisabled(ctx context.Context, accountID string, disabled bool, at time.Time) error
DeleteAccount(context.Context, string) error
AccountPassword(context.Context, string) (PasswordCredential, error)
AccountPasswordByID(context.Context, string) (PasswordCredential, error)
ReplacePassword(context.Context, string, string, string) error
CreateSession(context.Context, string, string, string, string, time.Time) error
ResolveSession(context.Context, string, time.Time) (Session, error)
DeleteSession(context.Context, string) error
CreateIdentityToken(context.Context, string, Token, string) error
IdentityTokens(context.Context, string) ([]Token, error)
DeleteIdentityToken(context.Context, string, string) error
ResolveIdentityToken(context.Context, string, time.Time) (TokenIdentity, error)
IdentityAccounts(context.Context) ([]Account, error)
GoogleStore
}
Store operations preserve credential races atomically. Password replacement revokes sessions in its transaction; session creation compares the verified hash and refuses disabled accounts.