Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion test/helpers/create.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@ GRANT USAGE ON SCHEMA tap TO :test_role;
*/

CREATE SCHEMA test AUTHORIZATION :test_role;
SET ROLE = :test_role;
/*
* SET SESSION AUTHORIZATION (not SET ROLE): it changes session_user too, not
* just current_user. Permission checks for a *further* SET ROLE (like the one
* test_factory's install does, and like issue #14's bug) are based on
* session_user's superuser status, not current_user's -- so a plain SET ROLE
* here would leave that one class of check silently bypassed for the rest of
* this file, since pg_regress always connects as a superuser.
*/
SET SESSION AUTHORIZATION :test_role;
SET search_path = test, tap;

CREATE TABLE customer(
Expand Down
8 changes: 8 additions & 0 deletions test/roles.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,12 @@
-- test/install/load.sql only -- see its own comment.
\set installer_role test_factory_installer

/*
* test/sql/security.sql only -- see its own comment. Deliberately not
* test_role: that role is set up by test/helpers/create.sql for other
* files, and this one exists specifically to have no setup beyond
* Postgres' own role defaults.
*/
\set bare_role test_factory_bare_user

-- vi: expandtab ts=2 sw=2
68 changes: 68 additions & 0 deletions test/sql/security.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
\set ECHO none
\i test/helpers/setup.sql

/*
* Prove the public tf.* API needs nothing beyond what a freshly-created,
* unprivileged login role already gets by default: no owned schema, no
* explicit GRANTs, and (deliberately) no membership in test_factory__owner.
* Everything it uses here (tf/_tf schema USAGE, EXECUTE on tf.* functions,
* CREATE TEMP TABLE) comes from either Postgres' own defaults or the GRANTs
* test_factory's install script makes to PUBLIC.
*/
SET ROLE = DEFAULT;
CREATE ROLE :bare_role;
/*
* USAGE on tap is a pgtap test-harness necessity (to call lives_ok() etc.
* below), not one of the grants under test here.
*/
GRANT USAGE ON SCHEMA tap TO :bare_role;
/*
* SET SESSION AUTHORIZATION, not SET ROLE: it changes session_user too, which
* is what a further SET ROLE's permission check actually looks at. A plain
* SET ROLE here would leave this session able to SET ROLE into anything
* (including test_factory__owner below) regardless of grants, since
* pg_regress always connects as a superuser.
*/
SET SESSION AUTHORIZATION :bare_role;

CREATE TEMP TABLE widget(
widget_id serial PRIMARY KEY
, name text NOT NULL
);

SELECT lives_ok(
$lives_ok$SELECT tf.register(
'widget'
, array[
row(
'base'
, $$INSERT INTO widget VALUES (DEFAULT, 'gadget') RETURNING *$$
)::tf.test_set
]
);$lives_ok$
, 'Bare, unprivileged role can register test data with zero extra grants'
);

SELECT results_eq(
$$SELECT * FROM tf.get( NULL::widget, 'base' )$$
, $$VALUES( 1, 'gadget' )$$
, 'Bare, unprivileged role can create+fetch test data with zero extra grants'
);

SELECT results_eq(
$$SELECT * FROM tf.get( NULL::widget, 'base' )$$
, $$VALUES( 1, 'gadget' )$$
, 'Bare, unprivileged role gets the cached row on a second call'
);

-- Confirm role isolation still holds for a role that otherwise works fine
SELECT throws_ok(
$$SET ROLE test_factory__owner$$
, '42501'
, NULL
, 'Bare role cannot SET ROLE into the extension owner role'
);

ROLLBACK;

-- vi: expandtab ts=2 sw=2
Loading