adding signature syntax validation

This commit is contained in:
mzack 2021-11-17 01:28:35 +01:00
parent 0379afc748
commit 38ff8f75b1
5 changed files with 132 additions and 39 deletions

View File

@ -138,8 +138,13 @@ type Request struct {
// description: | // description: |
// SelfContained specifies if the request is self contained. // SelfContained specifies if the request is self contained.
SelfContained bool `yaml:"-" json:"-"` SelfContained bool `yaml:"-" json:"-"`
PostProcessors []string `yaml:"-" json:"-"`
// description: |
// Signature is the request signature method
// values:
// - "AWS"
Signature SignatureTypeHolder `yaml:"signature,omitempty" jsonschema:"title=signature is the http request signature method,description=Signature is the HTTP Request signature Method,enum=AWS"`
// description: | // description: |
// CookieReuse is an optional setting that enables cookie reuse for // CookieReuse is an optional setting that enables cookie reuse for

View File

@ -197,10 +197,6 @@ func (request *Request) executeTurboHTTP(reqURL string, dynamicValues, previous
return requestErr return requestErr
} }
func (request *Request) hasPreprocessors() bool {
return len(request.PostProcessors) > 0
}
// ExecuteWithResults executes the final request on a URL // ExecuteWithResults executes the final request on a URL
func (request *Request) ExecuteWithResults(reqURL string, dynamicValues, previous output.InternalEvent, callback protocols.OutputEventCallback) error { func (request *Request) ExecuteWithResults(reqURL string, dynamicValues, previous output.InternalEvent, callback protocols.OutputEventCallback) error {
// verify if pipeline was requested // verify if pipeline was requested
@ -354,37 +350,35 @@ func (request *Request) executeRequest(reqURL string, generatedRequest *generate
} }
} }
if resp == nil { if resp == nil {
for _, postProcessor := range request.PostProcessors { switch request.Signature.Value {
switch postProcessor { case AWSSignature:
case "aws-sign": var awsSigner *AwsSigner
var awsSigner *AwsSigner payloads := request.options.Options.Vars.AsMap()
payloads := request.options.Options.Vars.AsMap() awsAccessKeyId := types.ToString(payloads["aws-id"])
awsAccessKeyId := types.ToString(payloads["aws-id"]) awsSecretAccessKey := types.ToString(payloads["aws-secret"])
awsSecretAccessKey := types.ToString(payloads["aws-secret"]) if awsAccessKeyId != "" && awsSecretAccessKey != "" {
if awsAccessKeyId != "" && awsSecretAccessKey != "" { awsSigner, err = NewAwsSigner(awsAccessKeyId, awsSecretAccessKey)
awsSigner, err = NewAwsSigner(awsAccessKeyId, awsSecretAccessKey) } else {
} else { awsSigner, err = NewAwsSignerFromEnv()
awsSigner, err = NewAwsSignerFromEnv() }
} if err != nil {
if err != nil { return err
return err }
}
service := types.ToString(payloads["service"]) service := types.ToString(payloads["service"])
region := types.ToString(payloads["region"]) region := types.ToString(payloads["region"])
if service == "" || region == "" { if service == "" || region == "" {
return errors.New("service and region are mandatory") return errors.New("service and region are mandatory")
} }
args := SignArguments{ args := SignArguments{
Service: types.ToString(payloads["service"]), Service: types.ToString(payloads["service"]),
Region: types.ToString(payloads["region"]), Region: types.ToString(payloads["region"]),
Time: time.Now(), Time: time.Now(),
} }
err = awsSigner.SignHTTP(generatedRequest.request.Request, args) err = awsSigner.SignHTTP(generatedRequest.request.Request, args)
if err != nil { if err != nil {
return err return err
}
} }
} }
resp, err = request.httpClient.Do(generatedRequest.request) resp, err = request.httpClient.Do(generatedRequest.request)

View File

@ -0,0 +1,89 @@
package http
import (
"encoding/json"
"strings"
"github.com/alecthomas/jsonschema"
"github.com/pkg/errors"
)
// SignatureType is the type of signature
type SignatureType int
// Supported values for the SignatureType
const (
AWSSignature SignatureType = iota + 1
limit
)
// signatureTypeMappings is a table for conversion of signature type from string.
var signatureTypeMappings = map[SignatureType]string{
AWSSignature: "aws",
}
func GetSupportedSignaturesTypes() []SignatureType {
var result []SignatureType
for index := SignatureType(1); index < limit; index++ {
result = append(result, index)
}
return result
}
func toSignatureType(valueToMap string) (SignatureType, error) {
normalizedValue := normalizeValue(valueToMap)
for key, currentValue := range signatureTypeMappings {
if normalizedValue == currentValue {
return key, nil
}
}
return -1, errors.New("invalid signature type: " + valueToMap)
}
func normalizeValue(value string) string {
return strings.TrimSpace(strings.ToLower(value))
}
func (t SignatureType) String() string {
return signatureTypeMappings[t]
}
// SignatureTypeHolder is used to hold internal type of the signature
type SignatureTypeHolder struct {
Value SignatureType
}
func (holder SignatureTypeHolder) JSONSchemaType() *jsonschema.Type {
gotType := &jsonschema.Type{
Type: "string",
Title: "type of the signature",
Description: "Type of the signature",
}
for _, types := range GetSupportedSignaturesTypes() {
gotType.Enum = append(gotType.Enum, types.String())
}
return gotType
}
func (holder *SignatureTypeHolder) UnmarshalYAML(unmarshal func(interface{}) error) error {
var marshalledTypes string
if err := unmarshal(&marshalledTypes); err != nil {
return err
}
computedType, err := toSignatureType(marshalledTypes)
if err != nil {
return err
}
holder.Value = computedType
return nil
}
func (holder *SignatureTypeHolder) MarshalJSON() ([]byte, error) {
return json.Marshal(holder.Value.String())
}
func (holder SignatureTypeHolder) MarshalYAML() (interface{}, error) {
return holder.Value.String(), nil
}

View File

@ -107,9 +107,9 @@ func Parse(filePath string, preprocessor Preprocessor, options protocols.Execute
// parseSelfContainedRequests parses the self contained template requests. // parseSelfContainedRequests parses the self contained template requests.
func (template *Template) parseSelfContainedRequests() { func (template *Template) parseSelfContainedRequests() {
if len(template.PostProcessors) > 0 { if template.Signature.Value.String() != "" {
for _, request := range template.RequestsHTTP { for _, request := range template.RequestsHTTP {
request.PostProcessors = template.PostProcessors request.Signature = template.Signature
} }
} }
if !template.SelfContained { if !template.SelfContained {

View File

@ -73,8 +73,13 @@ type Template struct {
// description: | // description: |
// Self Contained marks Requests for the template as self-contained // Self Contained marks Requests for the template as self-contained
SelfContained bool `yaml:"self-contained,omitempty" jsonschema:"title=mark requests as self-contained,description=Mark Requests for the template as self-contained"` SelfContained bool `yaml:"self-contained,omitempty" jsonschema:"title=mark requests as self-contained,description=Mark Requests for the template as self-contained"`
PostProcessors []string `yaml:"post-processors,omitempty"`
// description: |
// Signature is the request signature method
// values:
// - "AWS"
Signature http.SignatureTypeHolder `yaml:"signature,omitempty" jsonschema:"title=signature is the http request signature method,description=Signature is the HTTP Request signature Method,enum=AWS"`
// TotalRequests is the total number of requests for the template. // TotalRequests is the total number of requests for the template.
TotalRequests int `yaml:"-" json:"-"` TotalRequests int `yaml:"-" json:"-"`