chore: git cache cleanup
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/Wikid82/charon/backend/internal/models"
|
||||
"github.com/Wikid82/charon/backend/internal/services"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type wave4CaddyManager struct {
|
||||
calls int
|
||||
err error
|
||||
}
|
||||
|
||||
func (m *wave4CaddyManager) ApplyConfig(context.Context) error {
|
||||
m.calls++
|
||||
return m.err
|
||||
}
|
||||
|
||||
type wave4CacheInvalidator struct {
|
||||
calls int
|
||||
}
|
||||
|
||||
func (i *wave4CacheInvalidator) InvalidateCache() {
|
||||
i.calls++
|
||||
}
|
||||
|
||||
func registerCreatePermissionDeniedHook(t *testing.T, db *gorm.DB, name string, shouldFail func(*gorm.DB) bool) {
|
||||
t.Helper()
|
||||
require.NoError(t, db.Callback().Create().Before("gorm:create").Register(name, func(tx *gorm.DB) {
|
||||
if shouldFail(tx) {
|
||||
_ = tx.AddError(fmt.Errorf("permission denied"))
|
||||
}
|
||||
}))
|
||||
t.Cleanup(func() {
|
||||
_ = db.Callback().Create().Remove(name)
|
||||
})
|
||||
}
|
||||
|
||||
func settingKeyFromCreateCallback(tx *gorm.DB) string {
|
||||
if tx == nil || tx.Statement == nil || tx.Statement.Dest == nil {
|
||||
return ""
|
||||
}
|
||||
switch v := tx.Statement.Dest.(type) {
|
||||
case *models.Setting:
|
||||
return v.Key
|
||||
case models.Setting:
|
||||
return v.Key
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func attachDeterministicSecurityService(t *testing.T, h *SettingsHandler, db *gorm.DB) {
|
||||
t.Helper()
|
||||
|
||||
securitySvc := services.NewSecurityService(db)
|
||||
h.SecuritySvc = securitySvc
|
||||
|
||||
t.Cleanup(func() {
|
||||
securitySvc.Flush()
|
||||
securitySvc.Close()
|
||||
})
|
||||
}
|
||||
|
||||
func performUpdateSettingRequest(t *testing.T, h *SettingsHandler, payload map[string]any) *httptest.ResponseRecorder {
|
||||
t.Helper()
|
||||
g := gin.New()
|
||||
g.Use(func(c *gin.Context) {
|
||||
c.Set("role", "admin")
|
||||
c.Set("userID", uint(1))
|
||||
c.Next()
|
||||
})
|
||||
g.POST("/settings", h.UpdateSetting)
|
||||
|
||||
body, err := json.Marshal(payload)
|
||||
require.NoError(t, err)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodPost, "/settings", bytes.NewBuffer(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
g.ServeHTTP(w, req)
|
||||
return w
|
||||
}
|
||||
|
||||
func performPatchConfigRequest(t *testing.T, h *SettingsHandler, payload map[string]any) *httptest.ResponseRecorder {
|
||||
t.Helper()
|
||||
g := gin.New()
|
||||
g.Use(func(c *gin.Context) {
|
||||
c.Set("role", "admin")
|
||||
c.Set("userID", uint(1))
|
||||
c.Next()
|
||||
})
|
||||
g.PATCH("/config", h.PatchConfig)
|
||||
|
||||
body, err := json.Marshal(payload)
|
||||
require.NoError(t, err)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodPatch, "/config", bytes.NewBuffer(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
g.ServeHTTP(w, req)
|
||||
return w
|
||||
}
|
||||
|
||||
func TestSettingsHandlerWave4_UpdateSetting_ACLPathsPermissionErrors(t *testing.T) {
|
||||
t.Run("feature cerberus upsert permission denied", func(t *testing.T) {
|
||||
db := setupSettingsWave3DB(t)
|
||||
registerCreatePermissionDeniedHook(t, db, "wave4-deny-feature-cerberus", func(tx *gorm.DB) bool {
|
||||
return settingKeyFromCreateCallback(tx) == "feature.cerberus.enabled"
|
||||
})
|
||||
|
||||
h := NewSettingsHandler(db)
|
||||
attachDeterministicSecurityService(t, h, db)
|
||||
h.DataRoot = "/app/data"
|
||||
|
||||
w := performUpdateSettingRequest(t, h, map[string]any{
|
||||
"key": "security.acl.enabled",
|
||||
"value": "true",
|
||||
})
|
||||
|
||||
require.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
require.Contains(t, w.Body.String(), "permissions_write_denied")
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestSettingsHandlerWave4_PatchConfig_SecurityReloadSuccessLogsPath(t *testing.T) {
|
||||
db := setupSettingsWave3DB(t)
|
||||
mgr := &wave4CaddyManager{}
|
||||
inv := &wave4CacheInvalidator{}
|
||||
|
||||
h := NewSettingsHandlerWithDeps(db, mgr, inv, nil, "")
|
||||
w := performPatchConfigRequest(t, h, map[string]any{
|
||||
"security": map[string]any{
|
||||
"waf": map[string]any{"enabled": true},
|
||||
},
|
||||
})
|
||||
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
require.Equal(t, 1, mgr.calls)
|
||||
require.Equal(t, 1, inv.calls)
|
||||
}
|
||||
|
||||
func TestSettingsHandlerWave4_UpdateSetting_GenericSaveError(t *testing.T) {
|
||||
db := setupSettingsWave3DB(t)
|
||||
require.NoError(t, db.Callback().Create().Before("gorm:create").Register("wave4-generic-save-error", func(tx *gorm.DB) {
|
||||
if settingKeyFromCreateCallback(tx) == "security.waf.enabled" {
|
||||
_ = tx.AddError(fmt.Errorf("boom"))
|
||||
}
|
||||
}))
|
||||
t.Cleanup(func() {
|
||||
_ = db.Callback().Create().Remove("wave4-generic-save-error")
|
||||
})
|
||||
|
||||
h := NewSettingsHandler(db)
|
||||
attachDeterministicSecurityService(t, h, db)
|
||||
h.DataRoot = "/app/data"
|
||||
|
||||
w := performUpdateSettingRequest(t, h, map[string]any{
|
||||
"key": "security.waf.enabled",
|
||||
"value": "true",
|
||||
})
|
||||
|
||||
require.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
require.Contains(t, w.Body.String(), "Failed to save setting")
|
||||
}
|
||||
|
||||
func TestSettingsHandlerWave4_PatchConfig_InvalidAdminWhitelistFromSync(t *testing.T) {
|
||||
db := setupSettingsWave3DB(t)
|
||||
h := NewSettingsHandler(db)
|
||||
attachDeterministicSecurityService(t, h, db)
|
||||
h.DataRoot = "/app/data"
|
||||
|
||||
w := performPatchConfigRequest(t, h, map[string]any{
|
||||
"security": map[string]any{
|
||||
"admin_whitelist": "10.10.10.10/",
|
||||
},
|
||||
})
|
||||
|
||||
require.Equal(t, http.StatusBadRequest, w.Code)
|
||||
require.Contains(t, w.Body.String(), "Invalid admin_whitelist")
|
||||
}
|
||||
|
||||
func TestSettingsHandlerWave4_TestPublicURL_BindError(t *testing.T) {
|
||||
db := setupSettingsWave3DB(t)
|
||||
h := NewSettingsHandler(db)
|
||||
|
||||
g := gin.New()
|
||||
g.Use(func(c *gin.Context) {
|
||||
c.Set("role", "admin")
|
||||
c.Set("userID", uint(1))
|
||||
c.Next()
|
||||
})
|
||||
g.POST("/settings/test-public-url", h.TestPublicURL)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodPost, "/settings/test-public-url", bytes.NewBufferString("{"))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
g.ServeHTTP(w, req)
|
||||
|
||||
require.Equal(t, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
Reference in New Issue
Block a user