fix(api): allow serverScopedRoutes entries for routes outside /api group

TestServerScopeMapCoversEveryScopedRoute wrongly required serverScopedRoutes
to be a subset of routeScopes, which only covers the authenticated /api
group. The ESO route is registered on the root router and is exempt from
routeScopes by design, so it failed the test despite being correctly
declared. Lift the hardcoded exception in AssertScopeMapComplete into a
named routesOutsideAPIGroup set that both scopes.go and the test read.
This commit is contained in:
2026-09-09 11:32:52 +00:00
parent bfe58c4cd2
commit 52ac966cba
2 changed files with 20 additions and 5 deletions
+14 -3
View File
@@ -210,6 +210,17 @@ func RequireScopes() gin.HandlerFunc {
}
}
// routesOutsideAPIGroup lists routes matching the "/api/" path prefix that
// are nonetheless registered on the root router rather than the authenticated
// /api group, so they carry no session or API-token auth and are exempt from
// routeScopes. scopes.go and serverscope_test.go both read this set so the
// exception is stated once.
var routesOutsideAPIGroup = map[string]bool{
// The ESO endpoint keeps its own bearer scheme and is deliberately
// outside the token vocabulary.
"GET /api/secrets/:group/values": true,
}
// AssertScopeMapComplete fails boot when a registered /api route has no scope.
//
// Without it, adding a route silently makes it unreachable by every token, and
@@ -220,9 +231,9 @@ func AssertScopeMapComplete(r *gin.Engine) error {
if !strings.HasPrefix(route.Path, "/api/") {
continue
}
// The ESO endpoint keeps its own bearer scheme and is deliberately
// outside the token vocabulary.
if route.Path == "/api/secrets/:group/values" {
// Routes registered outside the authenticated /api group (their own
// bearer scheme, not the token vocabulary) are deliberately excluded.
if routesOutsideAPIGroup[route.Method+" "+route.Path] {
continue
}
if _, ok := routeScopes[route.Method+" "+route.Path]; !ok {
+6 -2
View File
@@ -13,9 +13,13 @@ func TestServerScopeMapCoversEveryScopedRoute(t *testing.T) {
}
}
for r := range serverScopedRoutes {
if _, ok := routeScopes[r]; !ok {
t.Errorf("route %q is declared in serverScopedRoutes but is not a registered route", r)
if _, ok := routeScopes[r]; ok {
continue
}
if routesOutsideAPIGroup[r] {
continue
}
t.Errorf("route %q is declared in serverScopedRoutes but is not a registered route", r)
}
}