|
|
|
@ -34,13 +34,16 @@ type Config struct {
|
|
|
|
|
type OIDCOptions struct {
|
|
|
|
|
Provider *Provider `json:"provider,omitempty"`
|
|
|
|
|
Config *Config `json:"config,omitempty"`
|
|
|
|
|
|
|
|
|
|
oidcProviderConfig *oidc.ProviderConfig
|
|
|
|
|
target *template.Template
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (o *OIDCOptions) GetProvider(ctx context.Context) *oidc.Provider {
|
|
|
|
|
if o == nil || o.Provider == nil {
|
|
|
|
|
if o == nil || o.Provider == nil || o.oidcProviderConfig == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return toOIDCProviderConfig(o.Provider).NewProvider(ctx)
|
|
|
|
|
return o.oidcProviderConfig.NewProvider(ctx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (o *OIDCOptions) GetConfig() *oidc.Config {
|
|
|
|
@ -59,40 +62,40 @@ func (o *OIDCOptions) GetConfig() *oidc.Config {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (o *OIDCOptions) validate() error {
|
|
|
|
|
func (o *OIDCOptions) validateAndInitialize() (err error) {
|
|
|
|
|
if o.Provider == nil {
|
|
|
|
|
return errors.New("provider not set")
|
|
|
|
|
}
|
|
|
|
|
if o.Provider.IssuerURL == "" {
|
|
|
|
|
return errors.New("issuer URL must not be empty")
|
|
|
|
|
}
|
|
|
|
|
if _, err := url.Parse(o.Provider.IssuerURL); err != nil {
|
|
|
|
|
return fmt.Errorf("failed parsing issuer URL: %w", err)
|
|
|
|
|
|
|
|
|
|
o.oidcProviderConfig, err = toOIDCProviderConfig(o.Provider)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed creationg OIDC provider config: %w", err)
|
|
|
|
|
}
|
|
|
|
|
if _, err := template.New("DeviceID").Parse(o.Provider.IssuerURL); err != nil {
|
|
|
|
|
return fmt.Errorf("failed parsing template: %w", err)
|
|
|
|
|
|
|
|
|
|
o.target, err = template.New("DeviceID").Parse(o.Provider.IssuerURL)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed parsing OIDC template: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (o *OIDCOptions) EvaluateTarget(deviceID string) (string, error) {
|
|
|
|
|
if o == nil {
|
|
|
|
|
return "", errors.New("misconfigured target template configuration")
|
|
|
|
|
}
|
|
|
|
|
tmpl, err := template.New("DeviceID").Parse(o.Provider.IssuerURL)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", fmt.Errorf("failed parsing OIDC template: %w", err)
|
|
|
|
|
}
|
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
|
if err = tmpl.Execute(buf, struct{ DeviceID string }{DeviceID: deviceID}); err != nil {
|
|
|
|
|
if err := o.target.Execute(buf, struct{ DeviceID string }{DeviceID: deviceID}); err != nil {
|
|
|
|
|
return "", fmt.Errorf("failed executing OIDC template: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return buf.String(), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func toOIDCProviderConfig(in *Provider) *oidc.ProviderConfig {
|
|
|
|
|
issuerURL, _ := url.Parse(in.IssuerURL) // NOTE: validation is performed in validate()
|
|
|
|
|
func toOIDCProviderConfig(in *Provider) (*oidc.ProviderConfig, error) {
|
|
|
|
|
issuerURL, err := url.Parse(in.IssuerURL)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed parsing issuer URL: %w", err)
|
|
|
|
|
}
|
|
|
|
|
// Removes query params from the URL because we use it as a way to notify client about the actual OAuth ClientId
|
|
|
|
|
// for this provisioner.
|
|
|
|
|
// This URL is going to look like: "https://idp:5556/dex?clientid=foo"
|
|
|
|
@ -107,5 +110,5 @@ func toOIDCProviderConfig(in *Provider) *oidc.ProviderConfig {
|
|
|
|
|
UserInfoURL: in.UserInfoURL,
|
|
|
|
|
JWKSURL: in.JWKSURL,
|
|
|
|
|
Algorithms: in.Algorithms,
|
|
|
|
|
}
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|