70 lines
2.8 KiB
PL/PgSQL
70 lines
2.8 KiB
PL/PgSQL
CREATE OR REPLACE FUNCTION shared.current_tenant_id() RETURNS uuid AS $$
|
|
SELECT CASE
|
|
WHEN setting IS NULL OR setting = '' THEN NULL
|
|
ELSE setting::uuid
|
|
END
|
|
FROM (SELECT current_setting('papercrate.tenant_id', true) AS setting) s;
|
|
$$ LANGUAGE SQL STABLE;
|
|
|
|
CREATE OR REPLACE FUNCTION shared.current_user_id() RETURNS uuid AS $$
|
|
SELECT CASE
|
|
WHEN setting IS NULL OR setting = '' THEN NULL
|
|
ELSE setting::uuid
|
|
END
|
|
FROM (SELECT current_setting('papercrate.user_id', true) AS setting) s;
|
|
$$ LANGUAGE SQL STABLE;
|
|
|
|
CREATE OR REPLACE FUNCTION shared.current_refresh_token_hash() RETURNS text AS $$
|
|
SELECT NULLIF(current_setting('papercrate.refresh_token_hash', true), '')
|
|
$$ LANGUAGE SQL STABLE;
|
|
|
|
-- Helper to create tenant isolation policy
|
|
CREATE OR REPLACE FUNCTION shared.ensure_tenant_policy(table_reg regclass) RETURNS void AS $$
|
|
BEGIN
|
|
EXECUTE format('ALTER TABLE %s ENABLE ROW LEVEL SECURITY', table_reg);
|
|
EXECUTE format('ALTER TABLE %s FORCE ROW LEVEL SECURITY', table_reg);
|
|
EXECUTE format(
|
|
'CREATE POLICY tenant_isolation_policy ON %s USING (tenant_id = shared.current_tenant_id()) WITH CHECK (tenant_id = shared.current_tenant_id())',
|
|
table_reg
|
|
);
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
SELECT shared.ensure_tenant_policy('tenant.correspondents');
|
|
SELECT shared.ensure_tenant_policy('tenant.document_asset_objects');
|
|
SELECT shared.ensure_tenant_policy('tenant.document_assets');
|
|
SELECT shared.ensure_tenant_policy('tenant.document_correspondents');
|
|
SELECT shared.ensure_tenant_policy('tenant.document_tags');
|
|
SELECT shared.ensure_tenant_policy('tenant.document_versions');
|
|
SELECT shared.ensure_tenant_policy('tenant.documents');
|
|
SELECT shared.ensure_tenant_policy('tenant.folders');
|
|
SELECT shared.ensure_tenant_policy('tenant.tags');
|
|
SELECT shared.ensure_tenant_policy('tenant.webdav_tokens');
|
|
|
|
-- user_memberships has a special read policy to allow tenant discovery during login
|
|
ALTER TABLE tenant.user_memberships ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE tenant.user_memberships FORCE ROW LEVEL SECURITY;
|
|
CREATE POLICY tenant_membership_select_policy ON tenant.user_memberships
|
|
USING (
|
|
tenant_id = shared.current_tenant_id()
|
|
OR (
|
|
shared.current_user_id() IS NOT NULL
|
|
AND user_id = shared.current_user_id()
|
|
)
|
|
)
|
|
WITH CHECK (tenant_id = shared.current_tenant_id());
|
|
|
|
ALTER TABLE tenant.refresh_tokens ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE tenant.refresh_tokens FORCE ROW LEVEL SECURITY;
|
|
CREATE POLICY tenant_refresh_token_policy ON tenant.refresh_tokens
|
|
USING (
|
|
tenant_id = shared.current_tenant_id()
|
|
OR (
|
|
shared.current_refresh_token_hash() IS NOT NULL
|
|
AND token_hash = shared.current_refresh_token_hash()
|
|
)
|
|
)
|
|
WITH CHECK (tenant_id = shared.current_tenant_id());
|
|
|
|
DROP FUNCTION shared.ensure_tenant_policy(regclass);
|