Create the provisioner type used to englobe all different provisioners.
This commit is contained in:
parent
bed3132028
commit
4b2b6ffe32
1 changed files with 117 additions and 0 deletions
117
authority/provisioner/provisioner.go
Normal file
117
authority/provisioner/provisioner.go
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
package provisioner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Interface is the interface that all provisioner types must implement.
|
||||||
|
type Interface interface {
|
||||||
|
ID() string
|
||||||
|
Init(claims *Claims) error
|
||||||
|
Authorize(token string) ([]SignOption, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type indicates the provisioner Type.
|
||||||
|
type Type int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// TypeJWK is used to indicate the JWK provisioners.
|
||||||
|
TypeJWK Type = 1
|
||||||
|
|
||||||
|
// TypeOIDC is used to indicate the OIDC provisioners.
|
||||||
|
TypeOIDC Type = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
type provisioner struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provisioner implmements the provisioner.Interface on a base provisioner. It
|
||||||
|
// also implements custom marshalers and unmarshalers so different provisioners
|
||||||
|
// can be represented in a configuration type.
|
||||||
|
type Provisioner struct {
|
||||||
|
typ Type
|
||||||
|
base Interface
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID returns the base provisioner unique ID. This identifier is used as the key
|
||||||
|
// in a provisioner.Collection.
|
||||||
|
func (p *Provisioner) ID() string {
|
||||||
|
return p.base.ID()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init initializes the base provisioner with the given claims.
|
||||||
|
func (p *Provisioner) Init(claims *Claims) error {
|
||||||
|
return p.base.Init(claims)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authorize validates the given token on the base provisioner returning a list
|
||||||
|
// of options to validate the signing request.
|
||||||
|
func (p *Provisioner) Authorize(token string) ([]SignOption, error) {
|
||||||
|
return p.base.Authorize(token)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements the json.Marshaler interface on the Provisioner type.
|
||||||
|
func (p *Provisioner) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(p.base)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the json.Unmarshaler interface on the Provisioner
|
||||||
|
// type.
|
||||||
|
func (p *Provisioner) UnmarshalJSON(data []byte) error {
|
||||||
|
var typ provisioner
|
||||||
|
if err := json.Unmarshal(data, &typ); err != nil {
|
||||||
|
return errors.Errorf("error unmarshalling provisioner")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch strings.ToLower(typ.Type) {
|
||||||
|
case "jwt":
|
||||||
|
p.base = &JWT{}
|
||||||
|
case "oidc":
|
||||||
|
p.base = &OIDC{}
|
||||||
|
default:
|
||||||
|
return errors.New("provisioner type not supported")
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(data, &p.base); err != nil {
|
||||||
|
return errors.Errorf("error unmarshalling provisioner")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collection is a memory map of provisioners.
|
||||||
|
type Collection struct {
|
||||||
|
byID *sync.Map
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCollection initializes a collection of provisioners.
|
||||||
|
func NewCollection() *Collection {
|
||||||
|
return &Collection{
|
||||||
|
byID: new(sync.Map),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load a provisioner by the ID.
|
||||||
|
func (c *Collection) Load(id string) (*Provisioner, bool) {
|
||||||
|
i, ok := c.byID.Load(id)
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
p, ok := i.(*Provisioner)
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return p, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store adds a provisioner to the collection, it makes sure two provisioner
|
||||||
|
// does not have the same ID.
|
||||||
|
func (c *Collection) Store(p *Provisioner) error {
|
||||||
|
if _, loaded := c.byID.LoadOrStore(p.ID(), p); loaded == false {
|
||||||
|
return errors.New("cannot add multiple provisioners with the same id")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in a new issue