v2_test.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package v2
  2. import (
  3. "bytes"
  4. "net/http"
  5. "net/url"
  6. "os"
  7. "testing"
  8. "time"
  9. "github.com/aws/aws-sdk-go/aws"
  10. "github.com/aws/aws-sdk-go/aws/credentials"
  11. "github.com/aws/aws-sdk-go/aws/request"
  12. "github.com/aws/aws-sdk-go/awstesting"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. type signerBuilder struct {
  16. ServiceName string
  17. Region string
  18. SignTime time.Time
  19. Query url.Values
  20. Method string
  21. SessionToken string
  22. }
  23. func (sb signerBuilder) BuildSigner() signer {
  24. endpoint := "https://" + sb.ServiceName + "." + sb.Region + ".amazonaws.com"
  25. var req *http.Request
  26. if sb.Method == "POST" {
  27. body := []byte(sb.Query.Encode())
  28. reader := bytes.NewReader(body)
  29. req, _ = http.NewRequest(sb.Method, endpoint, reader)
  30. req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
  31. req.Header.Add("Content-Length", string(len(body)))
  32. } else {
  33. req, _ = http.NewRequest(sb.Method, endpoint, nil)
  34. req.URL.RawQuery = sb.Query.Encode()
  35. }
  36. sig := signer{
  37. Request: req,
  38. Time: sb.SignTime,
  39. Credentials: credentials.NewStaticCredentials(
  40. "AKID",
  41. "SECRET",
  42. sb.SessionToken),
  43. }
  44. if os.Getenv("DEBUG") != "" {
  45. sig.Debug = aws.LogDebug
  46. sig.Logger = aws.NewDefaultLogger()
  47. }
  48. return sig
  49. }
  50. func TestSignRequestWithAndWithoutSession(t *testing.T) {
  51. assert := assert.New(t)
  52. // have to create more than once, so use a function
  53. newQuery := func() url.Values {
  54. query := make(url.Values)
  55. query.Add("Action", "CreateDomain")
  56. query.Add("DomainName", "TestDomain-1437033376")
  57. query.Add("Version", "2009-04-15")
  58. return query
  59. }
  60. // create request without a SecurityToken (session) in the credentials
  61. query := newQuery()
  62. timestamp := time.Date(2015, 7, 16, 7, 56, 16, 0, time.UTC)
  63. builder := signerBuilder{
  64. Method: "POST",
  65. ServiceName: "sdb",
  66. Region: "ap-southeast-2",
  67. SignTime: timestamp,
  68. Query: query,
  69. }
  70. signer := builder.BuildSigner()
  71. err := signer.Sign()
  72. assert.NoError(err)
  73. assert.Equal("tm4dX8Ks7pzFSVHz7qHdoJVXKRLuC4gWz9eti60d8ks=", signer.signature)
  74. assert.Equal(8, len(signer.Query))
  75. assert.Equal("AKID", signer.Query.Get("AWSAccessKeyId"))
  76. assert.Equal("2015-07-16T07:56:16Z", signer.Query.Get("Timestamp"))
  77. assert.Equal("HmacSHA256", signer.Query.Get("SignatureMethod"))
  78. assert.Equal("2", signer.Query.Get("SignatureVersion"))
  79. assert.Equal("tm4dX8Ks7pzFSVHz7qHdoJVXKRLuC4gWz9eti60d8ks=", signer.Query.Get("Signature"))
  80. assert.Equal("CreateDomain", signer.Query.Get("Action"))
  81. assert.Equal("TestDomain-1437033376", signer.Query.Get("DomainName"))
  82. assert.Equal("2009-04-15", signer.Query.Get("Version"))
  83. // should not have a SecurityToken parameter
  84. _, ok := signer.Query["SecurityToken"]
  85. assert.False(ok)
  86. // now sign again, this time with a security token (session)
  87. query = newQuery()
  88. builder.SessionToken = "SESSION"
  89. signer = builder.BuildSigner()
  90. err = signer.Sign()
  91. assert.NoError(err)
  92. assert.Equal("Ch6qv3rzXB1SLqY2vFhsgA1WQ9rnQIE2WJCigOvAJwI=", signer.signature)
  93. assert.Equal(9, len(signer.Query)) // expect one more parameter
  94. assert.Equal("Ch6qv3rzXB1SLqY2vFhsgA1WQ9rnQIE2WJCigOvAJwI=", signer.Query.Get("Signature"))
  95. assert.Equal("SESSION", signer.Query.Get("SecurityToken"))
  96. }
  97. func TestMoreComplexSignRequest(t *testing.T) {
  98. assert := assert.New(t)
  99. query := make(url.Values)
  100. query.Add("Action", "PutAttributes")
  101. query.Add("DomainName", "TestDomain-1437041569")
  102. query.Add("Version", "2009-04-15")
  103. query.Add("Attribute.2.Name", "Attr2")
  104. query.Add("Attribute.2.Value", "Value2")
  105. query.Add("Attribute.2.Replace", "true")
  106. query.Add("Attribute.1.Name", "Attr1-%\\+ %")
  107. query.Add("Attribute.1.Value", " \tValue1 +!@#$%^&*(){}[]\"';:?/.>,<\x12\x00")
  108. query.Add("Attribute.1.Replace", "true")
  109. query.Add("ItemName", "Item 1")
  110. timestamp := time.Date(2015, 7, 16, 10, 12, 51, 0, time.UTC)
  111. builder := signerBuilder{
  112. Method: "POST",
  113. ServiceName: "sdb",
  114. Region: "ap-southeast-2",
  115. SignTime: timestamp,
  116. Query: query,
  117. SessionToken: "SESSION",
  118. }
  119. signer := builder.BuildSigner()
  120. err := signer.Sign()
  121. assert.NoError(err)
  122. assert.Equal("WNdE62UJKLKoA6XncVY/9RDbrKmcVMdQPQOTAs8SgwQ=", signer.signature)
  123. }
  124. func TestGet(t *testing.T) {
  125. assert := assert.New(t)
  126. svc := awstesting.NewClient(&aws.Config{
  127. Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
  128. Region: aws.String("ap-southeast-2"),
  129. })
  130. r := svc.NewRequest(
  131. &request.Operation{
  132. Name: "OpName",
  133. HTTPMethod: "GET",
  134. HTTPPath: "/",
  135. },
  136. nil,
  137. nil,
  138. )
  139. r.Build()
  140. assert.Equal("GET", r.HTTPRequest.Method)
  141. assert.Equal("", r.HTTPRequest.URL.Query().Get("Signature"))
  142. SignSDKRequest(r)
  143. assert.NoError(r.Error)
  144. t.Logf("Signature: %s", r.HTTPRequest.URL.Query().Get("Signature"))
  145. assert.NotEqual("", r.HTTPRequest.URL.Query().Get("Signature"))
  146. }
  147. func TestAnonymousCredentials(t *testing.T) {
  148. assert := assert.New(t)
  149. svc := awstesting.NewClient(&aws.Config{
  150. Credentials: credentials.AnonymousCredentials,
  151. Region: aws.String("ap-southeast-2"),
  152. })
  153. r := svc.NewRequest(
  154. &request.Operation{
  155. Name: "PutAttributes",
  156. HTTPMethod: "POST",
  157. HTTPPath: "/",
  158. },
  159. nil,
  160. nil,
  161. )
  162. r.Build()
  163. SignSDKRequest(r)
  164. req := r.HTTPRequest
  165. req.ParseForm()
  166. assert.Empty(req.PostForm.Get("Signature"))
  167. }