Skip to content

Commit 1807d2b

Browse files
committed
cleanup roles and flow
1 parent ecc2aff commit 1807d2b

File tree

5 files changed

+215
-8
lines changed

5 files changed

+215
-8
lines changed

launchql.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"anonymous": "anon",
88
"authenticated": "authenticated",
99
"administrator": "service_role",
10-
"default": "anonymous"
10+
"default": "anon"
1111
}
1212
}
1313
}

packages/rls-demo/__tests__/rls.demo.test.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,39 @@ describe('RLS Demo - Data Insertion', () => {
3838
);
3939

4040
// Insert products
41-
const product1 = await pg.one(
41+
db.setContext({
42+
role: 'authenticated',
43+
'jwt.claims.user_id': user1.id
44+
});
45+
46+
const product1 = await db.one(
4247
`INSERT INTO rls_test.products (name, description, price, owner_id)
4348
VALUES ($1, $2, $3, $4)
4449
RETURNING id, name, price, owner_id`,
4550
['Laptop Pro', 'High-performance laptop', 1299.99, user1.id]
4651
);
4752

48-
const product2 = await pg.one(
53+
db.setContext({
54+
role: 'authenticated',
55+
'jwt.claims.user_id': user2.id
56+
});
57+
58+
const product2 = await db.one(
4959
`INSERT INTO rls_test.products (name, description, price, owner_id)
5060
VALUES ($1, $2, $3, $4)
5161
RETURNING id, name, price, owner_id`,
52-
['Wireless Mouse', 'Ergonomic mouse', 49.99, user1.id]
62+
['Wireless Mouse', 'Ergonomic mouse', 49.99, user2.id]
5363
);
5464

5565
expect(user1.email).toBe('[email protected]');
5666
expect(product1.name).toBe('Laptop Pro');
5767
expect(product1.owner_id).toEqual(user1.id);
68+
expect(product2.owner_id).toEqual(user2.id);
69+
expect(product2.name).toBe('Wireless Mouse');
5870
});
5971

6072
it('should query user products with joins', async () => {
61-
const result = await pg.many(
73+
const result = await db.many(
6274
`SELECT u.name, p.name as product_name, p.price
6375
FROM rls_test.users u
6476
JOIN rls_test.products p ON u.id = p.owner_id
@@ -72,7 +84,7 @@ describe('RLS Demo - Data Insertion', () => {
7284

7385
it('should test RLS context switching', async () => {
7486
// Get a user ID for context
75-
const user = await pg.one(`SELECT id FROM rls_test.users LIMIT 1`);
87+
const user = await db.one(`SELECT id FROM rls_test.users LIMIT 1`);
7688

7789
// Set context to simulate authenticated user with JWT claims
7890
db.setContext({
@@ -99,7 +111,7 @@ describe('RLS Demo - Data Insertion', () => {
99111

100112
it('should fail RLS when trying to access other user\'s data', async () => {
101113
// Get two different users
102-
const users = await pg.many(`SELECT id FROM rls_test.users ORDER BY email LIMIT 2`);
114+
const users = await db.many(`SELECT id FROM rls_test.users ORDER BY email LIMIT 2`);
103115
expect(users.length).toBeGreaterThanOrEqual(2);
104116

105117
const user1 = users[0];
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { getConnections, PgTestClient } from 'pgsql-test';
2+
3+
let db: PgTestClient;
4+
let pg: PgTestClient;
5+
let teardown: () => Promise<void>;
6+
7+
beforeAll(async () => {
8+
({ db, pg, teardown } = await getConnections());
9+
});
10+
11+
afterAll(async () => {
12+
await teardown();
13+
});
14+
15+
beforeEach(async () => {
16+
await db.beforeEach();
17+
});
18+
19+
afterEach(async () => {
20+
await db.afterEach();
21+
});
22+
23+
const user_id_1 = '550e8400-e29b-41d4-a716-446655440001';
24+
const user_id_2 = '550e8400-e29b-41d4-a716-446655440002';
25+
26+
describe('RLS Demo - Data Insertion', () => {
27+
it('should insert users and products', async () => {
28+
29+
// Insert users
30+
await db.any(
31+
`INSERT INTO rls_test.users (id, email, name)
32+
VALUES ($1, $2, $3)`,
33+
[user_id_1, '[email protected]', 'Alice Johnson']
34+
);
35+
36+
await db.any(
37+
`INSERT INTO rls_test.users (id, email, name)
38+
VALUES ($1, $2, $3)`,
39+
[user_id_2, '[email protected]', 'Bob Smith']
40+
);
41+
42+
// Insert products
43+
db.setContext({
44+
role: 'authenticated',
45+
'jwt.claims.user_id': user_id_1
46+
});
47+
48+
const product1 = await db.one(
49+
`INSERT INTO rls_test.products (name, description, price, owner_id)
50+
VALUES ($1, $2, $3, $4)
51+
RETURNING id, name, price, owner_id`,
52+
['Laptop Pro', 'High-performance laptop', 1299.99, user_id_1]
53+
);
54+
55+
db.setContext({
56+
role: 'authenticated',
57+
'jwt.claims.user_id': user_id_2
58+
});
59+
60+
const product2 = await db.one(
61+
`INSERT INTO rls_test.products (name, description, price, owner_id)
62+
VALUES ($1, $2, $3, $4)
63+
RETURNING id, name, price, owner_id`,
64+
['Wireless Mouse', 'Ergonomic mouse', 49.99, user_id_2]
65+
);
66+
67+
expect(product1.name).toBe('Laptop Pro');
68+
expect(product1.owner_id).toEqual(user_id_1);
69+
expect(product2.owner_id).toEqual(user_id_2);
70+
expect(product2.name).toBe('Wireless Mouse');
71+
});
72+
73+
it('should rollback to initial state', async () => {
74+
db.setContext({
75+
role: 'service_role'
76+
});
77+
78+
const result = await db.any(
79+
`SELECT u.name, p.name as product_name, p.price
80+
FROM rls_test.users u
81+
JOIN rls_test.products p ON u.id = p.owner_id
82+
ORDER BY u.name, p.name`
83+
);
84+
expect(result.length).toEqual(0);
85+
});
86+
});
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { getConnections, PgTestClient } from 'pgsql-test';
2+
3+
let db: PgTestClient;
4+
let teardown: () => Promise<void>;
5+
6+
beforeAll(async () => {
7+
({ db, teardown } = await getConnections());
8+
});
9+
10+
afterAll(async () => {
11+
await teardown();
12+
});
13+
14+
beforeEach(async () => {
15+
await db.beforeEach();
16+
});
17+
18+
afterEach(async () => {
19+
await db.afterEach();
20+
});
21+
22+
describe('RLS Demo - Data Insertion', () => {
23+
it('should insert users and products', async () => {
24+
25+
db.setContext({
26+
role: 'service_role',
27+
});
28+
29+
// Insert users
30+
const user1 = await db.one(
31+
`INSERT INTO rls_test.users (email, name)
32+
VALUES ($1, $2)
33+
RETURNING id, email, name`,
34+
['[email protected]', 'Alice Johnson']
35+
);
36+
37+
const user2 = await db.one(
38+
`INSERT INTO rls_test.users (email, name)
39+
VALUES ($1, $2)
40+
RETURNING id, email, name`,
41+
['[email protected]', 'Bob Smith']
42+
);
43+
44+
// Insert products
45+
db.setContext({
46+
role: 'authenticated',
47+
'jwt.claims.user_id': user1.id
48+
});
49+
50+
const product1 = await db.one(
51+
`INSERT INTO rls_test.products (name, description, price, owner_id)
52+
VALUES ($1, $2, $3, $4)
53+
RETURNING id, name, price, owner_id`,
54+
['Laptop Pro', 'High-performance laptop', 1299.99, user1.id]
55+
);
56+
57+
db.setContext({
58+
role: 'authenticated',
59+
'jwt.claims.user_id': user2.id
60+
});
61+
62+
const product2 = await db.one(
63+
`INSERT INTO rls_test.products (name, description, price, owner_id)
64+
VALUES ($1, $2, $3, $4)
65+
RETURNING id, name, price, owner_id`,
66+
['Wireless Mouse', 'Ergonomic mouse', 49.99, user2.id]
67+
);
68+
69+
expect(user1.email).toBe('[email protected]');
70+
expect(product1.name).toBe('Laptop Pro');
71+
expect(product1.owner_id).toEqual(user1.id);
72+
expect(product2.owner_id).toEqual(user2.id);
73+
expect(product2.name).toBe('Wireless Mouse');
74+
});
75+
76+
it('should rollback to initial state', async () => {
77+
db.setContext({
78+
role: 'service_role'
79+
});
80+
81+
const result = await db.any(
82+
`SELECT u.name, p.name as product_name, p.price
83+
FROM rls_test.users u
84+
JOIN rls_test.products p ON u.id = p.owner_id
85+
ORDER BY u.name, p.name`
86+
);
87+
expect(result.length).toEqual(0);
88+
});
89+
});

packages/rls-demo/deploy/rls-demo.sql

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ GRANT USAGE ON SCHEMA auth TO public;
3333
GRANT EXECUTE ON FUNCTION auth.uid() TO public;
3434
GRANT EXECUTE ON FUNCTION auth.role() TO public;
3535

36+
37+
38+
39+
40+
41+
42+
43+
44+
45+
46+
47+
48+
49+
50+
51+
3652
-- Create rls_test schema
3753
CREATE SCHEMA IF NOT EXISTS rls_test;
3854

@@ -71,7 +87,7 @@ CREATE POLICY "Users can update own data" ON rls_test.users
7187

7288
-- Users can insert their own data
7389
CREATE POLICY "Users can insert own data" ON rls_test.users
74-
FOR INSERT WITH CHECK (auth.uid() = id);
90+
FOR INSERT WITH CHECK (true);
7591

7692
-- Users can delete their own data
7793
CREATE POLICY "Users can delete own data" ON rls_test.users
@@ -94,6 +110,10 @@ CREATE POLICY "Users can update own products" ON rls_test.products
94110
CREATE POLICY "Users can delete own products" ON rls_test.products
95111
FOR DELETE USING (auth.uid() = owner_id);
96112

113+
-- Grant permissions to anon users
114+
GRANT USAGE ON SCHEMA rls_test TO anon;
115+
GRANT ALL ON rls_test.users TO anon;
116+
97117
-- Grant permissions to authenticated users
98118
GRANT USAGE ON SCHEMA rls_test TO authenticated;
99119
GRANT ALL ON rls_test.users TO authenticated;

0 commit comments

Comments
 (0)