Skip to content

Commit

Permalink
Move auth params from Params to Headers
Browse files Browse the repository at this point in the history
  • Loading branch information
kayrus committed Mar 23, 2020
1 parent cd91ce5 commit ba0c217
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 57 deletions.
53 changes: 24 additions & 29 deletions openstack/identity/v3/extensions/ec2tokens/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ type AuthOptions struct {
Region string `json:"-"`
// Service is a service name to calculate an AWS signature V4. Optional.
Service string `json:"-"`
// Params is a map of parameters, used to configure an AWS signature
// calculation method. Defaults to AWS signature V4 parameters.
// Optional.
// Params is a map of GET method parameters. Optional.
Params map[string]string `json:"params"`
// AllowReauth allows Gophercloud to re-authenticate automatically
// if/when your token expires.
Expand Down Expand Up @@ -152,7 +150,7 @@ func EC2CredentialsBuildSignatureKeyV4(secret, date, region, service string) []b
// EC2CredentialsBuildSignatureV4 builds an AWS v4 signature based on input
// parameters.
// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L251
func EC2CredentialsBuildSignatureV4(opts AuthOptions, params map[string]string, date time.Time, bodyHash string) string {
func EC2CredentialsBuildSignatureV4(opts AuthOptions, signedHeaders string, date time.Time, bodyHash string) string {
scope := strings.Join([]string{
date.Format(EC2CredentialsDateFormatV4),
opts.Region,
Expand All @@ -163,9 +161,9 @@ func EC2CredentialsBuildSignatureV4(opts AuthOptions, params map[string]string,
canonicalRequest := strings.Join([]string{
opts.Verb,
opts.Path,
EC2CredentialsBuildCanonicalQueryStringV4(opts.Verb, params),
EC2CredentialsBuildCanonicalHeadersV4(opts.Headers, params["X-Amz-SignedHeaders"]),
params["X-Amz-SignedHeaders"],
EC2CredentialsBuildCanonicalQueryStringV4(opts.Verb, opts.Params),
EC2CredentialsBuildCanonicalHeadersV4(opts.Headers, signedHeaders),
signedHeaders,
bodyHash,
}, "\n")
hash := sha256.Sum256([]byte(canonicalRequest))
Expand Down Expand Up @@ -205,7 +203,8 @@ func (opts *AuthOptions) ToTokenV3CreateMap(map[string]interface{}) (map[string]

// calculate signature, when it is not set
c, _ := b["credentials"].(map[string]interface{})
p := paramsToMap(c)
h := interfaceToMap(c, "headers")
p := interfaceToMap(c, "params")

// detect and process a signature v2
if v, ok := p["SignatureVersion"]; ok && v == "2" {
Expand Down Expand Up @@ -244,24 +243,20 @@ func (opts *AuthOptions) ToTokenV3CreateMap(map[string]interface{}) (map[string]
// when body_hash is not set, generate a random one
c["body_hash"] = randomBodyHash()
}
if v, _ := c["headers"]; v == nil {
// when headers is not set, make an empty map
c["headers"] = make(map[string]string)
}
if _, ok := p["X-Amz-SignedHeaders"]; !ok {
// when X-Amz-SignedHeaders is not set, make an empty string
p["X-Amz-SignedHeaders"] = ""
}
p["X-Amz-Date"] = date.Format(EC2CredentialsTimestampFormatV4)
p["X-Amz-Algorithm"] = EC2CredentialsAwsHmacV4
p["X-Amz-Credential"] = strings.Join([]string{

signedHeaders, _ := h["X-Amz-SignedHeaders"]
c["signature"] = EC2CredentialsBuildSignatureV4(*opts, signedHeaders, date, c["body_hash"].(string))

h["X-Amz-Date"] = date.Format(EC2CredentialsTimestampFormatV4)
h["Authorization"] = fmt.Sprintf("%s Credential=%s/%s/%s/%s/%s, SignedHeaders=%s, Signature=%s",
EC2CredentialsAwsHmacV4,
opts.Access,
date.Format(EC2CredentialsDateFormatV4),
opts.Region,
opts.Service,
EC2CredentialsAwsRequestV4,
}, "/")
c["signature"] = EC2CredentialsBuildSignatureV4(*opts, p, date, c["body_hash"].(string))
signedHeaders,
c["signature"])

return b, nil
}
Expand Down Expand Up @@ -308,18 +303,18 @@ func randomBodyHash() string {
return hex.EncodeToString(h)
}

// paramsToMap is a func used to represent a "credentials" map "params" value
// as a "map[string]string"
func paramsToMap(c map[string]interface{}) map[string]string {
// interfaceToMap is a func used to represent a "credentials" map element as a
// "map[string]string"
func interfaceToMap(c map[string]interface{}, key string) map[string]string {
// convert map[string]interface{} to map[string]string
p := make(map[string]string)
if v, _ := c["params"].(map[string]interface{}); v != nil {
m := make(map[string]string)
if v, _ := c[key].(map[string]interface{}); v != nil {
for k, v := range v {
p[k] = v.(string)
m[k] = v.(string)
}
}

c["params"] = p
c[key] = m

return p
return m
}
49 changes: 21 additions & 28 deletions openstack/identity/v3/extensions/ec2tokens/testing/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,15 @@ func TestCreateV4(t *testing.T) {
"body_hash": "foo",
"host": "",
"headers": {
"Host": "localhost"
"Host": "localhost",
"Authorization": "AWS4-HMAC-SHA256 Credential=a7f1e798b7c2417cba4a02de97dc3cdc/00010101/region1/ec2/aws4_request, SignedHeaders=, Signature=f36f79118f75d7d6ec86ead9a61679cbdcf94c0cbfe5e9cf2407e8406aa82028",
"X-Amz-Date": "00010101T000000Z"
},
"params": {
"Action": "Test",
"X-Amz-Algorithm": "AWS4-HMAC-SHA256",
"X-Amz-Credential": "a7f1e798b7c2417cba4a02de97dc3cdc/00010101/region1/ec2/aws4_request",
"X-Amz-Date": "00010101T000000Z",
"X-Amz-SignedHeaders": ""
"Action": "Test"
},
"path": "/",
"signature": "f8b67f8bc0c8c7a6b84fcb37dd9007f1c728625fe783fe8616b6ba150e1d0655",
"signature": "f36f79118f75d7d6ec86ead9a61679cbdcf94c0cbfe5e9cf2407e8406aa82028",
"verb": "GET"
}
}`)
Expand All @@ -130,15 +128,13 @@ func TestCreateV4Empty(t *testing.T) {
"access": "a7f1e798b7c2417cba4a02de97dc3cdc",
"body_hash": "",
"host": "",
"headers": {},
"params": {
"X-Amz-Algorithm": "AWS4-HMAC-SHA256",
"X-Amz-Credential": "a7f1e798b7c2417cba4a02de97dc3cdc/00010101///aws4_request",
"X-Amz-Date": "00010101T000000Z",
"X-Amz-SignedHeaders": ""
"headers": {
"Authorization": "AWS4-HMAC-SHA256 Credential=a7f1e798b7c2417cba4a02de97dc3cdc/00010101///aws4_request, SignedHeaders=, Signature=140a31abf1efe93a607dcac6cd8f66887b86d2bc8f712c290d9aa06edf428608",
"X-Amz-Date": "00010101T000000Z"
},
"params": {},
"path": "",
"signature": "a7f7a34f93ccd460e67079743d05d1b4488c6e9d708869b6b687d51244c68857",
"signature": "140a31abf1efe93a607dcac6cd8f66887b86d2bc8f712c290d9aa06edf428608",
"verb": ""
}
}`)
Expand Down Expand Up @@ -169,17 +165,15 @@ func TestCreateV4Headers(t *testing.T) {
"host": "",
"headers": {
"Foo": "Bar",
"Host": "localhost"
"Host": "localhost",
"Authorization": "AWS4-HMAC-SHA256 Credential=a7f1e798b7c2417cba4a02de97dc3cdc/00010101/region1/ec2/aws4_request, SignedHeaders=, Signature=f5cd6995be98e5576a130b30cca277375f10439217ea82169aa8386e83965611",
"X-Amz-Date": "00010101T000000Z"
},
"params": {
"Action": "Test",
"X-Amz-Algorithm": "AWS4-HMAC-SHA256",
"X-Amz-Credential": "a7f1e798b7c2417cba4a02de97dc3cdc/00010101/region1/ec2/aws4_request",
"X-Amz-Date": "00010101T000000Z",
"X-Amz-SignedHeaders": ""
"Action": "Test"
},
"path": "/",
"signature": "becc7d835c1d96835b772158198aed5583cb3fee4e7c7459a15fe710e3f533c6",
"signature": "f5cd6995be98e5576a130b30cca277375f10439217ea82169aa8386e83965611",
"verb": "GET"
}
}`)
Expand Down Expand Up @@ -282,12 +276,11 @@ func TestEC2CredentialsBuildSignatureV4(t *testing.T) {
Headers: map[string]string{
"Host": "localhost",
},
Params: map[string]string{
"Action": "foo",
"Value": "bar",
},
}
params := map[string]string{
"Action": "foo",
"Value": "bar",
"X-Amz-SignedHeaders": "host",
}
expected := "76ecaab5616b005227ad98bcdf7e802120a16a4e840faf5193e49db7fe7db178"
testhelper.CheckEquals(t, expected, ec2tokens.EC2CredentialsBuildSignatureV4(opts, params, time.Time{}, "foo"))
expected := "6a5febe41427bf601f0ae7c34dbb0fd67094776138b03fb8e65783d733d302a5"
testhelper.CheckEquals(t, expected, ec2tokens.EC2CredentialsBuildSignatureV4(opts, "host", time.Time{}, "foo"))
}

0 comments on commit ba0c217

Please sign in to comment.