mirror of
https://github.com/Hackdex-App/hackdex-website.git
synced 2026-04-26 08:18:20 -05:00
Implement supabase custom claims
This commit is contained in:
parent
b78e507578
commit
0ac0be342d
|
|
@ -279,6 +279,26 @@ export type Database = {
|
||||||
[_ in never]: never
|
[_ in never]: never
|
||||||
}
|
}
|
||||||
Functions: {
|
Functions: {
|
||||||
|
delete_claim: {
|
||||||
|
Args: { claim: string; uid: string }
|
||||||
|
Returns: string
|
||||||
|
}
|
||||||
|
get_claim: {
|
||||||
|
Args: { claim: string; uid: string }
|
||||||
|
Returns: Json
|
||||||
|
}
|
||||||
|
get_claims: {
|
||||||
|
Args: { uid: string }
|
||||||
|
Returns: Json
|
||||||
|
}
|
||||||
|
get_my_claim: {
|
||||||
|
Args: { claim: string }
|
||||||
|
Returns: Json
|
||||||
|
}
|
||||||
|
get_my_claims: {
|
||||||
|
Args: Record<PropertyKey, never>
|
||||||
|
Returns: Json
|
||||||
|
}
|
||||||
gtrgm_compress: {
|
gtrgm_compress: {
|
||||||
Args: { "": unknown }
|
Args: { "": unknown }
|
||||||
Returns: unknown
|
Returns: unknown
|
||||||
|
|
@ -303,6 +323,14 @@ export type Database = {
|
||||||
Args: Record<PropertyKey, never>
|
Args: Record<PropertyKey, never>
|
||||||
Returns: boolean
|
Returns: boolean
|
||||||
}
|
}
|
||||||
|
is_claims_admin: {
|
||||||
|
Args: Record<PropertyKey, never>
|
||||||
|
Returns: boolean
|
||||||
|
}
|
||||||
|
set_claim: {
|
||||||
|
Args: { claim: string; uid: string; value: Json }
|
||||||
|
Returns: string
|
||||||
|
}
|
||||||
set_limit: {
|
set_limit: {
|
||||||
Args: { "": number }
|
Args: { "": number }
|
||||||
Returns: number
|
Returns: number
|
||||||
|
|
|
||||||
186
supabase/migrations/20251011223628_remote_schema.sql
Normal file
186
supabase/migrations/20251011223628_remote_schema.sql
Normal file
|
|
@ -0,0 +1,186 @@
|
||||||
|
set check_function_bodies = off;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION public.delete_claim(uid uuid, claim text)
|
||||||
|
RETURNS text
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
SECURITY DEFINER
|
||||||
|
SET search_path TO 'public'
|
||||||
|
AS $function$
|
||||||
|
BEGIN
|
||||||
|
IF NOT is_claims_admin() THEN
|
||||||
|
RETURN 'error: access denied';
|
||||||
|
ELSE
|
||||||
|
update auth.users set raw_app_meta_data =
|
||||||
|
raw_app_meta_data - claim where id = uid;
|
||||||
|
return 'OK';
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
$function$
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION public.get_claim(uid uuid, claim text)
|
||||||
|
RETURNS jsonb
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
SECURITY DEFINER
|
||||||
|
SET search_path TO 'public'
|
||||||
|
AS $function$
|
||||||
|
DECLARE retval jsonb;
|
||||||
|
BEGIN
|
||||||
|
IF NOT is_claims_admin() THEN
|
||||||
|
RETURN '{"error":"access denied"}'::jsonb;
|
||||||
|
ELSE
|
||||||
|
select coalesce(raw_app_meta_data->claim, null) from auth.users into retval where id = uid::uuid;
|
||||||
|
return retval;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
$function$
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION public.get_claims(uid uuid)
|
||||||
|
RETURNS jsonb
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
SECURITY DEFINER
|
||||||
|
SET search_path TO 'public'
|
||||||
|
AS $function$
|
||||||
|
DECLARE retval jsonb;
|
||||||
|
BEGIN
|
||||||
|
IF NOT is_claims_admin() THEN
|
||||||
|
RETURN '{"error":"access denied"}'::jsonb;
|
||||||
|
ELSE
|
||||||
|
select raw_app_meta_data from auth.users into retval where id = uid::uuid;
|
||||||
|
return retval;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
$function$
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION public.get_my_claim(claim text)
|
||||||
|
RETURNS jsonb
|
||||||
|
LANGUAGE sql
|
||||||
|
STABLE
|
||||||
|
AS $function$
|
||||||
|
select
|
||||||
|
coalesce(nullif(current_setting('request.jwt.claims', true), '')::jsonb -> 'app_metadata' -> claim, null)
|
||||||
|
$function$
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION public.get_my_claims()
|
||||||
|
RETURNS jsonb
|
||||||
|
LANGUAGE sql
|
||||||
|
STABLE
|
||||||
|
AS $function$
|
||||||
|
select
|
||||||
|
coalesce(nullif(current_setting('request.jwt.claims', true), '')::jsonb -> 'app_metadata', '{}'::jsonb)::jsonb
|
||||||
|
$function$
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION public.is_claims_admin()
|
||||||
|
RETURNS boolean
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $function$
|
||||||
|
BEGIN
|
||||||
|
IF session_user = 'authenticator' THEN
|
||||||
|
--------------------------------------------
|
||||||
|
-- To disallow any authenticated app users
|
||||||
|
-- from editing claims, delete the following
|
||||||
|
-- block of code and replace it with:
|
||||||
|
-- RETURN FALSE;
|
||||||
|
--------------------------------------------
|
||||||
|
IF extract(epoch from now()) > coalesce((current_setting('request.jwt.claims', true)::jsonb)->>'exp', '0')::numeric THEN
|
||||||
|
return false; -- jwt expired
|
||||||
|
END IF;
|
||||||
|
If current_setting('request.jwt.claims', true)::jsonb->>'role' = 'service_role' THEN
|
||||||
|
RETURN true; -- service role users have admin rights
|
||||||
|
END IF;
|
||||||
|
IF coalesce((current_setting('request.jwt.claims', true)::jsonb)->'app_metadata'->'claims_admin', 'false')::bool THEN
|
||||||
|
return true; -- user has claims_admin set to true
|
||||||
|
ELSE
|
||||||
|
return false; -- user does NOT have claims_admin set to true
|
||||||
|
END IF;
|
||||||
|
--------------------------------------------
|
||||||
|
-- End of block
|
||||||
|
--------------------------------------------
|
||||||
|
ELSE -- not a user session, probably being called from a trigger or something
|
||||||
|
return true;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
$function$
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION public.set_claim(uid uuid, claim text, value jsonb)
|
||||||
|
RETURNS text
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
SECURITY DEFINER
|
||||||
|
SET search_path TO 'public'
|
||||||
|
AS $function$
|
||||||
|
BEGIN
|
||||||
|
IF NOT is_claims_admin() THEN
|
||||||
|
RETURN 'error: access denied';
|
||||||
|
ELSE
|
||||||
|
update auth.users set raw_app_meta_data =
|
||||||
|
raw_app_meta_data ||
|
||||||
|
json_build_object(claim, value)::jsonb where id = uid;
|
||||||
|
return 'OK';
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
$function$
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION public.hacks_update_guard()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $function$
|
||||||
|
begin
|
||||||
|
if not public.is_admin() then
|
||||||
|
if new.slug is distinct from old.slug then
|
||||||
|
raise exception 'non-admins cannot change slug';
|
||||||
|
end if;
|
||||||
|
if new.created_by is distinct from old.created_by then
|
||||||
|
raise exception 'non-admins cannot change created_by';
|
||||||
|
end if;
|
||||||
|
if new.approved is distinct from old.approved then
|
||||||
|
raise exception 'non-admins cannot change approved';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
return new;
|
||||||
|
end;
|
||||||
|
$function$
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION public.handle_new_user()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
SECURITY DEFINER
|
||||||
|
SET search_path TO ''
|
||||||
|
AS $function$
|
||||||
|
begin
|
||||||
|
insert into public.profiles (id, full_name, avatar_url)
|
||||||
|
values (new.id, new.raw_user_meta_data->>'full_name', new.raw_user_meta_data->>'avatar_url');
|
||||||
|
return new;
|
||||||
|
end;
|
||||||
|
$function$
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION public.is_admin()
|
||||||
|
RETURNS boolean
|
||||||
|
LANGUAGE sql
|
||||||
|
STABLE
|
||||||
|
AS $function$
|
||||||
|
select
|
||||||
|
coalesce(get_my_claim('claims_admin')::bool,false)
|
||||||
|
$function$
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION public.set_updated_at()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $function$
|
||||||
|
begin
|
||||||
|
new.updated_at = now();
|
||||||
|
return new;
|
||||||
|
end;
|
||||||
|
$function$
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user