Open3

Supabase の Storage の policy を一覧・削除する

プログラミングをするパンダプログラミングをするパンダ

GUI から Bucket を作成する

Supabase では GUI から Bucket を作成することができる。

postgress の RLS (Row Level Security)機能を使い、Bucket に対してポリシーを設定することができる。このため、参照や更新の制御が可能になる。

具体的には、参照は誰でも OK、アップロードはログインしている人のみなど。

https://supabase.io/docs/guides/storage#policy-examples

ポリシー名の重複に対処する

Bucket の作成と同様に削除も GUI から可能。しかし、Bucket を画面から削除すると、Backet に紐づいているポリシーは削除されない。

このため、同名のポリシーを作成しようとすると、policy 名が重複しているというエラーが出る。

policy "Avatar images are publicly accessible." for table "objects" already exists

これは、ポリシーは pg_policies テーブルに格納されており、このテーブル内ではbucket_nameというカラムは存在せず、リレーションがないため CASCADE で削除されることはないことが原因。

ポリシー名の一覧を表示する

そこで、以下のSQLを実行してポリシー名の一覧を表示する。

select * from pg_policies where schemaname = 'storage';

supabase のSQL実行結果

https://www.postgresql.org/docs/9.6/view-pg-policies.html

プログラミングをするパンダプログラミングをするパンダ

不要なポリシーを削除する

ポリシーは pg_policies テーブルに対して DELETE 文を発行しても削除できない。このため、以下の SQL を実行する。

drop policy if exists "Avatar images are publicly accessible." on storage.objects;

https://www.postgresql.org/docs/9.5/sql-droppolicy.html

ポリシーはstorage.objects(上記画像の schemaname.tablename)テーブルに対するものであるため、on句 以下に書くテーブル名はこれにする。

プログラミングをするパンダプログラミングをするパンダ

Storage を作成する SQL 文

最初は Storage に対して試行錯誤などあるだろうから、作り直しを考えて Policy の drop を全段に加えても良いだろう。

/**
 * avatar
 */
--  drop
drop table if exists "avatars";
drop policy if exists "Avatar images are publicly accessible." on storage.objects;
drop policy if exists "Logged-in user can upload an avatar." on storage.objects;
drop policy if exists "Users can update their own avatar." on storage.objects;
drop policy if exists "Users can delete their own avatar." on storage.objects;

insert into storage.buckets (id, name, public) values ('avatars', 'avatars', true);

-- RLS
create policy "Avatar images are publicly accessible."
  on storage.objects for select using ( bucket_id = 'avatars' );

create policy "Logged-in user can upload an avatar."
  on storage.objects for insert with check ( bucket_id = 'avatars' AND role() = 'authenticated' );

create policy "Users can update their own avatar."
  on storage.objects for update with check ( bucket_id = 'avatars' AND uid() = owner );

create policy "Users can delete their own avatar."
  on storage.objects for update with check ( bucket_id = 'avatars' AND uid() = owner );