github.com/aavshr/aws-sdk-go@v1.41.3/aws/signer/v4/functional_test.go (about) 1 package v4_test 2 3 import ( 4 "net/http" 5 "net/url" 6 "reflect" 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/aavshr/aws-sdk-go/aws" 12 "github.com/aavshr/aws-sdk-go/aws/request" 13 "github.com/aavshr/aws-sdk-go/aws/signer/v4" 14 "github.com/aavshr/aws-sdk-go/awstesting/unit" 15 "github.com/aavshr/aws-sdk-go/service/s3" 16 ) 17 18 var standaloneSignCases = []struct { 19 OrigURI string 20 OrigQuery string 21 Region, Service, SubDomain string 22 ExpSig string 23 EscapedURI string 24 }{ 25 { 26 OrigURI: `/logs-*/_search`, 27 OrigQuery: `pretty=true`, 28 Region: "us-west-2", Service: "es", SubDomain: "hostname-clusterkey", 29 EscapedURI: `/logs-%2A/_search`, 30 ExpSig: `AWS4-HMAC-SHA256 Credential=AKID/19700101/us-west-2/es/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=79d0760751907af16f64a537c1242416dacf51204a7dd5284492d15577973b91`, 31 }, 32 } 33 34 func epochTime() time.Time { return time.Unix(0, 0) } 35 36 func TestPresignHandler(t *testing.T) { 37 svc := s3.New(unit.Session) 38 svc.Handlers.Sign.SwapNamed(request.NamedHandler{ 39 Name: v4.SignRequestHandler.Name, 40 Fn: func(r *request.Request) { 41 v4.SignSDKRequestWithCurrentTime(r, epochTime) 42 }, 43 }) 44 45 req, _ := svc.PutObjectRequest(&s3.PutObjectInput{ 46 Bucket: aws.String("bucket"), 47 Key: aws.String("key"), 48 ContentDisposition: aws.String("a+b c$d"), 49 ACL: aws.String("public-read"), 50 }) 51 req.Time = epochTime() 52 urlstr, err := req.Presign(5 * time.Minute) 53 54 if err != nil { 55 t.Fatalf("expect no error, got %v", err) 56 } 57 58 expectedHost := "bucket.s3.mock-region.amazonaws.com" 59 expectedDate := "19700101T000000Z" 60 expectedHeaders := "content-disposition;host;x-amz-acl" 61 expectedSig := "2d76a414208c0eac2a23ef9c834db9635ecd5a0fbb447a00ad191f82d854f55b" 62 expectedCred := "AKID/19700101/mock-region/s3/aws4_request" 63 64 u, _ := url.Parse(urlstr) 65 urlQ := u.Query() 66 if e, a := expectedHost, u.Host; e != a { 67 t.Errorf("expect %v, got %v", e, a) 68 } 69 if e, a := expectedSig, urlQ.Get("X-Amz-Signature"); e != a { 70 t.Errorf("expect %v, got %v", e, a) 71 } 72 if e, a := expectedCred, urlQ.Get("X-Amz-Credential"); e != a { 73 t.Errorf("expect %v, got %v", e, a) 74 } 75 if e, a := expectedHeaders, urlQ.Get("X-Amz-SignedHeaders"); e != a { 76 t.Errorf("expect %v, got %v", e, a) 77 } 78 if e, a := expectedDate, urlQ.Get("X-Amz-Date"); e != a { 79 t.Errorf("expect %v, got %v", e, a) 80 } 81 if e, a := "300", urlQ.Get("X-Amz-Expires"); e != a { 82 t.Errorf("expect %v, got %v", e, a) 83 } 84 if a := urlQ.Get("X-Amz-Content-Sha256"); len(a) != 0 { 85 t.Errorf("expect no content sha256 got %v", a) 86 } 87 88 if e, a := "+", urlstr; strings.Contains(a, e) { // + encoded as %20 89 t.Errorf("expect %v not to be in %v", e, a) 90 } 91 } 92 93 func TestPresignRequest(t *testing.T) { 94 svc := s3.New(unit.Session) 95 svc.Handlers.Sign.SwapNamed(request.NamedHandler{ 96 Name: v4.SignRequestHandler.Name, 97 Fn: func(r *request.Request) { 98 v4.SignSDKRequestWithCurrentTime(r, epochTime) 99 }, 100 }) 101 102 req, _ := svc.PutObjectRequest(&s3.PutObjectInput{ 103 Bucket: aws.String("bucket"), 104 Key: aws.String("key"), 105 ContentDisposition: aws.String("a+b c$d"), 106 ACL: aws.String("public-read"), 107 }) 108 req.Time = epochTime() 109 urlstr, headers, err := req.PresignRequest(5 * time.Minute) 110 111 if err != nil { 112 t.Fatalf("expect no error, got %v", err) 113 } 114 115 expectedHost := "bucket.s3.mock-region.amazonaws.com" 116 expectedDate := "19700101T000000Z" 117 expectedHeaders := "content-disposition;host;x-amz-acl" 118 expectedSig := "2d76a414208c0eac2a23ef9c834db9635ecd5a0fbb447a00ad191f82d854f55b" 119 expectedCred := "AKID/19700101/mock-region/s3/aws4_request" 120 expectedHeaderMap := http.Header{ 121 "x-amz-acl": []string{"public-read"}, 122 "content-disposition": []string{"a+b c$d"}, 123 } 124 125 u, _ := url.Parse(urlstr) 126 urlQ := u.Query() 127 if e, a := expectedHost, u.Host; e != a { 128 t.Errorf("expect %v, got %v", e, a) 129 } 130 if e, a := expectedSig, urlQ.Get("X-Amz-Signature"); e != a { 131 t.Errorf("expect %v, got %v", e, a) 132 } 133 if e, a := expectedCred, urlQ.Get("X-Amz-Credential"); e != a { 134 t.Errorf("expect %v, got %v", e, a) 135 } 136 if e, a := expectedHeaders, urlQ.Get("X-Amz-SignedHeaders"); e != a { 137 t.Errorf("expect %v, got %v", e, a) 138 } 139 if e, a := expectedDate, urlQ.Get("X-Amz-Date"); e != a { 140 t.Errorf("expect %v, got %v", e, a) 141 } 142 if e, a := expectedHeaderMap, headers; !reflect.DeepEqual(e, a) { 143 t.Errorf("expect %v, got %v", e, a) 144 } 145 if e, a := "300", urlQ.Get("X-Amz-Expires"); e != a { 146 t.Errorf("expect %v, got %v", e, a) 147 } 148 if a := urlQ.Get("X-Amz-Content-Sha256"); len(a) != 0 { 149 t.Errorf("expect no content sha256 got %v", a) 150 } 151 152 if e, a := "+", urlstr; strings.Contains(a, e) { // + encoded as %20 153 t.Errorf("expect %v not to be in %v", e, a) 154 } 155 } 156 157 func TestStandaloneSign_CustomURIEscape(t *testing.T) { 158 var expectSig = `AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/es/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=6601e883cc6d23871fd6c2a394c5677ea2b8c82b04a6446786d64cd74f520967` 159 160 creds := unit.Session.Config.Credentials 161 signer := v4.NewSigner(creds, func(s *v4.Signer) { 162 s.DisableURIPathEscaping = true 163 }) 164 165 host := "https://subdomain.us-east-1.es.amazonaws.com" 166 req, err := http.NewRequest("GET", host, nil) 167 if err != nil { 168 t.Fatalf("expect no error, got %v", err) 169 } 170 171 req.URL.Path = `/log-*/_search` 172 req.URL.Opaque = "//subdomain.us-east-1.es.amazonaws.com/log-%2A/_search" 173 174 _, err = signer.Sign(req, nil, "es", "us-east-1", epochTime()) 175 if err != nil { 176 t.Fatalf("expect no error, got %v", err) 177 } 178 179 actual := req.Header.Get("Authorization") 180 if e, a := expectSig, actual; e != a { 181 t.Errorf("expect %v, got %v", e, a) 182 } 183 } 184 185 func TestStandaloneSign_WithPort(t *testing.T) { 186 187 cases := []struct { 188 description string 189 url string 190 expectedSig string 191 }{ 192 { 193 "default HTTPS port", 194 "https://estest.us-east-1.es.amazonaws.com:443/_search", 195 "AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/es/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=e573fc9aa3a156b720976419319be98fb2824a3abc2ddd895ecb1d1611c6a82d", 196 }, 197 { 198 "default HTTP port", 199 "http://example.com:80/_search", 200 "AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/es/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=54ebe60c4ae03a40948b849e13c333523235f38002e2807059c64a9a8c7cb951", 201 }, 202 { 203 "non-standard HTTP port", 204 "http://example.com:9200/_search", 205 "AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/es/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=cd9d926a460f8d3b58b57beadbd87666dc667e014c0afaa4cea37b2867f51b4f", 206 }, 207 { 208 "non-standard HTTPS port", 209 "https://example.com:9200/_search", 210 "AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/es/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=cd9d926a460f8d3b58b57beadbd87666dc667e014c0afaa4cea37b2867f51b4f", 211 }, 212 } 213 214 for _, c := range cases { 215 signer := v4.NewSigner(unit.Session.Config.Credentials) 216 req, _ := http.NewRequest("GET", c.url, nil) 217 _, err := signer.Sign(req, nil, "es", "us-east-1", epochTime()) 218 if err != nil { 219 t.Fatalf("expect no error, got %v", err) 220 } 221 222 actual := req.Header.Get("Authorization") 223 if e, a := c.expectedSig, actual; e != a { 224 t.Errorf("%s, expect %v, got %v", c.description, e, a) 225 } 226 } 227 } 228 229 func TestStandalonePresign_WithPort(t *testing.T) { 230 231 cases := []struct { 232 description string 233 url string 234 expectedSig string 235 }{ 236 { 237 "default HTTPS port", 238 "https://estest.us-east-1.es.amazonaws.com:443/_search", 239 "0abcf61a351063441296febf4b485734d780634fba8cf1e7d9769315c35255d6", 240 }, 241 { 242 "default HTTP port", 243 "http://example.com:80/_search", 244 "fce9976dd6c849c21adfa6d3f3e9eefc651d0e4a2ccd740d43efddcccfdc8179", 245 }, 246 { 247 "non-standard HTTP port", 248 "http://example.com:9200/_search", 249 "f33c25a81c735e42bef35ed5e9f720c43940562e3e616ff0777bf6dde75249b0", 250 }, 251 { 252 "non-standard HTTPS port", 253 "https://example.com:9200/_search", 254 "f33c25a81c735e42bef35ed5e9f720c43940562e3e616ff0777bf6dde75249b0", 255 }, 256 } 257 258 for _, c := range cases { 259 signer := v4.NewSigner(unit.Session.Config.Credentials) 260 req, _ := http.NewRequest("GET", c.url, nil) 261 _, err := signer.Presign(req, nil, "es", "us-east-1", 5*time.Minute, epochTime()) 262 if err != nil { 263 t.Fatalf("expect no error, got %v", err) 264 } 265 266 actual := req.URL.Query().Get("X-Amz-Signature") 267 if e, a := c.expectedSig, actual; e != a { 268 t.Errorf("%s, expect %v, got %v", c.description, e, a) 269 } 270 } 271 }