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  }