fix(db): protege conexoes e migrations de homologacao
This commit is contained in:
1 parent
4779d6b2a3
commit
8c22597420
21 files changed
+839
-45
No files matched your search
@@ -0,0 +1,62 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createReadyDb } from "../helpers/world";
|
||||
|
||||
describe("papéis de manutenção", () => {
|
||||
it("cria web e worker sem superuser, sem bypass e sem herança", async () => {
|
||||
const db = await createReadyDb();
|
||||
const rows = await db.withService((query) =>
|
||||
query.query<{ rolname: string; rolsuper: boolean; rolbypassrls: boolean; rolinherit: boolean; rolcanlogin: boolean }>(
|
||||
`select rolname, rolsuper, rolbypassrls, rolinherit, rolcanlogin
|
||||
from pg_roles
|
||||
where rolname in ('adaptador_web', 'adaptador_worker', 'app_user')
|
||||
order by rolname`,
|
||||
),
|
||||
);
|
||||
expect(rows.map((row) => row.rolname)).toEqual(["adaptador_web", "adaptador_worker", "app_user"]);
|
||||
for (const row of rows) {
|
||||
expect(row.rolsuper, row.rolname).toBe(false);
|
||||
expect(row.rolbypassrls, row.rolname).toBe(false);
|
||||
expect(row.rolcanlogin, row.rolname).toBe(false);
|
||||
}
|
||||
expect(rows.find((row) => row.rolname === "adaptador_web")?.rolinherit).toBe(false);
|
||||
expect(rows.find((row) => row.rolname === "adaptador_worker")?.rolinherit).toBe(false);
|
||||
await db.close();
|
||||
});
|
||||
|
||||
it("impede a web e o app_user de varrer a fila, e deixa o worker só nas funções", async () => {
|
||||
const db = await createReadyDb();
|
||||
const denied = [
|
||||
`begin; set local role adaptador_web; select * from public.spreadsheet_jobs; commit;`,
|
||||
`begin; set local role app_user; select * from public.adapter_list_queued_job_ids(); commit;`,
|
||||
`begin; set local role adaptador_web; select * from public.adapter_worker_context('aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa', '11111111-1111-4111-8111-111111111111'); commit;`,
|
||||
];
|
||||
for (const statement of denied) {
|
||||
await expect(db.exec(statement)).rejects.toThrow(/permission denied/i);
|
||||
await db.exec("rollback");
|
||||
}
|
||||
await expect(
|
||||
db.exec(`begin; set local role adaptador_worker; select * from public.adapter_list_queued_job_ids(); commit;`),
|
||||
).resolves.toBeUndefined();
|
||||
const signature = await db.withService((query) =>
|
||||
query.query<{ result: string; prosecdef: boolean; proconfig: string[] | null }>(
|
||||
`select pg_get_function_result(p.oid) as result, p.prosecdef, p.proconfig
|
||||
from pg_proc p
|
||||
join pg_namespace n on n.oid = p.pronamespace
|
||||
where n.nspname = 'public' and p.proname = 'adapter_read_queued_job'`,
|
||||
),
|
||||
);
|
||||
expect(signature[0]?.prosecdef).toBe(true);
|
||||
expect(signature[0]?.proconfig?.join(" ")).toContain("search_path=pg_catalog");
|
||||
expect(signature[0]?.result).not.toMatch(/content|cells|columns_schema|storage_key/i);
|
||||
await db.close();
|
||||
});
|
||||
|
||||
it("mantém SET LOCAL ROLE dentro da transação do usuário", async () => {
|
||||
const db = await createReadyDb();
|
||||
const rows = await db.withUser("aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", (query) =>
|
||||
query.query<{ current_user: string }>(`select current_user`),
|
||||
);
|
||||
expect(rows[0]?.current_user).toBe("app_user");
|
||||
await db.close();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user