Skip to content

Commit

Permalink
Merge pull request #568 from wasuradananjith/endpoint-security-2.x.x
Browse files Browse the repository at this point in the history
[2.x] Support endpoint security parameters and subscription policies from api_params.yaml
  • Loading branch information
uvindra authored Jan 4, 2021
2 parents 668b9c5 + 4e7ca0b commit dca2ac5
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 1 deletion.
130 changes: 129 additions & 1 deletion import-export-cli/cmd/importAPI.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,18 @@ func mergeAPI(apiDirectory string, environmentParams *params.Environment) error
}
}

// Handle security parameters in api_params.yaml
err = handleSecurityEndpointsParams(environmentParams.Security, api)
if err != nil {
return err
}

// Handle available subscription policies in api_params.yaml
err = handleSubscriptionPolicies(environmentParams.Policies, api)
if err != nil {
return err
}

apiPath = filepath.Join(apiDirectory, "Meta-information", "api.yaml")
utils.Logln(utils.LogPrefixInfo+"Writing merged API to:", apiPath)
// write this to disk
Expand All @@ -241,6 +253,122 @@ func mergeAPI(apiDirectory string, environmentParams *params.Environment) error
return nil
}

// Handle available subscription policies in api_params.yaml
// @param envPolicies : Available subscription policies from api_params.yaml in the environment
// @param api : Parameters from api.yaml
// @return error
func handleSubscriptionPolicies(envPolicies []string, api *gabs.Container) error {
if envPolicies != nil {
var availableTiers []v2.AvailableTiers
// Iterate the specified policies array
for _, tierName := range envPolicies {
if tierName != "" {
availableTiers = append(availableTiers, v2.AvailableTiers{Name: tierName})
}
}
// If the available tiers are not defined in api_params.yaml, the values in the api.yaml should be considered.
// Hence, this if statment will prevent setting the availableTiers in api.yaml to an empty array if the policies
// are not properly defined in the api_params.yaml
if availableTiers != nil {
if _, err := api.SetP(availableTiers, "availableTiers"); err != nil {
return err
}
}
}
return nil
}

// Handle security parameters in api_params.yaml
// @param envSecurityEndpointParams : Environment security endpoint parameters from api_params.yaml
// @param api : Parameters from api.yaml
// @return error
func handleSecurityEndpointsParams(envSecurityEndpointParams *params.SecurityData, api *gabs.Container) error {
// If the user has set (either true or false) the enabled field under security in api_params.yaml, the
// according to the api.yaml file as usually)
// In Go, irrespective of whether a boolean value is "" or false, it will contain false by default.
// That is why, here a string comparison was made since strings can have both "" and "false"
if envSecurityEndpointParams != nil && envSecurityEndpointParams.Enabled != "" {
// Convert the string enabled to boolean
boolEnabled, err := strconv.ParseBool(envSecurityEndpointParams.Enabled)
if err != nil {
return err
}
if _, err := api.SetP(boolEnabled, "endpointSecured"); err != nil {
return err
}
// If endpoint security is enabled
if boolEnabled {
// Set the security endpoint parameters when the enabled field is set to true
err := setSecurityEndpointsParams(envSecurityEndpointParams, api)
if err != nil {
return err
}
} else {
// If endpoint security is not enabled, the username and password should be empty.
// (otherwise the security will be enabled after importing the API, considering there are values
// for username and passwords)
if _, err := api.SetP("", "endpointUTUsername"); err != nil {
return err
}
if _, err := api.SetP("", "endpointUTPassword"); err != nil {
return err
}
}
}
return nil
}

// Set the security endpoint parameters when the enabled field is set to true
// @param envSecurityEndpointParams : Environment security endpoint parameters from api_params.yaml
// @param api : Parameters from api.yaml
// @return error
func setSecurityEndpointsParams(envSecurityEndpointParams *params.SecurityData, api *gabs.Container) error {
// Check whether the username, password and type fields have set in api_params.yaml
if envSecurityEndpointParams.Username == "" {
return errors.New("You have enabled endpoint security but the username is not found in the api_params.yaml")
} else if envSecurityEndpointParams.Password == "" {
return errors.New("You have enabled endpoint security but the password is not found in the api_params.yaml")
} else if envSecurityEndpointParams.Type == "" {
return errors.New("You have enabled endpoint security but the type is not found in the api_params.yaml")
} else {
// Override the username in api.yaml with the value in api_params.yaml
if _, err := api.SetP(envSecurityEndpointParams.Username, "endpointUTUsername"); err != nil {
return err
}
// Override the password in api.yaml with the value in api_params.yaml
if _, err := api.SetP(envSecurityEndpointParams.Password, "endpointUTPassword"); err != nil {
return err
}
// Set the fields in api.yaml according to the type field in api_params.yaml
err := setEndpointSecurityType(envSecurityEndpointParams, api)
if err != nil {
return err
}
}
return nil
}

