Files
2026-08-14 00:07:52 +08:00

112 lines
3.1 KiB
Go

package handler
import (
"encoding/json"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"time"
"silk-server-go/internal/model"
"github.com/gin-gonic/gin"
)
func TestCameraResponseNeverContainsSecrets(t *testing.T) {
password := "secret-password"
camera := model.Camera{
PasswordEnc: &password,
GbAuthPassword: &password,
}
raw, err := json.Marshal(camera)
if err != nil {
t.Fatalf("marshal camera: %v", err)
}
body := string(raw)
if strings.Contains(body, "passwordEnc") || strings.Contains(body, password) {
t.Fatalf("camera JSON must not contain password fields: %s", body)
}
if strings.Contains(body, "gbAuthPassword") {
t.Fatalf("camera JSON must not contain gbAuthPassword: %s", body)
}
}
func TestIssueAndValidateVideoToken(t *testing.T) {
SetVideoTokenSecret("test-secret")
token, err := IssueVideoToken("user-1", "camera", "12", time.Minute)
if err != nil {
t.Fatalf("issue video token: %v", err)
}
if token == "" {
t.Fatal("expected non-empty video token")
}
if err := ValidateVideoToken(token, "camera", "12"); err != nil {
t.Fatalf("valid video token rejected: %v", err)
}
if err := ValidateVideoToken(token, "camera", "13"); err == nil {
t.Fatal("expected resource mismatch error")
}
if err := ValidateVideoToken(token, "clip", "12"); err == nil {
t.Fatal("expected resource type mismatch error")
}
}
func TestValidateVideoTokenForUserRejectsMismatch(t *testing.T) {
SetVideoTokenSecret("test-secret")
token, err := IssueVideoToken("user-1", "camera", "12", time.Minute)
if err != nil {
t.Fatalf("issue video token: %v", err)
}
if err := ValidateVideoTokenForUser(token, "camera", "12", "user-1"); err != nil {
t.Fatalf("same-user token rejected: %v", err)
}
if err := ValidateVideoTokenForUser(token, "camera", "12", "user-2"); err == nil {
t.Fatal("expected cross-user token rejection")
}
}
func TestVideoTokenExpires(t *testing.T) {
SetVideoTokenSecret("test-secret")
token, err := IssueVideoToken("user-1", "camera", "12", -time.Second)
if err != nil {
t.Fatalf("issue expired token: %v", err)
}
if err := ValidateVideoToken(token, "camera", "12"); err == nil {
t.Fatal("expected expired token rejection")
}
}
func TestVideoStreamRequiresValidToken(t *testing.T) {
SetVideoTokenSecret("test-secret")
gin.SetMode(gin.TestMode)
rec := httptest.NewRecorder()
c, _ := gin.CreateTestContext(rec)
c.Request = &http.Request{URL: &url.URL{RawQuery: ""}}
if requireVideoToken(c, "camera", "12") {
t.Fatal("missing token should be rejected")
}
if rec.Code != http.StatusUnauthorized {
t.Fatalf("missing token status = %d, want 401", rec.Code)
}
token, err := IssueVideoToken("user-1", "camera", "13", time.Minute)
if err != nil {
t.Fatalf("issue token: %v", err)
}
rec2 := httptest.NewRecorder()
c2, _ := gin.CreateTestContext(rec2)
c2.Request = &http.Request{URL: &url.URL{RawQuery: "videoToken=" + token}}
if requireVideoToken(c2, "camera", "12") {
t.Fatal("wrong resource token should be rejected")
}
if rec2.Code != http.StatusForbidden {
t.Fatalf("wrong resource token status = %d, want 403", rec2.Code)
}
}