diff --git a/cli/server/server_test.go b/cli/server/server_test.go index c297f93..9f78554 100644 --- a/cli/server/server_test.go +++ b/cli/server/server_test.go @@ -34,36 +34,58 @@ func TestHandlerSelector(t *testing.T) { testPrefix := "/url/prefix" var ignoreReferrer []string testReferrer := []string{"http://localhost"} + testAccessKey := "access-key" testCases := []struct { - name string - folder string - prefix string - listing bool - debug bool - refer []string - cors bool + name string + folder string + prefix string + listing bool + debug bool + refer []string + cors bool + accessKey string }{ - {"Basic handler w/o debug", testFolder, "", true, false, ignoreReferrer, false}, - {"Prefix handler w/o debug", testFolder, testPrefix, true, false, ignoreReferrer, false}, - {"Basic and hide listing handler w/o debug", testFolder, "", false, false, ignoreReferrer, false}, - {"Prefix and hide listing handler w/o debug", testFolder, testPrefix, false, false, ignoreReferrer, false}, - {"Basic handler w/debug", testFolder, "", true, true, ignoreReferrer, false}, - {"Prefix handler w/debug", testFolder, testPrefix, true, true, ignoreReferrer, false}, - {"Basic and hide listing handler w/debug", testFolder, "", false, true, ignoreReferrer, false}, - {"Prefix and hide listing handler w/debug", testFolder, testPrefix, false, true, ignoreReferrer, false}, - {"Basic handler w/o debug w/refer", testFolder, "", true, false, testReferrer, false}, - {"Prefix handler w/o debug w/refer", testFolder, testPrefix, true, false, testReferrer, false}, - {"Basic and hide listing handler w/o debug w/refer", testFolder, "", false, false, testReferrer, false}, - {"Prefix and hide listing handler w/o debug w/refer", testFolder, testPrefix, false, false, testReferrer, false}, - {"Basic handler w/debug w/refer w/o cors", testFolder, "", true, true, testReferrer, false}, - {"Prefix handler w/debug w/refer w/o cors", testFolder, testPrefix, true, true, testReferrer, false}, - {"Basic and hide listing handler w/debug w/refer w/o cors", testFolder, "", false, true, testReferrer, false}, - {"Prefix and hide listing handler w/debug w/refer w/o cors", testFolder, testPrefix, false, true, testReferrer, false}, - {"Basic handler w/debug w/refer w/cors", testFolder, "", true, true, testReferrer, true}, - {"Prefix handler w/debug w/refer w/cors", testFolder, testPrefix, true, true, testReferrer, true}, - {"Basic and hide listing handler w/debug w/refer w/cors", testFolder, "", false, true, testReferrer, true}, - {"Prefix and hide listing handler w/debug w/refer w/cors", testFolder, testPrefix, false, true, testReferrer, true}, + {"Basic handler w/o debug", testFolder, "", true, false, ignoreReferrer, false, ""}, + {"Prefix handler w/o debug", testFolder, testPrefix, true, false, ignoreReferrer, false, ""}, + {"Basic and hide listing handler w/o debug", testFolder, "", false, false, ignoreReferrer, false, ""}, + {"Prefix and hide listing handler w/o debug", testFolder, testPrefix, false, false, ignoreReferrer, false, ""}, + {"Basic handler w/debug", testFolder, "", true, true, ignoreReferrer, false, ""}, + {"Prefix handler w/debug", testFolder, testPrefix, true, true, ignoreReferrer, false, ""}, + {"Basic and hide listing handler w/debug", testFolder, "", false, true, ignoreReferrer, false, ""}, + {"Prefix and hide listing handler w/debug", testFolder, testPrefix, false, true, ignoreReferrer, false, ""}, + {"Basic handler w/o debug w/refer", testFolder, "", true, false, testReferrer, false, ""}, + {"Prefix handler w/o debug w/refer", testFolder, testPrefix, true, false, testReferrer, false, ""}, + {"Basic and hide listing handler w/o debug w/refer", testFolder, "", false, false, testReferrer, false, ""}, + {"Prefix and hide listing handler w/o debug w/refer", testFolder, testPrefix, false, false, testReferrer, false, ""}, + {"Basic handler w/debug w/refer w/o cors", testFolder, "", true, true, testReferrer, false, ""}, + {"Prefix handler w/debug w/refer w/o cors", testFolder, testPrefix, true, true, testReferrer, false, ""}, + {"Basic and hide listing handler w/debug w/refer w/o cors", testFolder, "", false, true, testReferrer, false, ""}, + {"Prefix and hide listing handler w/debug w/refer w/o cors", testFolder, testPrefix, false, true, testReferrer, false, ""}, + {"Basic handler w/debug w/refer w/cors", testFolder, "", true, true, testReferrer, true, ""}, + {"Prefix handler w/debug w/refer w/cors", testFolder, testPrefix, true, true, testReferrer, true, ""}, + {"Basic and hide listing handler w/debug w/refer w/cors", testFolder, "", false, true, testReferrer, true, ""}, + {"Prefix and hide listing handler w/debug w/refer w/cors", testFolder, testPrefix, false, true, testReferrer, true, ""}, + {"Access Key and Basic handler w/o debug", testFolder, "", true, false, ignoreReferrer, false, testAccessKey}, + {"Access Key and Prefix handler w/o debug", testFolder, testPrefix, true, false, ignoreReferrer, false, testAccessKey}, + {"Access Key and Basic and hide listing handler w/o debug", testFolder, "", false, false, ignoreReferrer, false, testAccessKey}, + {"Access Key and Prefix and hide listing handler w/o debug", testFolder, testPrefix, false, false, ignoreReferrer, false, testAccessKey}, + {"Access Key and Basic handler w/debug", testFolder, "", true, true, ignoreReferrer, false, testAccessKey}, + {"Access Key and Prefix handler w/debug", testFolder, testPrefix, true, true, ignoreReferrer, false, testAccessKey}, + {"Access Key and Basic and hide listing handler w/debug", testFolder, "", false, true, ignoreReferrer, false, testAccessKey}, + {"Access Key and Prefix and hide listing handler w/debug", testFolder, testPrefix, false, true, ignoreReferrer, false, testAccessKey}, + {"Access Key and Basic handler w/o debug w/refer", testFolder, "", true, false, testReferrer, false, testAccessKey}, + {"Access Key and Prefix handler w/o debug w/refer", testFolder, testPrefix, true, false, testReferrer, false, testAccessKey}, + {"Access Key and Basic and hide listing handler w/o debug w/refer", testFolder, "", false, false, testReferrer, false, testAccessKey}, + {"Access Key and Prefix and hide listing handler w/o debug w/refer", testFolder, testPrefix, false, false, testReferrer, false, testAccessKey}, + {"Access Key and Basic handler w/debug w/refer w/o cors", testFolder, "", true, true, testReferrer, false, testAccessKey}, + {"Access Key and Prefix handler w/debug w/refer w/o cors", testFolder, testPrefix, true, true, testReferrer, false, testAccessKey}, + {"Access Key and Basic and hide listing handler w/debug w/refer w/o cors", testFolder, "", false, true, testReferrer, false, testAccessKey}, + {"Access Key and Prefix and hide listing handler w/debug w/refer w/o cors", testFolder, testPrefix, false, true, testReferrer, false, testAccessKey}, + {"Access Key and Basic handler w/debug w/refer w/cors", testFolder, "", true, true, testReferrer, true, testAccessKey}, + {"Access Key and Prefix handler w/debug w/refer w/cors", testFolder, testPrefix, true, true, testReferrer, true, testAccessKey}, + {"Access Key and Basic and hide listing handler w/debug w/refer w/cors", testFolder, "", false, true, testReferrer, true, testAccessKey}, + {"Access Key and Prefix and hide listing handler w/debug w/refer w/cors", testFolder, testPrefix, false, true, testReferrer, true, testAccessKey}, } for _, tc := range testCases { @@ -74,6 +96,7 @@ func TestHandlerSelector(t *testing.T) { config.Get.URLPrefix = tc.prefix config.Get.Referrers = tc.refer config.Get.Cors = tc.cors + config.Get.AccessKey = tc.accessKey handlerSelector() }) diff --git a/handle/handle.go b/handle/handle.go index 7103ba8..67e1a13 100644 --- a/handle/handle.go +++ b/handle/handle.go @@ -1,8 +1,8 @@ package handle import ( - "crypto/tls" "crypto/md5" + "crypto/tls" "fmt" "log" "net/http" @@ -153,18 +153,18 @@ func AddCorsWildcardHeaders(serve http.HandlerFunc) http.HandlerFunc { } } -// Access Control through url parameters. The access key is set by ACCESS_KEY. -// md5sum is computed by queried path + access key +// AddAccessKey provides Access Control through url parameters. The access key +// is set by ACCESS_KEY. md5sum is computed by queried path + access key // (e.g. "/my/file" + ACCESS_KEY) func AddAccessKey(serve http.HandlerFunc, accessKey string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // Get key or md5sum from this access. keys, keyOk := r.URL.Query()["key"] var code string - if !keyOk || len(keys[0]) < 1 { + if !keyOk || len(keys[0]) < 1 { // In case a code is provided codes, codeOk := r.URL.Query()["code"] - if !codeOk || len(codes[0]) < 1 { + if !codeOk || len(codes[0]) < 1 { http.NotFound(w, r) return } @@ -180,7 +180,7 @@ func AddAccessKey(serve http.HandlerFunc, accessKey string) http.HandlerFunc { localData := []byte(r.URL.Path + accessKey) hash := md5.Sum(localData) localCode := fmt.Sprintf("%X", hash) - + // Compare the two. if code != localCode { http.NotFound(w, r) diff --git a/handle/handle_test.go b/handle/handle_test.go index a557c6f..01108fc 100644 --- a/handle/handle_test.go +++ b/handle/handle_test.go @@ -1,8 +1,10 @@ package handle import ( + "crypto/md5" "crypto/tls" "errors" + "fmt" "io/ioutil" "log" "net/http" @@ -335,6 +337,98 @@ func TestIgnoreIndex(t *testing.T) { } } +func TestAddAccessKey(t *testing.T) { + // Prepare testing data. + accessKey := "my-access-key" + + code := func(path, key string) string { + data := []byte("/" + path + key) + fmt.Printf("TEST: '%s'\n", data) + return fmt.Sprintf("%X", md5.Sum(data)) + } + + // Define test cases. + testCases := []struct { + name string + path string + key string + value string + code int + contents string + }{ + { + "Good base file with code", tmpFileName, + "code", code(tmpFileName, accessKey), + ok, tmpFile, + }, + { + "Good base file with key", tmpFileName, + "key", accessKey, + ok, tmpFile, + }, + { + "Bad base file with code", tmpBadName, + "code", code(tmpBadName, accessKey), + missing, notFound, + }, + { + "Bad base file with key", tmpBadName, + "key", accessKey, + missing, notFound, + }, + { + "Good base file with no code or key", tmpFileName, + "my", "value", + missing, notFound, + }, + { + "Good base file with bad code", tmpFileName, + "code", code(tmpFileName, "bad-access-key"), + missing, notFound, + }, + { + "Good base file with bad key", tmpFileName, + "key", "bad-access-key", + missing, notFound, + }, + } + + for _, serveFile := range serveFileFuncs { + handler := AddAccessKey(Basic(serveFile, baseDir), accessKey) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + fullpath := fmt.Sprintf( + "http://localhost/%s?%s=%s", + tc.path, tc.key, tc.value, + ) + req := httptest.NewRequest("GET", fullpath, nil) + w := httptest.NewRecorder() + + handler(w, req) + + resp := w.Result() + body, err := ioutil.ReadAll(resp.Body) + if nil != err { + t.Errorf("While reading body got %v", err) + } + contents := string(body) + if tc.code != resp.StatusCode { + t.Errorf( + "While retrieving %s expected status code of %d but got %d", + fullpath, tc.code, resp.StatusCode, + ) + } + if tc.contents != contents { + t.Errorf( + "While retrieving %s expected contents '%s' but got '%s'", + fullpath, tc.contents, contents, + ) + } + }) + } + } +} + func TestListening(t *testing.T) { // Choose values for testing. called := false