mirror of
https://github.com/minio/minio.git
synced 2025-11-07 12:52:58 -05:00
signature: Add legacy signature v2 support transparently. (#2811)
Add new tests as well.
This commit is contained in:
159
cmd/signature-v2_test.go
Normal file
159
cmd/signature-v2_test.go
Normal file
@@ -0,0 +1,159 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Tests for 'func TestResourceListSorting(t *testing.T)'.
|
||||
func TestResourceListSorting(t *testing.T) {
|
||||
sortedResourceList := make([]string, len(resourceList))
|
||||
copy(sortedResourceList, resourceList)
|
||||
sort.Strings(sortedResourceList)
|
||||
for i := 0; i < len(resourceList); i++ {
|
||||
if resourceList[i] != sortedResourceList[i] {
|
||||
t.Errorf("Expected resourceList[%d] = \"%s\", resourceList is not correctly sorted.", i, sortedResourceList[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests validate the query encoding.
|
||||
func TestQueryEncode(t *testing.T) {
|
||||
testCases := []struct {
|
||||
// Input.
|
||||
input url.Values
|
||||
// Expected result.
|
||||
result string
|
||||
}{
|
||||
// % should be encoded as %25
|
||||
{url.Values{
|
||||
"key": []string{"thisisthe%url"},
|
||||
}, "key=thisisthe%25url"},
|
||||
// UTF-8 encoding.
|
||||
{url.Values{
|
||||
"key": []string{"本語"},
|
||||
}, "key=%E6%9C%AC%E8%AA%9E"},
|
||||
// UTF-8 encoding with ASCII.
|
||||
{url.Values{
|
||||
"key": []string{"本語.1"},
|
||||
}, "key=%E6%9C%AC%E8%AA%9E.1"},
|
||||
// Unusual ASCII characters.
|
||||
{url.Values{
|
||||
"key": []string{">123"},
|
||||
}, "key=%3E123"},
|
||||
// Fragment path characters.
|
||||
{url.Values{
|
||||
"key": []string{"myurl#link"},
|
||||
}, "key=myurl%23link"},
|
||||
// Space should be set to %20 not '+'.
|
||||
{url.Values{
|
||||
"key": []string{"space in url"},
|
||||
}, "key=space%20in%20url"},
|
||||
// '+' shouldn't be treated as space.
|
||||
{url.Values{
|
||||
"key": []string{"url+path"},
|
||||
}, "key=url%2Bpath"},
|
||||
// '/' shouldn't be treated as '/' should be percent coded.
|
||||
{url.Values{
|
||||
"key": []string{"url/+path"},
|
||||
}, "key=url%2F%2Bpath"},
|
||||
// Values is empty and empty string.
|
||||
{nil, ""},
|
||||
}
|
||||
|
||||
// Tests generated values from url encoded name.
|
||||
for i, testCase := range testCases {
|
||||
result := queryEncode(testCase.input)
|
||||
if testCase.result != result {
|
||||
t.Errorf("Test %d: Expected queryEncoded result to be \"%s\", but found it to be \"%s\" instead", i+1, testCase.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoesPresignedV2SignatureMatch(t *testing.T) {
|
||||
root, err := newTestConfig("us-east-1")
|
||||
if err != nil {
|
||||
t.Fatal("Unable to initialize test config.")
|
||||
}
|
||||
defer removeAll(root)
|
||||
|
||||
now := time.Now().UTC()
|
||||
|
||||
testCases := []struct {
|
||||
queryParams map[string]string
|
||||
headers map[string]string
|
||||
expected APIErrorCode
|
||||
}{
|
||||
// (0) Should error without a set URL query.
|
||||
{
|
||||
expected: ErrInvalidQueryParams,
|
||||
},
|
||||
// (1) Should error on an invalid access key.
|
||||
{
|
||||
queryParams: map[string]string{
|
||||
"Expires": "60",
|
||||
"Signature": "badsignature",
|
||||
"AWSAccessKeyId": "Z7IXGOO6BZ0REAN1Q26I",
|
||||
},
|
||||
expected: ErrInvalidAccessKeyID,
|
||||
},
|
||||
// (2) Should error with malformed expires.
|
||||
{
|
||||
queryParams: map[string]string{
|
||||
"Expires": "60s",
|
||||
"Signature": "badsignature",
|
||||
"AWSAccessKeyId": serverConfig.GetCredential().AccessKeyID,
|
||||
},
|
||||
expected: ErrMalformedExpires,
|
||||
},
|
||||
// (3) Should give an expired request if it has expired.
|
||||
{
|
||||
queryParams: map[string]string{
|
||||
"Expires": "60",
|
||||
"Signature": "badsignature",
|
||||
"AWSAccessKeyId": serverConfig.GetCredential().AccessKeyID,
|
||||
},
|
||||
expected: ErrExpiredPresignRequest,
|
||||
},
|
||||
// (4) Should error when the signature does not match.
|
||||
{
|
||||
queryParams: map[string]string{
|
||||
"Expires": fmt.Sprintf("%d", now.Unix()+60),
|
||||
"Signature": "badsignature",
|
||||
"AWSAccessKeyId": serverConfig.GetCredential().AccessKeyID,
|
||||
},
|
||||
expected: ErrSignatureDoesNotMatch,
|
||||
},
|
||||
}
|
||||
|
||||
// Run each test case individually.
|
||||
for i, testCase := range testCases {
|
||||
// Turn the map[string]string into map[string][]string, because Go.
|
||||
query := url.Values{}
|
||||
for key, value := range testCase.queryParams {
|
||||
query.Set(key, value)
|
||||
}
|
||||
|
||||
// Create a request to use.
|
||||
req, e := http.NewRequest(http.MethodGet, "http://host/a/b?"+query.Encode(), nil)
|
||||
if e != nil {
|
||||
t.Errorf("(%d) failed to create http.Request, got %v", i, e)
|
||||
}
|
||||
|
||||
// Do the same for the headers.
|
||||
for key, value := range testCase.headers {
|
||||
req.Header.Set(key, value)
|
||||
}
|
||||
|
||||
// Check if it matches!
|
||||
err := doesPresignV2SignatureMatch(req)
|
||||
if err != testCase.expected {
|
||||
t.Errorf("(%d) expected to get %s, instead got %s", i, niceError(testCase.expected), niceError(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user