storage: add a password resource
This commit is contained in:
parent
c50b44cf8f
commit
74b44e9757
1 changed files with 31 additions and 5 deletions
|
@ -16,12 +16,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// stubbed out for testing
|
// ErrNotFound is the error returned by storages if a resource cannot be found.
|
||||||
now = time.Now
|
ErrNotFound = errors.New("not found")
|
||||||
)
|
|
||||||
|
|
||||||
// ErrNotFound is the error returned by storages if a resource cannot be found.
|
// ErrAlreadyExists is the error returned by storages if a resource ID is taken during a create.
|
||||||
var ErrNotFound = errors.New("not found")
|
ErrAlreadyExists = errors.New("ID already exists")
|
||||||
|
)
|
||||||
|
|
||||||
// Kubernetes only allows lower case letters for names.
|
// Kubernetes only allows lower case letters for names.
|
||||||
//
|
//
|
||||||
|
@ -51,6 +51,7 @@ type Storage interface {
|
||||||
CreateClient(c Client) error
|
CreateClient(c Client) error
|
||||||
CreateAuthCode(c AuthCode) error
|
CreateAuthCode(c AuthCode) error
|
||||||
CreateRefresh(r RefreshToken) error
|
CreateRefresh(r RefreshToken) error
|
||||||
|
CreatePassword(p Password) error
|
||||||
|
|
||||||
// TODO(ericchiang): return (T, bool, error) so we can indicate not found
|
// TODO(ericchiang): return (T, bool, error) so we can indicate not found
|
||||||
// requests that way instead of using ErrNotFound.
|
// requests that way instead of using ErrNotFound.
|
||||||
|
@ -59,6 +60,7 @@ type Storage interface {
|
||||||
GetClient(id string) (Client, error)
|
GetClient(id string) (Client, error)
|
||||||
GetKeys() (Keys, error)
|
GetKeys() (Keys, error)
|
||||||
GetRefresh(id string) (RefreshToken, error)
|
GetRefresh(id string) (RefreshToken, error)
|
||||||
|
GetPassword(email string) (Password, error)
|
||||||
|
|
||||||
ListClients() ([]Client, error)
|
ListClients() ([]Client, error)
|
||||||
ListRefreshTokens() ([]RefreshToken, error)
|
ListRefreshTokens() ([]RefreshToken, error)
|
||||||
|
@ -68,6 +70,7 @@ type Storage interface {
|
||||||
DeleteAuthCode(code string) error
|
DeleteAuthCode(code string) error
|
||||||
DeleteClient(id string) error
|
DeleteClient(id string) error
|
||||||
DeleteRefresh(id string) error
|
DeleteRefresh(id string) error
|
||||||
|
DeletePassword(email string) error
|
||||||
|
|
||||||
// Update functions are assumed to be a performed within a single object transaction.
|
// Update functions are assumed to be a performed within a single object transaction.
|
||||||
//
|
//
|
||||||
|
@ -75,6 +78,7 @@ type Storage interface {
|
||||||
UpdateClient(id string, updater func(old Client) (Client, error)) error
|
UpdateClient(id string, updater func(old Client) (Client, error)) error
|
||||||
UpdateKeys(updater func(old Keys) (Keys, error)) error
|
UpdateKeys(updater func(old Keys) (Keys, error)) error
|
||||||
UpdateAuthRequest(id string, updater func(a AuthRequest) (AuthRequest, error)) error
|
UpdateAuthRequest(id string, updater func(a AuthRequest) (AuthRequest, error)) error
|
||||||
|
UpdatePassword(email string, updater func(p Password) (Password, error)) error
|
||||||
|
|
||||||
// TODO(ericchiang): Add a GarbageCollect(now time.Time) method so conformance tests
|
// TODO(ericchiang): Add a GarbageCollect(now time.Time) method so conformance tests
|
||||||
// can test implementations.
|
// can test implementations.
|
||||||
|
@ -217,6 +221,28 @@ type RefreshToken struct {
|
||||||
Nonce string
|
Nonce string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Password is an email to password mapping managed by the storage.
|
||||||
|
type Password struct {
|
||||||
|
// Email and identifying name of the password. Emails are assumed to be valid and
|
||||||
|
// determining that an end-user controls the address is left to an outside application.
|
||||||
|
//
|
||||||
|
// Emails are case insensitive and should be standardized by the storage.
|
||||||
|
//
|
||||||
|
// Storages that don't support an extended character set for IDs, such as '.' and '@'
|
||||||
|
// (cough cough, kubernetes), must map this value appropriately.
|
||||||
|
Email string `yaml:"email"`
|
||||||
|
|
||||||
|
// Bcrypt encoded hash of the password. This package recommends a cost value of at
|
||||||
|
// least 14.
|
||||||
|
Hash []byte `yaml:"hash"`
|
||||||
|
|
||||||
|
// Optional username to display. NOT used during login.
|
||||||
|
Username string `yaml:"username"`
|
||||||
|
|
||||||
|
// Randomly generated user ID. This is NOT the primary ID of the Password object.
|
||||||
|
UserID string `yaml:"userID"`
|
||||||
|
}
|
||||||
|
|
||||||
// VerificationKey is a rotated signing key which can still be used to verify
|
// VerificationKey is a rotated signing key which can still be used to verify
|
||||||
// signatures.
|
// signatures.
|
||||||
type VerificationKey struct {
|
type VerificationKey struct {
|
||||||
|
|
Reference in a new issue