fix(geoip): ограничить изменение баз правами записи трафика
This commit is contained in:
1 parent
65aeedd3b0
commit
f0d9f488e6
6 files changed
+46
-3
No files matched your search
@@ -28,7 +28,7 @@
|
||||
"test:backups": "tsx src/services/backup-scheduler-run.test.ts && tsx src/services/backup-restore.test.ts && tsx src/services/backup-deletion.test.ts && tsx src/services/backup-dto.test.ts && tsx src/services/backup-storage-update.test.ts && tsx src/services/backup-job-execution.test.ts && tsx src/routes/backups-operations.test.ts && tsx src/services/s3-backup-client.test.ts",
|
||||
"test:live-maps": "tsx src/services/ospf-route-parse.test.ts && tsx src/services/vxlan-live.test.ts && tsx src/services/containers-live.test.ts && tsx src/services/firewall-poll.test.ts && tsx src/services/gre-catalog-poll.test.ts && tsx src/routes/filters-gre-catalog.test.ts && tsx src/routes/bgp-catalog.test.ts && tsx src/services/bgp-catalog-parse.test.ts && tsx src/routes/ospf-catalog.test.ts && tsx src/services/ospf-observed-values.test.ts",
|
||||
"test": "npm run test:probes && npm run test:exec && npm run test:alert-engine && npm run test:auth && npm run test:wireguard && npm run test:traffic-rate && npm run test:traffic-flow && npm run test:users && npm run test:pg && npm run test:backups && npm run test:scheduler && npm run test:live-maps && npm run test:ospf-optimizer && npm run test:recursive-routes && npm run test:config-sync && npm run test:ros-file && npm run test:containers && npm run test:certificates",
|
||||
"test:geoip": "tsx src/services/traffic-flow-geoip.test.ts",
|
||||
"test:geoip": "tsx src/services/traffic-flow-geoip.test.ts && tsx src/plugins/auth.geoip.test.ts",
|
||||
"test:ospf-optimizer": "tsx src/services/ospf-optimizer-identity.test.ts && tsx src/services/ospf-optimizer-metrics.test.ts && tsx src/services/ospf-optimizer-plan.test.ts && tsx src/routes/ospf-optimizer.test.ts",
|
||||
"test:containers": "tsx src/services/containers-state.test.ts && tsx src/routes/containers-state.test.ts",
|
||||
"test:certificates": "tsx src/services/certificate-issue-execution.test.ts && tsx src/services/certificate-issue-request.test.ts && tsx src/routes/certificates-issue.test.ts && tsx src/services/certificate-issue-dto.test.ts && tsx src/services/certificate-parse.test.ts && tsx src/services/certificates-state.test.ts && tsx src/routes/certificates-state.test.ts"
|
||||
|
||||
@@ -42,6 +42,8 @@ type Rule = {
|
||||
}
|
||||
|
||||
const RULES: Rule[] = [
|
||||
{ methods: ["GET"], match: path => path === "/api/geoip", permission: "mm:traffic:read" },
|
||||
{ methods: ["PUT", "POST"], match: path => path === "/api/geoip" || path === "/api/geoip/update", permission: "mm:traffic:write" },
|
||||
{
|
||||
methods: ["GET"],
|
||||
match: p => /^\/api\/servers\/\d+\/ospf(?:\/|$)/.test(p),
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import assert from "node:assert/strict"
|
||||
import Fastify from "fastify"
|
||||
import { SignJWT } from "jose"
|
||||
process.env.AUTH_REQUIRED = "true"
|
||||
process.env.AUTH_JWT_SECRET = "geoip-test-secret"
|
||||
process.env.AUTH_ISSUER = "https://auth.test.local"
|
||||
process.env.NODE_ENV = "test"
|
||||
const { default: authPlugin, requireAuth } = await import("./auth.js")
|
||||
const { permissionForRequest } = await import("../lib/permissions.js")
|
||||
assert.equal(permissionForRequest("GET", "/api/geoip"), "mm:traffic:read")
|
||||
assert.equal(permissionForRequest("PUT", "/api/geoip"), "mm:traffic:write")
|
||||
assert.equal(permissionForRequest("POST", "/api/geoip/update?force=true"), "mm:traffic:write")
|
||||
const app = Fastify(); await app.register(authPlugin); app.addHook("preHandler", requireAuth)
|
||||
let applied = 0
|
||||
app.get("/api/geoip", async () => ({ known: true }))
|
||||
app.put("/api/geoip", async () => { applied++; return { ok: true } })
|
||||
app.post("/api/geoip/update", async () => { applied++; return { ok: true } })
|
||||
for (const permission of ["mm:dashboard:read", "mm:traffic:read", "mm:traffic:write", "mm:traffic:admin", "mm:settings:admin"]) {
|
||||
const token = await new SignJWT({ sub: "fixture", apps: ["mm"], permissions: [permission] }).setProtectedHeader({ alg: "HS256" }).setIssuer("https://auth.test.local").setExpirationTime("1h").sign(new TextEncoder().encode("geoip-test-secret"))
|
||||
for (const [method, url] of [["GET", "/api/geoip"], ["PUT", "/api/geoip"], ["POST", "/api/geoip/update"]] as const) {
|
||||
const before = applied; const response = await app.inject({ method, url, headers: { authorization: "Bearer " + token } })
|
||||
const allowed = permission === "mm:traffic:write" || permission === "mm:traffic:admin" || (method === "GET" && permission === "mm:traffic:read")
|
||||
assert.equal(response.statusCode, allowed ? 200 : 403); assert.equal(applied, before + (allowed && method !== "GET" ? 1 : 0))
|
||||
}
|
||||
}
|
||||
assert.equal((await app.inject({ method: "POST", url: "/api/geoip/update" })).statusCode, 401)
|
||||
await app.close(); console.log("GeoIP JWT gate: reader cannot mutate, writer/admin authorized before handler")
|
||||
Reference in new issue
Block a user