From 866af09b50eb4831747c115b457ff1d34858835e Mon Sep 17 00:00:00 2001 From: jordi fita mas Date: Tue, 8 Aug 2023 02:22:16 +0200 Subject: [PATCH] Move the user role down to company_user relation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I was starting to add the public page for campsite types, creating more granular row-level security policies for select, insert, update, and delete, because now the guest users needed to SELECT them and they have no related company to filter the rows with. Suddenly, i realized that the role was wrong in the user relation: a user can be an admin to one company, and employee to another, and guess to yet another company; the role should be in the company_user relation instead. That means that to know the role to set to, the user alone is not enough and have to know the company as well. Had to change all the cookie-related function to accept also the company’s host name, as this is the information that the Go application has. --- demo.sql | 12 ++-- deploy/campsite_type.sql | 37 ++++++++--- deploy/check_cookie.sql | 31 +++++---- deploy/company.sql | 3 +- deploy/company_user.sql | 21 ++---- deploy/current_company_id.sql | 24 +++++++ deploy/ensure_role_exists.sql | 9 +-- deploy/policies_company.sql | 25 +++++++ deploy/set_cookie.sql | 10 +-- deploy/user.sql | 1 - deploy/user_profile.sql | 6 ++ pkg/app/user.go | 3 +- revert/check_cookie.sql | 2 +- revert/company_user.sql | 1 - revert/current_company_id.sql | 7 ++ revert/ensure_role_exists.sql | 6 +- revert/policies_company.sql | 9 +++ revert/set_cookie.sql | 2 +- sqitch.plan | 16 +++-- test/build_cookie.sql | 30 ++++++--- test/campsite_type.sql | 121 +++++++++++++++++++++++++--------- test/change_password.sql | 24 +++++-- test/check_cookie.sql | 82 +++++++++++++++-------- test/company.sql | 67 +++++++++++-------- test/company_user.sql | 8 ++- test/current_company_id.sql | 88 +++++++++++++++++++++++++ test/current_user_cookie.sql | 30 +++++++-- test/current_user_email.sql | 30 +++++++-- test/encrypt_password.sql | 4 +- test/ensure_role_exists.sql | 41 +++++++----- test/login.sql | 4 +- test/logout.sql | 6 +- test/set_cookie.sql | 71 ++++++++++++++------ test/user.sql | 7 +- test/user_profile.sql | 45 +++++++++---- verify/campsite_type.sql | 5 +- verify/check_cookie.sql | 2 +- verify/company_user.sql | 4 +- verify/current_company_id.sql | 7 ++ verify/ensure_role_exists.sql | 4 +- verify/policies_company.sql | 10 +++ verify/set_cookie.sql | 2 +- verify/user.sql | 1 - 43 files changed, 671 insertions(+), 247 deletions(-) create mode 100644 deploy/current_company_id.sql create mode 100644 deploy/policies_company.sql create mode 100644 revert/current_company_id.sql create mode 100644 revert/policies_company.sql create mode 100644 test/current_company_id.sql create mode 100644 verify/current_company_id.sql create mode 100644 verify/policies_company.sql diff --git a/demo.sql b/demo.sql index ef480ea..d39aba7 100644 --- a/demo.sql +++ b/demo.sql @@ -3,9 +3,9 @@ begin; set search_path to camper, auth, public; alter sequence user_user_id_seq restart with 42; -insert into auth."user" (email, name, password, role) -values ('demo@camper', 'Demo User', 'demo', 'employee') - , ('admin@camper', 'Demo Admin', 'admin', 'admin') +insert into auth."user" (email, name, password) +values ('demo@camper', 'Demo User', 'demo') + , ('admin@camper', 'Demo Admin', 'admin') ; alter sequence company_company_id_seq restart with 52; @@ -17,9 +17,9 @@ values (52, 'localhost:8080') , (52, 'camper.tandem.ws') ; -insert into company_user (company_id, user_id) -values (52, 42) - , (52, 43) +insert into company_user (company_id, user_id, role) +values (52, 42, 'employee') + , (52, 43, 'admin') ; commit; diff --git a/deploy/campsite_type.sql b/deploy/campsite_type.sql index 53a69c4..9ce481f 100644 --- a/deploy/campsite_type.sql +++ b/deploy/campsite_type.sql @@ -2,6 +2,7 @@ -- requires: roles -- requires: schema_camper -- requires: company +-- requires: user_profile begin; @@ -16,6 +17,7 @@ create table campsite_type ( active boolean not null default true ); +grant select on table campsite_type to guest; grant select on table campsite_type to employee; grant select, insert, update, delete on table campsite_type to admin; @@ -23,16 +25,35 @@ grant usage on sequence campsite_type_campsite_type_id_seq to admin; alter table campsite_type enable row level security; -create policy company_policy +create policy guest_ok on campsite_type +for select +using (true) +; + +create policy insert_to_company +on campsite_type +for insert +with check ( + company_id in (select company_id from user_profile) +) +; + +create policy update_company +on campsite_type +for update using ( - exists( - select 1 - from company_user - join user_profile using (user_id) - where company_user.company_id = campsite_type.company_id - ) -); + company_id in (select company_id from user_profile) +) +; + +create policy delete_from_company +on campsite_type +for delete +using ( + company_id in (select company_id from user_profile) +) +; commit; diff --git a/deploy/check_cookie.sql b/deploy/check_cookie.sql index 522ba45..b74a7f0 100644 --- a/deploy/check_cookie.sql +++ b/deploy/check_cookie.sql @@ -3,46 +3,53 @@ -- requires: schema_public -- requires: schema_auth -- requires: user +-- requires: company_host +-- requires: company_user begin; set search_path to public, auth; -create or replace function check_cookie(input_cookie text) returns name as +create or replace function check_cookie(input_cookie text, host text) returns name as $$ declare - uid text; - user_email text; - user_role name; + cid text; + user_email text; + user_role name; user_cookie text; begin - select user_id::text, email::text, role, cookie - into uid, user_email, user_role, user_cookie + select company_id::text, email::text, role, cookie + into cid, user_email, user_role, user_cookie from "user" + join company_user using (user_id) + join public.company_host using (company_id) where email = split_part(input_cookie, '/', 2) and cookie_expires_at > current_timestamp and length(password) > 0 - and cookie = split_part(input_cookie, '/', 1); + and cookie = split_part(input_cookie, '/', 1) + and company_host.host = check_cookie.host + ; if user_role is null then - uid := '0'; + cid := '0'; user_email := ''; user_cookie := ''; user_role := 'guest'::name; end if; perform set_config('request.user.email', user_email, false); perform set_config('request.user.cookie', user_cookie, false); + perform set_config('request.company.id', cid, false); return user_role; end; $$ language plpgsql security definer stable -set search_path = auth, pg_temp; +set search_path = auth, camper, pg_temp; -comment on function check_cookie(text) is +comment on function check_cookie(text, text) is 'Checks whether a given cookie is for a valid users, returning their role, and setting current_user_email and current_user_cookie'; -revoke execute on function check_cookie(text) from public; -grant execute on function check_cookie(text) to authenticator; +revoke execute on function check_cookie(text, text) from public; +grant execute on function check_cookie(text, text) to authenticator; commit; diff --git a/deploy/company.sql b/deploy/company.sql index fa3560d..ededd1e 100644 --- a/deploy/company.sql +++ b/deploy/company.sql @@ -36,7 +36,8 @@ create table company ( created_at timestamptz not null default current_timestamp ); -grant select, update on table company to employee; +grant select on table company to guest; +grant select on table company to employee; grant select, update on table company to admin; commit; diff --git a/deploy/company_user.sql b/deploy/company_user.sql index b08b27a..130dde1 100644 --- a/deploy/company_user.sql +++ b/deploy/company_user.sql @@ -11,29 +11,16 @@ set search_path to camper, auth, public; create table company_user ( company_id integer not null references company, user_id integer not null references "user", + role name not null check (length(role) < 512), primary key (company_id, user_id) ); grant select on table company_user to employee; grant select on table company_user to admin; - -alter table company enable row level security; - -create policy company_policy -on company -using ( - exists( - select 1 - from company_user - join user_profile using (user_id) - where company_user.company_id = company.company_id - ) -); - -- TODO: --- I think we can not do the same for company_user because it would be --- an infinite loop, but in this case i think it is fine because we can --- only see ids, nothing more. +-- I think we can enable row-level security for company_user because it would +-- be an infinite loop with user_profile, but in this case i think it is fine +-- because we can only see ids, nothing more. commit; diff --git a/deploy/current_company_id.sql b/deploy/current_company_id.sql new file mode 100644 index 0000000..70c09cd --- /dev/null +++ b/deploy/current_company_id.sql @@ -0,0 +1,24 @@ +-- Deploy camper:current_company_id to pg +-- requires: roles +-- requires: schema_camper + +begin; + +set search_path to camper; + +create or replace function current_company_id() returns integer as +$$ +select current_setting('request.company.id', true)::integer; +$$ +language sql +stable; + +comment on function current_company_id() is +'Returns the ID of the current company'; + +revoke execute on function current_company_id() from public; +grant execute on function current_company_id() to guest; +grant execute on function current_company_id() to employee; +grant execute on function current_company_id() to admin; + +commit; diff --git a/deploy/ensure_role_exists.sql b/deploy/ensure_role_exists.sql index b8bbe1e..498b298 100644 --- a/deploy/ensure_role_exists.sql +++ b/deploy/ensure_role_exists.sql @@ -1,10 +1,11 @@ -- Deploy camper:ensure_role_exists to pg --- requires: schema_auth --- requires: user +-- requires: roles +-- requires: schema_camper +-- requires: company_user begin; -set search_path to auth, public; +set search_path to camper, public; create or replace function ensure_role_exists() returns trigger as $$ @@ -24,7 +25,7 @@ revoke execute on function ensure_role_exists() from public; create trigger ensure_role_exists after insert or update -on "user" +on company_user for each row execute procedure ensure_role_exists(); diff --git a/deploy/policies_company.sql b/deploy/policies_company.sql new file mode 100644 index 0000000..ad071ff --- /dev/null +++ b/deploy/policies_company.sql @@ -0,0 +1,25 @@ +-- Deploy camper:policies_company to pg +-- requires: company +-- requires: user_profile + +begin; + +set search_path to camper, public; + +alter table company enable row level security; + +create policy guest_ok +on company +for select +using (true) +; + +create policy update_company +on company +for update +using ( + company_id in (select company_id from user_profile) +) +; + +commit; diff --git a/deploy/set_cookie.sql b/deploy/set_cookie.sql index 70a25d9..67b5908 100644 --- a/deploy/set_cookie.sql +++ b/deploy/set_cookie.sql @@ -7,17 +7,17 @@ begin; set search_path to public; -create or replace function set_cookie(input_cookie text) returns void as +create or replace function set_cookie(input_cookie text, host text) returns void as $$ -select set_config('role', check_cookie(input_cookie), false); +select set_config('role', check_cookie(input_cookie, host), false); $$ language sql stable; -comment on function set_cookie(text) is +comment on function set_cookie(text, text) is 'Sets the user information for the cookie and switches to its role'; -revoke execute on function set_cookie(text) from public; -grant execute on function set_cookie(text) to authenticator; +revoke execute on function set_cookie(text, text) from public; +grant execute on function set_cookie(text, text) to authenticator; commit; diff --git a/deploy/user.sql b/deploy/user.sql index a04b811..cb31b28 100644 --- a/deploy/user.sql +++ b/deploy/user.sql @@ -13,7 +13,6 @@ create table "user" ( email email not null unique, name text not null, password text not null check (length(password) < 512), - role name not null check (length(role) < 512), lang_tag text not null default 'und' references language, cookie text not null default '', cookie_expires_at timestamptz not null default '-infinity'::timestamp, diff --git a/deploy/user_profile.sql b/deploy/user_profile.sql index ea2b3c4..8be249e 100644 --- a/deploy/user_profile.sql +++ b/deploy/user_profile.sql @@ -2,8 +2,10 @@ -- requires: roles -- requires: schema_camper -- requires: user +-- requires: company_user -- requires: current_user_email -- requires: current_user_cookie +-- requires: current_company_id begin; @@ -11,18 +13,22 @@ set search_path to camper, public; create or replace view user_profile with (security_barrier) as select user_id + , company_id , email , name , role , lang_tag , left(cookie, 10) as csrf_token from auth."user" + join company_user using (user_id) where email = current_user_email() and cookie = current_user_cookie() and cookie_expires_at > current_timestamp and length(cookie) > 30 + and company_id = current_company_id() union all select 0 + , 0 , null::email , '' , 'guest'::name diff --git a/pkg/app/user.go b/pkg/app/user.go index c903706..7229113 100644 --- a/pkg/app/user.go +++ b/pkg/app/user.go @@ -26,7 +26,8 @@ import ( func (h *App) getUser(r *http.Request, conn *database.Conn) (*auth.User, error) { cookie := auth.GetSessionCookie(r) - if _, err := conn.Exec(r.Context(), "select set_cookie($1)", cookie); err != nil { + host := httplib.Host(r) + if _, err := conn.Exec(r.Context(), "select set_cookie($1, $2)", cookie, host); err != nil { return nil, err } diff --git a/revert/check_cookie.sql b/revert/check_cookie.sql index e7e946c..9cbcf04 100644 --- a/revert/check_cookie.sql +++ b/revert/check_cookie.sql @@ -2,6 +2,6 @@ begin; -drop function if exists public.check_cookie(text); +drop function if exists public.check_cookie(text, text); commit; diff --git a/revert/company_user.sql b/revert/company_user.sql index 0476377..4179f6d 100644 --- a/revert/company_user.sql +++ b/revert/company_user.sql @@ -2,7 +2,6 @@ begin; -drop policy if exists company_policy on camper.company; drop table if exists camper.company_user; commit; diff --git a/revert/current_company_id.sql b/revert/current_company_id.sql new file mode 100644 index 0000000..ef73d19 --- /dev/null +++ b/revert/current_company_id.sql @@ -0,0 +1,7 @@ +-- Revert camper:current_company_id from pg + +begin; + +drop function if exists camper.current_company_id(); + +commit; diff --git a/revert/ensure_role_exists.sql b/revert/ensure_role_exists.sql index 0409459..5cb2b70 100644 --- a/revert/ensure_role_exists.sql +++ b/revert/ensure_role_exists.sql @@ -2,7 +2,9 @@ begin; -drop trigger if exists ensure_role_exists on auth."user"; -drop function if exists auth.ensure_role_exists(); +set search_path to camper; + +drop trigger if exists ensure_role_exists on company_user; +drop function if exists ensure_role_exists(); commit; diff --git a/revert/policies_company.sql b/revert/policies_company.sql new file mode 100644 index 0000000..368e784 --- /dev/null +++ b/revert/policies_company.sql @@ -0,0 +1,9 @@ +-- Revert camper:policies_company from pg + +begin; + +set search_path to camper, public; +drop policy if exists guest_ok on company; +drop policy if exists update_company on company; + +commit; diff --git a/revert/set_cookie.sql b/revert/set_cookie.sql index a71ccb3..5f13363 100644 --- a/revert/set_cookie.sql +++ b/revert/set_cookie.sql @@ -2,6 +2,6 @@ begin; -drop function if exists public.set_cookie(text); +drop function if exists public.set_cookie(text, text); commit; diff --git a/sqitch.plan b/sqitch.plan index 57babf5..3ac9433 100644 --- a/sqitch.plan +++ b/sqitch.plan @@ -11,19 +11,14 @@ schema_camper [roles] 2023-07-21T22:08:39Z jordi fita mas # email [schema_camper extension_citext] 2023-07-21T22:11:13Z jordi fita mas # Add email domain schema_auth [roles] 2023-07-21T22:13:23Z jordi fita mas # Add authentication schema user [roles schema_auth email language] 2023-07-21T22:37:20Z jordi fita mas # Add user relation -ensure_role_exists [schema_auth user] 2023-07-21T22:48:56Z jordi fita mas # Add trigger to ensure users’ role exists extension_pgcrypto [schema_auth] 2023-07-21T22:53:25Z jordi fita mas # Add pgcrypto extension encrypt_password [schema_auth user extension_pgcrypto] 2023-07-21T22:56:40Z jordi fita mas # Add function to encrypt users’ password current_user_cookie [roles schema_camper] 2023-07-21T23:05:26Z jordi fita mas # Add function to get the cookie of the current user -current_user_email [roles schema_camper] 2023-07-21T23:09:34Z jordi fita mas # Add function to ge the email of the current user +current_user_email [roles schema_camper] 2023-07-21T23:09:34Z jordi fita mas # Add function to get the email of the current user build_cookie [roles schema_camper current_user_email current_user_cookie] 2023-07-21T23:14:35Z jordi fita mas # Add function to build the cookie for the current user login_attempt [schema_auth] 2023-07-21T23:22:17Z jordi fita mas # Add relation of log in attempts login [roles schema_auth schema_camper extension_pgcrypto email user login_attempt build_cookie] 2023-07-21T23:29:18Z jordi fita mas # Add function to login logout [roles schema_auth schema_camper current_user_email current_user_cookie user] 2023-07-21T23:36:12Z jordi fita mas # Add function to logout -check_cookie [roles schema_public schema_auth user] 2023-07-21T23:40:55Z jordi fita mas # Add function to check if a user cookie is valid -set_cookie [roles schema_public check_cookie] 2023-07-21T23:44:30Z jordi fita mas # Add function to set the role base don the cookie -user_profile [roles schema_camper user current_user_email current_user_cookie] 2023-07-21T23:47:36Z jordi fita mas # Add view for user profile -change_password [roles schema_auth schema_camper user] 2023-07-21T23:54:52Z jordi fita mas # Add function to change the current user’s password extension_vat [schema_public] 2023-07-29T01:18:45Z jordi fita mas # Add vat extension extension_pg_libphonenumber [schema_public] 2023-07-29T01:21:12Z jordi fita mas # Add phone numbers extension extension_uri [schema_public] 2023-07-29T01:23:46Z jordi fita mas # Add URI extension @@ -36,6 +31,13 @@ country_i18n [roles schema_camper country_code language country] 2023-07-29T01:4 available_countries [schema_camper country country_i18n] 2023-07-29T01:48:40Z jordi fita mas # Add the list of available countries company [roles schema_camper extension_vat email extension_pg_libphonenumber extension_uri currency_code currency country_code country language] 2023-07-29T01:56:41Z jordi fita mas # Add relation for company company_user [roles schema_camper user company] 2023-07-29T02:08:07Z jordi fita mas # Add relation of company user +ensure_role_exists [roles schema_camper company_user] 2023-07-21T22:48:56Z jordi fita mas # Add trigger to ensure users’ role exists company_host [roles schema_public] 2023-08-03T17:46:45Z jordi fita mas # Add relation of DNS domain and company -campsite_type [roles schema_camper company] 2023-07-31T11:20:29Z jordi fita mas # Add relation of campsite type +check_cookie [roles schema_public schema_auth user company_host company_user] 2023-07-21T23:40:55Z jordi fita mas # Add function to check if a user cookie is valid +set_cookie [roles schema_public check_cookie] 2023-07-21T23:44:30Z jordi fita mas # Add function to set the role base don the cookie +current_company_id [roles schema_camper] 2023-08-07T10:44:36Z jordi fita mas # Add function to get the ID of the current company +user_profile [roles schema_camper user company_user current_user_email current_user_cookie current_company_id] 2023-07-21T23:47:36Z jordi fita mas # Add view for user profile +policies_company [company user_profile] 2023-08-07T20:04:26Z jordi fita mas # Add row-level security profiles to company +change_password [roles schema_auth schema_camper user] 2023-07-21T23:54:52Z jordi fita mas # Add function to change the current user’s password +campsite_type [roles schema_camper company user_profile] 2023-07-31T11:20:29Z jordi fita mas # Add relation of campsite type add_campsite_type [roles schema_camper campsite_type company] 2023-08-04T16:14:48Z jordi fita mas # Add function to create campsite types diff --git a/test/build_cookie.sql b/test/build_cookie.sql index a51c157..a4923f6 100644 --- a/test/build_cookie.sql +++ b/test/build_cookie.sql @@ -20,14 +20,28 @@ select function_privs_are('camper', 'build_cookie', array ['email', 'text'], 'ad select function_privs_are('camper', 'build_cookie', array ['email', 'text'], 'authenticator', array []::text[]); set client_min_messages to warning; +truncate company_host cascade; +truncate company_user cascade; +truncate company cascade; truncate auth."user" cascade; reset client_min_messages; -insert into auth."user" (user_id, email, name, password, role, cookie, cookie_expires_at) -values (1, 'demo@tandem.blog', 'Demo', 'test', 'employee', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', - current_timestamp + interval '1 month') - , (9, 'admin@tandem.blog', 'Demo', 'test', 'admin', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', - current_timestamp + interval '1 month') +insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at) +values (1, 'demo@tandem.blog', 'Demo', 'test', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') + , (9, 'admin@tandem.blog', 'Demo', 'test', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +; + +insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code, default_lang_tag) +values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR', 'ca') +; + +insert into company_user (company_id, user_id, role) +values (2, 1, 'employee') + , (2, 9, 'admin') +; + +insert into company_host (company_id, host) +values (2, 'localhost') ; select is( @@ -36,7 +50,7 @@ select is( 'Should build the cookie with the given user and cookie value' ); -select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog'); +select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'localhost'); reset role; select is( @@ -46,7 +60,7 @@ select is( ); -select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog'); +select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog', 'localhost'); reset role; select is( @@ -56,7 +70,7 @@ select is( ); -select set_cookie('ashtasth'); +select set_cookie('ashtasth', 'localhost'); reset role; select is( diff --git a/test/campsite_type.sql b/test/campsite_type.sql index 1a71dea..2fcfb66 100644 --- a/test/campsite_type.sql +++ b/test/campsite_type.sql @@ -5,13 +5,13 @@ reset client_min_messages; begin; -select plan(47); +select plan(55); set search_path to camper, public; select has_table('campsite_type'); select has_pk('campsite_type' ); -select table_privs_are('campsite_type', 'guest', array[]::text[]); +select table_privs_are('campsite_type', 'guest', array['SELECT']::text[]); select table_privs_are('campsite_type', 'employee', array['SELECT']); select table_privs_are('campsite_type', 'admin', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']); select table_privs_are('campsite_type', 'authenticator', array[]::text[]); @@ -63,14 +63,15 @@ select col_default_is('campsite_type', 'active', 'true'); set client_min_messages to warning; truncate campsite_type cascade; +truncate company_host cascade; truncate company_user cascade; truncate company cascade; truncate auth."user" cascade; reset client_min_messages; -insert into auth."user" (user_id, email, name, password, role, cookie, cookie_expires_at) -values (1, 'demo@tandem.blog', 'Demo', 'test', 'employee', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') - , (5, 'admin@tandem.blog', 'Demo', 'test', 'admin', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at) +values (1, 'demo@tandem.blog', 'Demo', 'test', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') + , (5, 'admin@tandem.blog', 'Demo', 'test', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') ; insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code, default_lang_tag) @@ -78,9 +79,14 @@ values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', ' , (4, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD', 'ca') ; -insert into company_user (company_id, user_id) -values (2, 1) - , (4, 5) +insert into company_user (company_id, user_id, role) +values (2, 1, 'admin') + , (4, 5, 'admin') +; + +insert into company_host (company_id, host) +values (2, 'co2') + , (4, 'co4') ; insert into campsite_type (company_id, name) @@ -93,44 +99,99 @@ select company_id, name from campsite_type order by company_id, name; -set role employee; -select is_empty('campsite_type_data', 'Should show no data when cookie is not set yet'); -reset role; - -select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog'); +set role guest; select bag_eq( 'campsite_type_data', $$ values (2, 'Wooden lodge') + , (4, 'Bungalow') $$, - 'Should only list campsite types of the companies where demo@tandem.blog is user of' + 'Everyone should be able to list all campsite types across all companies' ); reset role; -select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog'); +select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2'); + +select lives_ok( + $$ insert into campsite_type(company_id, name) values (2, 'Another type' ) $$, + 'Admin from company 2 should be able to insert a new campsite type to that company.' +); + select bag_eq( 'campsite_type_data', - $$ values (4, 'Bungalow') + $$ values (2, 'Wooden lodge') + , (2, 'Another type') + , (4, 'Bungalow') $$, - 'Should only list campsite type of the companies where admin@tandem.blog is user of' + 'The new row should have been added' ); -reset role; -select set_cookie('not-a-cookie'); -select throws_ok( +select lives_ok( + $$ update campsite_type set name = 'Another' where company_id = 2 and name = 'Another type' $$, + 'Admin from company 2 should be able to update campsite type of that company.' +); + +select bag_eq( 'campsite_type_data', - '42501', 'permission denied for table campsite_type', - 'Should not allow select campsite types to guest users' -); -reset role; - -select throws_ok( $$ - insert into campsite_type (company_id, name) - values (2, ' ') + $$ values (2, 'Wooden lodge') + , (2, 'Another') + , (4, 'Bungalow') $$, - '23514', 'new row for relation "campsite_type" violates check constraint "name_not_empty"', - 'Should not allow campsite types with blank name' + 'The row should have been updated.' ); +select lives_ok( + $$ delete from campsite_type where company_id = 2 and name = 'Another' $$, + 'Admin from company 2 should be able to delete campsite type from that company.' +); + +select bag_eq( + 'campsite_type_data', + $$ values (2, 'Wooden lodge') + , (4, 'Bungalow') + $$, + 'The row should have been deleted.' +); + +select throws_ok( + $$ insert into campsite_type (company_id, name) values (4, 'Another type' ) $$, + '42501', 'new row violates row-level security policy for table "campsite_type"', + 'Admin from company 2 should NOT be able to insert new campsite types to company 4.' +); + +select lives_ok( + $$ update campsite_type set name = 'Nope' where company_id = 4 $$, + 'Admin from company 2 should not be able to update new campsite types of company 4, but no error if company_id is not changed.' +); + +select bag_eq( + 'campsite_type_data', + $$ values (2, 'Wooden lodge') + , (4, 'Bungalow') + $$, + 'No row should have been changed.' +); + +select throws_ok( + $$ update campsite_type set company_id = 4 where company_id = 2 $$, + '42501', 'new row violates row-level security policy for table "campsite_type"', + 'Admin from company 2 should NOT be able to move campsite types to company 4' +); + +select lives_ok( + $$ delete from campsite_type where company_id = 4 $$, + 'Admin from company 2 should NOT be able to delete campsite types from company 4, but not error is thrown' +); + +select bag_eq( + 'campsite_type_data', + $$ values (2, 'Wooden lodge') + , (4, 'Bungalow') + $$, + 'No row should have been changed' +); + +reset role; + select * from finish(); diff --git a/test/change_password.sql b/test/change_password.sql index 1ee82e3..6fa2216 100644 --- a/test/change_password.sql +++ b/test/change_password.sql @@ -20,12 +20,28 @@ select function_privs_are('camper', 'change_password', array ['text'], 'admin', select function_privs_are('camper', 'change_password', array ['text'], 'authenticator', array []::text[]); set client_min_messages to warning; +truncate company_host cascade; +truncate company_user cascade; +truncate company cascade; truncate auth."user" cascade; reset client_min_messages; -insert into auth."user" (user_id, email, name, password, role, cookie, cookie_expires_at) -values (1, 'demo@tandem.blog', 'Demo', 'test', 'employee', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') - , (9, 'admin@tandem.blog', 'Demo', 'test', 'admin', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at) +values (1, 'demo@tandem.blog', 'Demo', 'test', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') + , (9, 'admin@tandem.blog', 'Demo', 'test', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +; + +insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code, default_lang_tag) +values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR', 'ca') +; + +insert into company_user (company_id, user_id, role) +values (2, 1, 'employee') + , (2, 9, 'admin') +; + +insert into company_host (company_id, host) +values (2, 'localhost') ; select lives_ok($$ select change_password('another') $$, 'Should run even without current user'); @@ -35,7 +51,7 @@ select isnt_empty( 'Should not have changed any password' ); -select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog'); +select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'localhost'); select lives_ok($$ select change_password('another') $$, 'Should run with the correct user'); diff --git a/test/check_cookie.sql b/test/check_cookie.sql index 4d456da..f53f622 100644 --- a/test/check_cookie.sql +++ b/test/check_cookie.sql @@ -5,77 +5,107 @@ reset client_min_messages; begin; -select plan(21); +select plan(23); set search_path to auth, camper, public; -select has_function('public', 'check_cookie', array ['text']); -select function_lang_is('public', 'check_cookie', array ['text'], 'plpgsql'); -select function_returns('public', 'check_cookie', array ['text'], 'name'); -select is_definer('public', 'check_cookie', array ['text']); -select volatility_is('public', 'check_cookie', array ['text'], 'stable'); -select function_privs_are('public', 'check_cookie', array ['text'], 'guest', array []::text[]); -select function_privs_are('public', 'check_cookie', array ['text'], 'employee', array []::text[]); -select function_privs_are('public', 'check_cookie', array ['text'], 'admin', array []::text[]); -select function_privs_are('public', 'check_cookie', array ['text'], 'authenticator', array ['EXECUTE']); +select has_function('public', 'check_cookie', array ['text', 'text']); +select function_lang_is('public', 'check_cookie', array ['text', 'text'], 'plpgsql'); +select function_returns('public', 'check_cookie', array ['text', 'text'], 'name'); +select is_definer('public', 'check_cookie', array ['text', 'text']); +select volatility_is('public', 'check_cookie', array ['text', 'text'], 'stable'); +select function_privs_are('public', 'check_cookie', array ['text', 'text'], 'guest', array []::text[]); +select function_privs_are('public', 'check_cookie', array ['text', 'text'], 'employee', array []::text[]); +select function_privs_are('public', 'check_cookie', array ['text', 'text'], 'admin', array []::text[]); +select function_privs_are('public', 'check_cookie', array ['text', 'text'], 'authenticator', array ['EXECUTE']); set client_min_messages to warning; +truncate company_host cascade; +truncate company_user cascade; +truncate company cascade; truncate auth."user" cascade; reset client_min_messages; -insert into auth."user" (user_id, email, name, password, role, cookie, cookie_expires_at) -values (1, 'demo@tandem.blog', 'Demo', 'test', 'employee', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') - , (9, 'admin@tandem.blog', 'Demo', 'test', 'admin', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at) +values (1, 'demo@tandem.blog', 'Demo', 'test', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') + , (9, 'admin@tandem.blog', 'Demo', 'test', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +; + +insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code, default_lang_tag) +values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR', 'ca') + , (4, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD', 'es') +; + +insert into company_user (company_id, user_id, role) +values (2, 1, 'employee') + , (4, 9, 'admin') +; + +insert into company_host (company_id, host) +values (2, 'co2') + , (4, 'co4') ; prepare user_info as -select current_user_email(), current_user_cookie(); +select current_user_email(), current_user_cookie(), current_company_id(); select is( - check_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog'), + check_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2'), 'employee'::name, 'Should validate the cookie for the first user' ); select results_eq( 'user_info', - $$ values ('demo@tandem.blog', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e') $$, + $$ values ('demo@tandem.blog', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', 2) $$, 'Should have updated the settings with the user info' ); select is( - check_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog'), + check_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog', 'co4'), 'admin'::name, 'Should validate the cookie for the second user' ); select results_eq( 'user_info', - $$ values ('admin@tandem.blog', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524') $$, + $$ values ('admin@tandem.blog', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', 4) $$, 'Should have updated the settings with the other user info' ); select is( - check_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/admin@tandem.blog'), + check_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/admin@tandem.blog', 'co2'), 'guest'::name, 'Should only match with the correct email' ); select results_eq( 'user_info', - $$ values ('', '') $$, + $$ values ('', '', 0) $$, 'Should have updated the settings with a guest user' ); select is( - check_cookie('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/admin@tandem.blog'), + check_cookie('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/admin@tandem.blog', 'co2'), 'guest'::name, 'Should only match with the correct cookie value' ); select results_eq( 'user_info', - $$ values ('', '') $$, + $$ values ('', '', 0) $$, + 'Should have left the settings with a guest user' +); + +select is( + check_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co4'), + 'guest'::name, + 'Should not allow cookies for a different company' +); + +select results_eq( + 'user_info', + $$ values ('', '', 0) $$, 'Should have left the settings with a guest user' ); @@ -83,26 +113,26 @@ update "user" set cookie_expires_at = current_timestamp - interval '1 minute'; select is( - check_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog'), + check_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2'), 'guest'::name, 'Should not allow expired cookies' ); select results_eq( 'user_info', - $$ values ('', '') $$, + $$ values ('', '', 0) $$, 'Should have left the settings with a guest user' ); select is( - check_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog'), + check_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog', 'co4'), 'guest'::name, 'Should not allow expired cookied for the other user as well' ); select results_eq( 'user_info', - $$ values ('', '') $$, + $$ values ('', '', 0) $$, 'Should have left the settings with a guest user' ); diff --git a/test/company.sql b/test/company.sql index 36eed64..f7dfe2a 100644 --- a/test/company.sql +++ b/test/company.sql @@ -5,14 +5,14 @@ reset client_min_messages; begin; -select plan(101); +select plan(102); set search_path to camper, public; select has_table('company'); select has_pk('company' ); -select table_privs_are('company', 'guest', array []::text[]); -select table_privs_are('company', 'employee', array ['SELECT', 'UPDATE']); +select table_privs_are('company', 'guest', array ['SELECT']); +select table_privs_are('company', 'employee', array ['SELECT']); select table_privs_are('company', 'admin', array ['SELECT', 'UPDATE']); select table_privs_are('company', 'authenticator', array []::text[]); @@ -127,27 +127,30 @@ select col_default_is('company', 'created_at', 'CURRENT_TIMESTAMP'); set client_min_messages to warning; +truncate company_host cascade; truncate company_user cascade; truncate company cascade; truncate auth."user" cascade; reset client_min_messages; -insert into auth."user" (user_id, email, name, password, role, cookie, cookie_expires_at) -values (1, 'demo@tandem.blog', 'Demo', 'test', 'employee', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') - , (5, 'admin@tandem.blog', 'Demo', 'test', 'admin', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at) +values (1, 'demo@tandem.blog', 'Demo', 'test', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') + , (5, 'admin@tandem.blog', 'Demo', 'test', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') ; insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code, default_lang_tag) values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR', 'ca') , (4, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD', 'es') - , (6, 'Company 6', 'XX345', '', '777-777-777', 'c@c', '', '', '', '', '', 'DE', 'USD', 'ca') ; -insert into company_user (company_id, user_id) -values (2, 1) - , (2, 5) - , (4, 1) - , (6, 5) +insert into company_user (company_id, user_id, role) +values (2, 1, 'admin') + , (4, 5, 'admin') +; + +insert into company_host (company_id, host) +values (2, 'co2') + , (4, 'co4') ; prepare company_data as @@ -155,36 +158,44 @@ select company_id, business_name from company order by company_id; -set role employee; -select is_empty('company_data', 'Should show no data when cookie is not set yet'); -reset role; - -select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog'); +set role guest; select results_eq( 'company_data', $$ values ( 2, 'Company 2' ) , ( 4, 'Company 4' ) $$, - 'Should only list companies where demo@tandem.blog is user of' + 'Everyone should be able to list all companies' ); reset role; -select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog'); +select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2'); + +select lives_ok( + $$ update company set business_name = 'Another Company 2' where company_id = 2 $$, + 'Admin from company 2 should be able to update that company.' +); + select results_eq( 'company_data', - $$ values ( 2, 'Company 2' ) - , ( 6, 'Company 6' ) + $$ values ( 2, 'Another Company 2' ) + , ( 4, 'Company 4' ) $$, - 'Should only list companies where admin@tandem.blog is user of' + 'Should have updated the row.' ); -reset role; -select set_cookie('not-a-cookie'); -select throws_ok( - 'company_data', - '42501', 'permission denied for table company', - 'Should not allow select to guest users' +select lives_ok( + $$ update company set business_name = 'Another Company 4' where company_id = 4 $$, + 'Admin from company 2 should NOT be able to update that company, but no error is raised.' ); + +select results_eq( + 'company_data', + $$ values ( 2, 'Another Company 2' ) + , ( 4, 'Company 4' ) + $$, + 'Should NOT have updated anything.' +); + reset role; select throws_ok( $$ diff --git a/test/company_user.sql b/test/company_user.sql index 2954745..1c55029 100644 --- a/test/company_user.sql +++ b/test/company_user.sql @@ -5,7 +5,7 @@ reset client_min_messages; begin; -select plan(19); +select plan(23); set search_path to camper, public; @@ -31,6 +31,12 @@ select col_type_is('company_user', 'user_id', 'integer'); select col_not_null('company_user', 'user_id'); select col_hasnt_default('company_user', 'user_id'); +select has_column('company_user', 'role'); +select col_type_is('company_user', 'role', 'name'); +select col_not_null('company_user', 'role'); +select col_hasnt_default('company_user', 'role'); + + select * from finish(); diff --git a/test/current_company_id.sql b/test/current_company_id.sql new file mode 100644 index 0000000..a937287 --- /dev/null +++ b/test/current_company_id.sql @@ -0,0 +1,88 @@ +-- Test current_company_id +set client_min_messages to warning; +create extension if not exists pgtap; +reset client_min_messages; + +begin; + +set search_path to camper, auth, public; + +select plan(15); + +select has_function('camper', 'current_company_id', array []::name[]); +select function_lang_is('camper', 'current_company_id', array []::name[], 'sql'); +select function_returns('camper', 'current_company_id', array []::name[], 'integer'); +select isnt_definer('camper', 'current_company_id', array []::name[]); +select volatility_is('camper', 'current_company_id', array []::name[], 'stable'); +select function_privs_are('camper', 'current_company_id', array []::name[], 'guest', array ['EXECUTE']); +select function_privs_are('camper', 'current_company_id', array []::name[], 'employee', array ['EXECUTE']); +select function_privs_are('camper', 'current_company_id', array []::name[], 'admin', array ['EXECUTE']); +select function_privs_are('camper', 'current_company_id', array []::name[], 'authenticator', array []::text[]); + +set client_min_messages to warning; +truncate company_host cascade; +truncate company_user cascade; +truncate company cascade; +truncate auth."user" cascade; +reset client_min_messages; + +insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at) +values (1, 'demo@tandem.blog', 'Demo', 'test', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') + , (5, 'admin@tandem.blog', 'Demo', 'test', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +; + +insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code, default_lang_tag) +values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR', 'ca') + , (4, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD', 'es') +; + +insert into company_user (company_id, user_id, role) +values (2, 1, 'employee') + , (4, 5, 'admin') +; + +insert into company_host (company_id, host) +values (2, 'co2') + , (4, 'co4') +; + +select lives_ok( + $$ select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2') $$, + 'Should change ok for the first user' +); + +select is( + current_company_id(), + 2, + 'Should return the company ID of the first user' +); + +reset role; + + +select lives_ok( + $$ select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog', 'co4') $$, + 'Should change ok for the second user' +); + +select is( + current_company_id(), + 4, + 'Should return the cookie of the second user' +); + +reset role; + +select lives_ok( + $$ select set_cookie('', 'co2') $$, + 'Should change ok for a guest user' +); + +select is(current_company_id(), 0, 'Should return zero'); + +reset role; + +select * +from finish(); + +rollback; diff --git a/test/current_user_cookie.sql b/test/current_user_cookie.sql index 6955b01..972ed45 100644 --- a/test/current_user_cookie.sql +++ b/test/current_user_cookie.sql @@ -20,16 +20,34 @@ select function_privs_are('camper', 'current_user_cookie', array []::name[], 'ad select function_privs_are('camper', 'current_user_cookie', array []::name[], 'authenticator', array []::text[]); set client_min_messages to warning; +truncate company_host cascade; +truncate company_user cascade; +truncate company cascade; truncate auth."user" cascade; reset client_min_messages; -insert into auth."user" (user_id, email, name, password, role, cookie, cookie_expires_at) -values (1, 'demo@tandem.blog', 'Demo', 'test', 'employee', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') - , (5, 'admin@tandem.blog', 'Demo', 'test', 'admin', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at) +values (1, 'demo@tandem.blog', 'Demo', 'test', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') + , (5, 'admin@tandem.blog', 'Demo', 'test', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +; + +insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code, default_lang_tag) +values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR', 'ca') + , (4, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD', 'es') +; + +insert into company_user (company_id, user_id, role) +values (2, 1, 'employee') + , (4, 5, 'admin') +; + +insert into company_host (company_id, host) +values (2, 'co2') + , (4, 'co4') ; select lives_ok( - $$ select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog') $$, + $$ select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2') $$, 'Should change ok for the first user' ); @@ -43,7 +61,7 @@ reset role; select lives_ok( - $$ select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog') $$, + $$ select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog', 'co4') $$, 'Should change ok for the second user' ); @@ -56,7 +74,7 @@ select is( reset role; select lives_ok( - $$ select set_cookie('') $$, + $$ select set_cookie('', 'co2') $$, 'Should change ok for a guest user' ); diff --git a/test/current_user_email.sql b/test/current_user_email.sql index 6718796..4aa058e 100644 --- a/test/current_user_email.sql +++ b/test/current_user_email.sql @@ -20,16 +20,34 @@ select function_privs_are('camper', 'current_user_email', array []::name[], 'adm select function_privs_are('camper', 'current_user_email', array []::name[], 'authenticator', array []::text[]); set client_min_messages to warning; +truncate company_host cascade; +truncate company_user cascade; +truncate company cascade; truncate auth."user" cascade; reset client_min_messages; -insert into auth."user" (user_id, email, name, password, role, cookie, cookie_expires_at) -values (1, 'demo@tandem.blog', 'Demo', 'test', 'employee', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') - , (5, 'admin@tandem.blog', 'Demo', 'test', 'admin', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at) +values (1, 'demo@tandem.blog', 'Demo', 'test', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') + , (5, 'admin@tandem.blog', 'Demo', 'test', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +; + +insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code, default_lang_tag) +values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR', 'ca') + , (4, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD', 'es') +; + +insert into company_user (company_id, user_id, role) +values (2, 1, 'employee') + , (4, 5, 'admin') +; + +insert into company_host (company_id, host) +values (2, 'co2') + , (4, 'co4') ; select lives_ok( - $$ select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog') $$, + $$ select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2') $$, 'Should change ok for the first user' ); @@ -39,7 +57,7 @@ reset role; select lives_ok( - $$ select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog') $$, + $$ select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog', 'co4') $$, 'Should change ok for the second user' ); @@ -48,7 +66,7 @@ select is(current_user_email(), 'admin@tandem.blog', 'Should return the email of reset role; select lives_ok( - $$ select set_cookie('') $$, + $$ select set_cookie('', '') $$, 'Should change ok for a guest user' ); diff --git a/test/encrypt_password.sql b/test/encrypt_password.sql index e3a29d8..38dbfb4 100644 --- a/test/encrypt_password.sql +++ b/test/encrypt_password.sql @@ -25,8 +25,8 @@ set client_min_messages to warning; truncate "user" cascade; reset client_min_messages; -insert into "user" (email, name, password, role) -values ('info@tandem.blog', 'Perita', 'test', 'guest'); +insert into "user" (email, name, password) +values ('info@tandem.blog', 'Perita', 'test'); select row_eq( $$ select email from "user" where password = crypt('test', password) $$, diff --git a/test/ensure_role_exists.sql b/test/ensure_role_exists.sql index 2f5f401..efcbed1 100644 --- a/test/ensure_role_exists.sql +++ b/test/ensure_role_exists.sql @@ -7,41 +7,52 @@ begin; select plan(14); -set search_path to auth, public; +set search_path to auth, camper, public; -select has_function('auth', 'ensure_role_exists', array []::name[]); -select function_lang_is('auth', 'ensure_role_exists', array []::name[], 'plpgsql'); -select function_returns('auth', 'ensure_role_exists', array []::name[], 'trigger'); -select isnt_definer('auth', 'ensure_role_exists', array []::name[]); -select volatility_is('auth', 'ensure_role_exists', array []::name[], 'volatile'); -select function_privs_are('auth', 'ensure_role_exists', array []::name[], 'guest', array []::text[]); -select function_privs_are('auth', 'ensure_role_exists', array []::name[], 'employee', array []::text[]); -select function_privs_are('auth', 'ensure_role_exists', array []::name[], 'admin', array []::text[]); -select function_privs_are('auth', 'ensure_role_exists', array []::name[], 'authenticator', array []::text[]); +select has_function('camper', 'ensure_role_exists', array []::name[]); +select function_lang_is('camper', 'ensure_role_exists', array []::name[], 'plpgsql'); +select function_returns('camper', 'ensure_role_exists', array []::name[], 'trigger'); +select isnt_definer('camper', 'ensure_role_exists', array []::name[]); +select volatility_is('camper', 'ensure_role_exists', array []::name[], 'volatile'); +select function_privs_are('camper', 'ensure_role_exists', array []::name[], 'guest', array []::text[]); +select function_privs_are('camper', 'ensure_role_exists', array []::name[], 'employee', array []::text[]); +select function_privs_are('camper', 'ensure_role_exists', array []::name[], 'admin', array []::text[]); +select function_privs_are('camper', 'ensure_role_exists', array []::name[], 'authenticator', array []::text[]); -select trigger_is('user', 'ensure_role_exists', 'ensure_role_exists'); +select trigger_is('company_user', 'ensure_role_exists', 'ensure_role_exists'); set client_min_messages to warning; +truncate company_user cascade; +truncate company cascade; truncate "user" cascade; reset client_min_messages; +insert into auth."user" (user_id, email, name, password) +values (1, 'demo@tandem.blog', 'Demo', 'test') + , (9, 'admin@tandem.blog', 'Demo', 'test') +; + +insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code, default_lang_tag) +values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR', 'ca') +; + select lives_ok( - $$ insert into "user" (email, name, password, role) values ('info@tandem.blog', 'Factura', 'test', 'guest') $$, + $$ insert into company_user (company_id, user_id, role) values (2, 1, 'guest') $$, 'Should be able to insert a user with a valid role' ); select throws_ok( - $$ insert into "user" (email, name, password, role) values ('nope@tandem.blog', 'Factura', 'test', 'non-existing-role') $$, + $$ insert into company_user (companY_id, user_id, role) values (2, 9, 'non-existing-role') $$, '23503', 'role not found: non-existing-role', 'Should not allow insert users with invalid roles' ); -select lives_ok($$ update "user" set role = 'employee' where email = 'info@tandem.blog' $$, +select lives_ok($$ update company_user set role = 'employee' where company_id = 2 and user_id = 1 $$, 'Should be able to change the role of a user to another valid role' ); -select throws_ok($$ update "user" set role = 'usurer' where email = 'info@tandem.blog' $$, +select throws_ok($$ update company_user set role = 'usurer' where company_id = 2 and user_id = 1 $$, '23503', 'role not found: usurer', 'Should not allow update users to invalid roles' diff --git a/test/login.sql b/test/login.sql index 286311c..3c4098e 100644 --- a/test/login.sql +++ b/test/login.sql @@ -24,8 +24,8 @@ truncate auth."user" cascade; truncate auth.login_attempt cascade; reset client_min_messages; -insert into auth."user" (email, name, password, role) -values ('info@tandem.blog', 'Tandem', 'test', 'employee'); +insert into auth."user" (email, name, password) +values ('info@tandem.blog', 'Tandem', 'test'); create temp table _login_test ( diff --git a/test/logout.sql b/test/logout.sql index 4611955..d7bcf57 100644 --- a/test/logout.sql +++ b/test/logout.sql @@ -23,9 +23,9 @@ set client_min_messages to warning; truncate auth."user" cascade; reset client_min_messages; -insert into auth."user" (user_id, email, name, password, role, cookie, cookie_expires_at) -values (1, 'info@tandem.blog', 'Tandem', 'test', 'employee', '8c23d4a8d777775f8fc507676a0d99d3dfa54b03b1b257c838', current_timestamp + interval '1 day') - , (12, 'admin@tandem.blog', 'Admin', 'test', 'admin', '0169e5f668eec1e6749fd25388b057997358efa8dfd697961a', current_timestamp + interval '2 day') +insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at) +values (1, 'info@tandem.blog', 'Tandem', 'test', '8c23d4a8d777775f8fc507676a0d99d3dfa54b03b1b257c838', current_timestamp + interval '1 day') + , (12, 'admin@tandem.blog', 'Admin', 'test', '0169e5f668eec1e6749fd25388b057997358efa8dfd697961a', current_timestamp + interval '2 day') ; prepare user_cookies as diff --git a/test/set_cookie.sql b/test/set_cookie.sql index a701d31..3eb9faa 100644 --- a/test/set_cookie.sql +++ b/test/set_cookie.sql @@ -5,66 +5,97 @@ reset client_min_messages; begin; -select plan(15); +select plan(17); set search_path to auth, camper, public; -select has_function('public', 'set_cookie', array ['text']); -select function_lang_is('public', 'set_cookie', array ['text'], 'sql'); -select function_returns('public', 'set_cookie', array ['text'], 'void'); -select isnt_definer('public', 'set_cookie', array ['text']); -select volatility_is('public', 'set_cookie', array ['text'], 'stable'); -select function_privs_are('public', 'set_cookie', array ['text'], 'guest', array []::text[]); -select function_privs_are('public', 'set_cookie', array ['text'], 'employee', array []::text[]); -select function_privs_are('public', 'set_cookie', array ['text'], 'admin', array []::text[]); -select function_privs_are('public', 'set_cookie', array ['text'], 'authenticator', array ['EXECUTE']); +select has_function('public', 'set_cookie', array ['text', 'text']); +select function_lang_is('public', 'set_cookie', array ['text', 'text'], 'sql'); +select function_returns('public', 'set_cookie', array ['text', 'text'], 'void'); +select isnt_definer('public', 'set_cookie', array ['text', 'text']); +select volatility_is('public', 'set_cookie', array ['text', 'text'], 'stable'); +select function_privs_are('public', 'set_cookie', array ['text', 'text'], 'guest', array []::text[]); +select function_privs_are('public', 'set_cookie', array ['text', 'text'], 'employee', array []::text[]); +select function_privs_are('public', 'set_cookie', array ['text', 'text'], 'admin', array []::text[]); +select function_privs_are('public', 'set_cookie', array ['text', 'text'], 'authenticator', array ['EXECUTE']); set client_min_messages to warning; +truncate company_host cascade; +truncate company_user cascade; +truncate company cascade; truncate auth."user" cascade; reset client_min_messages; -insert into auth."user" (user_id, email, name, password, role, cookie, cookie_expires_at) -values (1, 'demo@tandem.blog', 'Demo', 'test', 'employee', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') - , (5, 'admin@tandem.blog', 'Demo', 'test', 'admin', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at) +values (1, 'demo@tandem.blog', 'Demo', 'test', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month') + , (5, 'admin@tandem.blog', 'Demo', 'test', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month') +; + +insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code, default_lang_tag) +values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR', 'ca') + , (4, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD', 'es') +; + +insert into company_user (company_id, user_id, role) +values (2, 1, 'employee') + , (4, 5, 'admin') +; + +insert into company_host (company_id, host) +values (2, 'co2') + , (4, 'co4') ; prepare user_info as -select current_user_email(), current_user_cookie(), current_user; +select current_user_email(), current_user_cookie(), current_company_id(), current_user; select lives_ok( - $$ select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog') $$, + $$ select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2') $$, 'Should run ok for a valid cookie' ); select results_eq( 'user_info', - $$ values ('demo@tandem.blog', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', 'employee'::name) $$, + $$ values ('demo@tandem.blog', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', 2, 'employee'::name) $$, 'Should have updated the info with the correct user' ); reset role; select lives_ok( - $$ select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog') $$, + $$ select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co4') $$, + 'Should run ok for a valid cookie, even for the wrong company' +); + +select results_eq( + 'user_info', + $$ values ('', '', 0, 'guest'::name) $$, + 'Should have updated the info as a guest user for this company' +); + +reset role; + +select lives_ok( + $$ select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog', 'co4') $$, 'Should run ok for a different cookie' ); select results_eq( 'user_info', - $$ values ('admin@tandem.blog', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', 'admin'::name) $$, + $$ values ('admin@tandem.blog', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', 4, 'admin'::name) $$, 'Should have updated the info with the other user' ); reset role; select lives_ok( - $$ select set_cookie('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/admin@tandem.blog') $$, + $$ select set_cookie('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/admin@tandem.blog', 'asth') $$, 'Should run ok even for an invalid cookie' ); select results_eq( 'user_info', - $$ values ('', '', 'guest'::name) $$, + $$ values ('', '', 0, 'guest'::name) $$, 'Should have updated the info as a guest user' ); diff --git a/test/user.sql b/test/user.sql index e830dac..f95472c 100644 --- a/test/user.sql +++ b/test/user.sql @@ -5,7 +5,7 @@ reset client_min_messages; begin; -select plan(56); +select plan(52); set search_path to auth, public; @@ -45,11 +45,6 @@ select col_type_is('user', 'password', 'text'); select col_not_null('user', 'password'); select col_hasnt_default('user', 'password'); -select has_column('user', 'role'); -select col_type_is('user', 'role', 'name'); -select col_not_null('user', 'role'); -select col_hasnt_default('user', 'role'); - select has_column('user', 'lang_tag'); select col_is_fk('user', 'lang_tag'); select fk_ok('user', 'lang_tag', 'language', 'lang_tag'); diff --git a/test/user_profile.sql b/test/user_profile.sql index 425d909..3c5cdd1 100644 --- a/test/user_profile.sql +++ b/test/user_profile.sql @@ -59,34 +59,51 @@ select column_privs_are('user_profile', 'csrf_token', 'authenticator', array []: set client_min_messages to warning; +truncate company_host cascade; +truncate company_user cascade; +truncate company cascade; truncate auth."user" cascade; reset client_min_messages; -insert into auth."user" (user_id, email, name, password, role, cookie, cookie_expires_at, lang_tag) -values (1, 'demo@tandem.blog', 'Demo', 'test', 'employee', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', - current_timestamp + interval '1 month', 'ca') -, (5, 'admin@tandem.blog', 'Admin', 'test', 'admin', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', - current_timestamp + interval '1 month', 'es') -, (7, 'another@tandem.blog', 'Another Admin', 'test', 'admin', default, default, default) +insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at, lang_tag) +values (1, 'demo@tandem.blog', 'Demo', 'test', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month', 'ca') + , (5, 'admin@tandem.blog', 'Admin', 'test', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month', 'es') + , (7, 'another@tandem.blog', 'Another Admin', 'test', default, default, default) +; + +insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code, default_lang_tag) +values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR', 'ca') + , (4, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', 'FR', 'USD', 'es') +; + +insert into company_user (company_id, user_id, role) +values (2, 1, 'employee') + , (4, 5, 'admin') + , (4, 7, 'admin') +; + +insert into company_host (company_id, host) +values (2, 'co2') + , (4, 'co4') ; prepare profile as -select user_id, email, name, role, lang_tag, csrf_token +select user_id, company_id, email, name, role, lang_tag, csrf_token from user_profile; select set_config('request.user.cookie', '', false); select results_eq( 'profile', - $$ values (0, null::email, '', 'guest'::name, 'und', '') $$, + $$ values (0, 0, null::email, '', 'guest'::name, 'und', '') $$, 'Should be set up with the guest user when no user logged in yet.' ); -select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog'); +select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2'); select results_eq( 'profile', - $$ values (1, 'demo@tandem.blog'::email, 'Demo', 'employee'::name, 'ca', '44facbb30d') $$, + $$ values (1, 2, 'demo@tandem.blog'::email, 'Demo', 'employee'::name, 'ca', '44facbb30d') $$, 'Should only see the profile of the first user' ); @@ -113,17 +130,17 @@ select throws_ok( select results_eq( 'profile', - $$ values (1, 'demo+update@tandem.blog'::email, 'Demo Update', 'employee'::name, 'es', '44facbb30d') $$, + $$ values (1, 2, 'demo+update@tandem.blog'::email, 'Demo Update', 'employee'::name, 'es', '44facbb30d') $$, 'Should see the changed profile of the first user' ); reset role; -select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog'); +select set_cookie('12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524/admin@tandem.blog', 'co4'); select results_eq( 'profile', - $$ values (5, 'admin@tandem.blog'::email, 'Admin', 'admin'::name, 'es', '12af4c88b5') $$, + $$ values (5, 4, 'admin@tandem.blog'::email, 'Admin', 'admin'::name, 'es', '12af4c88b5') $$, 'Should only see the profile of the second user' ); @@ -150,7 +167,7 @@ select throws_ok( select results_eq( 'profile', - $$ values (5, 'admin+update@tandem.blog'::email, 'Admin Update', 'admin'::name, 'ca', '12af4c88b5') $$, + $$ values (5, 4, 'admin+update@tandem.blog'::email, 'Admin Update', 'admin'::name, 'ca', '12af4c88b5') $$, 'Should see the changed profile of the first user' ); diff --git a/verify/campsite_type.sql b/verify/campsite_type.sql index 6eaba0d..db74927 100644 --- a/verify/campsite_type.sql +++ b/verify/campsite_type.sql @@ -12,6 +12,9 @@ from camper.campsite_type where false; select 1 / count(*) from pg_class where oid = 'camper.campsite_type'::regclass and relrowsecurity; -select 1 / count(*) from pg_policy where polname = 'company_policy' and polrelid = 'camper.campsite_type'::regclass; +select 1 / count(*) from pg_policy where polname = 'guest_ok' and polrelid = 'camper.campsite_type'::regclass; +select 1 / count(*) from pg_policy where polname = 'insert_to_company' and polrelid = 'camper.campsite_type'::regclass; +select 1 / count(*) from pg_policy where polname = 'update_company' and polrelid = 'camper.campsite_type'::regclass; +select 1 / count(*) from pg_policy where polname = 'delete_from_company' and polrelid = 'camper.campsite_type'::regclass; rollback; diff --git a/verify/check_cookie.sql b/verify/check_cookie.sql index 116a7bd..059686e 100644 --- a/verify/check_cookie.sql +++ b/verify/check_cookie.sql @@ -2,6 +2,6 @@ begin; -select has_function_privilege('public.check_cookie(text)', 'execute'); +select has_function_privilege('public.check_cookie(text, text)', 'execute'); rollback; diff --git a/verify/company_user.sql b/verify/company_user.sql index 1b5a048..55c9e05 100644 --- a/verify/company_user.sql +++ b/verify/company_user.sql @@ -4,10 +4,8 @@ begin; select company_id , user_id + , role from camper.company_user where false; -select 1 / count(*) from pg_class where oid = 'camper.company'::regclass and relrowsecurity; -select 1 / count(*) from pg_policy where polname = 'company_policy' and polrelid = 'camper.company'::regclass; - rollback; diff --git a/verify/current_company_id.sql b/verify/current_company_id.sql new file mode 100644 index 0000000..c45e20c --- /dev/null +++ b/verify/current_company_id.sql @@ -0,0 +1,7 @@ +-- Verify camper:current_company_id on pg + +begin; + +select has_function_privilege('camper.current_company_id()', 'execute'); + +rollback; diff --git a/verify/ensure_role_exists.sql b/verify/ensure_role_exists.sql index 404f27b..e14f26b 100644 --- a/verify/ensure_role_exists.sql +++ b/verify/ensure_role_exists.sql @@ -2,13 +2,13 @@ begin; -select has_function_privilege('auth.ensure_role_exists()', 'execute'); +select has_function_privilege('camper.ensure_role_exists()', 'execute'); select 1 / count(*) from pg_trigger where not tgisinternal and tgname = 'ensure_role_exists' - and tgrelid = 'auth.user'::regclass + and tgrelid = 'camper.company_user'::regclass and tgtype = b'00010101'::int; -- │││││││ -- ││││││└─> row diff --git a/verify/policies_company.sql b/verify/policies_company.sql new file mode 100644 index 0000000..acbef32 --- /dev/null +++ b/verify/policies_company.sql @@ -0,0 +1,10 @@ +-- Verify camper:policies_company on pg + +begin; + +set search_path to camper, public; +select 1 / count(*) from pg_class where oid = 'company'::regclass and relrowsecurity; +select 1 / count(*) from pg_policy where polname = 'guest_ok' and polrelid = 'company'::regclass; +select 1 / count(*) from pg_policy where polname = 'update_company' and polrelid = 'company'::regclass; + +rollback; diff --git a/verify/set_cookie.sql b/verify/set_cookie.sql index 8e8b140..607ef15 100644 --- a/verify/set_cookie.sql +++ b/verify/set_cookie.sql @@ -2,6 +2,6 @@ begin; -select has_function_privilege('public.set_cookie(text)', 'execute'); +select has_function_privilege('public.set_cookie(text, text)', 'execute'); rollback; diff --git a/verify/user.sql b/verify/user.sql index c2606f6..33deb17 100644 --- a/verify/user.sql +++ b/verify/user.sql @@ -6,7 +6,6 @@ select user_id , email , name , password - , role , lang_tag , cookie , cookie_expires_at