mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-28 19:41:17 +00:00
161 lines
5.2 KiB
Go
161 lines
5.2 KiB
Go
package api
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"runtime"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestRouterFrontendRouteInventory(t *testing.T) {
|
|
block := extractRouterBlock(t, "isFrontendRoute :=", "isStaticAsset :=")
|
|
|
|
prefixes := matchAll(block, `!strings\.HasPrefix\(req\.URL\.Path, "([^"]+)"\)`)
|
|
exacts := matchAll(block, `req\.URL\.Path != "([^"]+)"`)
|
|
|
|
expectedPrefixes := sliceToSet(t, frontendRoutePrefixExclusionAllowlist, "frontend route prefix allowlist")
|
|
expectedExacts := sliceToSet(t, frontendRouteExactExclusionAllowlist, "frontend route exact allowlist")
|
|
|
|
actualPrefixes := sliceToSet(t, prefixes, "frontend route prefixes")
|
|
actualExacts := sliceToSet(t, exacts, "frontend route exacts")
|
|
|
|
if missing := setDifference(actualPrefixes, expectedPrefixes); len(missing) > 0 {
|
|
t.Fatalf("frontend route prefixes missing from allowlist: %s", strings.Join(sortedKeys(missing), ", "))
|
|
}
|
|
if stale := setDifference(expectedPrefixes, actualPrefixes); len(stale) > 0 {
|
|
t.Fatalf("frontend prefix allowlist contains entries not in router.go: %s", strings.Join(sortedKeys(stale), ", "))
|
|
}
|
|
if missing := setDifference(actualExacts, expectedExacts); len(missing) > 0 {
|
|
t.Fatalf("frontend exact exclusions missing from allowlist: %s", strings.Join(sortedKeys(missing), ", "))
|
|
}
|
|
if stale := setDifference(expectedExacts, actualExacts); len(stale) > 0 {
|
|
t.Fatalf("frontend exact allowlist contains entries not in router.go: %s", strings.Join(sortedKeys(stale), ", "))
|
|
}
|
|
}
|
|
|
|
func TestRouterStaticAssetInventory(t *testing.T) {
|
|
block := extractRouterBlock(t, "isStaticAsset :=", "isPublic :=")
|
|
|
|
prefixes := matchAll(block, `strings\.HasPrefix\(req\.URL\.Path, "([^"]+)"\)`)
|
|
suffixes := matchAll(block, `strings\.HasSuffix\(req\.URL\.Path, "([^"]+)"\)`)
|
|
exacts := matchAll(block, `req\.URL\.Path == "([^"]+)"`)
|
|
|
|
expectedPrefixes := sliceToSet(t, staticAssetPrefixAllowlist, "static asset prefix allowlist")
|
|
expectedSuffixes := sliceToSet(t, staticAssetSuffixAllowlist, "static asset suffix allowlist")
|
|
expectedExacts := sliceToSet(t, staticAssetExactAllowlist, "static asset exact allowlist")
|
|
|
|
actualPrefixes := sliceToSet(t, prefixes, "static asset prefixes")
|
|
actualSuffixes := sliceToSet(t, suffixes, "static asset suffixes")
|
|
actualExacts := sliceToSet(t, exacts, "static asset exacts")
|
|
|
|
if missing := setDifference(actualPrefixes, expectedPrefixes); len(missing) > 0 {
|
|
t.Fatalf("static asset prefixes missing from allowlist: %s", strings.Join(sortedKeys(missing), ", "))
|
|
}
|
|
if stale := setDifference(expectedPrefixes, actualPrefixes); len(stale) > 0 {
|
|
t.Fatalf("static asset prefix allowlist contains entries not in router.go: %s", strings.Join(sortedKeys(stale), ", "))
|
|
}
|
|
if missing := setDifference(actualSuffixes, expectedSuffixes); len(missing) > 0 {
|
|
t.Fatalf("static asset suffixes missing from allowlist: %s", strings.Join(sortedKeys(missing), ", "))
|
|
}
|
|
if stale := setDifference(expectedSuffixes, actualSuffixes); len(stale) > 0 {
|
|
t.Fatalf("static asset suffix allowlist contains entries not in router.go: %s", strings.Join(sortedKeys(stale), ", "))
|
|
}
|
|
if missing := setDifference(actualExacts, expectedExacts); len(missing) > 0 {
|
|
t.Fatalf("static asset exacts missing from allowlist: %s", strings.Join(sortedKeys(missing), ", "))
|
|
}
|
|
if stale := setDifference(expectedExacts, actualExacts); len(stale) > 0 {
|
|
t.Fatalf("static asset exact allowlist contains entries not in router.go: %s", strings.Join(sortedKeys(stale), ", "))
|
|
}
|
|
}
|
|
|
|
func extractRouterBlock(t *testing.T, startMarker, endMarker string) string {
|
|
t.Helper()
|
|
|
|
_, file, _, ok := runtime.Caller(0)
|
|
if !ok {
|
|
t.Fatalf("failed to locate test file path")
|
|
}
|
|
routerPath := filepath.Join(filepath.Dir(file), "router.go")
|
|
data, err := os.ReadFile(routerPath)
|
|
if err != nil {
|
|
t.Fatalf("read router.go: %v", err)
|
|
}
|
|
|
|
src := string(data)
|
|
start := strings.Index(src, startMarker)
|
|
if start == -1 {
|
|
t.Fatalf("marker %q not found in router.go", startMarker)
|
|
}
|
|
end := strings.Index(src[start:], endMarker)
|
|
if end == -1 {
|
|
t.Fatalf("marker %q not found after %q in router.go", endMarker, startMarker)
|
|
}
|
|
return src[start : start+end]
|
|
}
|
|
|
|
func matchAll(block, pattern string) []string {
|
|
re := regexp.MustCompile(pattern)
|
|
matches := re.FindAllStringSubmatch(block, -1)
|
|
if len(matches) == 0 {
|
|
return nil
|
|
}
|
|
seen := map[string]struct{}{}
|
|
values := make([]string, 0, len(matches))
|
|
for _, match := range matches {
|
|
value := match[1]
|
|
if _, ok := seen[value]; ok {
|
|
continue
|
|
}
|
|
seen[value] = struct{}{}
|
|
values = append(values, value)
|
|
}
|
|
sort.Strings(values)
|
|
return values
|
|
}
|
|
|
|
var frontendRoutePrefixExclusionAllowlist = []string{
|
|
"/api/",
|
|
"/ws",
|
|
"/socket.io/",
|
|
"/download/",
|
|
}
|
|
|
|
var frontendRouteExactExclusionAllowlist = []string{
|
|
"/simple-stats",
|
|
"/install-docker-agent.sh",
|
|
"/install-container-agent.sh",
|
|
"/install-host-agent.sh",
|
|
"/install-host-agent.ps1",
|
|
"/uninstall-host-agent.sh",
|
|
"/uninstall-host-agent.ps1",
|
|
"/install.sh",
|
|
"/install.ps1",
|
|
}
|
|
|
|
var staticAssetPrefixAllowlist = []string{
|
|
"/assets/",
|
|
"/@vite/",
|
|
"/@solid-refresh",
|
|
"/src/",
|
|
"/node_modules/",
|
|
}
|
|
|
|
var staticAssetSuffixAllowlist = []string{
|
|
".js",
|
|
".css",
|
|
".map",
|
|
".ts",
|
|
".tsx",
|
|
".mjs",
|
|
".jsx",
|
|
}
|
|
|
|
var staticAssetExactAllowlist = []string{
|
|
"/",
|
|
"/index.html",
|
|
"/favicon.ico",
|
|
"/logo.svg",
|
|
}
|