-
Notifications
You must be signed in to change notification settings - Fork 283
refactor(db): remove user team provision triggers #2421
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
base: remove/user-team-provision-triggers
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,183 @@ | ||
| -- +goose Up | ||
|
|
||
| -- The application now owns auth user projection and default team bootstrap. | ||
| -- Remove the legacy database triggers/functions that used to keep public.users | ||
| -- in sync and auto-create default teams on signup. | ||
|
|
||
| DROP TRIGGER IF EXISTS sync_inserts_to_public_users ON auth.users; | ||
| DROP TRIGGER IF EXISTS sync_updates_to_public_users ON auth.users; | ||
| DROP TRIGGER IF EXISTS sync_deletes_to_public_users ON auth.users; | ||
| DROP TRIGGER IF EXISTS post_user_signup ON public.users; | ||
|
|
||
| DROP FUNCTION IF EXISTS public.sync_insert_auth_users_to_public_users_trigger(); | ||
| DROP FUNCTION IF EXISTS public.sync_update_auth_users_to_public_users_trigger(); | ||
| DROP FUNCTION IF EXISTS public.sync_delete_auth_users_to_public_users_trigger(); | ||
| DROP FUNCTION IF EXISTS public.post_user_signup(); | ||
| DROP FUNCTION IF EXISTS public.extra_for_post_user_signup(uuid, uuid); | ||
|
|
||
| DROP POLICY IF EXISTS "Allow to create a new user" ON public.users; | ||
| DROP POLICY IF EXISTS "Allow to select a user" ON public.users; | ||
| DROP POLICY IF EXISTS "Allow to update a user" ON public.users; | ||
| DROP POLICY IF EXISTS "Allow to delete a user" ON public.users; | ||
|
|
||
| DROP POLICY IF EXISTS "Allow to create a team to new user" ON public.teams; | ||
| DROP POLICY IF EXISTS "Allow to create a user team connection to new user" ON public.users_teams; | ||
| DROP POLICY IF EXISTS "Allow to select a team for supabase auth admin" ON public.teams; | ||
|
|
||
| REVOKE INSERT ON public.users FROM trigger_user; | ||
| REVOKE SELECT (id) ON public.users FROM trigger_user; | ||
| REVOKE UPDATE ON public.users FROM trigger_user; | ||
| REVOKE DELETE ON public.users FROM trigger_user; | ||
|
|
||
| REVOKE SELECT, INSERT, TRIGGER ON public.teams FROM trigger_user; | ||
| REVOKE INSERT ON public.users_teams FROM trigger_user; | ||
|
|
||
| -- +goose Down | ||
|
Comment on lines
+28
to
+35
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. 🔴 The Up migration revokes Extended reasoning...What the bug is: The migration explicitly cleans up Code path that triggered these grants: In Why existing code doesn't prevent it: The migration correctly removes the triggers and functions, but the permission cleanup section (lines 28–35 of the new file) only issues REVOKE for Impact: After this migration, Step-by-step proof:
How to fix: Add to the Up migration's REVOKE block: REVOKE INSERT ON public.team_api_keys FROM trigger_user;
REVOKE INSERT ON public.access_tokens FROM trigger_user;
DROP POLICY IF EXISTS "Allow to create a team api key to new user" ON public.team_api_keys;
DROP POLICY IF EXISTS "Allow to create an access token to new user" ON public.access_tokens;And add corresponding GRANT + CREATE POLICY statements to the Down section for symmetry. On the duplicate refutation: A refutation claims this duplicates bug_005. While both bugs cover the missing REVOKEs, this bug additionally identifies the two orphaned RLS policies that were never dropped. The policies independently allow
Comment on lines
+28
to
+35
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. 🟡 The migration revokes all table-level grants from Extended reasoning...What the bug is and how it manifests Migration The specific code path Lines 28–35 of the new migration revoke Why existing code doesn't prevent it PostgreSQL schema-level grants are entirely independent of object-level grants and are not automatically cascaded or cleaned up when object-level grants are revoked. There is no mechanism that automatically removes Impact After this migration, How to fix it Add the following three REVOKE CREATE, USAGE ON SCHEMA public FROM trigger_user;
REVOKE USAGE ON SCHEMA extensions FROM trigger_user;
REVOKE USAGE ON SCHEMA auth FROM trigger_user;Step-by-step proof
|
||
| -- +goose StatementBegin | ||
|
|
||
| GRANT SELECT, INSERT, TRIGGER ON public.teams TO trigger_user; | ||
| GRANT INSERT ON public.users_teams TO trigger_user; | ||
| GRANT INSERT ON public.users TO trigger_user; | ||
| GRANT SELECT (id) ON public.users TO trigger_user; | ||
| GRANT UPDATE ON public.users TO trigger_user; | ||
| GRANT DELETE ON public.users TO trigger_user; | ||
|
|
||
| CREATE POLICY "Allow to create a new user" | ||
| ON public.users | ||
| AS PERMISSIVE | ||
| FOR INSERT | ||
| TO trigger_user | ||
| WITH CHECK (TRUE); | ||
|
|
||
| CREATE POLICY "Allow to select a user" | ||
| ON public.users | ||
| AS PERMISSIVE | ||
| FOR SELECT | ||
| TO trigger_user | ||
| USING (true); | ||
|
|
||
| CREATE POLICY "Allow to update a user" | ||
| ON public.users | ||
| AS PERMISSIVE | ||
| FOR UPDATE | ||
| TO trigger_user | ||
| USING (true) | ||
| WITH CHECK (true); | ||
|
|
||
| CREATE POLICY "Allow to delete a user" | ||
| ON public.users | ||
| AS PERMISSIVE | ||
| FOR DELETE | ||
| TO trigger_user | ||
| USING (true); | ||
|
|
||
| CREATE POLICY "Allow to create a team to new user" | ||
| ON public.teams | ||
| AS PERMISSIVE | ||
| FOR INSERT | ||
| TO trigger_user | ||
| WITH CHECK (TRUE); | ||
|
|
||
| CREATE POLICY "Allow to create a user team connection to new user" | ||
| ON public.users_teams | ||
| AS PERMISSIVE | ||
| FOR INSERT | ||
| TO trigger_user | ||
| WITH CHECK (TRUE); | ||
|
|
||
| CREATE POLICY "Allow to select a team for supabase auth admin" | ||
| ON public.teams | ||
| AS PERMISSIVE | ||
| FOR SELECT | ||
| TO trigger_user | ||
| USING (TRUE); | ||
|
|
||
| CREATE OR REPLACE FUNCTION public.extra_for_post_user_signup(user_id uuid, team_id uuid) | ||
| RETURNS void | ||
| LANGUAGE plpgsql | ||
| AS $extra_for_post_user_signup$ | ||
| DECLARE | ||
| BEGIN | ||
| END | ||
| $extra_for_post_user_signup$ SECURITY DEFINER SET search_path = public; | ||
|
|
||
| ALTER FUNCTION public.extra_for_post_user_signup(uuid, uuid) OWNER TO trigger_user; | ||
|
|
||
| CREATE OR REPLACE FUNCTION public.post_user_signup() | ||
| RETURNS TRIGGER | ||
| LANGUAGE plpgsql | ||
| AS $post_user_signup$ | ||
| DECLARE | ||
| team_id uuid; | ||
| BEGIN | ||
| RAISE NOTICE 'Creating default team for user %', NEW.id; | ||
| INSERT INTO public.teams(name, tier, email) VALUES (NEW.email, 'base_v1', NEW.email) RETURNING id INTO team_id; | ||
| INSERT INTO public.users_teams(user_id, team_id, is_default) VALUES (NEW.id, team_id, true); | ||
| RAISE NOTICE 'Created default team for user % and team %', NEW.id, team_id; | ||
|
|
||
| PERFORM public.extra_for_post_user_signup(NEW.id, team_id); | ||
|
|
||
| RETURN NEW; | ||
| END | ||
| $post_user_signup$ SECURITY DEFINER SET search_path = public; | ||
|
|
||
| ALTER FUNCTION public.post_user_signup() OWNER TO trigger_user; | ||
|
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. Down migration restores incomplete post_user_signup functionMedium Severity The Reviewed by Cursor Bugbot for commit 5f9fdf7. Configure here. |
||
|
|
||
| CREATE OR REPLACE FUNCTION public.sync_insert_auth_users_to_public_users_trigger() RETURNS TRIGGER | ||
| LANGUAGE plpgsql | ||
| AS $func$ | ||
| BEGIN | ||
| INSERT INTO public.users (id, email) | ||
| VALUES (NEW.id, NEW.email); | ||
|
|
||
| RETURN NEW; | ||
| END; | ||
| $func$ SECURITY DEFINER SET search_path = public; | ||
|
|
||
| CREATE OR REPLACE FUNCTION public.sync_update_auth_users_to_public_users_trigger() RETURNS TRIGGER | ||
| LANGUAGE plpgsql | ||
| AS $func$ | ||
| BEGIN | ||
| UPDATE public.users | ||
| SET email = NEW.email, | ||
| updated_at = now() | ||
| WHERE id = NEW.id; | ||
|
|
||
| IF NOT FOUND THEN | ||
| RAISE EXCEPTION 'User with id % does not exist in public.users', NEW.id; | ||
| END IF; | ||
|
|
||
| RETURN NEW; | ||
| END; | ||
| $func$ SECURITY DEFINER SET search_path = public; | ||
|
|
||
| CREATE OR REPLACE FUNCTION public.sync_delete_auth_users_to_public_users_trigger() RETURNS TRIGGER | ||
| LANGUAGE plpgsql | ||
| AS $func$ | ||
| BEGIN | ||
| DELETE FROM public.users WHERE id = OLD.id; | ||
| RETURN OLD; | ||
| END; | ||
| $func$ SECURITY DEFINER SET search_path = public; | ||
|
|
||
| ALTER FUNCTION public.sync_insert_auth_users_to_public_users_trigger() OWNER TO trigger_user; | ||
| ALTER FUNCTION public.sync_update_auth_users_to_public_users_trigger() OWNER TO trigger_user; | ||
| ALTER FUNCTION public.sync_delete_auth_users_to_public_users_trigger() OWNER TO trigger_user; | ||
|
|
||
| CREATE TRIGGER sync_inserts_to_public_users | ||
| AFTER INSERT ON auth.users | ||
| FOR EACH ROW EXECUTE FUNCTION public.sync_insert_auth_users_to_public_users_trigger(); | ||
|
|
||
| CREATE TRIGGER sync_updates_to_public_users | ||
| AFTER UPDATE ON auth.users | ||
| FOR EACH ROW EXECUTE FUNCTION public.sync_update_auth_users_to_public_users_trigger(); | ||
|
|
||
| CREATE TRIGGER sync_deletes_to_public_users | ||
| AFTER DELETE ON auth.users | ||
| FOR EACH ROW EXECUTE FUNCTION public.sync_delete_auth_users_to_public_users_trigger(); | ||
|
|
||
| CREATE TRIGGER post_user_signup | ||
| AFTER INSERT ON public.users | ||
| FOR EACH ROW EXECUTE FUNCTION public.post_user_signup(); | ||
|
|
||
| -- +goose StatementEnd | ||


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.
The trigger_user role itself is not dropped here. The 20231220094836 migration granted CREATE+USAGE ON SCHEMA public, USAGE ON SCHEMA extensions, and USAGE ON SCHEMA auth to trigger_user - none of which are revoked in this migration. After applying this Up, trigger_user retains schema-level access despite having no functions or triggers. If trigger_user is being fully retired, add REVOKE for the schema grants and DROP ROLE IF EXISTS trigger_user (plus restore in Down).