Documentation
¶
Overview ¶
Package twofactor is the second factor of a local account (R-405): an authenticator app's time-based codes (TOTP, RFC 6238) and recovery codes.
Local accounts only. An account from an identity provider gets its second factor from the provider, and Pando never asks it for one (R-044: the provider authenticates).
Index ¶
- Constants
- func IsAuthenticatorCode(s string) bool
- func IssuerFor(external *url.URL) string
- type Enrollment
- type Method
- type Service
- func (s *Service) Begin(ctx context.Context, userID, username string) (Enrollment, error)
- func (s *Service) Confirm(ctx context.Context, userID, presented string) ([]string, error)
- func (s *Service) Decline(ctx context.Context, userID string) error
- func (s *Service) NewRecoveryCodes(ctx context.Context, userID string) ([]string, error)
- func (s *Service) Required(ctx context.Context) (bool, error)
- func (s *Service) Reset(ctx context.Context, userID string) (bool, error)
- func (s *Service) SetupPending(ctx context.Context, user state.User) (bool, error)
- func (s *Service) Summarize(ctx context.Context, userID string) (Summary, error)
- func (s *Service) TurnOff(ctx context.Context, userID string) (bool, error)
- func (s *Service) Verify(ctx context.Context, userID, presented string) (Method, error)
- type Store
- type Summary
Constants ¶
const RecoveryCodeCount = 10
RecoveryCodeCount is how many recovery codes a set holds.
Variables ¶
This section is empty.
Functions ¶
func IsAuthenticatorCode ¶
IsAuthenticatorCode says whether what someone typed is shaped like an authenticator code rather than a recovery code, spaces aside.
Types ¶
type Enrollment ¶
type Enrollment struct {
Secret secret.Value `json:"-"`
URI secret.Value `json:"-"`
QRSVG string `json:"-"`
}
Enrollment is a new authenticator, shown to its holder once: the secret to type in, and the same as a key URI and a QR code holding it.
type Service ¶
type Service struct {
Store Store
// Policy is host policy as in force, startup overlay included.
Policy interface {
Load(ctx context.Context) (policy.Document, error)
}
Clock clock.Clock
// Issuer names this installation in an authenticator app, beside the
// account's username: "Pando (pando.example.com)".
Issuer string
}
Service is a local account's second factor (R-405). It decides nothing about who may change whose: the caller has already, and audits what it did.
func (*Service) Begin ¶
Begin makes a new authenticator secret for an account and keeps it pending until Confirm sees a code from it. Replaces any pending one. The one in use, if any, stays in use until then, so starting over never locks anyone out.
func (*Service) Confirm ¶
Confirm checks a code from the pending authenticator and, if it is right, puts the authenticator in use with a fresh set of recovery codes, which are returned to be shown once and never again.
func (*Service) Decline ¶
Decline records that the holder chose not to set one up when asked, so they are not asked again. Refused where policy requires one.
func (*Service) NewRecoveryCodes ¶
NewRecoveryCodes replaces an account's recovery codes with a fresh set.
func (*Service) Required ¶
Required says whether host policy requires a second factor on every local account.
func (*Service) Reset ¶
Reset removes an account's second factor at an administrator's asking, or from the host: someone who lost their authenticator and their recovery codes. They are asked to set it up again at the next sign-in, and must if policy requires it.
func (*Service) SetupPending ¶
SetupPending says a session of this account may do nothing but set up its second factor: a local account without one, where policy requires it. Read on every request a session makes, so the account's own row decides first and policy is read only for the accounts it could hold back.
func (*Service) TurnOff ¶
TurnOff removes an account's second factor at its holder's asking, which host policy may forbid.
type Store ¶
type Store interface {
Status(ctx context.Context, userID string) (state.TwoFactorStatus, error)
PutPending(ctx context.Context, userID string, v secret.Value) error
Secrets(ctx context.Context, userID string) (current, pending secret.Value, err error)
Enable(ctx context.Context, userID string, v secret.Value, lastStep int64, digests []string) error
AcceptStep(ctx context.Context, userID string, step int64) (bool, error)
UseRecoveryCode(ctx context.Context, userID, digest string) (bool, error)
ReplaceRecoveryCodes(ctx context.Context, userID string, digests []string) error
Disable(ctx context.Context, userID string, reoffer bool) (bool, error)
MarkOffered(ctx context.Context, userID string) error
}
Store is where second factors are kept (state.TwoFactor).
type Summary ¶
type Summary struct {
Enabled bool `json:"enabled"`
// Required says host policy requires a second factor on local accounts.
Required bool `json:"required"`
// SetupRequired is Required without one: the account can do nothing but
// set it up.
SetupRequired bool `json:"setup_required"`
// Offer says to ask the holder to set one up: not required, not on, and
// not asked before. Asked once.
Offer bool `json:"offer"`
RecoveryCodesRemaining int `json:"recovery_codes_remaining"`
}
Summary is an account's second factor as the account's holder sees it.