2020-02-03 11:16:02 +03:00
|
|
|
package auth
|
|
|
|
|
2020-02-26 16:42:32 +03:00
|
|
|
import (
|
|
|
|
"encoding/base32"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2020-02-03 11:16:02 +03:00
|
|
|
var (
|
2020-02-24 18:07:27 +03:00
|
|
|
DefaultAuth = NewAuth()
|
2020-02-03 11:16:02 +03:00
|
|
|
)
|
|
|
|
|
2020-02-26 16:42:32 +03:00
|
|
|
func genAccount(id string) *Account {
|
|
|
|
// return a pseudo account
|
|
|
|
return &Account{
|
|
|
|
Id: id,
|
|
|
|
Token: base32.StdEncoding.EncodeToString([]byte(id)),
|
|
|
|
Created: time.Now(),
|
|
|
|
Expiry: time.Now().Add(time.Hour * 24),
|
|
|
|
Metadata: make(map[string]string),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewAuth returns a new default registry which is memory
|
2020-02-24 18:07:27 +03:00
|
|
|
func NewAuth(opts ...Option) Auth {
|
2020-02-26 01:15:44 +03:00
|
|
|
var options Options
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&options)
|
|
|
|
}
|
2020-02-26 16:42:32 +03:00
|
|
|
|
|
|
|
return &memory{
|
|
|
|
accounts: make(map[string]*Account),
|
|
|
|
opts: options,
|
2020-02-26 01:15:44 +03:00
|
|
|
}
|
2020-02-03 11:16:02 +03:00
|
|
|
}
|
|
|
|
|
2020-02-26 16:42:32 +03:00
|
|
|
// TODO: replace with https://github.com/nats-io/nkeys
|
|
|
|
// We'll then register public key in registry to use
|
|
|
|
type memory struct {
|
2020-02-26 01:15:44 +03:00
|
|
|
opts Options
|
2020-02-26 16:42:32 +03:00
|
|
|
// accounts
|
|
|
|
sync.RWMutex
|
|
|
|
accounts map[string]*Account
|
2020-02-26 01:15:44 +03:00
|
|
|
}
|
2020-02-03 11:16:02 +03:00
|
|
|
|
2020-02-26 16:42:32 +03:00
|
|
|
func (n *memory) Init(opts ...Option) error {
|
2020-02-26 01:15:44 +03:00
|
|
|
for _, o := range opts {
|
|
|
|
o(&n.opts)
|
|
|
|
}
|
2020-02-03 11:16:02 +03:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-02-26 16:42:32 +03:00
|
|
|
func (n *memory) Options() Options {
|
2020-02-26 01:15:44 +03:00
|
|
|
return n.opts
|
2020-02-10 11:26:28 +03:00
|
|
|
}
|
|
|
|
|
2020-02-26 16:42:32 +03:00
|
|
|
func (n *memory) Generate(id string, opts ...GenerateOption) (*Account, error) {
|
|
|
|
var options GenerateOptions
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&options)
|
|
|
|
}
|
|
|
|
|
|
|
|
// return a pseudo account
|
|
|
|
acc := genAccount(id)
|
|
|
|
|
|
|
|
// set opts
|
|
|
|
if len(options.Roles) > 0 {
|
|
|
|
acc.Roles = options.Roles
|
|
|
|
}
|
|
|
|
if options.Metadata != nil {
|
|
|
|
acc.Metadata = options.Metadata
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: don't overwrite
|
|
|
|
n.Lock()
|
|
|
|
// maybe save by account id?
|
|
|
|
n.accounts[acc.Token] = acc
|
|
|
|
n.Unlock()
|
|
|
|
|
|
|
|
return acc, nil
|
2020-02-03 11:16:02 +03:00
|
|
|
}
|
|
|
|
|
2020-02-26 16:42:32 +03:00
|
|
|
func (n *memory) Revoke(token string) error {
|
|
|
|
n.Lock()
|
|
|
|
delete(n.accounts, token)
|
|
|
|
n.Unlock()
|
2020-02-03 11:16:02 +03:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-02-26 16:42:32 +03:00
|
|
|
func (n *memory) Verify(token string) (*Account, error) {
|
|
|
|
n.RLock()
|
|
|
|
defer n.RUnlock()
|
|
|
|
|
|
|
|
if len(token) == 0 {
|
|
|
|
// pseudo account?
|
|
|
|
return genAccount(""), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// try get the local account if it exists
|
|
|
|
if acc, ok := n.accounts[token]; ok {
|
|
|
|
return acc, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// decode the token otherwise
|
|
|
|
b, err := base32.StdEncoding.DecodeString(token)
|
|
|
|
if err != nil {
|
2020-02-27 19:11:05 +03:00
|
|
|
return genAccount(""), nil
|
2020-02-26 16:42:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// return a pseudo account based on token/id
|
|
|
|
return &Account{
|
|
|
|
Id: string(b),
|
|
|
|
Token: token,
|
|
|
|
Created: time.Now(),
|
|
|
|
Expiry: time.Now().Add(time.Hour * 24),
|
|
|
|
Metadata: make(map[string]string),
|
|
|
|
}, nil
|
2020-02-03 11:16:02 +03:00
|
|
|
}
|
2020-02-24 18:07:27 +03:00
|
|
|
|
2020-02-26 16:42:32 +03:00
|
|
|
func (n *memory) String() string {
|
|
|
|
return "memory"
|
2020-02-24 18:07:27 +03:00
|
|
|
}
|