Skip to content

Commit

Permalink
private/model/api: Adding support for unsigned trait (#1130)
Browse files Browse the repository at this point in the history
* Adding support for unsigned trait

* Removing type aliased option
  • Loading branch information
xibz committed Mar 21, 2017
1 parent 5b99715 commit 90e1e93
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 5 deletions.
7 changes: 7 additions & 0 deletions aws/signer/v4/options.go
@@ -0,0 +1,7 @@
package v4

// WithUnsignedPayload will enable and set the UnsignedPayload field to
// true of the signer.
func WithUnsignedPayload(v4 *Signer) {
v4.UnsignedPayload = true
}
27 changes: 24 additions & 3 deletions aws/signer/v4/v4.go
Expand Up @@ -194,6 +194,10 @@ type Signer struct {
// This value should only be used for testing. If it is nil the default
// time.Now will be used.
currentTimeFn func() time.Time

// UnsignedPayload will prevent signing of the payload. This will only
// work for services that have support for this.
UnsignedPayload bool
}

// NewSigner returns a Signer pointer configured with the credentials and optional
Expand Down Expand Up @@ -227,6 +231,7 @@ type signingCtx struct {
isPresign bool
formattedTime string
formattedShortTime string
unsignedPayload bool

bodyDigest string
signedHeaders string
Expand Down Expand Up @@ -317,6 +322,7 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
ServiceName: service,
Region: region,
DisableURIPathEscaping: v4.DisableURIPathEscaping,
unsignedPayload: v4.UnsignedPayload,
}

for key := range ctx.Query {
Expand Down Expand Up @@ -409,7 +415,18 @@ var SignRequestHandler = request.NamedHandler{
func SignSDKRequest(req *request.Request) {
signSDKRequestWithCurrTime(req, time.Now)
}
func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time) {

// BuildNamedHandler will build a generic handler for signing.
func BuildNamedHandler(name string, opts ...func(*Signer)) request.NamedHandler {
return request.NamedHandler{
Name: name,
Fn: func(req *request.Request) {
signSDKRequestWithCurrTime(req, time.Now, opts...)
},
}
}

func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time, opts ...func(*Signer)) {
// If the request does not need to be signed ignore the signing of the
// request if the AnonymousCredentials object is used.
if req.Config.Credentials == credentials.AnonymousCredentials {
Expand Down Expand Up @@ -441,6 +458,10 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time
v4.DisableRequestBodyOverwrite = true
})

for _, opt := range opts {
opt(v4)
}

signingTime := req.Time
if !req.LastSignedAt.IsZero() {
signingTime = req.LastSignedAt
Expand Down Expand Up @@ -634,14 +655,14 @@ func (ctx *signingCtx) buildSignature() {
func (ctx *signingCtx) buildBodyDigest() {
hash := ctx.Request.Header.Get("X-Amz-Content-Sha256")
if hash == "" {
if ctx.isPresign && ctx.ServiceName == "s3" {
if ctx.unsignedPayload || (ctx.isPresign && ctx.ServiceName == "s3") {
hash = "UNSIGNED-PAYLOAD"
} else if ctx.Body == nil {
hash = emptyStringSHA256
} else {
hash = hex.EncodeToString(makeSha256Reader(ctx.Body))
}
if ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" {
if ctx.unsignedPayload || ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" {
ctx.Request.Header.Set("X-Amz-Content-Sha256", hash)
}
}
Expand Down
23 changes: 21 additions & 2 deletions private/model/api/operation.go
Expand Up @@ -44,6 +44,26 @@ func (o *Operation) HasOutput() bool {
return o.OutputRef.ShapeName != ""
}

func (o *Operation) GetSigner() string {
if o.AuthType == "v4-unsigned-body" {
o.API.imports["github.com/aws/aws-sdk-go/aws/signer/v4"] = true
}

buf := bytes.NewBuffer(nil)

switch o.AuthType {
case "none":
buf.WriteString("req.Config.Credentials = credentials.AnonymousCredentials")
case "v4-unsigned-body":
buf.WriteString("req.Handlers.Sign.Remove(v4.SignRequestHandler)\n")
buf.WriteString("handler := v4.BuildNamedHandler(\"v4.CustomSignerHandler\", v4.WithUnsignedPayload)\n")
buf.WriteString("req.Handlers.Sign.PushFrontNamed(handler)")
}

buf.WriteString("\n")
return buf.String()
}

// tplOperation defines a template for rendering an API Operation
var tplOperation = template.Must(template.New("operation").Funcs(template.FuncMap{
"GetCrosslinkURL": GetCrosslinkURL,
Expand Down Expand Up @@ -104,8 +124,7 @@ func (c *{{ .API.StructName }}) {{ .ExportedName }}Request(` +
req = c.newRequest(op, input, output){{ if eq .OutputRef.Shape.Placeholder true }}
req.Handlers.Unmarshal.Remove({{ .API.ProtocolPackage }}.UnmarshalHandler)
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler){{ end }}
{{ if eq .AuthType "none" }}req.Config.Credentials = credentials.AnonymousCredentials
{{ end -}}
{{ if ne .AuthType "" }}{{ .GetSigner }}{{ end -}}
return
}
Expand Down

0 comments on commit 90e1e93

Please sign in to comment.