Files
upstream-corteza/server/system/service/sink_test.go
upstream-mirror 7e385fc126
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:22:23 +05:00

233 lines
6.0 KiB
Go

package service
import (
"bytes"
"github.com/cortezaproject/corteza/server/pkg/errors"
"io"
"net/http"
"reflect"
"strings"
"testing"
"time"
internalAuth "github.com/cortezaproject/corteza/server/pkg/auth"
)
func Test_sink_SignURL(t *testing.T) {
var (
signer = internalAuth.HmacSigner("test")
tests = []struct {
name string
surp SinkRequestUrlParams
wantSignedURL string
wantErr bool
}{
{
name: "basic",
surp: SinkRequestUrlParams{
Method: "POST",
Origin: "test",
Expires: nil,
MaxBodySize: 1024,
ContentType: "plain/text",
},
wantSignedURL: "/sink?__sign=d8a8c5591acb0f5f6695ab6aa4a205a7066b3bf4_eyJtdGQiOiJQT1NUIiwib3JpZ2luIjoidGVzdCIsIm1icyI6MTAyNCwiY3QiOiJwbGFpbi90ZXh0In0%3D",
},
{
name: "signature in a path",
surp: SinkRequestUrlParams{
Method: "POST",
Origin: "test",
Expires: nil,
MaxBodySize: 1024,
ContentType: "plain/text",
SignatureInPath: true,
},
wantSignedURL: "/sink/__sign=a4a5652c66159ed0142c01a9aa5d90b3e9f76241_eyJtdGQiOiJQT1NUIiwib3JpZ2luIjoidGVzdCIsIm1icyI6MTAyNCwiY3QiOiJwbGFpbi90ZXh0Iiwic2lwIjp0cnVlfQ==",
},
{
name: "required path",
surp: SinkRequestUrlParams{
Path: "/foo/bar",
},
wantSignedURL: "/sink/foo/bar?__sign=910436a3944ad1ee010db07b936209f198be481d_eyJwdCI6Ii9mb28vYmFyIn0%3D",
},
}
)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
svc := sink{
signer: signer,
}
gotSignedURL, _, err := svc.SignURL(tt.surp)
if (err != nil) != tt.wantErr {
t.Errorf("SignURL() \n"+
" error: %v, \n"+
"wantErr: %v", err, tt.wantErr)
return
}
if gotSignedURL.String() != tt.wantSignedURL {
t.Errorf("SignURL() \n"+
"gotSignedURL: %v\n"+
" want: %v", gotSignedURL, tt.wantSignedURL)
}
})
}
}
func Test_sink_handleRequest(t *testing.T) {
var (
signer = internalAuth.HmacSigner("test")
svc = sink{signer: signer}
signParams = SinkRequestUrlParams{
Method: "POST",
Origin: "test",
Expires: nil,
MaxBodySize: 1024,
ContentType: "plain/text",
}
signedUrl, _, _ = svc.SignURL(signParams)
signParamsNoPref = SinkRequestUrlParams{}
signedUrlNoPref, _, _ = svc.SignURL(signParamsNoPref)
signParamsExp = SinkRequestUrlParams{Expires: &time.Time{}}
signedUrlExp, _, _ = svc.SignURL(signParamsExp)
signParamsInPath = SinkRequestUrlParams{SignatureInPath: true, Path: "/foo"}
signedUrlInPath, _, _ = svc.SignURL(signParamsInPath)
signParamsInPathNoPath = SinkRequestUrlParams{SignatureInPath: true}
signedUrlInPathNoPath, _, _ = svc.SignURL(signParamsInPathNoPath)
signParamsFixedPath = SinkRequestUrlParams{Path: "/foo/bar"}
signedUrlFixedPath, _, _ = svc.SignURL(signParamsFixedPath)
)
var (
tests = []struct {
name string
withMethod string
withURL string
withBody io.Reader
withHeader http.Header
wantParams *SinkRequestUrlParams
wantErr error
}{
{
name: "missing signature",
withURL: "/sink",
wantErr: SinkErrMissingSignature(),
},
{
name: "invalid signature",
withURL: "/sink?" + SinkSignUrlParamName + "=foo",
wantErr: SinkErrInvalidSignatureParam(),
},
{
name: "invalid signature",
withURL: "/sink?__sign=foo_bar",
wantErr: SinkErrBadSinkParamEncoding(),
},
{
name: "invalid signature",
withURL: "/sink?__sign=foo_eyJtdGQiOiJQT1NUIiwib3JpZ2luIjoidGVzdCIsIm1icyI6MTAyNCwiY3QiOiJwbGFpbi90ZXh0In0%3D",
wantErr: SinkErrInvalidSignature(),
},
{
name: "any HTTP method (no pref. method)",
withMethod: "DELETE",
withURL: signedUrlNoPref.String(),
wantParams: &signParamsNoPref,
wantErr: nil,
},
{
name: "invalid HTTP method (POST only)",
withMethod: "GET",
withURL: signedUrl.String(),
wantErr: SinkErrInvalidHttpMethod(),
},
{
name: "invalid content type",
withMethod: "POST",
withHeader: map[string][]string{"content-type": {"foo/bar"}},
withURL: signedUrl.String(),
wantErr: SinkErrInvalidContentType(),
},
{
name: "valid content type",
withMethod: "POST",
withHeader: map[string][]string{"content-type": {"plain/text"}},
withURL: signedUrl.String(),
wantErr: nil,
wantParams: &signParams,
},
{
name: "expired",
withMethod: "POST",
withURL: signedUrlExp.String(),
wantErr: SinkErrSignatureExpired(),
},
{
name: "content length exceeds",
withMethod: "POST",
withHeader: map[string][]string{"content-type": {"plain/text"}},
withBody: bytes.NewBufferString(strings.Repeat(".", 1025)),
withURL: signedUrl.String(),
wantErr: SinkErrContentLengthExceedsMaxAllowedSize(),
},
{
name: "signature in a path (no path constraint)",
withURL: signedUrlInPathNoPath.String(),
wantParams: &signParamsInPathNoPath,
},
{
name: "signature in a path (with path constraint)",
withURL: signedUrlInPath.String(),
wantParams: &signParamsInPath,
},
{
name: "signed fixed path",
withURL: signedUrlFixedPath.String(),
wantParams: &signParamsFixedPath,
},
}
)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.withMethod == "" {
tt.withMethod = "GET"
}
req, err := http.NewRequest(tt.withMethod, tt.withURL, tt.withBody)
if err != nil {
panic(err)
}
for n, vv := range tt.withHeader {
for _, v := range vv {
req.Header.Add(n, v)
}
}
got, err := svc.handleRequest(req)
if tt.wantErr != nil && err != nil && !errors.Is(err, tt.wantErr) {
t.Errorf("handleRequest()\n"+
" error: %v\n"+
"wantErr: %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.wantParams) {
t.Errorf("handleRequest()\n"+
"params: %v\n"+
" want: %v", got, tt.wantParams)
}
})
}
}