Skip to content

Commit eba1b9d

Browse files
committed
feat: adds policies to each table
This change adds a new array of policies to each table. The policies are used for Row Level Security
1 parent b79a4d4 commit eba1b9d

File tree

5 files changed

+29
-14
lines changed

5 files changed

+29
-14
lines changed

src/api/tables.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Router } from 'express'
22

33
import sql = require('../lib/sql')
4-
const { columns, grants, primary_keys, relationships, tables } = sql
4+
const { columns, grants, policies, primary_keys, relationships, tables } = sql
55
import { coalesceRowsToArray, formatColumns } from '../lib/helpers'
66
import { RunQuery } from '../lib/connectionPool'
77
import { DEFAULT_SYSTEM_SCHEMAS } from '../lib/constants'
@@ -15,11 +15,13 @@ WITH tables AS ( ${tables} ),
1515
columns AS ( ${columns} ),
1616
grants AS ( ${grants} ),
1717
primary_keys AS ( ${primary_keys} ),
18+
policies AS ( ${policies} ),
1819
relationships AS ( ${relationships} )
1920
SELECT
2021
*,
2122
${coalesceRowsToArray('columns', 'SELECT * FROM columns WHERE columns.table_id = tables.id')},
2223
${coalesceRowsToArray('grants', 'SELECT * FROM grants WHERE grants.table_id = tables.id')},
24+
${coalesceRowsToArray('policies', 'SELECT * FROM policies WHERE policies.table_id = tables.id')},
2325
${coalesceRowsToArray(
2426
'primary_keys',
2527
'SELECT * FROM primary_keys WHERE primary_keys.table_id = tables.id'

src/lib/sql/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export = {
66
config: fs.readFileSync(path.join(__dirname, '/config.sql')).toString(),
77
constraints: fs.readFileSync(path.join(__dirname, '/constraints.sql')).toString(),
88
extensions: fs.readFileSync(path.join(__dirname, '/extensions.sql')).toString(),
9+
functions: fs.readFileSync(path.join(__dirname, '/functions.sql')).toString(),
910
grants: fs.readFileSync(path.join(__dirname, '/grants.sql')).toString(),
1011
joins: fs.readFileSync(path.join(__dirname, '/joins.sql')).toString(),
1112
primary_keys: fs.readFileSync(path.join(__dirname, '/primary_keys.sql')).toString(),

src/lib/sql/policies.sql

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
SELECT
2-
n.nspname AS schemaname,
3-
c.relname AS tablename,
4-
pol.polname AS policyname,
1+
select
2+
n.oid as id,
3+
n.nspname AS schema,
4+
c.relname AS table,
5+
c.oid AS table_id,
6+
pol.polname AS name,
57
CASE
68
WHEN pol.polpermissive THEN 'PERMISSIVE' :: text
79
ELSE 'RESTRICTIVE' :: text
810
END AS permissive,
911
CASE
10-
WHEN pol.polroles = '{0}' :: oid [] THEN string_to_array('public' :: text, '' :: text) :: name []
11-
ELSE ARRAY(
12+
WHEN pol.polroles = '{0}' :: oid []
13+
THEN array_to_json(string_to_array('public' :: text, '' :: text) :: name [])
14+
ELSE array_to_json(ARRAY(
1215
SELECT
1316
pg_authid.rolname
1417
FROM
@@ -17,7 +20,7 @@ SELECT
1720
pg_authid.oid = ANY (pol.polroles)
1821
ORDER BY
1922
pg_authid.rolname
20-
)
23+
))
2124
END AS roles,
2225
CASE
2326
pol.polcmd
@@ -33,4 +36,4 @@ SELECT
3336
FROM
3437
pg_policy pol
3538
JOIN pg_class c ON c.oid = pol.polrelid
36-
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
39+
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace

test/integration/index.spec.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ describe('/tables', async () => {
141141
assert.equal(true, !!datum)
142142
assert.equal(true, !notIncluded)
143143
})
144-
it('should return the columns', async () => {
144+
it('should return the columns, grants, and policies', async () => {
145145
const tables = await axios.get(`${URL}/tables`)
146146
const datum = tables.data.find((x) => `${x.schema}.${x.name}` === 'public.users')
147147
const idColumn = datum.columns.find((x) => x.name === 'id')
@@ -152,11 +152,8 @@ describe('/tables', async () => {
152152
assert.equal(idColumn.is_updatable, true)
153153
assert.equal(idColumn.is_identity, true)
154154
assert.equal(nameColumn.is_identity, false)
155-
})
156-
it('should return the grants', async () => {
157-
const tables = await axios.get(`${URL}/tables`)
158-
const datum = tables.data.find((x) => `${x.schema}.${x.name}` === 'public.users')
159155
assert.equal(datum.grants.length > 0, true)
156+
assert.equal(datum.policies.length == 0, true)
160157
})
161158
it('should return the relationships', async () => {
162159
const tables = await axios.get(`${URL}/tables`)

test/postgres/mnt/01-memes.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
1+
2+
13
CREATE TABLE public.category (
24
id serial NOT NULL PRIMARY KEY,
35
name text NOT NULL
46
);
57

8+
-- Fake policies
9+
grant select, update(name)
10+
on category
11+
to postgres;
12+
13+
create policy categories_update_policy
14+
on category for update
15+
to postgres
16+
using(current_setting('my.username') IN (name));
17+
618
INSERT INTO public.category (id, name) VALUES
719
(1, 'Funny'),
820
(2, 'Weird'),

0 commit comments

Comments
 (0)