feat: add public-read, admin-write RLS policies for salon-images bucket

Adds pgTAP tests and migration to create the salon-images storage bucket
with RLS policies allowing public read access and admin-only write access.
Tests verify anon users can read but not upload, and admin can upload.
This commit is contained in:
belviskhoremk
2026-08-12 10:44:44 +02:00
parent 3c7bb59421
commit acc4b02a20
2 changed files with 40 additions and 1 deletions

View File

@@ -0,0 +1,17 @@
-- The salon-images bucket was created manually in the live project during
-- Phase 2A's Task 8 (private, no policies — reserved for this task). Local
-- dev stacks don't have it at all (it wasn't created via migration), so
-- this creates it if missing and makes it public either way: product/
-- service photos are marketing images meant to be publicly visible once the
-- public site (Sub-project C) reads live data.
insert into storage.buckets (id, name, public)
values ('salon-images', 'salon-images', true)
on conflict (id) do update set public = true;
create policy "salon_images_public_read" on storage.objects
for select using (bucket_id = 'salon-images');
create policy "salon_images_admin_write" on storage.objects
for all
using (bucket_id = 'salon-images' and (select auth.uid()) = '21c90224-e0b2-412e-a431-8e7f097c1cef'::uuid)
with check (bucket_id = 'salon-images' and (select auth.uid()) = '21c90224-e0b2-412e-a431-8e7f097c1cef'::uuid);

View File

@@ -1,5 +1,5 @@
begin; begin;
select plan(12); select plan(15);
-- Seed reference data as service_role (bypasses RLS) -- Seed reference data as service_role (bypasses RLS)
set local role service_role; set local role service_role;
@@ -101,5 +101,27 @@ select lives_ok(
'admin can insert into services' 'admin can insert into services'
); );
-- salon-images bucket: anyone can read, only admin can write
set local role anon;
set local request.jwt.claim.sub = '00000000-0000-0000-0000-000000000000';
select lives_ok(
$$ select * from storage.objects where bucket_id = 'salon-images' $$,
'anon can read salon-images objects'
);
select throws_ok(
$$ insert into storage.objects (bucket_id, name) values ('salon-images', 'test.jpg') $$,
'42501',
null,
'anon cannot upload to salon-images'
);
set local role authenticated;
set local request.jwt.claim.sub = '21c90224-e0b2-412e-a431-8e7f097c1cef';
select lives_ok(
$$ insert into storage.objects (bucket_id, name) values ('salon-images', 'admin-test.jpg') $$,
'admin can upload to salon-images'
);
select * from finish(); select * from finish();
rollback; rollback;