Skip to content

Commit 404d104

Browse files
kangmingtaysamrose
andauthored
fix: update pgbouncer.get_auth (INFRA-1530) (#1554)
* fix: update pgbouncer.get_auth * chore: add tests for pgbouncer * chore: add pgbouncer test for role privileges * chore: fix pgbouncer tests * chore: include test for pgbouncer schema * chore: remove unnecessary comment * test: update schema files used for testing (#1559) --------- Co-authored-by: samrose <samuel@supabase.io>
1 parent dd2363e commit 404d104

File tree

7 files changed

+191
-27
lines changed

7 files changed

+191
-27
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
-- migrate:up
2+
3+
create or replace function pgbouncer.get_auth(p_usename text) returns table (username text, password text)
4+
language plpgsql security definer
5+
as $$
6+
begin
7+
raise debug 'PgBouncer auth request: %', p_usename;
8+
9+
return query
10+
select
11+
rolname::text,
12+
case when rolvaliduntil < now()
13+
then null
14+
else rolpassword::text
15+
end
16+
from pg_authid
17+
where rolname=$1 and rolcanlogin;
18+
end;
19+
$$;
20+
21+
-- from migrations/db/migrations/20250312095419_pgbouncer_ownership.sql
22+
grant execute on function pgbouncer.get_auth(p_usename text) to postgres;
23+
24+
-- migrate:down

migrations/schema-15.sql

+15-9
Original file line numberDiff line numberDiff line change
@@ -483,15 +483,21 @@ COMMENT ON FUNCTION extensions.set_graphql_placeholder() IS 'Reintroduces placeh
483483

484484
CREATE FUNCTION pgbouncer.get_auth(p_usename text) RETURNS TABLE(username text, password text)
485485
LANGUAGE plpgsql SECURITY DEFINER
486-
AS $$
487-
BEGIN
488-
RAISE WARNING 'PgBouncer auth request: %', p_usename;
489-
490-
RETURN QUERY
491-
SELECT usename::TEXT, passwd::TEXT FROM pg_catalog.pg_shadow
492-
WHERE usename = p_usename;
493-
END;
494-
$$;
486+
AS $_$
487+
begin
488+
raise debug 'PgBouncer auth request: %', p_usename;
489+
490+
return query
491+
select
492+
rolname::text,
493+
case when rolvaliduntil < now()
494+
then null
495+
else rolpassword::text
496+
end
497+
from pg_authid
498+
where rolname=$1 and rolcanlogin;
499+
end;
500+
$_$;
495501

496502

497503
--

migrations/schema-17.sql

+15-9
Original file line numberDiff line numberDiff line change
@@ -470,15 +470,21 @@ COMMENT ON FUNCTION extensions.set_graphql_placeholder() IS 'Reintroduces placeh
470470

471471
CREATE FUNCTION pgbouncer.get_auth(p_usename text) RETURNS TABLE(username text, password text)
472472
LANGUAGE plpgsql SECURITY DEFINER
473-
AS $$
474-
BEGIN
475-
RAISE WARNING 'PgBouncer auth request: %', p_usename;
476-
477-
RETURN QUERY
478-
SELECT usename::TEXT, passwd::TEXT FROM pg_catalog.pg_shadow
479-
WHERE usename = p_usename;
480-
END;
481-
$$;
473+
AS $_$
474+
begin
475+
raise debug 'PgBouncer auth request: %', p_usename;
476+
477+
return query
478+
select
479+
rolname::text,
480+
case when rolvaliduntil < now()
481+
then null
482+
else rolpassword::text
483+
end
484+
from pg_authid
485+
where rolname=$1 and rolcanlogin;
486+
end;
487+
$_$;
482488

483489

484490
--

migrations/schema-orioledb-17.sql

+15-9
Original file line numberDiff line numberDiff line change
@@ -484,15 +484,21 @@ COMMENT ON FUNCTION extensions.set_graphql_placeholder() IS 'Reintroduces placeh
484484

485485
CREATE FUNCTION pgbouncer.get_auth(p_usename text) RETURNS TABLE(username text, password text)
486486
LANGUAGE plpgsql SECURITY DEFINER
487-
AS $$
488-
BEGIN
489-
RAISE WARNING 'PgBouncer auth request: %', p_usename;
490-
491-
RETURN QUERY
492-
SELECT usename::TEXT, passwd::TEXT FROM pg_catalog.pg_shadow
493-
WHERE usename = p_usename;
494-
END;
495-
$$;
487+
AS $_$
488+
begin
489+
raise debug 'PgBouncer auth request: %', p_usename;
490+
491+
return query
492+
select
493+
rolname::text,
494+
case when rolvaliduntil < now()
495+
then null
496+
else rolpassword::text
497+
end
498+
from pg_authid
499+
where rolname=$1 and rolcanlogin;
500+
end;
501+
$_$;
496502

497503

498504
--

migrations/tests/database/exists.sql

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
SELECT has_schema('public');
33
SELECT has_schema('auth');
4+
SELECT has_schema('pgbouncer');
45
SELECT has_schema('extensions');
56
SELECT has_schema('graphql');
67
SELECT has_schema('graphql_public');

nix/tests/expected/pgbouncer.out

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
-- pgbouncer schema owner
2+
select
3+
n.nspname as schema_name,
4+
r.rolname as owner
5+
from
6+
pg_namespace n
7+
join
8+
pg_roles r on n.nspowner = r.oid
9+
where
10+
n.nspname = 'pgbouncer';
11+
schema_name | owner
12+
-------------+-----------
13+
pgbouncer | pgbouncer
14+
(1 row)
15+
16+
-- pgbouncer schema functions with owners
17+
select
18+
n.nspname as schema_name,
19+
p.proname as function_name,
20+
r.rolname as owner
21+
from
22+
pg_proc p
23+
join
24+
pg_namespace n on p.pronamespace = n.oid
25+
join
26+
pg_roles r on p.proowner = r.oid
27+
where
28+
n.nspname = 'pgbouncer'
29+
order by
30+
p.proname;
31+
schema_name | function_name | owner
32+
-------------+---------------+----------------
33+
pgbouncer | get_auth | supabase_admin
34+
(1 row)
35+
36+
-- Tests role privileges on the pgbouncer objects
37+
WITH schema_obj AS (
38+
SELECT oid, nspname
39+
FROM pg_namespace
40+
WHERE nspname = 'pgbouncer'
41+
)
42+
SELECT
43+
s.nspname AS schema,
44+
c.relname AS object_name,
45+
acl.grantee::regrole::text AS grantee,
46+
acl.privilege_type
47+
FROM pg_class c
48+
JOIN schema_obj s ON s.oid = c.relnamespace
49+
CROSS JOIN LATERAL aclexplode(c.relacl) AS acl
50+
WHERE c.relkind IN ('r', 'v', 'm', 'f', 'p')
51+
AND acl.privilege_type <> 'MAINTAIN'
52+
UNION ALL
53+
SELECT
54+
s.nspname AS schema,
55+
p.proname AS object_name,
56+
acl.grantee::regrole::text AS grantee,
57+
acl.privilege_type
58+
FROM pg_proc p
59+
JOIN schema_obj s ON s.oid = p.pronamespace
60+
CROSS JOIN LATERAL aclexplode(p.proacl) AS acl
61+
ORDER BY object_name, grantee, privilege_type;
62+
schema | object_name | grantee | privilege_type
63+
-----------+-------------+----------------+----------------
64+
pgbouncer | get_auth | pgbouncer | EXECUTE
65+
pgbouncer | get_auth | postgres | EXECUTE
66+
pgbouncer | get_auth | supabase_admin | EXECUTE
67+
(3 rows)
68+

nix/tests/sql/pgbouncer.sql

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
-- pgbouncer schema owner
2+
select
3+
n.nspname as schema_name,
4+
r.rolname as owner
5+
from
6+
pg_namespace n
7+
join
8+
pg_roles r on n.nspowner = r.oid
9+
where
10+
n.nspname = 'pgbouncer';
11+
12+
-- pgbouncer schema functions with owners
13+
select
14+
n.nspname as schema_name,
15+
p.proname as function_name,
16+
r.rolname as owner
17+
from
18+
pg_proc p
19+
join
20+
pg_namespace n on p.pronamespace = n.oid
21+
join
22+
pg_roles r on p.proowner = r.oid
23+
where
24+
n.nspname = 'pgbouncer'
25+
order by
26+
p.proname;
27+
28+
-- Tests role privileges on the pgbouncer objects
29+
WITH schema_obj AS (
30+
SELECT oid, nspname
31+
FROM pg_namespace
32+
WHERE nspname = 'pgbouncer'
33+
)
34+
SELECT
35+
s.nspname AS schema,
36+
c.relname AS object_name,
37+
acl.grantee::regrole::text AS grantee,
38+
acl.privilege_type
39+
FROM pg_class c
40+
JOIN schema_obj s ON s.oid = c.relnamespace
41+
CROSS JOIN LATERAL aclexplode(c.relacl) AS acl
42+
WHERE c.relkind IN ('r', 'v', 'm', 'f', 'p')
43+
AND acl.privilege_type <> 'MAINTAIN'
44+
UNION ALL
45+
SELECT
46+
s.nspname AS schema,
47+
p.proname AS object_name,
48+
acl.grantee::regrole::text AS grantee,
49+
acl.privilege_type
50+
FROM pg_proc p
51+
JOIN schema_obj s ON s.oid = p.pronamespace
52+
CROSS JOIN LATERAL aclexplode(p.proacl) AS acl
53+
ORDER BY object_name, grantee, privilege_type;

0 commit comments

Comments
 (0)