-
-
Notifications
You must be signed in to change notification settings - Fork 433
feat: setup supabase_realtime_admin
#1852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
leandrocp
wants to merge
9
commits into
main
Choose a base branch
from
lp-revoke-supabase_realtime_admin
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
9353942
feat: setup supabase_realtime_admin
leandrocp 3560c43
Merge branch 'main' into lp-revoke-supabase_realtime_admin
leandrocp 2ce3d1b
use supabase_realtime_admin in compose.tests too
leandrocp 5c2c82f
fixes and cleanup
leandrocp 82eab19
Merge remote-tracking branch 'origin/main' into lp-revoke-supabase_re…
leandrocp 96d353d
feature flag: use_supabase_realtime_admin
leandrocp 0a3e0be
Merge remote-tracking branch 'origin/main' into lp-revoke-supabase_re…
leandrocp 6ed268c
fix tests
leandrocp e171dee
chore: update tenant_db_baseline.json
github-actions[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| -- dev/test | ||
|
|
||
| CREATE SCHEMA IF NOT EXISTS realtime AUTHORIZATION supabase_admin; | ||
| CREATE SCHEMA IF NOT EXISTS _realtime; | ||
|
|
||
| DO $$ | ||
| BEGIN | ||
| IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'supabase_realtime_admin') THEN | ||
| CREATE USER supabase_realtime_admin NOINHERIT CREATEROLE LOGIN REPLICATION; | ||
| END IF; | ||
| END $$; | ||
|
|
||
| ALTER USER supabase_realtime_admin WITH LOGIN REPLICATION PASSWORD 'postgres'; | ||
| ALTER USER supabase_realtime_admin SET search_path = public, extensions, realtime; | ||
| GRANT CREATE ON DATABASE postgres TO supabase_realtime_admin; | ||
| GRANT SET ON PARAMETER log_min_messages TO supabase_realtime_admin; | ||
| GRANT anon, authenticated, service_role TO supabase_realtime_admin; | ||
| GRANT CREATE, USAGE ON SCHEMA public TO supabase_realtime_admin; | ||
| GRANT USAGE ON SCHEMA extensions TO supabase_realtime_admin; | ||
| GRANT USAGE ON SCHEMA auth TO supabase_realtime_admin; | ||
| GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA auth TO supabase_realtime_admin; | ||
| GRANT USAGE ON SCHEMA realtime TO postgres, anon, authenticated, service_role; | ||
| GRANT ALL ON SCHEMA realtime TO supabase_realtime_admin WITH GRANT OPTION; | ||
| GRANT CREATE, USAGE ON SCHEMA _realtime TO supabase_realtime_admin; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
...ime/tenants/repo/migrations/20260506120000_subscription_check_filters_use_pg_attribute.ex
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| defmodule Realtime.Tenants.Migrations.SubscriptionCheckFiltersUsePgAttribute do | ||
| @moduledoc false | ||
|
|
||
| use Ecto.Migration | ||
|
|
||
| def change do | ||
| execute(""" | ||
| create or replace function realtime.subscription_check_filters() | ||
| returns trigger | ||
| language plpgsql | ||
| as $$ | ||
| declare | ||
| col_names text[] = coalesce( | ||
| array_agg(a.attname order by a.attnum), | ||
| '{}'::text[] | ||
| ) | ||
| from | ||
| pg_catalog.pg_attribute a | ||
| where | ||
| a.attrelid = new.entity | ||
| and a.attnum > 0 | ||
| and not a.attisdropped | ||
| and pg_catalog.has_column_privilege( | ||
| (new.claims ->> 'role'), | ||
| a.attrelid, | ||
| a.attnum, | ||
| 'SELECT' | ||
| ); | ||
| filter realtime.user_defined_filter; | ||
| col_type regtype; | ||
|
|
||
| in_val jsonb; | ||
| begin | ||
| for filter in select * from unnest(new.filters) loop | ||
| if not filter.column_name = any(col_names) then | ||
| raise exception 'invalid column for filter %', filter.column_name; | ||
| end if; | ||
|
|
||
| col_type = ( | ||
| select atttypid::regtype | ||
| from pg_catalog.pg_attribute | ||
| where attrelid = new.entity | ||
| and attname = filter.column_name | ||
| ); | ||
| if col_type is null then | ||
| raise exception 'failed to lookup type for column %', filter.column_name; | ||
| end if; | ||
|
|
||
| if filter.op = 'in'::realtime.equality_op then | ||
| in_val = realtime.cast(filter.value, (col_type::text || '[]')::regtype); | ||
| if coalesce(jsonb_array_length(in_val), 0) > 100 then | ||
| raise exception 'too many values for `in` filter. Maximum 100'; | ||
| end if; | ||
| else | ||
| perform realtime.cast(filter.value, col_type); | ||
| end if; | ||
| end loop; | ||
|
|
||
| new.filters = coalesce( | ||
| array_agg(f order by f.column_name, f.op, f.value), | ||
| '{}' | ||
| ) from unnest(new.filters) f; | ||
|
|
||
| return new; | ||
| end; | ||
| $$; | ||
| """) | ||
| end | ||
| end |
73 changes: 73 additions & 0 deletions
73
lib/realtime/tenants/repo/migrations/20260511170200_setup_supabase_realtime_admin.ex
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| defmodule Realtime.Tenants.Migrations.SetupSupabaseRealtimeAdmin do | ||
| @moduledoc false | ||
|
|
||
| use Ecto.Migration | ||
|
|
||
| def change do | ||
| execute(""" | ||
| DO $$ | ||
| BEGIN | ||
| IF (SELECT rolsuper FROM pg_roles WHERE rolname = current_user) THEN | ||
| ALTER ROLE supabase_realtime_admin WITH NOINHERIT CREATEROLE LOGIN REPLICATION; | ||
| ALTER ROLE supabase_realtime_admin SET search_path = public, extensions, realtime; | ||
| GRANT CREATE ON DATABASE postgres TO supabase_realtime_admin; | ||
| GRANT SET ON PARAMETER log_min_messages TO supabase_realtime_admin; | ||
| GRANT anon, authenticated, service_role TO supabase_realtime_admin; | ||
| GRANT CREATE, USAGE ON SCHEMA public TO supabase_realtime_admin; | ||
| GRANT USAGE ON SCHEMA extensions TO supabase_realtime_admin; | ||
| GRANT USAGE ON SCHEMA auth TO supabase_realtime_admin; | ||
| GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA auth TO supabase_realtime_admin; | ||
| GRANT USAGE ON SCHEMA realtime TO postgres, anon, authenticated, service_role; | ||
| GRANT ALL ON SCHEMA realtime TO supabase_realtime_admin WITH GRANT OPTION; | ||
| END IF; | ||
| END $$; | ||
| """) | ||
|
|
||
| execute("ALTER TABLE realtime.messages OWNER TO supabase_realtime_admin") | ||
| execute("ALTER TABLE realtime.subscription OWNER TO supabase_realtime_admin") | ||
| execute("ALTER TYPE realtime.action OWNER TO supabase_realtime_admin") | ||
| execute("ALTER TYPE realtime.equality_op OWNER TO supabase_realtime_admin") | ||
| execute("ALTER TYPE realtime.user_defined_filter OWNER TO supabase_realtime_admin") | ||
| execute("ALTER TYPE realtime.wal_column OWNER TO supabase_realtime_admin") | ||
| execute("ALTER TYPE realtime.wal_rls OWNER TO supabase_realtime_admin") | ||
| execute("ALTER FUNCTION realtime.apply_rls(jsonb, integer) OWNER TO supabase_realtime_admin") | ||
|
|
||
| execute( | ||
| "ALTER FUNCTION realtime.broadcast_changes(text, text, text, text, text, record, record, text) OWNER TO supabase_realtime_admin" | ||
| ) | ||
|
|
||
| execute( | ||
| "ALTER FUNCTION realtime.build_prepared_statement_sql(text, regclass, realtime.wal_column[]) OWNER TO supabase_realtime_admin" | ||
| ) | ||
|
|
||
| execute("ALTER FUNCTION realtime.cast(text, regtype) OWNER TO supabase_realtime_admin") | ||
|
|
||
| execute( | ||
| "ALTER FUNCTION realtime.check_equality_op(realtime.equality_op, regtype, text, text) OWNER TO supabase_realtime_admin" | ||
| ) | ||
|
|
||
| execute( | ||
| "ALTER FUNCTION realtime.is_visible_through_filters(realtime.wal_column[], realtime.user_defined_filter[]) OWNER TO supabase_realtime_admin" | ||
| ) | ||
|
|
||
| execute("ALTER FUNCTION realtime.list_changes(name, name, integer, integer) OWNER TO supabase_realtime_admin") | ||
| execute("ALTER FUNCTION realtime.quote_wal2json(regclass) OWNER TO supabase_realtime_admin") | ||
| execute("ALTER FUNCTION realtime.send(jsonb, text, text, boolean) OWNER TO supabase_realtime_admin") | ||
| execute("ALTER FUNCTION realtime.subscription_check_filters() OWNER TO supabase_realtime_admin") | ||
| execute("ALTER FUNCTION realtime.to_regrole(text) OWNER TO supabase_realtime_admin") | ||
| execute("ALTER FUNCTION realtime.topic() OWNER TO supabase_realtime_admin") | ||
|
|
||
| execute(""" | ||
| DO $$ | ||
| BEGIN | ||
| IF (SELECT rolsuper FROM pg_roles WHERE rolname = current_user) THEN | ||
| REVOKE supabase_realtime_admin FROM postgres; | ||
| END IF; | ||
| END $$; | ||
| """) | ||
|
|
||
| execute("REVOKE CREATE ON SCHEMA realtime FROM postgres") | ||
| execute("REVOKE ALL ON realtime.schema_migrations FROM anon, authenticated, service_role, postgres") | ||
| execute("GRANT USAGE ON SCHEMA realtime TO postgres WITH GRANT OPTION") | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ alias Realtime.Tenants | |
|
|
||
| tenant_name = "realtime-dev" | ||
| default_db_host = "127.0.0.1" | ||
| publication = "supabase_realtime" | ||
|
|
||
| {:ok, tenant} = | ||
| Repo.transaction(fn -> | ||
|
|
@@ -26,7 +27,7 @@ default_db_host = "127.0.0.1" | |
| "settings" => %{ | ||
| "db_name" => System.get_env("DB_NAME", "postgres"), | ||
| "db_host" => System.get_env("DB_HOST", default_db_host), | ||
| "db_user" => System.get_env("DB_USER", "supabase_admin"), | ||
| "db_user" => System.get_env("DB_USER", "supabase_realtime_admin"), | ||
| "db_password" => System.get_env("DB_PASSWORD", "postgres"), | ||
| "db_port" => System.get_env("DB_PORT", "5433"), | ||
| "region" => "us-east-1", | ||
|
|
@@ -43,19 +44,17 @@ default_db_host = "127.0.0.1" | |
| end) | ||
|
|
||
| # Reset Tenant DB | ||
| {:ok, settings} = Database.from_tenant(tenant, "realtime_migrations", :stop) | ||
| settings = %{settings | max_restarts: 0, ssl: false} | ||
| {:ok, tenant_conn} = Database.connect_db(settings) | ||
| publication = "supabase_realtime" | ||
| {:ok, settings} = Database.from_tenant(tenant, "realtime_seeds", :stop) | ||
| {:ok, admin_conn} = Database.connect_db(%{settings | username: "supabase_admin", max_restarts: 0, ssl: false}) | ||
|
|
||
| Postgrex.transaction(tenant_conn, fn db_conn -> | ||
| Postgrex.transaction(admin_conn, fn db_conn -> | ||
| [ | ||
| "grant usage on schema realtime to postgres, anon, authenticated, service_role", | ||
| "grant all on schema realtime to supabase_realtime_admin with grant option", | ||
| "drop publication if exists #{publication}", | ||
| "drop table if exists public.test_tenant;", | ||
| "create table public.test_tenant ( id SERIAL PRIMARY KEY, details text );", | ||
| "grant all on table public.test_tenant to anon;", | ||
| "grant all on table public.test_tenant to supabase_admin;", | ||
| "grant all on table public.test_tenant to authenticated;", | ||
| "drop table if exists public.test_tenant", | ||
| "create table public.test_tenant ( id SERIAL PRIMARY KEY, details text )", | ||
| "grant all on table public.test_tenant to anon, authenticated, supabase_realtime_admin", | ||
| "create publication #{publication} for table public.test_tenant" | ||
| ] | ||
| |> Enum.each(&Postgrex.query!(db_conn, &1)) | ||
|
|
@@ -66,5 +65,3 @@ case Tenants.Migrations.run_migrations(tenant) do | |
| :noop -> :ok | ||
| _ -> raise "Running Migrations failed" | ||
| end | ||
|
|
||
| Tenants.Migrations.run_migrations(tenant) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems redundant so I removed it but not sure about this change. |
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previous function required
grant usagebecause of::regclasscasting, see test"subscription works when role lacks usage permission".