Skip to content

Commit dee8a93

Browse files
committed
feat(policies): allow include/exclude schema(s)
1 parent 6d090b6 commit dee8a93

File tree

3 files changed

+56
-2
lines changed

3 files changed

+56
-2
lines changed

src/lib/PostgresMetaPolicies.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,33 @@ export default class PostgresMetaPolicies {
1212

1313
async list({
1414
includeSystemSchemas = false,
15+
includedSchemas,
16+
excludedSchemas,
1517
limit,
1618
offset,
1719
}: {
1820
includeSystemSchemas?: boolean
21+
includedSchemas?: string[]
22+
excludedSchemas?: string[]
1923
limit?: number
2024
offset?: number
2125
} = {}): Promise<PostgresMetaResult<PostgresPolicy[]>> {
2226
let sql = policiesSql
23-
if (!includeSystemSchemas) {
27+
28+
if (includedSchemas?.length) {
29+
sql = `${sql} WHERE (n.nspname IN (${includedSchemas.map(literal).join(',')}))`
30+
} else if (!includeSystemSchemas) {
2431
sql = `${sql} WHERE NOT (n.nspname IN (${DEFAULT_SYSTEM_SCHEMAS.map(literal).join(',')}))`
2532
}
33+
34+
if (excludedSchemas?.length) {
35+
if (includedSchemas?.length || !includeSystemSchemas) {
36+
sql = `${sql} AND NOT (n.nspname IN (${excludedSchemas.map(literal).join(',')}))`
37+
} else {
38+
sql = `${sql} WHERE NOT (n.nspname IN (${excludedSchemas.map(literal).join(',')}))`
39+
}
40+
}
41+
2642
if (limit) {
2743
sql = `${sql} LIMIT ${limit}`
2844
}

src/server/routes/policies.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,22 @@ export default async (fastify: FastifyInstance) => {
88
Headers: { pg: string }
99
Querystring: {
1010
include_system_schemas?: string
11+
// Note: this only supports comma separated values (e.g., ".../policies?included_schemas=public,core")
12+
included_schemas?: string
13+
excluded_schemas?: string
1114
limit?: number
1215
offset?: number
1316
}
1417
}>('/', async (request, reply) => {
1518
const connectionString = request.headers.pg
1619
const includeSystemSchemas = request.query.include_system_schemas === 'true'
20+
const includedSchemas = request.query.included_schemas?.split(',')
21+
const excludedSchemas = request.query.excluded_schemas?.split(',')
1722
const limit = request.query.limit
1823
const offset = request.query.offset
1924

2025
const pgMeta = new PostgresMeta({ ...DEFAULT_POOL_CONFIG, connectionString })
21-
const { data, error } = await pgMeta.policies.list({ includeSystemSchemas, limit, offset })
26+
const { data, error } = await pgMeta.policies.list({ includeSystemSchemas, includedSchemas, excludedSchemas, limit, offset })
2227
await pgMeta.end()
2328
if (error) {
2429
request.log.error({ error, request: extractRequestForLogging(request) })

test/lib/policies.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,39 @@ test('list', async () => {
2323
)
2424
})
2525

26+
test('list policies with included schemas', async () => {
27+
let res = await pgMeta.policies.list({
28+
includedSchemas: ['public'],
29+
})
30+
31+
expect(res.data?.length).toBeGreaterThan(0)
32+
33+
res.data?.forEach((policy) => {
34+
expect(policy.schema).toBe('public')
35+
})
36+
})
37+
38+
test('list policies with excluded schemas', async () => {
39+
let res = await pgMeta.policies.list({
40+
excludedSchemas: ['public'],
41+
})
42+
43+
res.data?.forEach((policy) => {
44+
expect(policy.schema).not.toBe('public')
45+
})
46+
})
47+
48+
test('list policies with excluded schemas and include System Schemas', async () => {
49+
let res = await pgMeta.policies.list({
50+
excludedSchemas: ['public'],
51+
includeSystemSchemas: true,
52+
})
53+
54+
res.data?.forEach((policy) => {
55+
expect(policy.schema).not.toBe('public')
56+
})
57+
})
58+
2659
test('retrieve, create, update, delete', async () => {
2760
let res = await pgMeta.policies.create({
2861
name: 'test policy',

0 commit comments

Comments
 (0)