diff --git a/Makefile b/Makefile index 6662a16..04a69cb 100644 --- a/Makefile +++ b/Makefile @@ -20,5 +20,5 @@ release: .PHONY: \ release \ test \ - test-package \ - test-examples + test-package \ + test-examples diff --git a/transloadit.go b/transloadit.go index 5e25700..acdb038 100755 --- a/transloadit.go +++ b/transloadit.go @@ -293,7 +293,7 @@ func (client *Client) CreateSignedSmartCDNUrl(opts SignedSmartCDNUrlOptions) str stringToSign := fmt.Sprintf("%s/%s/%s?%s", workspaceSlug, templateSlug, inputField, queryString) - // Create signature using SHA-256 + // Smart CDN signatures intentionally remain SHA-256; API request signatures use SHA-384. hash := hmac.New(sha256.New, []byte(client.config.AuthSecret)) hash.Write([]byte(stringToSign)) signature := url.QueryEscape("sha256:" + hex.EncodeToString(hash.Sum(nil))) diff --git a/transloadit_signature_test.go b/transloadit_signature_test.go new file mode 100644 index 0000000..70f5eaa --- /dev/null +++ b/transloadit_signature_test.go @@ -0,0 +1,97 @@ +package transloadit + +import ( + "context" + "crypto/hmac" + "crypto/sha512" + "encoding/hex" + "fmt" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestSign_UsesSha384WithAlgorithmPrefix(t *testing.T) { + client := NewClient(Config{ + AuthKey: "foo_key", + AuthSecret: "foo_secret", + Endpoint: "https://api2.transloadit.com", + }) + + params, signature, err := client.sign(map[string]interface{}{ + "foo": "bar", + }) + if err != nil { + t.Fatal(err) + } + + if !strings.HasPrefix(signature, "sha384:") { + t.Fatalf("signature prefix should be sha384:, got %q", signature) + } + + hash := hmac.New(sha512.New384, []byte(client.config.AuthSecret)) + hash.Write([]byte(params)) + expected := "sha384:" + hex.EncodeToString(hash.Sum(nil)) + + if signature != expected { + t.Fatalf("wrong signature, expected %q got %q", expected, signature) + } +} + +func TestListRequest_UsesSha384WithAlgorithmPrefix(t *testing.T) { + client := NewClient(Config{ + AuthKey: "foo_key", + AuthSecret: "foo_secret", + }) + + errCh := make(chan error, 1) + reportErr := func(err error) { + select { + case errCh <- err: + default: + } + } + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + params := r.URL.Query().Get("params") + signature := r.URL.Query().Get("signature") + + if params == "" { + reportErr(fmt.Errorf("params query should be set")) + } + + if !strings.HasPrefix(signature, "sha384:") { + reportErr(fmt.Errorf("listRequest signature prefix should be sha384:, got %q", signature)) + } + + hash := hmac.New(sha512.New384, []byte(client.config.AuthSecret)) + hash.Write([]byte(params)) + expected := "sha384:" + hex.EncodeToString(hash.Sum(nil)) + + if signature != expected { + reportErr(fmt.Errorf("wrong listRequest signature, expected %q got %q", expected, signature)) + } + + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"items":[],"count":0}`)) + })) + defer server.Close() + + client.config.Endpoint = server.URL + + list, err := client.ListTemplates(context.Background(), &ListOptions{PageSize: 1}) + if err != nil { + t.Fatal(err) + } + + if list.Count != 0 { + t.Fatalf("expected empty list count 0, got %d", list.Count) + } + + select { + case verifyErr := <-errCh: + t.Fatal(verifyErr) + default: + } +}