github.com/Venafi/vcert/v5@v5.10.2/pkg/playbook/app/domain/authentication.go (about)

     1  /*
     2   * Copyright 2023 Venafi, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *  http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package domain
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"gopkg.in/yaml.v3"
    23  
    24  	"github.com/Venafi/vcert/v5/pkg/endpoint"
    25  )
    26  
    27  const (
    28  	accessToken  = "accessToken"
    29  	apiKey       = "apiKey"
    30  	clientID     = "clientId"
    31  	clientSecret = "clientSecret"
    32  	externalJWT  = "externalJWT"
    33  	idP          = "idP"
    34  	idPTokenURL  = "tokenURL"
    35  	idPAudience  = "audience"
    36  	p12Task      = "p12Task"
    37  	refreshToken = "refreshToken"
    38  	scope        = "scope"
    39  	tokenURL     = "tokenURL"
    40  )
    41  
    42  // Authentication holds the credentials to connect to Venafi platforms: TPP and TLSPC
    43  type Authentication struct {
    44  	endpoint.Authentication `yaml:"-"`
    45  	P12Task                 string `yaml:"p12Task,omitempty"`
    46  }
    47  
    48  // MarshalYAML customizes the behavior of Authentication when being marshaled into a YAML document.
    49  // The returned value is marshaled in place of the original value implementing Marshaller
    50  func (a Authentication) MarshalYAML() (interface{}, error) {
    51  	values := make(map[string]interface{})
    52  
    53  	if a.AccessToken != "" {
    54  		values[accessToken] = a.AccessToken
    55  	}
    56  	if a.APIKey != "" {
    57  		values[apiKey] = a.APIKey
    58  	}
    59  	if a.ClientId != "" {
    60  		values[clientID] = a.ClientId
    61  	}
    62  	if a.ClientSecret != "" {
    63  		values[clientSecret] = a.ClientSecret
    64  	}
    65  	if a.ExternalJWT != "" {
    66  		values[externalJWT] = a.ExternalJWT
    67  	}
    68  	if a.IdentityProvider != nil {
    69  		idpMap := make(map[string]interface{})
    70  		if a.IdentityProvider.Audience != "" {
    71  			idpMap[idPAudience] = a.IdentityProvider.Audience
    72  		}
    73  		if a.IdentityProvider.TokenURL != "" {
    74  			idpMap[idPTokenURL] = a.IdentityProvider.TokenURL
    75  		}
    76  		values[idP] = idpMap
    77  	}
    78  	if a.RefreshToken != "" {
    79  		values[refreshToken] = a.RefreshToken
    80  	}
    81  	if a.P12Task != "" {
    82  		values[p12Task] = a.P12Task
    83  	}
    84  	if a.Scope != "" {
    85  		values[scope] = a.Scope
    86  	}
    87  	if a.TokenURL != "" {
    88  		values[tokenURL] = a.TokenURL
    89  	}
    90  
    91  	return values, nil
    92  }
    93  
    94  // UnmarshalYAML customizes the behavior when being unmarshalled from a YAML document
    95  func (a *Authentication) UnmarshalYAML(value *yaml.Node) error {
    96  	var authMap map[string]interface{}
    97  	err := value.Decode(&authMap)
    98  	if err != nil {
    99  		return err
   100  	}
   101  
   102  	if val, found := authMap[accessToken]; found {
   103  		a.AccessToken = val.(string)
   104  	}
   105  	if val, found := authMap[apiKey]; found {
   106  		a.APIKey = val.(string)
   107  	}
   108  	if val, found := authMap[clientID]; found {
   109  		a.ClientId = val.(string)
   110  	}
   111  	if val, found := authMap[clientSecret]; found {
   112  		a.ClientSecret = val.(string)
   113  	}
   114  	if val, found := authMap[externalJWT]; found {
   115  		a.ExternalJWT = val.(string)
   116  	}
   117  	if val, found := authMap[refreshToken]; found {
   118  		a.RefreshToken = val.(string)
   119  	}
   120  	if val, found := authMap[p12Task]; found {
   121  		a.P12Task = val.(string)
   122  	}
   123  	if val, found := authMap[scope]; found {
   124  		a.Scope = val.(string)
   125  	}
   126  	if val, found := authMap[tokenURL]; found {
   127  		a.TokenURL = val.(string)
   128  	}
   129  
   130  	if val, found := authMap[idP]; found {
   131  		provider, err := unmarshallIdP(val)
   132  		if err != nil {
   133  			return err
   134  		}
   135  		a.IdentityProvider = provider
   136  	}
   137  
   138  	return nil
   139  }
   140  
   141  func unmarshallIdP(value interface{}) (*endpoint.OAuthProvider, error) {
   142  	if value == nil {
   143  		return nil, fmt.Errorf("authentication map value is nil")
   144  	}
   145  	authMap, ok := value.(map[string]interface{})
   146  	if !ok {
   147  		return nil, fmt.Errorf("expected map but got %v", value)
   148  	}
   149  
   150  	url, tokenURLFound := authMap[idPTokenURL]
   151  	aud, audienceFound := authMap[idPAudience]
   152  
   153  	if !tokenURLFound && !audienceFound {
   154  		return nil, nil
   155  	}
   156  
   157  	provider := &endpoint.OAuthProvider{}
   158  	if tokenURLFound {
   159  		provider.TokenURL = url.(string)
   160  	}
   161  	if audienceFound {
   162  		provider.Audience = aud.(string)
   163  	}
   164  
   165  	return provider, nil
   166  }