tests: Adding unknown signature type test for API handlers. (#2905)

master
Karthic Rao 8 years ago committed by Harshavardhana
parent a6357502c1
commit ff91ecb177
  1. 58
      cmd/object-handlers_test.go
  2. 54
      cmd/test-utils_test.go

@ -2032,61 +2032,3 @@ func testAPIListObjectPartsHandlerV2(obj ObjectLayer, instanceType, bucketName s
signatureMismatchErr.Code, errXML.Code) signatureMismatchErr.Code, errXML.Code)
} }
} }
// TestAPIListObjectPartsHandler - Tests validate the response of ListObjectParts HTTP handler
// when signature type of the HTTP request is `anonynous/unsigned`.
func TestAPIListObjectPartsHandlerUnknown(t *testing.T) {
ExecObjectLayerAPITest(t, testAPIListObjectPartsHandlerUnknown,
[]string{"PutObjectPart", "NewMultipart", "ListObjectParts"})
}
func testAPIListObjectPartsHandlerUnknown(obj ObjectLayer, instanceType, bucketName string, apiRouter http.Handler,
credentials credential, t *testing.T) {
testObject := "testobject"
rec := httptest.NewRecorder()
req, err := newTestSignedRequestV4("POST", getNewMultipartURL("", bucketName, testObject),
0, nil, credentials.AccessKeyID, credentials.SecretAccessKey)
if err != nil {
t.Fatalf("[%s] - Failed to create a signed request to initiate multipart upload for %s/%s: <ERROR> %v",
instanceType, bucketName, testObject, err)
}
apiRouter.ServeHTTP(rec, req)
// Get uploadID of the mulitpart upload initiated.
var mpartResp InitiateMultipartUploadResponse
mpartRespBytes, err := ioutil.ReadAll(rec.Result().Body)
if err != nil {
t.Fatalf("[%s] Failed to read NewMultipartUpload response <ERROR> %v", instanceType, err)
}
err = xml.Unmarshal(mpartRespBytes, &mpartResp)
if err != nil {
t.Fatalf("[%s] Failed to unmarshal NewMultipartUpload response <ERROR> %v", instanceType, err)
}
accessDeniedErr := getAPIError(ErrAccessDenied)
unKnownRec := httptest.NewRecorder()
unKnownReq, aErr := newTestRequest("GET",
getListMultipartURLWithParams("", bucketName, testObject, mpartResp.UploadID, "", "", ""),
0, nil)
if aErr != nil {
t.Fatalf("Test %d %s Failed to create an unKnownymous request to list multipart of an upload for %s/%s: <ERROR> %v",
1, instanceType, bucketName, testObject, aErr)
}
unKnownReq.Header.Set("Authorization", "nothingElse")
apiRouter.ServeHTTP(unKnownRec, unKnownReq)
unKnownErrBytes, err := ioutil.ReadAll(unKnownRec.Result().Body)
if err != nil {
t.Fatalf("Test %d %s Failed to read error response from list object parts request %s/%s: <ERROR> %v",
1, instanceType, bucketName, testObject, err)
}
var unKnownErrXML APIErrorResponse
err = xml.Unmarshal(unKnownErrBytes, &unKnownErrXML)
if err != nil {
t.Fatalf("Test %d %s Failed to unmarshal error response from list object parts request %s/%s: <ERROR> %v",
1, instanceType, bucketName, testObject, err)
}
if accessDeniedErr.Code != unKnownErrXML.Code {
t.Errorf("Test %d %s expected to fail with error %s, but received %s", 1, instanceType,
accessDeniedErr.Code, unKnownErrXML.Code)
}
}

