Now we have a concept of an avatar at the server, realm, and scene level
and we have the groundwork for a realm store. New uesrs no longer props,
they get a default avatar. New system supports gender
{male,female,neutral} and {child,adult}.
1038 lines
31 KiB
PL/PgSQL
1038 lines
31 KiB
PL/PgSQL
-- Chattyness Row-Level Security Policies
|
|
-- PostgreSQL 18
|
|
--
|
|
-- RLS policies for data isolation and access control
|
|
-- Load via: psql -f schema/policies/001_rls.sql
|
|
--
|
|
-- IMPORTANT: The application must set session variables before queries:
|
|
--
|
|
-- For authenticated users:
|
|
-- SELECT public.set_current_user_id('user-uuid-here');
|
|
-- SELECT public.set_current_realm_id('realm-uuid-here'); -- when in a realm
|
|
--
|
|
-- For guest users:
|
|
-- SELECT public.set_current_user_id(NULL);
|
|
-- SELECT public.set_current_guest_session_id('guest-session-uuid-here');
|
|
-- SELECT public.set_current_realm_id('realm-uuid-here'); -- when in a realm
|
|
--
|
|
-- The chattyness_app role is used by the application backend.
|
|
|
|
\set ON_ERROR_STOP on
|
|
|
|
BEGIN;
|
|
|
|
-- =============================================================================
|
|
-- Grant Usage on Schemas to Application Role
|
|
-- =============================================================================
|
|
|
|
GRANT USAGE ON SCHEMA server TO chattyness_app;
|
|
GRANT USAGE ON SCHEMA auth TO chattyness_app;
|
|
GRANT USAGE ON SCHEMA realm TO chattyness_app;
|
|
GRANT USAGE ON SCHEMA scene TO chattyness_app;
|
|
GRANT USAGE ON SCHEMA chat TO chattyness_app;
|
|
GRANT USAGE ON SCHEMA audit TO chattyness_app;
|
|
|
|
-- =============================================================================
|
|
-- SERVER SCHEMA POLICIES
|
|
-- =============================================================================
|
|
-- Server data is readable by all, writable only by server admins.
|
|
-- =============================================================================
|
|
|
|
-- server.config
|
|
ALTER TABLE server.config ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY server_config_select ON server.config
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
GRANT SELECT ON server.config TO chattyness_app;
|
|
|
|
-- server.staff
|
|
ALTER TABLE server.staff ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY server_staff_select ON server.staff
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
GRANT SELECT ON server.staff TO chattyness_app;
|
|
|
|
-- server.props
|
|
ALTER TABLE server.props ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY server_props_select ON server.props
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY server_props_insert ON server.props
|
|
FOR INSERT TO chattyness_app
|
|
WITH CHECK (public.is_server_admin());
|
|
|
|
CREATE POLICY server_props_update ON server.props
|
|
FOR UPDATE TO chattyness_app
|
|
USING (public.is_server_admin())
|
|
WITH CHECK (public.is_server_admin());
|
|
|
|
CREATE POLICY server_props_delete ON server.props
|
|
FOR DELETE TO chattyness_app
|
|
USING (public.is_server_admin());
|
|
|
|
GRANT SELECT ON server.props TO chattyness_app;
|
|
GRANT INSERT, UPDATE, DELETE ON server.props TO chattyness_app;
|
|
|
|
-- server.avatars
|
|
ALTER TABLE server.avatars ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY server_avatars_select ON server.avatars
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY server_avatars_insert ON server.avatars
|
|
FOR INSERT TO chattyness_app
|
|
WITH CHECK (public.is_server_admin());
|
|
|
|
CREATE POLICY server_avatars_update ON server.avatars
|
|
FOR UPDATE TO chattyness_app
|
|
USING (public.is_server_admin())
|
|
WITH CHECK (public.is_server_admin());
|
|
|
|
CREATE POLICY server_avatars_delete ON server.avatars
|
|
FOR DELETE TO chattyness_app
|
|
USING (public.is_server_admin());
|
|
|
|
GRANT SELECT ON server.avatars TO chattyness_app;
|
|
GRANT INSERT, UPDATE, DELETE ON server.avatars TO chattyness_app;
|
|
|
|
-- server.audio
|
|
ALTER TABLE server.audio ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY server_audio_select ON server.audio
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY server_audio_modify ON server.audio
|
|
FOR ALL TO chattyness_app
|
|
USING (public.is_server_admin())
|
|
WITH CHECK (public.is_server_admin());
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON server.audio TO chattyness_app;
|
|
|
|
-- server.reserved_names
|
|
ALTER TABLE server.reserved_names ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY server_reserved_names_select ON server.reserved_names
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY server_reserved_names_modify ON server.reserved_names
|
|
FOR ALL TO chattyness_app
|
|
USING (public.is_server_admin())
|
|
WITH CHECK (public.is_server_admin());
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON server.reserved_names TO chattyness_app;
|
|
|
|
-- server.scripts
|
|
ALTER TABLE server.scripts ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY server_scripts_select ON server.scripts
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY server_scripts_modify ON server.scripts
|
|
FOR ALL TO chattyness_app
|
|
USING (public.is_server_admin())
|
|
WITH CHECK (public.is_server_admin());
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON server.scripts TO chattyness_app;
|
|
|
|
-- server.ip_bans
|
|
ALTER TABLE server.ip_bans ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY server_ip_bans_select ON server.ip_bans
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY server_ip_bans_modify ON server.ip_bans
|
|
FOR ALL TO chattyness_app
|
|
USING (public.is_server_admin())
|
|
WITH CHECK (public.is_server_admin());
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON server.ip_bans TO chattyness_app;
|
|
|
|
-- server.bans
|
|
ALTER TABLE server.bans ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY server_bans_select ON server.bans
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY server_bans_modify ON server.bans
|
|
FOR ALL TO chattyness_app
|
|
USING (public.is_server_moderator())
|
|
WITH CHECK (public.is_server_moderator());
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON server.bans TO chattyness_app;
|
|
|
|
-- server.mutes
|
|
ALTER TABLE server.mutes ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY server_mutes_select ON server.mutes
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY server_mutes_modify ON server.mutes
|
|
FOR ALL TO chattyness_app
|
|
USING (public.is_server_moderator())
|
|
WITH CHECK (public.is_server_moderator());
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON server.mutes TO chattyness_app;
|
|
|
|
-- server.content_filters
|
|
ALTER TABLE server.content_filters ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY server_content_filters_select ON server.content_filters
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY server_content_filters_modify ON server.content_filters
|
|
FOR ALL TO chattyness_app
|
|
USING (public.is_server_admin())
|
|
WITH CHECK (public.is_server_admin());
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON server.content_filters TO chattyness_app;
|
|
|
|
-- server.moderation_actions
|
|
ALTER TABLE server.moderation_actions ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY server_moderation_actions_target ON server.moderation_actions
|
|
FOR SELECT TO chattyness_app
|
|
USING (target_user_id = public.current_user_id());
|
|
|
|
CREATE POLICY server_moderation_actions_mod ON server.moderation_actions
|
|
FOR ALL TO chattyness_app
|
|
USING (public.is_server_moderator())
|
|
WITH CHECK (public.is_server_moderator());
|
|
|
|
GRANT SELECT, INSERT ON server.moderation_actions TO chattyness_app;
|
|
|
|
-- =============================================================================
|
|
-- AUTH SCHEMA POLICIES
|
|
-- =============================================================================
|
|
|
|
-- auth.users
|
|
ALTER TABLE auth.users ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY auth_users_select ON auth.users
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
id = public.current_user_id()
|
|
OR NOT auth.has_blocked(id, public.current_user_id())
|
|
);
|
|
|
|
CREATE POLICY auth_users_update ON auth.users
|
|
FOR UPDATE TO chattyness_app
|
|
USING (id = public.current_user_id())
|
|
WITH CHECK (id = public.current_user_id());
|
|
|
|
CREATE POLICY auth_users_insert ON auth.users
|
|
FOR INSERT TO chattyness_app
|
|
WITH CHECK (true);
|
|
|
|
CREATE POLICY auth_users_admin ON auth.users
|
|
FOR ALL TO chattyness_app
|
|
USING (public.is_server_admin())
|
|
WITH CHECK (public.is_server_admin());
|
|
|
|
GRANT SELECT, UPDATE ON auth.users TO chattyness_app;
|
|
GRANT INSERT, DELETE ON auth.users TO chattyness_app;
|
|
|
|
-- auth.sessions
|
|
ALTER TABLE auth.sessions ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY auth_sessions_own ON auth.sessions
|
|
FOR ALL TO chattyness_app
|
|
USING (user_id = public.current_user_id())
|
|
WITH CHECK (user_id = public.current_user_id());
|
|
|
|
CREATE POLICY auth_sessions_admin ON auth.sessions
|
|
FOR SELECT TO chattyness_app
|
|
USING (public.is_server_admin());
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON auth.sessions TO chattyness_app;
|
|
|
|
-- auth.guest_sessions
|
|
ALTER TABLE auth.guest_sessions ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY auth_guest_sessions_all ON auth.guest_sessions
|
|
FOR ALL TO chattyness_app
|
|
USING (true)
|
|
WITH CHECK (true);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON auth.guest_sessions TO chattyness_app;
|
|
|
|
-- auth.tower_sessions
|
|
ALTER TABLE auth.tower_sessions ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY auth_tower_sessions_all ON auth.tower_sessions
|
|
FOR ALL TO chattyness_app
|
|
USING (true)
|
|
WITH CHECK (true);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON auth.tower_sessions TO chattyness_app;
|
|
|
|
-- auth.friendships
|
|
ALTER TABLE auth.friendships ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY auth_friendships_own ON auth.friendships
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
friend_a = public.current_user_id()
|
|
OR friend_b = public.current_user_id()
|
|
)
|
|
WITH CHECK (
|
|
friend_a = public.current_user_id()
|
|
OR friend_b = public.current_user_id()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON auth.friendships TO chattyness_app;
|
|
|
|
-- auth.blocks
|
|
ALTER TABLE auth.blocks ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY auth_blocks_own ON auth.blocks
|
|
FOR ALL TO chattyness_app
|
|
USING (blocker_id = public.current_user_id())
|
|
WITH CHECK (blocker_id = public.current_user_id());
|
|
|
|
CREATE POLICY auth_blocks_mod ON auth.blocks
|
|
FOR SELECT TO chattyness_app
|
|
USING (public.is_server_moderator());
|
|
|
|
GRANT SELECT, INSERT, DELETE ON auth.blocks TO chattyness_app;
|
|
|
|
-- auth.mutes (user personal mutes)
|
|
ALTER TABLE auth.mutes ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY auth_mutes_own ON auth.mutes
|
|
FOR ALL TO chattyness_app
|
|
USING (muter_id = public.current_user_id())
|
|
WITH CHECK (muter_id = public.current_user_id());
|
|
|
|
GRANT SELECT, INSERT, DELETE ON auth.mutes TO chattyness_app;
|
|
|
|
-- auth.user_scripts
|
|
ALTER TABLE auth.user_scripts ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY auth_user_scripts_own ON auth.user_scripts
|
|
FOR ALL TO chattyness_app
|
|
USING (user_id = public.current_user_id())
|
|
WITH CHECK (user_id = public.current_user_id());
|
|
|
|
CREATE POLICY auth_user_scripts_admin ON auth.user_scripts
|
|
FOR SELECT TO chattyness_app
|
|
USING (public.is_server_admin());
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON auth.user_scripts TO chattyness_app;
|
|
|
|
-- auth.inventory
|
|
ALTER TABLE auth.inventory ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY auth_inventory_own ON auth.inventory
|
|
FOR ALL TO chattyness_app
|
|
USING (user_id = public.current_user_id())
|
|
WITH CHECK (user_id = public.current_user_id());
|
|
|
|
CREATE POLICY auth_inventory_view ON auth.inventory
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON auth.inventory TO chattyness_app;
|
|
|
|
-- auth.avatars
|
|
ALTER TABLE auth.avatars ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY auth_avatars_own ON auth.avatars
|
|
FOR ALL TO chattyness_app
|
|
USING (user_id = public.current_user_id())
|
|
WITH CHECK (user_id = public.current_user_id());
|
|
|
|
CREATE POLICY auth_avatars_view ON auth.avatars
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON auth.avatars TO chattyness_app;
|
|
|
|
-- auth.active_avatars
|
|
ALTER TABLE auth.active_avatars ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY auth_active_avatars_own ON auth.active_avatars
|
|
FOR ALL TO chattyness_app
|
|
USING (user_id = public.current_user_id())
|
|
WITH CHECK (user_id = public.current_user_id());
|
|
|
|
CREATE POLICY auth_active_avatars_view ON auth.active_avatars
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
-- Allow realm moderators to update forced avatar columns on any user in their realm
|
|
CREATE POLICY auth_active_avatars_mod ON auth.active_avatars
|
|
FOR UPDATE TO chattyness_app
|
|
USING (public.is_realm_moderator(realm_id))
|
|
WITH CHECK (public.is_realm_moderator(realm_id));
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON auth.active_avatars TO chattyness_app;
|
|
|
|
-- =============================================================================
|
|
-- REALM SCHEMA POLICIES
|
|
-- =============================================================================
|
|
|
|
-- realm.realms
|
|
ALTER TABLE realm.realms ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY realm_realms_select ON realm.realms
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
privacy = 'public'
|
|
OR privacy = 'unlisted'
|
|
OR owner_id = public.current_user_id()
|
|
OR public.has_realm_membership(id)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
CREATE POLICY realm_realms_owner ON realm.realms
|
|
FOR UPDATE TO chattyness_app
|
|
USING (owner_id = public.current_user_id())
|
|
WITH CHECK (owner_id = public.current_user_id());
|
|
|
|
CREATE POLICY realm_realms_insert ON realm.realms
|
|
FOR INSERT TO chattyness_app
|
|
WITH CHECK (owner_id = public.current_user_id());
|
|
|
|
CREATE POLICY realm_realms_delete ON realm.realms
|
|
FOR DELETE TO chattyness_app
|
|
USING (owner_id = public.current_user_id() OR public.is_server_admin());
|
|
|
|
CREATE POLICY realm_realms_admin ON realm.realms
|
|
FOR ALL TO chattyness_app
|
|
USING (public.is_server_admin())
|
|
WITH CHECK (public.is_server_admin());
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON realm.realms TO chattyness_app;
|
|
|
|
-- realm.scenes
|
|
ALTER TABLE realm.scenes ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY realm_scenes_select ON realm.scenes
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.realms r
|
|
WHERE r.id = realm_id
|
|
AND (
|
|
r.privacy IN ('public', 'unlisted')
|
|
OR r.owner_id = public.current_user_id()
|
|
OR public.has_realm_membership(r.id)
|
|
OR public.is_server_admin()
|
|
)
|
|
)
|
|
);
|
|
|
|
CREATE POLICY realm_scenes_modify ON realm.scenes
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.memberships m
|
|
WHERE m.realm_id = realm.scenes.realm_id
|
|
AND m.user_id = public.current_user_id()
|
|
AND m.role IN ('owner', 'builder')
|
|
)
|
|
OR public.is_server_admin()
|
|
)
|
|
WITH CHECK (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.memberships m
|
|
WHERE m.realm_id = realm.scenes.realm_id
|
|
AND m.user_id = public.current_user_id()
|
|
AND m.role IN ('owner', 'builder')
|
|
)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON realm.scenes TO chattyness_app;
|
|
|
|
-- realm.memberships
|
|
ALTER TABLE realm.memberships ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY realm_memberships_select ON realm.memberships
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
user_id = public.current_user_id()
|
|
OR EXISTS (
|
|
SELECT 1 FROM realm.realms r
|
|
WHERE r.id = realm_id
|
|
AND (r.privacy = 'public' OR public.has_realm_membership(r.id))
|
|
)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
CREATE POLICY realm_memberships_own ON realm.memberships
|
|
FOR ALL TO chattyness_app
|
|
USING (user_id = public.current_user_id())
|
|
WITH CHECK (user_id = public.current_user_id());
|
|
|
|
CREATE POLICY realm_memberships_mod ON realm.memberships
|
|
FOR ALL TO chattyness_app
|
|
USING (public.is_realm_moderator(realm_id))
|
|
WITH CHECK (public.is_realm_moderator(realm_id));
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON realm.memberships TO chattyness_app;
|
|
|
|
-- realm.realm_scripts
|
|
ALTER TABLE realm.realm_scripts ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY realm_realm_scripts_select ON realm.realm_scripts
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.realms r
|
|
WHERE r.id = realm_id
|
|
)
|
|
);
|
|
|
|
CREATE POLICY realm_realm_scripts_modify ON realm.realm_scripts
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.memberships m
|
|
WHERE m.realm_id = realm.realm_scripts.realm_id
|
|
AND m.user_id = public.current_user_id()
|
|
AND m.role IN ('owner', 'builder')
|
|
)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON realm.realm_scripts TO chattyness_app;
|
|
|
|
-- realm.props
|
|
ALTER TABLE realm.props ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY realm_props_select ON realm.props
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
public.has_realm_membership(realm_id)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
CREATE POLICY realm_props_modify ON realm.props
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.memberships m
|
|
WHERE m.realm_id = realm.props.realm_id
|
|
AND m.user_id = public.current_user_id()
|
|
AND m.role IN ('owner', 'builder')
|
|
)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON realm.props TO chattyness_app;
|
|
|
|
-- realm.avatars
|
|
ALTER TABLE realm.avatars ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY realm_avatars_select ON realm.avatars
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
public.has_realm_membership(realm_id)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
CREATE POLICY realm_avatars_modify ON realm.avatars
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.memberships m
|
|
WHERE m.realm_id = realm.avatars.realm_id
|
|
AND m.user_id = public.current_user_id()
|
|
AND m.role IN ('owner', 'builder')
|
|
)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON realm.avatars TO chattyness_app;
|
|
|
|
-- realm.reports
|
|
ALTER TABLE realm.reports ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY realm_reports_own ON realm.reports
|
|
FOR SELECT TO chattyness_app
|
|
USING (reporter_id = public.current_user_id());
|
|
|
|
CREATE POLICY realm_reports_insert ON realm.reports
|
|
FOR INSERT TO chattyness_app
|
|
WITH CHECK (reporter_id = public.current_user_id());
|
|
|
|
CREATE POLICY realm_reports_mod ON realm.reports
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
public.is_server_moderator()
|
|
OR public.is_realm_moderator(realm_id)
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE ON realm.reports TO chattyness_app;
|
|
|
|
-- realm.bans
|
|
ALTER TABLE realm.bans ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY realm_bans_select ON realm.bans
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY realm_bans_modify ON realm.bans
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
public.is_server_moderator()
|
|
OR public.is_realm_moderator(realm_id)
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON realm.bans TO chattyness_app;
|
|
|
|
-- realm.mutes (realm moderation mutes)
|
|
ALTER TABLE realm.mutes ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY realm_mutes_select ON realm.mutes
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY realm_mutes_modify ON realm.mutes
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
public.is_server_moderator()
|
|
OR public.is_realm_moderator(realm_id)
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON realm.mutes TO chattyness_app;
|
|
|
|
-- realm.content_filters
|
|
ALTER TABLE realm.content_filters ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY realm_content_filters_select ON realm.content_filters
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
public.has_realm_membership(realm_id)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
CREATE POLICY realm_content_filters_modify ON realm.content_filters
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.memberships m
|
|
WHERE m.realm_id = realm.content_filters.realm_id
|
|
AND m.user_id = public.current_user_id()
|
|
AND m.role IN ('owner', 'moderator')
|
|
)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON realm.content_filters TO chattyness_app;
|
|
|
|
-- realm.moderation_actions
|
|
ALTER TABLE realm.moderation_actions ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY realm_moderation_actions_target ON realm.moderation_actions
|
|
FOR SELECT TO chattyness_app
|
|
USING (target_user_id = public.current_user_id());
|
|
|
|
CREATE POLICY realm_moderation_actions_mod ON realm.moderation_actions
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
public.is_server_moderator()
|
|
OR public.is_realm_moderator(realm_id)
|
|
);
|
|
|
|
GRANT SELECT, INSERT ON realm.moderation_actions TO chattyness_app;
|
|
|
|
-- =============================================================================
|
|
-- SCENE SCHEMA POLICIES
|
|
-- =============================================================================
|
|
|
|
-- scene.instances
|
|
ALTER TABLE scene.instances ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY scene_instances_select ON scene.instances
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
instance_type = 'public'
|
|
AND EXISTS (
|
|
SELECT 1 FROM realm.scenes s
|
|
JOIN realm.realms r ON r.id = s.realm_id
|
|
WHERE s.id = scene_id
|
|
AND (
|
|
r.privacy IN ('public', 'unlisted')
|
|
OR r.owner_id = public.current_user_id()
|
|
OR public.has_realm_membership(r.id)
|
|
)
|
|
)
|
|
OR
|
|
(
|
|
instance_type = 'private'
|
|
AND (
|
|
created_by = public.current_user_id()
|
|
OR EXISTS (
|
|
SELECT 1 FROM scene.instance_invites ii
|
|
WHERE ii.instance_id = scene.instances.id
|
|
AND ii.invited_user_id = public.current_user_id()
|
|
AND ii.accepted_at IS NOT NULL
|
|
)
|
|
)
|
|
)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
CREATE POLICY scene_instances_insert ON scene.instances
|
|
FOR INSERT TO chattyness_app
|
|
WITH CHECK (true);
|
|
|
|
CREATE POLICY scene_instances_modify ON scene.instances
|
|
FOR UPDATE TO chattyness_app
|
|
USING (
|
|
created_by = public.current_user_id()
|
|
OR public.is_realm_moderator(
|
|
(SELECT s.realm_id FROM realm.scenes s WHERE s.id = scene_id)
|
|
)
|
|
);
|
|
|
|
CREATE POLICY scene_instances_delete ON scene.instances
|
|
FOR DELETE TO chattyness_app
|
|
USING (
|
|
created_by = public.current_user_id()
|
|
OR public.is_realm_moderator(
|
|
(SELECT s.realm_id FROM realm.scenes s WHERE s.id = scene_id)
|
|
)
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON scene.instances TO chattyness_app;
|
|
|
|
-- scene.instance_members
|
|
ALTER TABLE scene.instance_members ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY scene_instance_members_select ON scene.instance_members
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.scenes s
|
|
WHERE s.id = instance_id
|
|
)
|
|
);
|
|
|
|
CREATE POLICY scene_instance_members_own ON scene.instance_members
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
user_id = public.current_user_id()
|
|
OR guest_session_id = public.current_guest_session_id()
|
|
)
|
|
WITH CHECK (
|
|
user_id = public.current_user_id()
|
|
OR guest_session_id = public.current_guest_session_id()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON scene.instance_members TO chattyness_app;
|
|
|
|
-- scene.instance_invites
|
|
ALTER TABLE scene.instance_invites ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY scene_instance_invites_select ON scene.instance_invites
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
invited_user_id = public.current_user_id()
|
|
OR invited_by = public.current_user_id()
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
CREATE POLICY scene_instance_invites_own ON scene.instance_invites
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
invited_user_id = public.current_user_id()
|
|
OR invited_by = public.current_user_id()
|
|
)
|
|
WITH CHECK (
|
|
invited_by = public.current_user_id()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON scene.instance_invites TO chattyness_app;
|
|
|
|
-- scene.spots
|
|
ALTER TABLE scene.spots ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY scene_spots_select ON scene.spots
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.scenes s
|
|
WHERE s.id = scene_id
|
|
)
|
|
);
|
|
|
|
CREATE POLICY scene_spots_modify ON scene.spots
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.scenes s
|
|
JOIN realm.memberships m ON m.realm_id = s.realm_id
|
|
WHERE s.id = scene_id
|
|
AND m.user_id = public.current_user_id()
|
|
AND m.role IN ('owner', 'builder')
|
|
)
|
|
OR public.is_server_admin()
|
|
)
|
|
WITH CHECK (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.scenes s
|
|
JOIN realm.memberships m ON m.realm_id = s.realm_id
|
|
WHERE s.id = scene_id
|
|
AND m.user_id = public.current_user_id()
|
|
AND m.role IN ('owner', 'builder')
|
|
)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON scene.spots TO chattyness_app;
|
|
|
|
-- scene.spot_states
|
|
ALTER TABLE scene.spot_states ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY scene_spot_states_select ON scene.spot_states
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM scene.spots sp
|
|
WHERE sp.id = spot_id
|
|
)
|
|
);
|
|
|
|
CREATE POLICY scene_spot_states_modify ON scene.spot_states
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM scene.spots sp
|
|
JOIN realm.scenes s ON s.id = sp.scene_id
|
|
JOIN realm.memberships m ON m.realm_id = s.realm_id
|
|
WHERE sp.id = spot_id
|
|
AND m.user_id = public.current_user_id()
|
|
AND m.role IN ('owner', 'builder')
|
|
)
|
|
OR public.is_server_admin()
|
|
)
|
|
WITH CHECK (
|
|
EXISTS (
|
|
SELECT 1 FROM scene.spots sp
|
|
JOIN realm.scenes s ON s.id = sp.scene_id
|
|
JOIN realm.memberships m ON m.realm_id = s.realm_id
|
|
WHERE sp.id = spot_id
|
|
AND m.user_id = public.current_user_id()
|
|
AND m.role IN ('owner', 'builder')
|
|
)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON scene.spot_states TO chattyness_app;
|
|
|
|
-- scene.scripts
|
|
ALTER TABLE scene.scripts ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY scene_scripts_select ON scene.scripts
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.scenes s
|
|
WHERE s.id = scene_id
|
|
)
|
|
);
|
|
|
|
CREATE POLICY scene_scripts_modify ON scene.scripts
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.scenes s
|
|
JOIN realm.memberships m ON m.realm_id = s.realm_id
|
|
WHERE s.id = scene_id
|
|
AND m.user_id = public.current_user_id()
|
|
AND m.role IN ('owner', 'builder')
|
|
)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON scene.scripts TO chattyness_app;
|
|
|
|
-- scene.loose_props
|
|
ALTER TABLE scene.loose_props ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY scene_loose_props_select ON scene.loose_props
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM scene.instances i
|
|
WHERE i.id = instance_id
|
|
)
|
|
);
|
|
|
|
CREATE POLICY scene_loose_props_modify ON scene.loose_props
|
|
FOR ALL TO chattyness_app
|
|
USING (true)
|
|
WITH CHECK (true);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON scene.loose_props TO chattyness_app;
|
|
|
|
-- scene.decorations
|
|
ALTER TABLE scene.decorations ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY scene_decorations_select ON scene.decorations
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.scenes s
|
|
WHERE s.id = scene_id
|
|
)
|
|
);
|
|
|
|
CREATE POLICY scene_decorations_modify ON scene.decorations
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM realm.scenes s
|
|
JOIN realm.memberships m ON m.realm_id = s.realm_id
|
|
WHERE s.id = scene_id
|
|
AND m.user_id = public.current_user_id()
|
|
AND m.role IN ('owner', 'builder')
|
|
)
|
|
OR public.is_server_admin()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON scene.decorations TO chattyness_app;
|
|
|
|
-- =============================================================================
|
|
-- CHAT SCHEMA POLICIES
|
|
-- =============================================================================
|
|
|
|
-- chat.messages
|
|
ALTER TABLE chat.messages ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY chat_messages_select ON chat.messages
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
(NOT is_deleted OR public.is_server_moderator())
|
|
AND EXISTS (
|
|
SELECT 1 FROM scene.instances i
|
|
WHERE i.id = instance_id
|
|
)
|
|
);
|
|
|
|
CREATE POLICY chat_messages_insert ON chat.messages
|
|
FOR INSERT TO chattyness_app
|
|
WITH CHECK (
|
|
user_id = public.current_user_id()
|
|
OR guest_session_id = public.current_guest_session_id()
|
|
);
|
|
|
|
CREATE POLICY chat_messages_update ON chat.messages
|
|
FOR UPDATE TO chattyness_app
|
|
USING (
|
|
user_id = public.current_user_id()
|
|
OR guest_session_id = public.current_guest_session_id()
|
|
OR public.is_server_moderator()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE ON chat.messages TO chattyness_app;
|
|
|
|
-- chat.whispers
|
|
ALTER TABLE chat.whispers ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY chat_whispers_own ON chat.whispers
|
|
FOR ALL TO chattyness_app
|
|
USING (
|
|
sender_id = public.current_user_id()
|
|
OR recipient_id = public.current_user_id()
|
|
)
|
|
WITH CHECK (
|
|
sender_id = public.current_user_id()
|
|
);
|
|
|
|
GRANT SELECT, INSERT, UPDATE ON chat.whispers TO chattyness_app;
|
|
|
|
-- chat.reactions
|
|
ALTER TABLE chat.reactions ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY chat_reactions_select ON chat.reactions
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY chat_reactions_own ON chat.reactions
|
|
FOR ALL TO chattyness_app
|
|
USING (user_id = public.current_user_id())
|
|
WITH CHECK (user_id = public.current_user_id());
|
|
|
|
GRANT SELECT, INSERT, DELETE ON chat.reactions TO chattyness_app;
|
|
|
|
-- chat.shouts
|
|
ALTER TABLE chat.shouts ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY chat_shouts_select ON chat.shouts
|
|
FOR SELECT TO chattyness_app
|
|
USING (true);
|
|
|
|
CREATE POLICY chat_shouts_insert ON chat.shouts
|
|
FOR INSERT TO chattyness_app
|
|
WITH CHECK (public.is_server_admin());
|
|
|
|
GRANT SELECT, INSERT ON chat.shouts TO chattyness_app;
|
|
|
|
-- =============================================================================
|
|
-- AUDIT SCHEMA POLICIES
|
|
-- =============================================================================
|
|
|
|
-- audit.events
|
|
ALTER TABLE audit.events ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY audit_events_own ON audit.events
|
|
FOR SELECT TO chattyness_app
|
|
USING (user_id = public.current_user_id());
|
|
|
|
CREATE POLICY audit_events_admin ON audit.events
|
|
FOR SELECT TO chattyness_app
|
|
USING (public.is_server_admin());
|
|
|
|
CREATE POLICY audit_events_realm ON audit.events
|
|
FOR SELECT TO chattyness_app
|
|
USING (
|
|
realm_id IS NOT NULL
|
|
AND EXISTS (
|
|
SELECT 1 FROM realm.realms r
|
|
WHERE r.id = realm_id
|
|
AND r.owner_id = public.current_user_id()
|
|
)
|
|
);
|
|
|
|
CREATE POLICY audit_events_insert ON audit.events
|
|
FOR INSERT TO chattyness_app
|
|
WITH CHECK (true);
|
|
|
|
GRANT SELECT, INSERT ON audit.events TO chattyness_app;
|
|
|
|
-- audit.login_history
|
|
ALTER TABLE audit.login_history ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY audit_login_history_own ON audit.login_history
|
|
FOR SELECT TO chattyness_app
|
|
USING (user_id = public.current_user_id());
|
|
|
|
CREATE POLICY audit_login_history_admin ON audit.login_history
|
|
FOR SELECT TO chattyness_app
|
|
USING (public.is_server_admin());
|
|
|
|
CREATE POLICY audit_login_history_insert ON audit.login_history
|
|
FOR INSERT TO chattyness_app
|
|
WITH CHECK (true);
|
|
|
|
GRANT SELECT, INSERT ON audit.login_history TO chattyness_app;
|
|
|
|
COMMIT;
|