2020-03-23 16:19:30 +00:00
|
|
|
package basic
|
|
|
|
|
|
|
|
import (
|
2020-09-17 15:41:49 +03:00
|
|
|
"context"
|
2020-03-23 16:19:30 +00:00
|
|
|
"encoding/json"
|
2020-03-26 13:12:43 +00:00
|
|
|
"fmt"
|
2020-03-23 16:19:30 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/google/uuid"
|
2020-08-19 17:47:17 +03:00
|
|
|
"github.com/unistack-org/micro/v3/auth"
|
|
|
|
"github.com/unistack-org/micro/v3/store"
|
|
|
|
"github.com/unistack-org/micro/v3/util/token"
|
2020-03-23 16:19:30 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Basic implementation of token provider, backed by the store
|
|
|
|
type Basic struct {
|
|
|
|
store store.Store
|
|
|
|
}
|
|
|
|
|
2020-03-26 13:12:43 +00:00
|
|
|
var (
|
|
|
|
// StorePrefix to isolate tokens
|
|
|
|
StorePrefix = "tokens/"
|
|
|
|
)
|
|
|
|
|
2020-03-23 16:19:30 +00:00
|
|
|
// NewTokenProvider returns an initialized basic provider
|
|
|
|
func NewTokenProvider(opts ...token.Option) token.Provider {
|
|
|
|
options := token.NewOptions(opts...)
|
|
|
|
|
|
|
|
if options.Store == nil {
|
|
|
|
options.Store = store.DefaultStore
|
|
|
|
}
|
|
|
|
|
|
|
|
return &Basic{
|
|
|
|
store: options.Store,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generate a token for an account
|
2020-04-01 14:25:00 +01:00
|
|
|
func (b *Basic) Generate(acc *auth.Account, opts ...token.GenerateOption) (*token.Token, error) {
|
2020-03-23 16:19:30 +00:00
|
|
|
options := token.NewGenerateOptions(opts...)
|
|
|
|
|
|
|
|
// marshal the account to bytes
|
2020-04-01 14:25:00 +01:00
|
|
|
bytes, err := json.Marshal(acc)
|
2020-03-23 16:19:30 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// write to the store
|
2020-04-01 14:25:00 +01:00
|
|
|
key := uuid.New().String()
|
2020-12-10 22:08:56 +03:00
|
|
|
err = b.store.Write(context.Background(), fmt.Sprintf("%v%v", StorePrefix, key), bytes, store.WriteTTL(options.Expiry))
|
2020-03-23 16:19:30 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// return the token
|
2020-04-01 14:25:00 +01:00
|
|
|
return &token.Token{
|
|
|
|
Token: key,
|
|
|
|
Created: time.Now(),
|
|
|
|
Expiry: time.Now().Add(options.Expiry),
|
|
|
|
}, nil
|
2020-03-23 16:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Inspect a token
|
2020-04-01 14:25:00 +01:00
|
|
|
func (b *Basic) Inspect(t string) (*auth.Account, error) {
|
2020-03-23 16:19:30 +00:00
|
|
|
// lookup the token in the store
|
2020-12-10 22:08:56 +03:00
|
|
|
var val []byte
|
|
|
|
err := b.store.Read(context.Background(), StorePrefix+t, val)
|
2020-03-23 16:19:30 +00:00
|
|
|
if err == store.ErrNotFound {
|
|
|
|
return nil, token.ErrInvalidToken
|
|
|
|
} else if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
// unmarshal the bytes
|
2020-04-01 14:25:00 +01:00
|
|
|
var acc *auth.Account
|
2020-12-10 22:08:56 +03:00
|
|
|
if err := json.Unmarshal(val, &acc); err != nil {
|
2020-03-23 16:19:30 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-04-01 14:25:00 +01:00
|
|
|
return acc, nil
|
2020-03-23 16:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// String returns basic
|
|
|
|
func (b *Basic) String() string {
|
|
|
|
return "basic"
|
|
|
|
}
|