@ -1461,20 +1461,27 @@ func initAPIHandlerTest(obj ObjectLayer, endPoints []string) (bucketName, rootPa
return bucketName, rootPath, apiRouter, nil return bucketName, rootPath, apiRouter, nil
} }
// ExecObjectLayerAPIAnonTest - Helper function to validate object Layer API handler response for anonymous/unsigned HTTP request. // ExecObjectLayerAPIAnonTest - Helper function to validate object Layer API handler
// response for anonymous/unsigned and unknown signature type HTTP request.
// Here is the brief description of some of the arguments to the function below. // Here is the brief description of some of the arguments to the function below.
// apiRouter - http.Handler with the relevant API endPoint (API endPoint under test) registered. // apiRouter - http.Handler with the relevant API endPoint (API endPoint under test) registered.
// anonReq - unsigned *http.Request to invoke the handler's response for anonymous requests. // anonReq - unsigned *http.Request to invoke the handler's response for anonymous requests.
// policyFunc - function to return bucketPolicy statement which would permit the anonymous request to be served. // policyFunc - function to return bucketPolicy statement which would permit the anonymous request to be served.
// The test works in 2 steps, here is the description of the steps. // The test works in 2 steps, here is the description of the steps.
// STEP 1: Call the handler with the unsigned HTTP request (anonReq), assert for the `ErrAccessDenied` error response. // STEP 1: Call the handler with the unsigned HTTP request (anonReq), assert for the `ErrAccessDenied` error response.
// STEP 2: Set the policy to allow the unsigned request, use the policyFunc to obtain the relevant statement and call the handler again to verify its success. // STEP 2: Set the policy to allow the unsigned request, use the policyFunc to obtain the relevant statement and call
// the handler again to verify its success.
func ExecObjectLayerAPIAnonTest(t *testing.T, testName, bucketName, objectName, instanceType string, apiRouter http.Handler, func ExecObjectLayerAPIAnonTest(t *testing.T, testName, bucketName, objectName, instanceType string, apiRouter http.Handler,
anonReq *http.Request, policyFunc func(string, string) policyStatement) { anonReq *http.Request, policyFunc func(string, string) policyStatement) {
anonTestStr := "Anonymous HTTP request test"
unknownSignTestStr := "Unknown HTTP signature test"
// simple function which ends the test by printing the common message which gives the context of the test // simple function which ends the test by printing the common message which gives the context of the test
// and then followed by the the actual error message. // and then followed by the the actual error message.
failTest := func(failMsg string) { failTest := func(testType, failMsg string) {
t.Fatalf("Minio %s: Anonymous HTTP request test Fail for \"%s\": \n<Error> %s.", instanceType, testName, failMsg) t.Fatalf("Minio %s: %s fail for \"%s\": \n<Error> %s.", instanceType, testType, testName, failMsg)
} }
// httptest Recorder to capture all the response by the http handler. // httptest Recorder to capture all the response by the http handler.
rec := httptest.NewRecorder() rec := httptest.NewRecorder()
@ -1482,12 +1489,13 @@ func ExecObjectLayerAPIAnonTest(t *testing.T, testName, bucketName, objectName,
// If the body is read in the handler the same request cannot be made use of. // If the body is read in the handler the same request cannot be made use of.
buf, err := ioutil.ReadAll(anonReq.Body) buf, err := ioutil.ReadAll(anonReq.Body)
if err != nil { if err != nil {
failTest(err.Error()) failTest(anonTestStr, err.Error())
} }
// creating 2 read closer (to set as request body) from the body content. // creating 2 read closer (to set as request body) from the body content.
readerOne := ioutil.NopCloser(bytes.NewBuffer(buf)) readerOne := ioutil.NopCloser(bytes.NewBuffer(buf))
readerTwo := ioutil.NopCloser(bytes.NewBuffer(buf)) readerTwo := ioutil.NopCloser(bytes.NewBuffer(buf))
readerThree := ioutil.NopCloser(bytes.NewBuffer(buf))
anonReq.Body = readerOne anonReq.Body = readerOne
@ -1497,7 +1505,7 @@ func ExecObjectLayerAPIAnonTest(t *testing.T, testName, bucketName, objectName,
// expected error response when the unsigned HTTP request is not permitted. // expected error response when the unsigned HTTP request is not permitted.
accesDeniedHTTPStatus := getAPIError(ErrAccessDenied).HTTPStatusCode accesDeniedHTTPStatus := getAPIError(ErrAccessDenied).HTTPStatusCode
if rec.Code != accesDeniedHTTPStatus { if rec.Code != accesDeniedHTTPStatus {
failTest(fmt.Sprintf("Object API Nil Test expected to fail with %d, but failed with %d.", accesDeniedHTTPStatus, rec.Code)) failTest(anonTestStr, fmt.Sprintf("Object API Nil Test expected to fail with %d, but failed with %d.", accesDeniedHTTPStatus, rec.Code))
} }
// expected error response in bytes when objectLayer is not initialized, or set to `nil`. // expected error response in bytes when objectLayer is not initialized, or set to `nil`.
@ -1508,11 +1516,11 @@ func ExecObjectLayerAPIAnonTest(t *testing.T, testName, bucketName, objectName,
// read the response body. // read the response body.
actualContent, err := ioutil.ReadAll(rec.Body) actualContent, err := ioutil.ReadAll(rec.Body)
if err != nil { if err != nil {
failTest(fmt.Sprintf("Failed parsing response body: <ERROR> %v", err)) failTest(anonTestStr, fmt.Sprintf("Failed parsing response body: <ERROR> %v", err))
} }
// verify whether actual error response (from the response body), matches the expected error response. // verify whether actual error response (from the response body), matches the expected error response.
if !bytes.Equal(expectedErrResponse, actualContent) { if !bytes.Equal(expectedErrResponse, actualContent) {
failTest("error response content differs from expected value") failTest(anonTestStr, "error response content differs from expected value")
} }
} }
// Set write only policy on bucket to allow anonymous HTTP request for the operation under test. // Set write only policy on bucket to allow anonymous HTTP request for the operation under test.
@ -1544,9 +1552,37 @@ func ExecObjectLayerAPIAnonTest(t *testing.T, testName, bucketName, objectName,
// compare the HTTP response status code with the expected one. // compare the HTTP response status code with the expected one.
if rec.Code != expectedHTTPStatus { if rec.Code != expectedHTTPStatus {
failTest(fmt.Sprintf("Expected the anonymous HTTP request to be served after the policy changes\n,Expected response HTTP status code to be %d, got %d.", failTest(anonTestStr, fmt.Sprintf("Expected the anonymous HTTP request to be served after the policy changes\n,Expected response HTTP status code to be %d, got %d.",
expectedHTTPStatus, rec.Code)) expectedHTTPStatus, rec.Code))
} }
// test for unknown auth case.
anonReq.Body = readerThree
// Setting the `Authorization` header to a random value so that the signature falls into unknown auth case.
anonReq.Header.Set("Authorization", "nothingElse")
// initialize new response recorder.
rec = httptest.NewRecorder()
// call the handler using the HTTP Request.
apiRouter.ServeHTTP(rec, anonReq)
// verify the response body for `ErrAccessDenied` message =.
if anonReq.Method != "HEAD" {
// read the response body.
actualContent, err := ioutil.ReadAll(rec.Body)
if err != nil {
failTest(unknownSignTestStr, fmt.Sprintf("Failed parsing response body: <ERROR> %v", err))
}
// verify whether actual error response (from the response body), matches the expected error response.
if !bytes.Equal(expectedErrResponse, actualContent) {
fmt.Println(string(expectedErrResponse))
fmt.Println(string(actualContent))
failTest(unknownSignTestStr, "error response content differs from expected value")
}
}
if rec.Code != accesDeniedHTTPStatus {
failTest(unknownSignTestStr, fmt.Sprintf("Object API Unknow auth test for \"%s\", expected to fail with %d, but failed with %d.", testName, accesDeniedHTTPStatus, rec.Code))
}
} }
// ExecObjectLayerAPINilTest - Sets the object layer to `nil`, and calls rhe registered object layer API endpoint, and assert the error response. // ExecObjectLayerAPINilTest - Sets the object layer to `nil`, and calls rhe registered object layer API endpoint, and assert the error response.

Loading…
Cancel
Save