Files

85 lines
3.3 KiB
Go
Raw Permalink Normal View History

package onboarding
import (
"context"
"data-terminal-cloud/internal/config"
"errors"
captcha "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/captcha/v20190722"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"net/http/httptest"
"strings"
"testing"
)
type fakeCaptchaAPI struct {
web, mini int
result int64
err error
t *testing.T
}
func (f *fakeCaptchaAPI) DescribeCaptchaResultWithContext(_ context.Context, r *captcha.DescribeCaptchaResultRequest) (*captcha.DescribeCaptchaResultResponse, error) {
f.web++
if *r.CaptchaAppId != 123 || *r.AppSecretKey != "web-secret-123456" || *r.Randstr != "random" || *r.CaptchaType != 9 {
f.t.Fatal("wrong web request")
}
return &captcha.DescribeCaptchaResultResponse{Response: &captcha.DescribeCaptchaResultResponseParams{CaptchaCode: common.Int64Ptr(f.result)}}, f.err
}
func (f *fakeCaptchaAPI) DescribeCaptchaMiniResultWithContext(_ context.Context, r *captcha.DescribeCaptchaMiniResultRequest) (*captcha.DescribeCaptchaMiniResultResponse, error) {
f.mini++
if *r.CaptchaAppId != 456 || *r.AppSecretKey != "mini-secret-12345" || *r.CaptchaType != 9 {
f.t.Fatal("wrong mini request")
}
return &captcha.DescribeCaptchaMiniResultResponse{Response: &captcha.DescribeCaptchaMiniResultResponseParams{CaptchaCode: common.Int64Ptr(f.result)}}, f.err
}
func TestTencentCaptchaProviderSeparatesClientsAndFailsClosed(t *testing.T) {
f := &fakeCaptchaAPI{t: t, result: 1}
p := &tencentCaptchaProvider{api: f, config: config.TencentCaptchaConfig{SaaS: config.CaptchaClientConfig{AppID: "123", AppSecretKey: "web-secret-123456"}, Mini: config.CaptchaClientConfig{AppID: "456", AppSecretKey: "mini-secret-12345"}}}
ctx := context.Background()
if err := p.Verify(ctx, "saas", "ticket", "random", "203.0.113.1"); err != nil {
t.Fatal(err)
}
if err := p.Verify(ctx, "mini_program", "ticket", "", "203.0.113.1"); err != nil {
t.Fatal(err)
}
if f.web != 1 || f.mini != 1 {
t.Fatal("wrong API")
}
for _, code := range []int64{0, 7, 8, 9, 21, 100} {
f.result = code
if p.Verify(ctx, "saas", "ticket", "random", "203.0.113.1") == nil {
t.Fatal("rejection accepted", code)
}
}
f.result = 1
f.err = errors.New("contains-secret-value")
if err := p.Verify(ctx, "saas", "ticket", "random", "203.0.113.1"); err == nil || strings.Contains(err.Error(), "secret-value") {
t.Fatal("error must be closed and sanitized")
}
before := f.web
for _, ticket := range []string{"", "trerror_123", strings.Repeat("x", 4097)} {
if p.Verify(ctx, "saas", ticket, "random", "203.0.113.1") == nil {
t.Fatal("bad ticket accepted")
}
}
if f.web != before {
t.Fatal("bad ticket caused API call")
}
}
func TestCaptchaClientIPTrustBoundary(t *testing.T) {
s := &Service{options: Options{TrustedProxyCIDRs: []string{"172.18.0.0/16"}}}
for _, tc := range []struct{ remote, forwarded, want string }{
{"203.0.113.9:123", "1.1.1.1", "203.0.113.9"},
{"172.18.0.4:123", "1.1.1.1, 203.0.113.9", "203.0.113.9"},
{"172.18.0.4:123", "203.0.113.9, 172.18.0.3", "203.0.113.9"},
{"[2001:db8::1]:123", "1.1.1.1", "2001:db8::1"},
} {
r := httptest.NewRequest("POST", "https://example.test", nil)
r.RemoteAddr = tc.remote
r.Header.Set("X-Forwarded-For", tc.forwarded)
if got := s.clientIP(r); got != tc.want {
t.Fatalf("ip %s want %s", got, tc.want)
}
}
}