2019-11-25 11:30:26 +02:00
|
|
|
// Package auth provides authentication and authorization capability
|
|
|
|
package auth
|
|
|
|
|
2019-11-25 11:33:30 +02:00
|
|
|
import (
|
2020-03-04 11:54:52 +02:00
|
|
|
"context"
|
|
|
|
"encoding/json"
|
2019-11-25 11:33:30 +02:00
|
|
|
"time"
|
2020-03-04 11:54:52 +02:00
|
|
|
|
|
|
|
"github.com/micro/go-micro/v2/metadata"
|
2019-11-25 11:33:30 +02:00
|
|
|
)
|
|
|
|
|
2019-11-25 11:30:26 +02:00
|
|
|
// Auth providers authentication and authorization
|
|
|
|
type Auth interface {
|
2020-02-03 10:16:02 +02:00
|
|
|
// Init the auth package
|
|
|
|
Init(opts ...Option) error
|
2020-02-10 10:26:28 +02:00
|
|
|
// Options returns the options set
|
|
|
|
Options() Options
|
2020-02-03 10:16:02 +02:00
|
|
|
// Generate a new auth Account
|
|
|
|
Generate(id string, opts ...GenerateOption) (*Account, error)
|
|
|
|
// Revoke an authorization Account
|
|
|
|
Revoke(token string) error
|
2020-02-26 00:15:44 +02:00
|
|
|
// Verify an account token
|
|
|
|
Verify(token string) (*Account, error)
|
2020-02-16 21:36:45 +02:00
|
|
|
// String returns the implementation
|
|
|
|
String() string
|
2019-12-17 23:27:05 +02:00
|
|
|
}
|
|
|
|
|
2020-02-03 10:16:02 +02:00
|
|
|
// Resource is an entity such as a user or
|
|
|
|
type Resource struct {
|
2019-12-17 23:27:05 +02:00
|
|
|
// Name of the resource
|
|
|
|
Name string
|
2020-02-03 10:16:02 +02:00
|
|
|
// Type of resource, e.g.
|
|
|
|
Type string
|
2019-11-25 11:30:26 +02:00
|
|
|
}
|
|
|
|
|
2020-02-03 10:16:02 +02:00
|
|
|
// Role an account has
|
|
|
|
type Role struct {
|
2020-02-26 00:15:44 +02:00
|
|
|
// Name of the role
|
|
|
|
Name string
|
|
|
|
// The resource it has access
|
|
|
|
// TODO: potentially remove
|
2020-02-03 10:16:02 +02:00
|
|
|
Resource *Resource
|
|
|
|
}
|
|
|
|
|
|
|
|
// Account provided by an auth provider
|
|
|
|
type Account struct {
|
|
|
|
// ID of the account (UUID or email)
|
2020-02-14 09:32:02 +02:00
|
|
|
Id string `json:"id"`
|
2020-02-03 10:16:02 +02:00
|
|
|
// Token used to authenticate
|
2020-02-14 09:32:02 +02:00
|
|
|
Token string `json:"token"`
|
2020-02-03 10:16:02 +02:00
|
|
|
// Time of Account creation
|
2019-11-25 11:30:26 +02:00
|
|
|
Created time.Time `json:"created"`
|
2020-02-03 10:16:02 +02:00
|
|
|
// Time of Account expiry
|
2019-11-25 11:30:26 +02:00
|
|
|
Expiry time.Time `json:"expiry"`
|
2020-02-03 10:16:02 +02:00
|
|
|
// Roles associated with the Account
|
|
|
|
Roles []*Role `json:"roles"`
|
2019-11-25 11:30:26 +02:00
|
|
|
// Any other associated metadata
|
|
|
|
Metadata map[string]string `json:"metadata"`
|
|
|
|
}
|
2020-03-04 11:54:52 +02:00
|
|
|
|
|
|
|
const (
|
|
|
|
// MetadataKey is the key used when storing the account
|
|
|
|
// in metadata
|
|
|
|
MetadataKey = "auth-account"
|
|
|
|
)
|
|
|
|
|
|
|
|
// AccountFromContext gets the account from the context, which
|
|
|
|
// is set by the auth wrapper at the start of a call. If the account
|
|
|
|
// is not set, a nil account will be returned. The error is only returned
|
|
|
|
// when there was a problem retrieving an account
|
|
|
|
func AccountFromContext(ctx context.Context) (*Account, error) {
|
|
|
|
str, ok := metadata.Get(ctx, MetadataKey)
|
|
|
|
// there was no account set
|
|
|
|
if !ok {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var acc *Account
|
|
|
|
// metadata is stored as a string, so unmarshal to an account
|
|
|
|
if err := json.Unmarshal([]byte(str), &acc); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return acc, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ContextWithAccount sets the account in the context
|
|
|
|
func ContextWithAccount(ctx context.Context, account *Account) (context.Context, error) {
|
|
|
|
// metadata is stored as a string, so marshal to bytes
|
|
|
|
bytes, err := json.Marshal(account)
|
|
|
|
if err != nil {
|
|
|
|
return ctx, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// generate a new context with the MetadataKey set
|
|
|
|
return metadata.Set(ctx, MetadataKey, string(bytes)), nil
|
|
|
|
}
|