Files
opsx-vpn/backend/internal/identityprovider/admin_test.go
T

58 lines
2.0 KiB
Go

package identityprovider
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/gin-gonic/gin"
"vpn-platform/backend/internal/store"
)
func TestAdminNeverEchoesFeishuSecretAndKeepsEncryptedValue(t *testing.T) {
dir := t.TempDir()
t.Setenv("VPN_DATA_DIR", dir)
if err := store.Init(dir); err != nil {
t.Fatal(err)
}
gin.SetMode(gin.TestMode)
server := gin.New()
p := New()
server.PUT("/config", func(c *gin.Context) { c.Set("username", "admin"); p.Configure(c) })
server.GET("/config", p.Status)
body := []byte(`{"app_id":"cli_test","app_secret":"feishu-private-value","tenant_key":"tenant_1","enabled":false}`)
resp := httptest.NewRecorder()
request := httptest.NewRequest(http.MethodPut, "/config", bytes.NewReader(body))
request.RemoteAddr = "127.0.0.1:12345"
request.Header.Set("X-Forwarded-Proto", "https")
server.ServeHTTP(resp, request)
if resp.Code != 200 || strings.Contains(resp.Body.String(), "feishu-private-value") {
t.Fatalf("unsafe response: %d %s", resp.Code, resp.Body.String())
}
rejected := httptest.NewRecorder()
server.ServeHTTP(rejected, httptest.NewRequest(http.MethodPut, "/config", bytes.NewReader(body)))
if rejected.Code != http.StatusForbidden {
t.Fatal("plaintext management request accepted credentials")
}
cfg, err := current()
if err != nil || cfg.AppSecret == "feishu-private-value" {
t.Fatal("app secret stored in plaintext")
}
plain, err := store.DecryptSecret(cfg.AppSecret)
if err != nil || plain != "feishu-private-value" {
t.Fatal("app secret not recoverable")
}
var saved map[string]any
if json.Unmarshal(resp.Body.Bytes(), &saved) != nil || saved["client_id"] == "" || saved["client_secret"] != nil {
t.Fatal("client secret must remain server-side")
}
resp = httptest.NewRecorder()
server.ServeHTTP(resp, httptest.NewRequest(http.MethodGet, "/config", nil))
if resp.Code != 200 || strings.Contains(resp.Body.String(), "feishu-private-value") || strings.Contains(resp.Body.String(), cfg.ClientSecret) {
t.Fatal("secret leaked from status")
}
}