fix(rls): status-gate user_has_role_in_space + user_has_permission (046)
Lifts the deliberately-deferred SECURITY DEFINER status-gate. The
deferral's blocking reason ('no way to verify it breaks nothing') is
resolved by the integration harness, so the gap is now closed at the
RLS layer too (defense-in-depth beyond D2's app layer): an unverified/
inactive member can no longer exercise a role or permission via direct
PostgREST. Scoped to the two privilege entrypoints; get_user_space_ids
+ user_effective_roles deliberately untouched so unverified self-reads/
onboarding still work. Migration 046 + schema.sql mirror. New
integration test (5) proves both halves: gap closed AND
current/late/approval/unverified-reads all unbroken. 31 integration
tests green; default pnpm test 532/26 hermetic; build clean.
This commit is contained in:
+14
-6
@@ -385,6 +385,7 @@ AS $$
|
||||
WHERE user_id = uid
|
||||
AND space_id = sid
|
||||
AND role::text = ANY(allowed_roles)
|
||||
AND status IN ('current','late') -- privilege-eligible only (046)
|
||||
);
|
||||
$$;
|
||||
|
||||
@@ -1753,12 +1754,19 @@ $$;
|
||||
CREATE OR REPLACE FUNCTION public.user_has_permission(uid uuid, sid uuid, perm text)
|
||||
RETURNS boolean LANGUAGE sql STABLE SECURITY DEFINER SET search_path = public
|
||||
AS $$
|
||||
SELECT public.user_has_role_in_space(uid, sid, ARRAY['admin'])
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.space_role_permissions p
|
||||
WHERE p.space_id = sid AND p.permission = perm
|
||||
AND p.subject IN (SELECT public.user_effective_roles(uid, sid))
|
||||
);
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM public.space_members
|
||||
WHERE user_id = uid AND space_id = sid
|
||||
AND status IN ('current','late') -- no permission unless privilege-eligible (046)
|
||||
)
|
||||
AND (
|
||||
public.user_has_role_in_space(uid, sid, ARRAY['admin'])
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.space_role_permissions p
|
||||
WHERE p.space_id = sid AND p.permission = perm
|
||||
AND p.subject IN (SELECT public.user_effective_roles(uid, sid))
|
||||
)
|
||||
);
|
||||
$$;
|
||||
|
||||
ALTER TABLE public.space_role_permissions ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
Reference in New Issue
Block a user