Further Refactoring

This commit is contained in:
Ben Toogood
2020-04-01 14:25:00 +01:00
parent 82bc3cbf8d
commit 8e4d9e1702
13 changed files with 223 additions and 401 deletions

View File

@@ -35,30 +35,19 @@ func NewTokenProvider(opts ...token.Option) token.Provider {
}
// Generate a token for an account
func (b *Basic) Generate(subject string, opts ...token.GenerateOption) (*auth.Token, error) {
func (b *Basic) Generate(acc *auth.Account, opts ...token.GenerateOption) (*token.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)
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, token.Token),
Key: fmt.Sprintf("%v%v", StorePrefix, key),
Value: bytes,
Expiry: options.Expiry,
})
@@ -67,11 +56,15 @@ func (b *Basic) Generate(subject string, opts ...token.GenerateOption) (*auth.To
}
// return the token
return &token, nil
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.Token, error) {
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 {
@@ -82,18 +75,12 @@ func (b *Basic) Inspect(t string) (*auth.Token, error) {
bytes := recs[0].Value
// unmarshal the bytes
var tok *auth.Token
if err := json.Unmarshal(bytes, &tok); err != nil {
var acc *auth.Account
if err := json.Unmarshal(bytes, &acc); 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
return acc, nil
}
// String returns basic

View File

@@ -11,7 +11,9 @@ import (
// authClaims to be encoded in the JWT
type authClaims struct {
Type string `json:"type"`
Roles []string `json:"roles"`
Provider string `json:"provider"`
Metadata map[string]string `json:"metadata"`
Namespace string `json:"namespace"`
@@ -31,7 +33,7 @@ func NewTokenProvider(opts ...token.Option) token.Provider {
}
// Generate a new JWT
func (j *JWT) Generate(subject string, opts ...token.GenerateOption) (*auth.Token, error) {
func (j *JWT) Generate(acc *auth.Account, opts ...token.GenerateOption) (*token.Token, error) {
// decode the private key
priv, err := base64.StdEncoding.DecodeString(j.opts.PrivateKey)
if err != nil {
@@ -50,8 +52,8 @@ func (j *JWT) Generate(subject string, opts ...token.GenerateOption) (*auth.Toke
// generate the JWT
expiry := time.Now().Add(options.Expiry)
t := jwt.NewWithClaims(jwt.SigningMethodRS256, authClaims{
options.Roles, options.Metadata, options.Namespace, jwt.StandardClaims{
Subject: subject,
acc.Type, acc.Roles, acc.Provider, acc.Metadata, acc.Namespace, jwt.StandardClaims{
Subject: acc.ID,
ExpiresAt: expiry.Unix(),
},
})
@@ -61,20 +63,15 @@ func (j *JWT) Generate(subject string, opts ...token.GenerateOption) (*auth.Toke
}
// return the token
return &auth.Token{
Subject: subject,
Token: tok,
Type: j.String(),
Created: time.Now(),
Expiry: expiry,
Roles: options.Roles,
Metadata: options.Metadata,
Namespace: options.Namespace,
return &token.Token{
Token: tok,
Expiry: expiry,
Created: time.Now(),
}, nil
}
// Inspect a JWT
func (j *JWT) Inspect(t string) (*auth.Token, error) {
func (j *JWT) Inspect(t string) (*auth.Account, error) {
// decode the public key
pub, err := base64.StdEncoding.DecodeString(j.opts.PublicKey)
if err != nil {
@@ -99,11 +96,12 @@ func (j *JWT) Inspect(t string) (*auth.Token, error) {
}
// return the token
return &auth.Token{
Token: t,
Subject: claims.Subject,
Metadata: claims.Metadata,
return &auth.Account{
ID: claims.Subject,
Type: claims.Type,
Roles: claims.Roles,
Provider: claims.Provider,
Metadata: claims.Metadata,
Namespace: claims.Namespace,
}, nil
}

View File

@@ -53,12 +53,6 @@ func NewOptions(opts ...Option) Options {
type GenerateOptions struct {
// Expiry for the token
Expiry time.Duration
// Metadata associated with the account
Metadata map[string]string
// Roles/scopes associated with the account
Roles []string
// Namespace the account belongs too
Namespace string
}
type GenerateOption func(o *GenerateOptions)
@@ -70,27 +64,6 @@ func WithExpiry(d time.Duration) GenerateOption {
}
}
// WithMetadata for the token
func WithMetadata(md map[string]string) func(o *GenerateOptions) {
return func(o *GenerateOptions) {
o.Metadata = md
}
}
// WithRoles for the token
func WithRoles(rs ...string) func(o *GenerateOptions) {
return func(o *GenerateOptions) {
o.Roles = rs
}
}
// WithNamespace for the token
func WithNamespace(n string) func(o *GenerateOptions) {
return func(o *GenerateOptions) {
o.Namespace = n
}
}
// NewGenerateOptions from a slice of options
func NewGenerateOptions(opts ...GenerateOption) GenerateOptions {
var options GenerateOptions

View File

@@ -2,6 +2,7 @@ package token
import (
"errors"
"time"
"github.com/micro/go-micro/v2/auth"
)
@@ -17,7 +18,16 @@ var (
// Provider generates and inspects tokens
type Provider interface {
Generate(subject string, opts ...GenerateOption) (*auth.Token, error)
Inspect(token string) (*auth.Token, error)
Generate(account *auth.Account, opts ...GenerateOption) (*Token, error)
Inspect(token string) (*auth.Account, error)
String() string
}
type Token struct {
// The actual token
Token string `json:"token"`
// Time of token creation
Created time.Time `json:"created"`
// Time of token expiry
Expiry time.Time `json:"expiry"`
}