// Set the fields in api.yaml according to the type field in api_params.yaml
// @param envSecurityEndpointParams : Environment security endpoint parameters from api_params.yaml
// @param api : Parameters from api.yaml
// @return error
func setEndpointSecurityType(envSecurityEndpointParams *params.SecurityData, api *gabs.Container) error {
// Check whether the type is either basic or digest
if envSecurityEndpointParams.Type == "digest" {
if _, err := api.SetP(true, "endpointAuthDigest"); err != nil {
return err
}
} else if envSecurityEndpointParams.Type == "basic" {
if _, err := api.SetP(false, "endpointAuthDigest"); err != nil {
return err
}
} else {
// If the type is not either basic or digest, return an error
return errors.New("Invalid endpoint security type found in the api_params.yaml. Should be either basic or digest")
}
return nil
}

// isEndpointsFieldsValid returns false if either of the two fields: endpoints, loadBalanceEndpoints and failOverEndpoints are defined
// in api_params.yaml file by the user mistakenly. This will return true , if only one of them is defined.
func isEndpointsFieldsValid(endpoints *params.EndpointData, loadBalanceEndpoints *params.LoadBalanceEndpointsData, failoverEndpoints *params.FailoverEndpointsData) bool {
Expand Down Expand Up @@ -745,7 +873,7 @@ func NewFileUploadRequest(uri string, method string, params map[string]string, p
// Set headers
headers := make(map[string]string)
headers[utils.HeaderContentType] = writer.FormDataContentType()
headers[utils.HeaderAuthorization] = utils.HeaderValueAuthBasicPrefix+" "+b64encodedCredentials
headers[utils.HeaderAuthorization] = utils.HeaderValueAuthBasicPrefix + " " + b64encodedCredentials
headers[utils.HeaderAccept] = "*/*"
headers[utils.HeaderConnection] = utils.HeaderValueKeepAlive

Expand Down
16 changes: 16 additions & 0 deletions import-export-cli/specs/params/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ type FailoverEndpointsData struct {
Failover bool `yaml:"failOver" json:"failOver,omitempty"`
}

// SecurityData contains the details about endpoint security from api_params.yaml
type SecurityData struct {
// Decides whether the endpoint security is enabled
Enabled string `yaml:"enabled" json:"enabled,omitempty"`
// Type of the endpoint security (can be Basic or Digest)
Type string `yaml:"type" json:"type,omitempty"`
// Username for the endpoint
Username string `yaml:"username" json:"username,omitempty"`
// Password for the endpoint
Password string `yaml:"password" json:"password,omitempty"`
}

// Cert stores certificate details
type Cert struct {
// Host of the certificate
Expand Down Expand Up @@ -126,11 +138,15 @@ type Environment struct {
LoadBalanceEndpoints *LoadBalanceEndpointsData `yaml:"loadBalanceEndpoints"`
// FailoverEndpoints contain details about endpoints in a configuration for failover scenarios
FailoverEndpoints *FailoverEndpointsData `yaml:"failoverEndpoints"`
// Security contains the details about endpoint security
Security *SecurityData `yaml:"security"`
// GatewayEnvironments contains environments that used to deploy API
GatewayEnvironments []string `yaml:"gatewayEnvironments"`
// Certs for environment
Certs []Cert `yaml:"certs"`
MutualSslCerts []MutualSslCert `yaml:"mutualSslCerts"`
// Policies contains the available subscription policies in an environment that can be enforced to an API
Policies []string `yaml:"policies"`
}

// ApiParams represents environments defined in configuration file
Expand Down

0 comments on commit dca2ac5

Please sign in to comment.