Move out the token package to util
This commit is contained in:
89
util/token/basic/basic.go
Normal file
89
util/token/basic/basic.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package basic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/micro/go-micro/v2/auth"
|
||||
"github.com/micro/go-micro/v2/store"
|
||||
"github.com/micro/go-micro/v2/util/token"
|
||||
)
|
||||
|
||||
// Basic implementation of token provider, backed by the store
|
||||
type Basic struct {
|
||||
store store.Store
|
||||
}
|
||||
|
||||
var (
|
||||
// StorePrefix to isolate tokens
|
||||
StorePrefix = "tokens/"
|
||||
)
|
||||
|
||||
// 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
|
||||
func (b *Basic) Generate(acc *auth.Account, opts ...token.GenerateOption) (*token.Token, error) {
|
||||
options := token.NewGenerateOptions(opts...)
|
||||
|
||||
// marshal the account to bytes
|
||||
bytes, err := json.Marshal(acc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// write to the store
|
||||
key := uuid.New().String()
|
||||
err = b.store.Write(&store.Record{
|
||||
Key: fmt.Sprintf("%v%v", StorePrefix, key),
|
||||
Value: bytes,
|
||||
Expiry: options.Expiry,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// return the token
|
||||
return &token.Token{
|
||||
Token: key,
|
||||
Created: time.Now(),
|
||||
Expiry: time.Now().Add(options.Expiry),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Inspect a token
|
||||
func (b *Basic) Inspect(t string) (*auth.Account, error) {
|
||||
// lookup the token in the store
|
||||
recs, err := b.store.Read(StorePrefix + t)
|
||||
if err == store.ErrNotFound {
|
||||
return nil, token.ErrInvalidToken
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bytes := recs[0].Value
|
||||
|
||||
// unmarshal the bytes
|
||||
var acc *auth.Account
|
||||
if err := json.Unmarshal(bytes, &acc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return acc, nil
|
||||
}
|
||||
|
||||
// String returns basic
|
||||
func (b *Basic) String() string {
|
||||
return "basic"
|
||||
}
|
64
util/token/basic/basic_test.go
Normal file
64
util/token/basic/basic_test.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package basic
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/micro/go-micro/v2/auth"
|
||||
"github.com/micro/go-micro/v2/store/memory"
|
||||
"github.com/micro/go-micro/v2/util/token"
|
||||
)
|
||||
|
||||
func TestGenerate(t *testing.T) {
|
||||
store := memory.NewStore()
|
||||
b := NewTokenProvider(token.WithStore(store))
|
||||
|
||||
_, err := b.Generate(&auth.Account{ID: "test"})
|
||||
if err != nil {
|
||||
t.Fatalf("Generate returned %v error, expected nil", err)
|
||||
}
|
||||
|
||||
recs, err := store.List()
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read from store: %v", err)
|
||||
}
|
||||
if len(recs) != 1 {
|
||||
t.Errorf("Generate didn't write to the store, expected 1 record, got %v", len(recs))
|
||||
}
|
||||
}
|
||||
|
||||
func TestInspect(t *testing.T) {
|
||||
store := memory.NewStore()
|
||||
b := NewTokenProvider(token.WithStore(store))
|
||||
|
||||
t.Run("Valid token", func(t *testing.T) {
|
||||
md := map[string]string{"foo": "bar"}
|
||||
scopes := []string{"admin"}
|
||||
subject := "test"
|
||||
|
||||
tok, err := b.Generate(&auth.Account{ID: subject, Scopes: scopes, Metadata: md})
|
||||
if err != nil {
|
||||
t.Fatalf("Generate returned %v error, expected nil", err)
|
||||
}
|
||||
|
||||
tok2, err := b.Inspect(tok.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Inspect returned %v error, expected nil", err)
|
||||
}
|
||||
if tok2.ID != subject {
|
||||
t.Errorf("Inspect returned %v as the token subject, expected %v", tok2.ID, subject)
|
||||
}
|
||||
if len(tok2.Scopes) != len(scopes) {
|
||||
t.Errorf("Inspect returned %v scopes, expected %v", len(tok2.Scopes), len(scopes))
|
||||
}
|
||||
if len(tok2.Metadata) != len(md) {
|
||||
t.Errorf("Inspect returned %v as the token metadata, expected %v", tok2.Metadata, md)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Invalid token", func(t *testing.T) {
|
||||
_, err := b.Inspect("Invalid token")
|
||||
if err != token.ErrInvalidToken {
|
||||
t.Fatalf("Inspect returned %v error, expected %v", err, token.ErrInvalidToken)
|
||||
}
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user