From 78b9f9bd298df054a9a00224e5c5fb8cb9939a7d Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 21 Jun 2022 14:17:58 +0800 Subject: [PATCH 1/2] perf: remove test --- parser_test.go | 106 ------------------------------------ signer_integration_test.go | 109 ------------------------------------- signer_internals_test.go | 20 ------- signer_test.go | 89 ------------------------------ utils_internal_test.go | 40 -------------- verify_integration_test.go | 86 ----------------------------- verify_test.go | 62 --------------------- 7 files changed, 512 deletions(-) delete mode 100644 parser_test.go delete mode 100644 signer_integration_test.go delete mode 100644 signer_internals_test.go delete mode 100644 signer_test.go delete mode 100644 utils_internal_test.go delete mode 100644 verify_integration_test.go delete mode 100644 verify_test.go diff --git a/parser_test.go b/parser_test.go deleted file mode 100644 index 2f2c578..0000000 --- a/parser_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package httpsig - -import ( - "fmt" - "github.com/stretchr/testify/assert" - "net/http" - "regexp" - "strings" - "testing" - "time" -) - -const ( - SampleKeyID = "keyId" - SampleAlgorithm = "rsa-sha256" - SampleHeaders = "host date" - SampleSignature = "abcdefg" -) - -func TestParseRequestWithNoAuthorizationHeader(t *testing.T) { - req, _ := http.NewRequest("GET", "http://example.com/path/to/resource", nil) - parsed, err := ParseRequest(req) - assert.NotNil(t, err) - assert.Nil(t, parsed) - assert.Contains(t, err.Error(), "no authorization header present") -} - -func TestParseRequest(t *testing.T) { - req, _ := http.NewRequest("GET", "http://example.com/path/to/resource", nil) - req.Header.Set("Authorization", fmt.Sprintf("Signature keyId=\"%s\",algorithm=\"%s\",headers=\"%s\",signature=\"%s\"", SampleKeyID, SampleAlgorithm, SampleHeaders, SampleSignature)) - req.Header.Set("Date", time.Now().Format(time.RFC1123)) - parsed, err := ParseRequest(req) - assert.Nil(t, err) - assert.NotNil(t, parsed) - assert.Equal(t, "Signature", parsed.Scheme()) - assert.NotNil(t, parsed.Params()) - assert.Equal(t, SampleKeyID, parsed.KeyId()) - assert.Equal(t, strings.ToUpper(SampleAlgorithm), parsed.Algorithm()) - assert.Equal(t, SampleHeaders, strings.Join(parsed.Headers(), " ")) - assert.Equal(t, SampleSignature, parsed.Signature()) - - rx, _ := regexp.Compile("host: example.com\ndate: [^\n]+") - assert.Regexp(t, rx, parsed.SigningString()) -} - -func TestParseRequestWithNoHeaders(t *testing.T) { - req, _ := http.NewRequest("GET", "http://example.com/path/to/resource", nil) - req.Header.Set("Authorization", fmt.Sprintf("Signature keyId=\"%s\",algorithm=\"%s\",signature=\"%s\"", SampleKeyID, SampleAlgorithm, SampleSignature)) - req.Header.Set("Date", time.Now().Format(time.RFC1123)) - parsed, err := ParseRequest(req) - assert.Nil(t, err) - assert.NotNil(t, parsed) - assert.Equal(t, "date", strings.Join(parsed.Headers(), " ")) - rx, _ := regexp.Compile("date: [^\n]+") - assert.Regexp(t, rx, parsed.SigningString()) -} - -func TestParseRequestWithRequestLine(t *testing.T) { - req, _ := http.NewRequest("GET", "http://example.com/path/to/resource", nil) - req.RequestURI = "/path/to/resource" - req.Header.Set("Authorization", fmt.Sprintf("Signature keyId=\"%s\",algorithm=\"%s\",headers=\"%s request-line\",signature=\"%s\"", SampleKeyID, SampleAlgorithm, SampleHeaders, SampleSignature)) - req.Header.Set("Date", time.Now().Format(time.RFC1123)) - parsed, err := ParseRequest(req) - assert.Nil(t, err) - assert.NotNil(t, parsed) - assert.Equal(t, fmt.Sprintf("%s %s", SampleHeaders, "request-line"), strings.Join(parsed.Headers(), " ")) - assert.Equal(t, SampleSignature, parsed.Signature()) - - rx, _ := regexp.Compile("host: example.com\ndate: [^\n]+\nGET /path/to/resource HTTP/1.1") - assert.Regexp(t, rx, parsed.SigningString()) -} - -func TestParseRequestWithRequestTarget(t *testing.T) { - req, _ := http.NewRequest("GET", "http://example.com/path/to/resource", nil) - req.RequestURI = "/path/to/resource" - req.Header.Set("Authorization", fmt.Sprintf("Signature keyId=\"%s\",algorithm=\"%s\",headers=\"%s (request-target)\",signature=\"%s\"", SampleKeyID, SampleAlgorithm, SampleHeaders, SampleSignature)) - req.Header.Set("Date", time.Now().Format(time.RFC1123)) - parsed, err := ParseRequest(req) - assert.Nil(t, err) - assert.NotNil(t, parsed) - assert.Equal(t, fmt.Sprintf("%s %s", SampleHeaders, "(request-target)"), strings.Join(parsed.Headers(), " ")) - assert.Equal(t, SampleSignature, parsed.Signature()) - - rx, _ := regexp.Compile("host: example.com\ndate: [^\n]+\n\\(request-target\\): get /path/to/resource") - assert.Regexp(t, rx, parsed.SigningString()) -} - -func TestParseRequestWithDateBeforeClockSkewRange(t *testing.T) { - req, _ := http.NewRequest("GET", "http://example.com/path/to/resource", nil) - req.Header.Set("Authorization", fmt.Sprintf("Signature keyId=\"%s\",algorithm=\"%s\",signature=\"%s\"", SampleKeyID, SampleAlgorithm, SampleSignature)) - req.Header.Set("Date", time.Now().Add(-DefaultClockSkew-time.Second).Format(time.RFC1123)) - parsed, err := ParseRequest(req) - assert.NotNil(t, err) - assert.Nil(t, parsed) - assert.Contains(t, err.Error(), "Expired Request error") -} - -func TestParseRequestWithDateAfterClockSkewRange(t *testing.T) { - req, _ := http.NewRequest("GET", "http://example.com/path/to/resource", nil) - req.Header.Set("Authorization", fmt.Sprintf("Signature keyId=\"%s\",algorithm=\"%s\",signature=\"%s\"", SampleKeyID, SampleAlgorithm, SampleSignature)) - req.Header.Set("Date", time.Now().Add(DefaultClockSkew+time.Second).Format(time.RFC1123)) - parsed, err := ParseRequest(req) - assert.NotNil(t, err) - assert.Nil(t, parsed) - assert.Contains(t, err.Error(), "Expired Request error") -} diff --git a/signer_integration_test.go b/signer_integration_test.go deleted file mode 100644 index 302da83..0000000 --- a/signer_integration_test.go +++ /dev/null @@ -1,109 +0,0 @@ -// +build integration - -package httpsig - -import ( - "bufio" - "fmt" - "github.com/stretchr/testify/assert" - "io" - "net/http" - "os" - "os/exec" - "testing" -) - -func TestClientCanCallNodeServer(t *testing.T) { - npmInstall() - - port := os.Getenv("PORT") - if port == "" { - port = "8080" - } - ready := make(chan *exec.Cmd) - go startNodeServer(t, port, ready) - cmd := <-ready - defer cmd.Process.Kill() - - verifyClientCanCallNodeServer(t, port, "hmac-sha1") - verifyClientCanCallNodeServer(t, port, "hmac-sha256") - verifyClientCanCallNodeServer(t, port, "hmac-sha512") - verifyClientCanCallNodeServer(t, port, "rsa-sha1") - verifyClientCanCallNodeServer(t, port, "rsa-sha256") - verifyClientCanCallNodeServer(t, port, "rsa-sha512") - verifyClientCanCallNodeServer(t, port, "dsa-sha1") - verifyClientCanCallNodeServer(t, port, "dsa-sha256") - verifyClientCanCallNodeServer(t, port, "dsa-sha512") - verifyClientCanCallNodeServer(t, port, "ecdsa-sha1") - verifyClientCanCallNodeServer(t, port, "ecdsa-sha256") - verifyClientCanCallNodeServer(t, port, "ecdsa-sha512") -} - -func verifyClientCanCallNodeServer(t *testing.T, port string, algorithm string) { - t.Logf("Calling node server with %s algorithm", algorithm) - req, _ := http.NewRequest("GET", fmt.Sprintf("http://localhost:%s/", port), nil) - signer, _ := NewRequestSigner(getKeyIDForTests(algorithm), getPrivateKeyForTests(algorithm), algorithm) - err := signer.SignRequest(req, []string{"date", "(request-target)"}, nil) - if err != nil { - t.Error(err) - return - } - - client := &http.Client{} - res, err := client.Do(req) - if err != nil { - t.Error(err) - return - } - assert.Equal(t, http.StatusOK, res.StatusCode) - t.Log(res.StatusCode) -} - -func getKeyIDForTests(alg string) string { - algorithm, _ := validateAlgorithm(alg) - if algorithm.sign == "hmac" { - return getPrivateKeyForTests(alg) - } - return fmt.Sprintf("%s_public.pem", algorithm.sign) -} - -func startNodeServer(t *testing.T, port string, ch chan *exec.Cmd) { - r, w := io.Pipe() - read := bufio.NewReader(r) - - cmd := exec.Command("node", "server.js", port) - cmd.Dir = "./test" - cmd.Stdout = w - cmd.Stderr = w - cmd.Start() - - out := make(chan string, 12) - go logOut(t, read, out) - - <-out // wait for Listening - - ch <- cmd - - return -} - -func logOut(t *testing.T, r *bufio.Reader, out chan string) { - for { - line, e := r.ReadString('\n') - if e != nil { - t.Log(e) - return - } - t.Logf("server: %s", line) - out <- line - } -} - -func npmInstall() { - cmd := exec.Command("npm", "install") - cmd.Dir = "./test" - err := cmd.Run() - if err != nil { - panic(err) - } -} diff --git a/signer_internals_test.go b/signer_internals_test.go deleted file mode 100644 index c32c9e3..0000000 --- a/signer_internals_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package httpsig - -import ( - "github.com/stretchr/testify/assert" - u "net/url" - "testing" -) - -func doGetPathAndQueryFromURL(urlString string) string { - url, _ := u.Parse(urlString) - return getPathAndQueryFromURL(url) -} - -func TestGetPathAndQueryFromURL(t *testing.T) { - assert.Equal(t, "/", doGetPathAndQueryFromURL("http://example.com")) - assert.Equal(t, "/", doGetPathAndQueryFromURL("http://example.com/")) - assert.Equal(t, "/?withquery=string", doGetPathAndQueryFromURL("http://example.com/?withquery=string")) - assert.Equal(t, "/test/path", doGetPathAndQueryFromURL("http://example.com/test/path")) - assert.Equal(t, "/test/path?withquery=string%20andspaces", doGetPathAndQueryFromURL("http://example.com/test/path?withquery=string%20andspaces")) -} diff --git a/signer_test.go b/signer_test.go deleted file mode 100644 index 1fca82f..0000000 --- a/signer_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package httpsig - -import ( - "fmt" - "github.com/dgrijalva/jwt-go" - "github.com/stretchr/testify/assert" - "io/ioutil" - "net/http" - "testing" - "time" -) - -// These tests just verify that a signature is made, the verify tests will verify that the signature was valid -func TestSignRequests(t *testing.T) { - // hmac - signAndAssert(t, "hmac-sha1", false) - signAndAssert(t, "hmac-sha256", false) - signAndAssert(t, "hmac-sha512", false) - signAndAssert(t, "hmac-sha1", true) - signAndAssert(t, "hmac-sha256", true) - signAndAssert(t, "hmac-sha512", true) - // rsa - signAndAssert(t, "rsa-sha1", false) - signAndAssert(t, "rsa-sha256", false) - signAndAssert(t, "rsa-sha512", false) - signAndAssert(t, "rsa-sha1", true) - signAndAssert(t, "rsa-sha256", true) - signAndAssert(t, "rsa-sha512", true) - // dsa - signAndAssert(t, "dsa-sha1", false) - signAndAssert(t, "dsa-sha256", false) - signAndAssert(t, "dsa-sha512", false) - signAndAssert(t, "dsa-sha1", true) - signAndAssert(t, "dsa-sha256", true) - signAndAssert(t, "dsa-sha512", true) - // ecdsa - signAndAssert(t, "ecdsa-sha1", false) - signAndAssert(t, "ecdsa-sha256", false) - signAndAssert(t, "ecdsa-sha512", false) - signAndAssert(t, "ecdsa-sha1", true) - signAndAssert(t, "ecdsa-sha256", true) - signAndAssert(t, "ecdsa-sha512", true) -} - -func signAndAssert(t *testing.T, alg string, withJWT bool) { - var ext map[string]string - if withJWT { - ext = getJWT() - } - req, err := getExampleSignedRequest(alg, ext) - assert.Nil(t, err) - authz := req.Header.Get("Authorization") - assert.NotEmpty(t, authz) -} - -func getExampleSignedRequest(alg string, ext map[string]string) (req *http.Request, err error) { - req, _ = http.NewRequest("GET", "http://example.com/path/to/resource", nil) - signer, _ := NewRequestSigner(SampleKeyID, getPrivateKeyForTests(alg), alg) - err = signer.SignRequest(req, []string{"date", "(request-target)"}, ext) - return -} - -func getJWT() map[string]string { - token := jwt.NewWithClaims(jwt.SigningMethodNone, jwt.MapClaims{ - "foo": "bar", - "exp": time.Now().Unix() + 30000, - }) - - tokenString, _ := token.SignedString("ignored") - return map[string]string{ - "jwt": tokenString, - } -} - -func getPrivateKeyForTests(alg string) string { - algorithm, _ := validateAlgorithm(alg) - if algorithm.sign == "hmac" { - return "sooper-seekrit-kee" - } - return getTestKey(fmt.Sprintf("%s_private.pem", algorithm.sign)) -} - -func getTestKey(file string) string { - f, err := ioutil.ReadFile(fmt.Sprintf("test/%s", file)) - if err != nil { - panic(err) - } - return string(f) -} diff --git a/utils_internal_test.go b/utils_internal_test.go deleted file mode 100644 index ae844d9..0000000 --- a/utils_internal_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package httpsig - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -func TestDetectAlgorithmFromRSAKey(t *testing.T) { - key := getTestKey("rsa_private.pem") - alg, err := autoDetectAlgorithm(key) - assert.Nil(t, err) - assert.Equal(t, "rsa-sha256", alg.String()) -} - -func TestDetectAlgorithmFromDSAKey(t *testing.T) { - key := getTestKey("dsa_private.pem") - alg, err := autoDetectAlgorithm(key) - assert.Nil(t, err) - assert.Equal(t, "dsa-sha256", alg.String()) -} - -func TestDetectAlgorithmFromECDSAKey(t *testing.T) { - key := getTestKey("ecdsa_private.pem") - alg, err := autoDetectAlgorithm(key) - assert.Nil(t, err) - assert.Equal(t, "ecdsa-sha256", alg.String()) -} - -func TestDetectAlgorithmFromNonPEMKey(t *testing.T) { - alg, err := autoDetectAlgorithm("NOT A PEM KEY") - assert.Nil(t, alg) - assert.Contains(t, err.Error(), "PEM format") -} - -func TestDetectAlgorithmFromPublicKey(t *testing.T) { - key := getTestKey("rsa_public.pem") - alg, err := autoDetectAlgorithm(key) - assert.Nil(t, alg) - assert.Contains(t, err.Error(), "(pem block type 'PUBLIC KEY')") -} diff --git a/verify_integration_test.go b/verify_integration_test.go deleted file mode 100644 index b6e1a2d..0000000 --- a/verify_integration_test.go +++ /dev/null @@ -1,86 +0,0 @@ -// +build integration - -package httpsig - -import ( - "bytes" - "github.com/stretchr/testify/assert" - "net/http" - "net/http/httptest" - "os/exec" - "testing" -) - -func TestNodeClientCanCallServer(t *testing.T) { - npmInstall() - - handler := &TestHandler{t} - server := httptest.NewServer(handler) - address := server.Listener.Addr().String() - defer server.Close() - - verifyNodeClientCanCallServer(t, address, "hmac-sha1") - verifyNodeClientCanCallServer(t, address, "hmac-sha256") - verifyNodeClientCanCallServer(t, address, "hmac-sha512") - verifyNodeClientCanCallServer(t, address, "rsa-sha1") - verifyNodeClientCanCallServer(t, address, "rsa-sha256") - verifyNodeClientCanCallServer(t, address, "rsa-sha512") - verifyNodeClientCanCallServer(t, address, "dsa-sha1") - verifyNodeClientCanCallServer(t, address, "dsa-sha256") - verifyNodeClientCanCallServer(t, address, "dsa-sha512") - verifyNodeClientCanCallServer(t, address, "ecdsa-sha1") - verifyNodeClientCanCallServer(t, address, "ecdsa-sha256") - verifyNodeClientCanCallServer(t, address, "ecdsa-sha512") -} - -func verifyNodeClientCanCallServer(t *testing.T, address string, algorithm string) { - t.Logf("Calling go server with %s algorithm\n", algorithm) - output := runNodeClient(t, address, algorithm) - t.Log(output) - assert.Equal(t, "200\n", output) -} - -func runNodeClient(t *testing.T, address string, algorithm string) string { - cmd := exec.Command("node", "client.js", address, algorithm) - cmd.Dir = "./test" - var out bytes.Buffer - cmd.Stdout = &out - cmd.Stderr = &out - err := cmd.Run() - rs, _ := out.ReadString(byte(0)) - if err != nil { - t.Log(rs) - panic(err) - } - return rs -} - -type TestHandler struct { - *testing.T -} - -func (h *TestHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { - parsed, err := ParseRequest(req) - if err != nil { - h.Log(err) - w.WriteHeader(http.StatusUnauthorized) - return - } - publicKey := getPublicKeyForTests(parsed.Algorithm(), parsed.KeyId()) - verified, err := VerifySignature(parsed, publicKey) - if err != nil || !verified { - h.Logf("Unverified: %v\n", err) - w.WriteHeader(http.StatusUnauthorized) - return - } - w.WriteHeader(http.StatusOK) - w.Write([]byte("Authoirzation Passed")) -} - -func getPublicKeyForTests(alg string, keyID string) string { - algorithm, _ := validateAlgorithm(alg) - if algorithm.sign == "hmac" { - return getPrivateKeyForTests(alg) - } - return getTestKey(keyID) -} diff --git a/verify_test.go b/verify_test.go deleted file mode 100644 index 42ee49f..0000000 --- a/verify_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package httpsig - -import ( - "fmt" - "github.com/stretchr/testify/assert" - "testing" -) - -func getTestPublicKey(alg string) string { - parts, _ := validateAlgorithm(alg) - if parts.sign == "hmac" { - return getPrivateKeyForTests(alg) - } - return getTestKey(fmt.Sprintf("%s_public.pem", parts.sign)) -} - -func TestVerifyRequests(t *testing.T) { - // hmac - signVerifyAndAssert(t, "hmac-sha1", false) - signVerifyAndAssert(t, "hmac-sha256", false) - signVerifyAndAssert(t, "hmac-sha512", false) - signVerifyAndAssert(t, "hmac-sha1", true) - signVerifyAndAssert(t, "hmac-sha256", true) - signVerifyAndAssert(t, "hmac-sha512", true) - // rsa - signVerifyAndAssert(t, "rsa-sha1", false) - signVerifyAndAssert(t, "rsa-sha256", false) - signVerifyAndAssert(t, "rsa-sha512", false) - signVerifyAndAssert(t, "rsa-sha1", true) - signVerifyAndAssert(t, "rsa-sha256", true) - signVerifyAndAssert(t, "rsa-sha512", true) - // dsa - signVerifyAndAssert(t, "dsa-sha1", false) - signVerifyAndAssert(t, "dsa-sha256", false) - signVerifyAndAssert(t, "dsa-sha512", false) - signVerifyAndAssert(t, "dsa-sha1", true) - signVerifyAndAssert(t, "dsa-sha256", true) - signVerifyAndAssert(t, "dsa-sha512", true) - // ecdsa - signVerifyAndAssert(t, "ecdsa-sha1", false) - signVerifyAndAssert(t, "ecdsa-sha256", false) - signVerifyAndAssert(t, "ecdsa-sha512", false) - signVerifyAndAssert(t, "ecdsa-sha1", true) - signVerifyAndAssert(t, "ecdsa-sha256", true) - signVerifyAndAssert(t, "ecdsa-sha512", true) -} - -func signVerifyAndAssert(t *testing.T, alg string, withJWT bool) { - var ext map[string]string - if withJWT { - ext = getJWT() - } - req, err := getExampleSignedRequest(alg, ext) - // this is only needed to simulate an actual request - req.RequestURI = getPathAndQueryFromURL(req.URL) - assert.Nil(t, err) - parsed, err := ParseRequest(req) - assert.Nil(t, err) - verified, err := VerifySignature(parsed, getTestPublicKey(alg)) - assert.Nil(t, err) - assert.True(t, verified) -} From 49b453a5fa97a200e45dbb96fb20b459a32d6f4a Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 21 Jun 2022 14:20:33 +0800 Subject: [PATCH 2/2] perf: add go.mod --- go.mod | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 go.mod diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..35c6988 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/LeeEirc/httpsig + +go 1.17