forked from TrueCloudLab/certificates
Complete first version of provisioner implementations.
This commit is contained in:
parent
7eb6eb1d3e
commit
0dee841a4f
3 changed files with 222 additions and 131 deletions
|
@ -1,110 +1,53 @@
|
||||||
package authority
|
package provisioner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/x509"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/cli/crypto/x509util"
|
"github.com/smallstep/cli/crypto/x509util"
|
||||||
|
"github.com/smallstep/cli/jose"
|
||||||
jose "gopkg.in/square/go-jose.v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProvisionerClaims so that individual provisioners can override global claims.
|
// jwtPayload extends jwt.Claims with step attributes.
|
||||||
type ProvisionerClaims struct {
|
type jwtPayload struct {
|
||||||
globalClaims *ProvisionerClaims
|
jose.Claims
|
||||||
MinTLSDur *Duration `json:"minTLSCertDuration,omitempty"`
|
SANs []string `json:"sans,omitempty"`
|
||||||
MaxTLSDur *Duration `json:"maxTLSCertDuration,omitempty"`
|
|
||||||
DefaultTLSDur *Duration `json:"defaultTLSCertDuration,omitempty"`
|
|
||||||
DisableRenewal *bool `json:"disableRenewal,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init initializes and validates the individual provisioner claims.
|
// JWT is the default provisioner, an entity that can sign tokens necessary for
|
||||||
func (pc *ProvisionerClaims) Init(global *ProvisionerClaims) (*ProvisionerClaims, error) {
|
// signature requests.
|
||||||
if pc == nil {
|
type JWT struct {
|
||||||
pc = &ProvisionerClaims{}
|
Name string `json:"name,omitempty"`
|
||||||
}
|
Type string `json:"type,omitempty"`
|
||||||
pc.globalClaims = global
|
Key *jose.JSONWebKey `json:"key,omitempty"`
|
||||||
err := pc.Validate()
|
EncryptedKey string `json:"encryptedKey,omitempty"`
|
||||||
return pc, err
|
Claims *Claims `json:"claims,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultTLSCertDuration returns the default TLS cert duration for the
|
// GetID returns the provisioner unique identifier. The name and credential id
|
||||||
// provisioner. If the default is not set within the provisioner, then the global
|
// should uniquely identify any JWT provisioner.
|
||||||
// default from the authority configuration will be used.
|
func (p *JWT) GetID() string {
|
||||||
func (pc *ProvisionerClaims) DefaultTLSCertDuration() time.Duration {
|
return p.Name + ":" + p.Key.KeyID
|
||||||
if pc.DefaultTLSDur == nil || pc.DefaultTLSDur.Duration == 0 {
|
|
||||||
return pc.globalClaims.DefaultTLSCertDuration()
|
|
||||||
}
|
|
||||||
return pc.DefaultTLSDur.Duration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MinTLSCertDuration returns the minimum TLS cert duration for the provisioner.
|
// GetName returns the name of the provisioner
|
||||||
// If the minimum is not set within the provisioner, then the global
|
func (p *JWT) GetName() string {
|
||||||
// minimum from the authority configuration will be used.
|
return p.Name
|
||||||
func (pc *ProvisionerClaims) MinTLSCertDuration() time.Duration {
|
|
||||||
if pc.MinTLSDur == nil || pc.MinTLSDur.Duration == 0 {
|
|
||||||
return pc.globalClaims.MinTLSCertDuration()
|
|
||||||
}
|
|
||||||
return pc.MinTLSDur.Duration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MaxTLSCertDuration returns the maximum TLS cert duration for the provisioner.
|
// GetType returns the type of provisioner.
|
||||||
// If the maximum is not set within the provisioner, then the global
|
func (p *JWT) GetType() Type {
|
||||||
// maximum from the authority configuration will be used.
|
return TypeJWK
|
||||||
func (pc *ProvisionerClaims) MaxTLSCertDuration() time.Duration {
|
|
||||||
if pc.MaxTLSDur == nil || pc.MaxTLSDur.Duration == 0 {
|
|
||||||
return pc.globalClaims.MaxTLSCertDuration()
|
|
||||||
}
|
|
||||||
return pc.MaxTLSDur.Duration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDisableRenewal returns if the renewal flow is disabled for the
|
// GetEncryptedKey returns the base provisioner encrypted key if it's defined.
|
||||||
// provisioner. If the property is not set within the provisioner, then the
|
func (p *JWT) GetEncryptedKey() (string, string, bool) {
|
||||||
// global value from the authority configuration will be used.
|
return p.Key.KeyID, p.EncryptedKey, len(p.EncryptedKey) > 0
|
||||||
func (pc *ProvisionerClaims) IsDisableRenewal() bool {
|
|
||||||
if pc.DisableRenewal == nil {
|
|
||||||
return pc.globalClaims.IsDisableRenewal()
|
|
||||||
}
|
|
||||||
return *pc.DisableRenewal
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate validates and modifies the Claims with default values.
|
|
||||||
func (pc *ProvisionerClaims) Validate() error {
|
|
||||||
var (
|
|
||||||
min = pc.MinTLSCertDuration()
|
|
||||||
max = pc.MaxTLSCertDuration()
|
|
||||||
def = pc.DefaultTLSCertDuration()
|
|
||||||
)
|
|
||||||
switch {
|
|
||||||
case min == 0:
|
|
||||||
return errors.Errorf("claims: MinTLSCertDuration cannot be empty")
|
|
||||||
case max == 0:
|
|
||||||
return errors.Errorf("claims: MaxTLSCertDuration cannot be empty")
|
|
||||||
case def == 0:
|
|
||||||
return errors.Errorf("claims: DefaultTLSCertDuration cannot be empty")
|
|
||||||
case max < min:
|
|
||||||
return errors.Errorf("claims: MaxCertDuration cannot be less "+
|
|
||||||
"than MinCertDuration: MaxCertDuration - %v, MinCertDuration - %v", max, min)
|
|
||||||
case def < min:
|
|
||||||
return errors.Errorf("claims: DefaultCertDuration cannot be less than MinCertDuration: DefaultCertDuration - %v, MinCertDuration - %v", def, min)
|
|
||||||
case max < def:
|
|
||||||
return errors.Errorf("claims: MaxCertDuration cannot be less than DefaultCertDuration: MaxCertDuration - %v, DefaultCertDuration - %v", max, def)
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provisioner - authorized entity that can sign tokens necessary for signature requests.
|
|
||||||
type Provisioner struct {
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Type string `json:"type,omitempty"`
|
|
||||||
Key *jose.JSONWebKey `json:"key,omitempty"`
|
|
||||||
EncryptedKey string `json:"encryptedKey,omitempty"`
|
|
||||||
Claims *ProvisionerClaims `json:"claims,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init initializes and validates a the fields of Provisioner type.
|
// Init initializes and validates a the fields of Provisioner type.
|
||||||
func (p *Provisioner) Init(global *ProvisionerClaims) error {
|
func (p *JWT) Init(global *Claims) (err error) {
|
||||||
switch {
|
switch {
|
||||||
case p.Name == "":
|
case p.Name == "":
|
||||||
return errors.New("provisioner name cannot be empty")
|
return errors.New("provisioner name cannot be empty")
|
||||||
|
@ -115,30 +58,108 @@ func (p *Provisioner) Init(global *ProvisionerClaims) error {
|
||||||
case p.Key == nil:
|
case p.Key == nil:
|
||||||
return errors.New("provisioner key cannot be empty")
|
return errors.New("provisioner key cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
|
||||||
p.Claims, err = p.Claims.Init(global)
|
p.Claims, err = p.Claims.Init(global)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// getTLSApps returns a list of modifiers and validators that will be applied to
|
func (p *JWT) Authorize(token string) ([]SignOption, error) {
|
||||||
// the certificate.
|
jwt, err := jose.ParseSigned(token)
|
||||||
func (p *Provisioner) getTLSApps(so SignOptions) ([]x509util.WithOption, []certClaim, error) {
|
if err != nil {
|
||||||
c := p.Claims
|
return nil, errors.Wrapf(err, "error parsing token")
|
||||||
return []x509util.WithOption{
|
}
|
||||||
x509util.WithNotBeforeAfterDuration(so.NotBefore,
|
|
||||||
so.NotAfter, c.DefaultTLSCertDuration()),
|
var claims jwtPayload
|
||||||
withProvisionerOID(p.Name, p.Key.KeyID),
|
if err = jwt.Claims(p.Key, &claims); err != nil {
|
||||||
}, []certClaim{
|
return nil, errors.Wrap(err, "error parsing claims")
|
||||||
&certTemporalClaim{
|
}
|
||||||
min: c.MinTLSCertDuration(),
|
|
||||||
max: c.MaxTLSCertDuration(),
|
// According to "rfc7519 JSON Web Token" acceptable skew should be no
|
||||||
},
|
// more than a few minutes.
|
||||||
}, nil
|
if err = claims.ValidateWithLeeway(jose.Expected{
|
||||||
|
Issuer: p.Name,
|
||||||
|
}, time.Minute); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "invalid token")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not accept tokens issued before the start of the ca.
|
||||||
|
// This check is meant as a stopgap solution to the current lack of a persistence layer.
|
||||||
|
// if a.config.AuthorityConfig != nil && !a.config.AuthorityConfig.DisableIssuedAtCheck {
|
||||||
|
// if claims.IssuedAt > 0 && claims.IssuedAt.Time().Before(a.startTime) {
|
||||||
|
// return nil, &apiError{errors.New("token issued before the bootstrap of certificate authority"),
|
||||||
|
// http.StatusUnauthorized, errContext}
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if !matchesAudience(claims.Audience, a.audiences) {
|
||||||
|
// return nil, &apiError{errors.New("authorize: token audience invalid"), http.StatusUnauthorized,
|
||||||
|
// errContext}
|
||||||
|
// }
|
||||||
|
|
||||||
|
if claims.Subject == "" {
|
||||||
|
return nil, errors.New("token subject cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: This is for backwards compatibility with older versions of cli
|
||||||
|
// and certificates. Older versions added the token subject as the only SAN
|
||||||
|
// in a CSR by default.
|
||||||
|
if len(claims.SANs) == 0 {
|
||||||
|
claims.SANs = []string{claims.Subject}
|
||||||
|
}
|
||||||
|
|
||||||
|
dnsNames, ips := x509util.SplitSANs(claims.SANs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
signOps := []SignOption{
|
||||||
|
commonNameValidator(claims.Subject),
|
||||||
|
dnsNamesValidator(dnsNames),
|
||||||
|
ipAddressesValidator(ips),
|
||||||
|
// profileWithOption(x509util.WithNotBeforeAfterDuration(so.NotBefore, so.NotAfter, p.Claims.DefaultTLSCertDuration())),
|
||||||
|
&validityValidator{
|
||||||
|
min: p.Claims.MinTLSCertDuration(),
|
||||||
|
max: p.Claims.MaxTLSCertDuration(),
|
||||||
|
},
|
||||||
|
newProvisionerExtensionOption(TypeJWK, p.Name, p.Key.KeyID),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the token to protect against reuse.
|
||||||
|
// if _, ok := a.ottMap.LoadOrStore(claims.ID, &idUsed{
|
||||||
|
// UsedAt: time.Now().Unix(),
|
||||||
|
// Subject: claims.Subject,
|
||||||
|
// }); ok {
|
||||||
|
// return nil, &apiError{errors.Errorf("token already used"), http.StatusUnauthorized,
|
||||||
|
// errContext}
|
||||||
|
// }
|
||||||
|
|
||||||
|
return signOps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID returns the provisioner identifier. The name and credential id should
|
// AuthorizeRenewal returns an error if the renewal is disabled.
|
||||||
// uniquely identify any provisioner.
|
func (p *JWT) AuthorizeRenewal(cert *x509.Certificate) error {
|
||||||
func (p *Provisioner) ID() string {
|
if p.Claims.IsDisableRenewal() {
|
||||||
return p.Name + ":" + p.Key.KeyID
|
return errors.Errorf("renew is disabled for provisioner %s", p.GetID())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AuthorizeRevoke returns an error if the provisioner does not have rights to
|
||||||
|
// revoke the certificate with serial number in the `sub` property.
|
||||||
|
func (p *JWT) AuthorizeRevoke(token string) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// // getTLSApps returns a list of modifiers and validators that will be applied to
|
||||||
|
// // the certificate.
|
||||||
|
// func (p *JWT) getTLSApps(so SignOptions) ([]x509util.WithOption, []certClaim, error) {
|
||||||
|
// c := p.Claims
|
||||||
|
// return []x509util.WithOption{
|
||||||
|
// x509util.WithNotBeforeAfterDuration(so.NotBefore, so.NotAfter, c.DefaultTLSCertDuration()),
|
||||||
|
// withProvisionerOID(p.Name, p.Key.KeyID),
|
||||||
|
// }, []certClaim{
|
||||||
|
// &certTemporalClaim{
|
||||||
|
// min: c.MinTLSCertDuration(),
|
||||||
|
// max: c.MaxTLSCertDuration(),
|
||||||
|
// },
|
||||||
|
// }, nil
|
||||||
|
// }
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package provisioner
|
package provisioner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/x509"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
@ -9,6 +10,8 @@ import (
|
||||||
"github.com/smallstep/cli/jose"
|
"github.com/smallstep/cli/jose"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// openIDConfiguration contains the necessary properties in the
|
||||||
|
// `/.well-known/openid-configuration` document.
|
||||||
type openIDConfiguration struct {
|
type openIDConfiguration struct {
|
||||||
Issuer string `json:"issuer"`
|
Issuer string `json:"issuer"`
|
||||||
JWKSetURI string `json:"jwks_uri"`
|
JWKSetURI string `json:"jwks_uri"`
|
||||||
|
@ -20,7 +23,7 @@ type openIDPayload struct {
|
||||||
AtHash string `json:"at_hash"`
|
AtHash string `json:"at_hash"`
|
||||||
AuthorizedParty string `json:"azp"`
|
AuthorizedParty string `json:"azp"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
EmailVerified string `json:"email_verified"`
|
EmailVerified bool `json:"email_verified"`
|
||||||
Hd string `json:"hd"`
|
Hd string `json:"hd"`
|
||||||
Nonce string `json:"nonce"`
|
Nonce string `json:"nonce"`
|
||||||
}
|
}
|
||||||
|
@ -32,7 +35,7 @@ type OIDC struct {
|
||||||
ClientID string `json:"clientID"`
|
ClientID string `json:"clientID"`
|
||||||
ConfigurationEndpoint string `json:"configurationEndpoint"`
|
ConfigurationEndpoint string `json:"configurationEndpoint"`
|
||||||
Claims *Claims `json:"claims,omitempty"`
|
Claims *Claims `json:"claims,omitempty"`
|
||||||
Admins []string `json:"admins"`
|
Admins []string `json:"admins,omitempty"`
|
||||||
configuration openIDConfiguration
|
configuration openIDConfiguration
|
||||||
keyStore *keyStore
|
keyStore *keyStore
|
||||||
}
|
}
|
||||||
|
@ -48,8 +51,29 @@ func (o *OIDC) IsAdmin(email string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates and initializes the OIDC provider.
|
// GetID returns the provisioner unique identifier, the OIDC provisioner the
|
||||||
func (o *OIDC) Validate() error {
|
// uses the clientID for this.
|
||||||
|
func (o *OIDC) GetID() string {
|
||||||
|
return o.ClientID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetName returns the name of the provisioner.
|
||||||
|
func (o *OIDC) GetName() string {
|
||||||
|
return o.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetType returns the type of provisioner.
|
||||||
|
func (o *OIDC) GetType() Type {
|
||||||
|
return TypeOIDC
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEncryptedKey is not available in an OIDC provisioner.
|
||||||
|
func (o *OIDC) GetEncryptedKey() (kid string, key string, ok bool) {
|
||||||
|
return "", "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init validates and initializes the OIDC provider.
|
||||||
|
func (o *OIDC) Init(global *Claims) (err error) {
|
||||||
switch {
|
switch {
|
||||||
case o.Name == "":
|
case o.Name == "":
|
||||||
return errors.New("name cannot be empty")
|
return errors.New("name cannot be empty")
|
||||||
|
@ -59,21 +83,22 @@ func (o *OIDC) Validate() error {
|
||||||
return errors.New("configurationEndpoint cannot be empty")
|
return errors.New("configurationEndpoint cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode openid-configuration endpoint
|
// Update claims with global ones
|
||||||
var conf openIDConfiguration
|
if o.Claims, err = o.Claims.Init(global); err != nil {
|
||||||
if err := getAndDecode(o.ConfigurationEndpoint, &conf); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if conf.JWKSetURI == "" {
|
// Decode openid-configuration endpoint
|
||||||
|
if err := getAndDecode(o.ConfigurationEndpoint, &o.configuration); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if o.configuration.JWKSetURI == "" {
|
||||||
return errors.Errorf("error parsing %s: jwks_uri cannot be empty", o.ConfigurationEndpoint)
|
return errors.Errorf("error parsing %s: jwks_uri cannot be empty", o.ConfigurationEndpoint)
|
||||||
}
|
}
|
||||||
// Get JWK key set
|
// Get JWK key set
|
||||||
keyStore, err := newKeyStore(conf.JWKSetURI)
|
o.keyStore, err = newKeyStore(o.configuration.JWKSetURI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
o.configuration = conf
|
|
||||||
o.keyStore = keyStore
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +127,8 @@ func (o *OIDC) Authorize(token string) ([]SignOption, error) {
|
||||||
return nil, errors.Wrapf(err, "error parsing token")
|
return nil, errors.Wrapf(err, "error parsing token")
|
||||||
}
|
}
|
||||||
|
|
||||||
var claims openIDPayload
|
|
||||||
// Parse claims to get the kid
|
// Parse claims to get the kid
|
||||||
|
var claims openIDPayload
|
||||||
if err := jwt.UnsafeClaimsWithoutVerification(&claims); err != nil {
|
if err := jwt.UnsafeClaimsWithoutVerification(&claims); err != nil {
|
||||||
return nil, errors.Wrap(err, "error parsing claims")
|
return nil, errors.Wrap(err, "error parsing claims")
|
||||||
}
|
}
|
||||||
|
@ -131,9 +156,24 @@ func (o *OIDC) Authorize(token string) ([]SignOption, error) {
|
||||||
|
|
||||||
return []SignOption{
|
return []SignOption{
|
||||||
emailOnlyIdentity(claims.Email),
|
emailOnlyIdentity(claims.Email),
|
||||||
|
newProvisionerExtensionOption(TypeOIDC, o.Name, o.ClientID),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AuthorizeRenewal returns an error if the renewal is disabled.
|
||||||
|
func (o *OIDC) AuthorizeRenewal(cert *x509.Certificate) error {
|
||||||
|
if o.Claims.IsDisableRenewal() {
|
||||||
|
return errors.Errorf("renew is disabled for provisioner %s", o.GetID())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthorizeRevoke returns an error if the provisioner does not have rights to
|
||||||
|
// revoke the certificate with serial number in the `sub` property.
|
||||||
|
func (o *OIDC) AuthorizeRevoke(token string) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
func getAndDecode(uri string, v interface{}) error {
|
func getAndDecode(uri string, v interface{}) error {
|
||||||
resp, err := http.Get(uri)
|
resp, err := http.Get(uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package provisioner
|
package provisioner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/x509"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -9,10 +10,14 @@ import (
|
||||||
|
|
||||||
// Interface is the interface that all provisioner types must implement.
|
// Interface is the interface that all provisioner types must implement.
|
||||||
type Interface interface {
|
type Interface interface {
|
||||||
ID() string
|
GetID() string
|
||||||
|
GetName() string
|
||||||
|
GetType() Type
|
||||||
GetEncryptedKey() (kid string, key string, ok bool)
|
GetEncryptedKey() (kid string, key string, ok bool)
|
||||||
Init(claims *Claims) error
|
Init(claims *Claims) error
|
||||||
Authorize(token string) ([]SignOption, error)
|
Authorize(token string) ([]SignOption, error)
|
||||||
|
AuthorizeRenewal(cert *x509.Certificate) error
|
||||||
|
AuthorizeRevoke(token string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type indicates the provisioner Type.
|
// Type indicates the provisioner Type.
|
||||||
|
@ -34,14 +39,25 @@ type provisioner struct {
|
||||||
// also implements custom marshalers and unmarshalers so different provisioners
|
// also implements custom marshalers and unmarshalers so different provisioners
|
||||||
// can be represented in a configuration type.
|
// can be represented in a configuration type.
|
||||||
type Provisioner struct {
|
type Provisioner struct {
|
||||||
typ Type
|
|
||||||
base Interface
|
base Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID returns the base provisioner unique ID. This identifier is used as the key
|
// New creates a new provisioner from the base provisioner.
|
||||||
// in a provisioner.Collection.
|
func New(base Interface) *Provisioner {
|
||||||
func (p *Provisioner) ID() string {
|
return &Provisioner{
|
||||||
return p.base.ID()
|
base: base,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Base returns the base type of the provisioner.
|
||||||
|
func (p *Provisioner) Base() Interface {
|
||||||
|
return p.base
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetID returns the base provisioner unique ID. This identifier is used as the
|
||||||
|
// key in a provisioner.Collection.
|
||||||
|
func (p *Provisioner) GetID() string {
|
||||||
|
return p.base.GetID()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEncryptedKey returns the base provisioner encrypted key if it's defined.
|
// GetEncryptedKey returns the base provisioner encrypted key if it's defined.
|
||||||
|
@ -49,9 +65,14 @@ func (p *Provisioner) GetEncryptedKey() (string, string, bool) {
|
||||||
return p.base.GetEncryptedKey()
|
return p.base.GetEncryptedKey()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type return the provisioners type.
|
// GetName returns the name of the provisioner
|
||||||
func (p *Provisioner) Type() Type {
|
func (p *Provisioner) GetName() string {
|
||||||
return p.typ
|
return p.base.GetName()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetType return the provisioners type.
|
||||||
|
func (p *Provisioner) GetType() Type {
|
||||||
|
return p.base.GetType()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init initializes the base provisioner with the given claims.
|
// Init initializes the base provisioner with the given claims.
|
||||||
|
@ -65,6 +86,17 @@ func (p *Provisioner) Authorize(token string) ([]SignOption, error) {
|
||||||
return p.base.Authorize(token)
|
return p.base.Authorize(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AuthorizeRenewal checks if the base provisioner authorizes the renewal.
|
||||||
|
func (p *Provisioner) AuthorizeRenewal(cert *x509.Certificate) error {
|
||||||
|
return p.base.AuthorizeRenewal(cert)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthorizeRevoke checks on the base provisioner if the given token has revoke
|
||||||
|
// access.
|
||||||
|
func (p *Provisioner) AuthorizeRevoke(token string) error {
|
||||||
|
return p.base.AuthorizeRevoke(token)
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalJSON implements the json.Marshaler interface on the Provisioner type.
|
// MarshalJSON implements the json.Marshaler interface on the Provisioner type.
|
||||||
func (p *Provisioner) MarshalJSON() ([]byte, error) {
|
func (p *Provisioner) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(p.base)
|
return json.Marshal(p.base)
|
||||||
|
@ -79,14 +111,12 @@ func (p *Provisioner) UnmarshalJSON(data []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch strings.ToLower(typ.Type) {
|
switch strings.ToLower(typ.Type) {
|
||||||
case "jwt":
|
case "jwk":
|
||||||
p.typ = TypeJWK
|
|
||||||
p.base = &JWT{}
|
p.base = &JWT{}
|
||||||
case "oidc":
|
case "oidc":
|
||||||
p.typ = TypeOIDC
|
|
||||||
p.base = &OIDC{}
|
p.base = &OIDC{}
|
||||||
default:
|
default:
|
||||||
return errors.New("provisioner type not supported")
|
return errors.Errorf("provisioner type %s not supported", typ.Type)
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(data, &p.base); err != nil {
|
if err := json.Unmarshal(data, &p.base); err != nil {
|
||||||
return errors.Errorf("error unmarshalling provisioner")
|
return errors.Errorf("error unmarshalling provisioner")
|
||||||
|
|
Loading…
Reference in a new issue