103 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package basic
 | |
| 
 | |
| import (
 | |
| 	"encoding/json"
 | |
| 	"fmt"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/google/uuid"
 | |
| 	"github.com/micro/go-micro/v2/auth"
 | |
| 	"github.com/micro/go-micro/v2/auth/token"
 | |
| 	"github.com/micro/go-micro/v2/store"
 | |
| )
 | |
| 
 | |
| // 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(subject string, opts ...token.GenerateOption) (*auth.Token, error) {
 | |
| 	options := token.NewGenerateOptions(opts...)
 | |
| 
 | |
| 	// construct the token
 | |
| 	token := auth.Token{
 | |
| 		Subject:   subject,
 | |
| 		Type:      b.String(),
 | |
| 		Token:     uuid.New().String(),
 | |
| 		Created:   time.Now(),
 | |
| 		Expiry:    time.Now().Add(options.Expiry),
 | |
| 		Metadata:  options.Metadata,
 | |
| 		Roles:     options.Roles,
 | |
| 		Namespace: options.Namespace,
 | |
| 	}
 | |
| 
 | |
| 	// marshal the account to bytes
 | |
| 	bytes, err := json.Marshal(token)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	// write to the store
 | |
| 	err = b.store.Write(&store.Record{
 | |
| 		Key:    fmt.Sprintf("%v%v", StorePrefix, token.Token),
 | |
| 		Value:  bytes,
 | |
| 		Expiry: options.Expiry,
 | |
| 	})
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	// return the token
 | |
| 	return &token, nil
 | |
| }
 | |
| 
 | |
| // Inspect a token
 | |
| func (b *Basic) Inspect(t string) (*auth.Token, 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 tok *auth.Token
 | |
| 	if err := json.Unmarshal(bytes, &tok); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	// ensure the token hasn't expired, the store should
 | |
| 	// expire the token but we're checking again
 | |
| 	if tok.Expiry.Unix() < time.Now().Unix() {
 | |
| 		return nil, token.ErrInvalidToken
 | |
| 	}
 | |
| 
 | |
| 	return tok, err
 | |
| }
 | |
| 
 | |
| // String returns basic
 | |
| func (b *Basic) String() string {
 | |
| 	return "basic"
 | |
| }
 |