\set show_rows 0 \unset ECHO \set QUIET 1 \pset format unaligned \pset tuples_only true \pset pager off -- This makes the test easier to implement. grant execute on function veil2.session_context( integer, bigint, integer, integer, integer, integer, integer, integer, bigint) to demouser; create extension if not exists pgtap; \c vpd demouser \echo Unconnected user tests... begin; select plan(6); select is(cnt, 0, 'Unconnected user sees no users') from (select count(*)::integer as cnt from users) x; -- Insert not allowed select throws_like( $$insert into users values (12, 'user12', 'passwd12')$$, '%violates row-level%', 'Unconnected used cannot create users'); select is(cnt, 0, 'Unconnected user sees no follower_types') from (select count(*)::integer as cnt from follower_types) x; select is(cnt, 0, 'Unconnected user sees no followers') from (select count(*)::integer as cnt from followers) x; select is(cnt, 0, 'Unconnected user sees no post_types') from (select count(*)::integer as cnt from post_types) x; select is(cnt, 0, 'Unconnected user sees no posts') from (select count(*)::integer as cnt from posts) x; select * from finish(); rollback; \echo \echo admin/superuser user tests... begin; select plan(12); with login as ( select * from veil2.create_session('Alice', 'bcrypt') c cross join veil2.open_connection(c.session_id, 1, 'passwd_alice') ) select is(success, true, 'Alice successfully logs in (with admin role') from login; select is(cnt, 7, 'Alice sees all users') from (select count(*)::integer as cnt from users) x; with ins as ( insert into users values (12, 'user12', 'passwd12') returning accessor_id ) select is(accessor_id, 12, 'Alice can insert new user') from ins; select is(password, 'xxxx', 'New user password is hidden') from users where accessor_id = 12; select is(cnt, 0, 'Alice cannot see new accessor record') from (select count(*)::integer as cnt from veil2.accessors where accessor_id = 12) x; select is(cnt, 0, 'Alice cannot see authentication details record') from (select count(*)::integer as cnt from veil2.authentication_details where accessor_id = 12) x; select is(cnt, 3, 'Alice sees follower_types') from (select count(*)::integer as cnt from follower_types) x; select is(cnt, 2, 'Alice sees followers') from (select count(*)::integer as cnt from followers) x; with login as ( select * from veil2.create_session('Carol', 'bcrypt') c cross join veil2.open_connection(c.session_id, 1, 'passwd_carol') ) select is(success, true, 'Carol successfully logs in (with superuser role') from login; select is(cnt, 8, -- One more user than before 'Carol sees all users') from (select count(*)::integer as cnt from users) x; select is(cnt, 1, 'Carol can see new accessor record') from (select count(*)::integer as cnt from veil2.accessors where accessor_id = 12) x; select is(cnt, 1, 'Carol can see authentication details record') from (select count(*)::integer as cnt from veil2.authentication_details where accessor_id = 12) x; select * from finish(); rollback; \echo \echo friends tests... begin; select plan(27); with login as ( select * from veil2.create_session('Bob', 'bcrypt') c cross join veil2.open_connection(c.session_id, 1, 'passwd_bob') ) select is(success, true, 'Bob successfully logs in (with only connect role') from login; select is(cnt, 2, -- Bob only sees himself and his friends 'Bob sees only himself') from (select count(*)::integer as cnt from users) x; with upd as ( update users set password = 'wibble' where accessor_id = ( select accessor_id from veil2.session_context()) returning accessor_id ) select is(cnt, 1, 'Bob updates password') from (select count(*)::integer cnt from upd) x; with login as ( select * from veil2.create_session('Bob', 'bcrypt') c cross join veil2.open_connection(c.session_id, 1, 'passwd_bob') ) select is(success, false, 'Bob cannot log in with old password') from login; with login as ( select * from veil2.create_session('Bob', 'bcrypt') c cross join veil2.open_connection(c.session_id, 1, 'wibble') ) select is(success, true, 'Bob logs in with new password') from login; select is(cnt, 3, 'Bob sees follower_types') from (select count(*)::integer as cnt from follower_types) x; select is(cnt, 2, 'Bob sees followers') from (select count(*)::integer as cnt from followers) x; with ins as ( insert into followers (follower_type_id, follower, follows) values (1, 2, 5) returning follower ) select is(cnt, 1, 'Bob can follow others') from (select count(*)::integer as cnt from ins) x; select throws_like( $$insert into followers (follower_type_id, follower, follows) values (1, 3, 2) $$, '%violates row-level%', 'Bob cannot insert a follower for himself.'); with login as ( select * from veil2.create_session('Eve', 'bcrypt') c cross join veil2.open_connection(c.session_id, 1, 'passwd_eve') ) select is(success, true, 'Eve successfully logs in (with only connect role') from login; select is(cnt, 1, 'Eve sees single follower (Bob)') from (select count(*)::integer as cnt from followers) x; with ins as ( insert into followers (follower_type_id, follower, follows) values (2, 5, 2) returning follower ) select is(cnt, 1, 'Eve can follow Bob') from (select count(*)::integer as cnt from ins) x; -- Eve creates some posts with ins as ( insert into posts (post_type_id, poster, post) values (11, 5, 'Public post'), (12, 5, 'Private post'), (13, 5, 'For friends') returning post_id ) select is(cnt, 3, 'Eve successfully posts') from (select count(*)::integer as cnt from ins) x; -- Eve can see all her posts select is(cnt, 3, 'Eve sees all her posts') from (select count(*)::integer as cnt from posts where poster = 5) x; with login as ( select * from veil2.create_session('Alice', 'bcrypt') c cross join veil2.open_connection(c.session_id, 1, 'passwd_alice') ) select is(success, true, 'Alice successfully logs in again') from login; -- Alice sees all of Eve's posts select is(cnt, 3, 'Alice sees all Eve''s posts') from (select count(*)::integer as cnt from posts where poster = 5) x; with login as ( select * from veil2.create_session('Bob', 'bcrypt') c cross join veil2.open_connection(c.session_id, 1, 'wibble') ) select is(success, true, 'Bob logs in again') from login; -- What friend stuff can Bob see? select is(cnt, 1, 'Bob sees all Eve''s public posts') from (select count(*)::integer as cnt from posts where poster = 5 and post_type_id = 11) x; select is(cnt, 1, 'Bob sees all Eve''s friend posts') from (select count(*)::integer as cnt from posts where poster = 5 and post_type_id = 12) x; select is(cnt, 0, 'Bob does not see Eve''s private posts') from (select count(*)::integer as cnt from posts where poster = 5 and post_type_id = 13) x; select is(cnt, 4, 'Bob only sees followers records about himself') from (select count(*)::integer as cnt from followers) x; select is(cnt, 3, 'Bob only sees himself and his friends and followers') from (select count(*)::integer as cnt from users) x; with login as ( select * from veil2.create_session('Carol', 'bcrypt') c cross join veil2.open_connection(c.session_id, 1, 'passwd_carol') ) select is(success, true, 'Carol logs in') from login; with login as ( select * from veil2.create_session('Carol', 'bcrypt') c cross join veil2.open_connection(c.session_id, 1, 'passwd_carol') ) select is(success, true, 'Carol logs in') from login; select is(cnt, 7, 'Carol sees everyone') from (select count(*)::integer as cnt from users) x; select is(cnt, 3, 'Carol sees all of Eve''s posts') from (select count(*)::integer as cnt from posts where poster = 5) x; select throws_like($$ insert into posts (post_type_id, poster, post) values (12, 5, 'Private post spoofed by Carol')$$, '%new row violates row-level sec%', 'Carol cannot spoof a post from someone else'); select * from finish(); rollback; \pset tuples_only false \pset format aligned