249 lines
7.9 KiB
PL/PgSQL
249 lines
7.9 KiB
PL/PgSQL
-- ============================================================================
|
|
-- GLM HUB — MIGRACIÓN: ACCESO AUTOMÁTICO POR DOMINIO
|
|
-- ============================================================================
|
|
-- Ejecutar una sola vez sobre la base existente.
|
|
-- Resultado:
|
|
-- * Todo correo @gomezleemarketing.com entra automáticamente como Usuario.
|
|
-- * glm_hub_authorized_users conserva solo administradores y bloqueos.
|
|
-- * Los permisos internos de cada aplicación continúan fuera del Hub.
|
|
-- ============================================================================
|
|
|
|
begin;
|
|
|
|
comment on table public.glm_hub_authorized_users is
|
|
'Excepciones de acceso del GLM Hub: administradores activos y usuarios bloqueados. Los usuarios corporativos normales no requieren registro.';
|
|
|
|
-- Permite que cada persona consulte únicamente su propia excepción, incluyendo
|
|
-- un posible bloqueo con is_active = false.
|
|
drop policy if exists "GLM Hub users can read only their active access"
|
|
on public.glm_hub_authorized_users;
|
|
drop policy if exists "GLM Hub users can read their own control record"
|
|
on public.glm_hub_authorized_users;
|
|
|
|
create policy "GLM Hub users can read their own control record"
|
|
on public.glm_hub_authorized_users
|
|
for select
|
|
to authenticated
|
|
using (
|
|
email = lower(coalesce((select auth.jwt() ->> 'email'), ''))
|
|
);
|
|
|
|
-- Garantiza los cinco administradores definidos.
|
|
insert into public.glm_hub_authorized_users (email, full_name, role, is_active)
|
|
values
|
|
('jgomez@gomezleemarketing.com', 'José Leopoldo Gómez', 'admin', true),
|
|
('iaracena@gomezleemarketing.com', 'Isaac Aracena', 'admin', true),
|
|
('ethen@gomezleemarketing.com', 'Eidan Then', 'admin', true),
|
|
('mgomez@gomezleemarketing.com', 'Máximo Gomez', 'admin', true),
|
|
('lmatos@gomezleemarketing.com', 'Luis Matos', 'admin', true)
|
|
on conflict (email) do update
|
|
set
|
|
full_name = excluded.full_name,
|
|
role = excluded.role,
|
|
is_active = true,
|
|
updated_at = now();
|
|
|
|
-- Los usuarios normales ya no requieren una fila. Se conservan administradores
|
|
-- y bloqueos (member con is_active = false).
|
|
delete from public.glm_hub_authorized_users
|
|
where role = 'member'
|
|
and is_active = true;
|
|
|
|
create or replace function public.glm_hub_is_active_user()
|
|
returns boolean
|
|
language plpgsql
|
|
stable
|
|
security definer
|
|
set search_path = ''
|
|
as $$
|
|
declare
|
|
v_email text;
|
|
begin
|
|
v_email := lower(coalesce(auth.jwt() ->> 'email', ''));
|
|
|
|
return
|
|
auth.uid() is not null
|
|
and v_email ~ '^[a-z0-9.!#$%&''*+/=?^_`{|}~-]+@gomezleemarketing\.com$'
|
|
and not exists (
|
|
select 1
|
|
from public.glm_hub_authorized_users as access
|
|
where access.email = v_email
|
|
and access.is_active = false
|
|
);
|
|
end;
|
|
$$;
|
|
|
|
create or replace function public.glm_hub_is_admin()
|
|
returns boolean
|
|
language plpgsql
|
|
stable
|
|
security definer
|
|
set search_path = ''
|
|
as $$
|
|
declare
|
|
v_email text;
|
|
begin
|
|
v_email := lower(coalesce(auth.jwt() ->> 'email', ''));
|
|
|
|
return
|
|
auth.uid() is not null
|
|
and exists (
|
|
select 1
|
|
from public.glm_hub_authorized_users as access
|
|
where access.email = v_email
|
|
and access.role = 'admin'
|
|
and access.is_active = true
|
|
);
|
|
end;
|
|
$$;
|
|
|
|
alter function public.glm_hub_is_active_user() owner to postgres;
|
|
alter function public.glm_hub_is_admin() owner to postgres;
|
|
|
|
revoke all on function public.glm_hub_is_active_user() from public, anon;
|
|
revoke all on function public.glm_hub_is_admin() from public, anon;
|
|
grant execute on function public.glm_hub_is_active_user() to authenticated;
|
|
grant execute on function public.glm_hub_is_admin() to authenticated;
|
|
grant execute on function public.glm_hub_is_active_user() to service_role;
|
|
grant execute on function public.glm_hub_is_admin() to service_role;
|
|
|
|
-- Actualiza la solicitud de acceso para que un usuario corporativo no necesite
|
|
-- existir previamente en glm_hub_authorized_users.
|
|
create or replace function public.glm_hub_prepare_access_request(p_app_id uuid)
|
|
returns jsonb
|
|
language plpgsql
|
|
volatile
|
|
security definer
|
|
set search_path = ''
|
|
as $$
|
|
declare
|
|
v_user_id uuid;
|
|
v_email text;
|
|
v_name text;
|
|
v_control_name text;
|
|
v_role text;
|
|
v_is_active boolean;
|
|
v_app_name text;
|
|
v_app_category text;
|
|
v_request_id uuid;
|
|
begin
|
|
v_user_id := auth.uid();
|
|
v_email := lower(coalesce(auth.jwt() ->> 'email', ''));
|
|
|
|
if v_user_id is null or v_email = '' then
|
|
return jsonb_build_object('ok', false, 'error', 'Tu sesión no es válida. Cierra sesión e inicia nuevamente.');
|
|
end if;
|
|
|
|
if v_email !~ '^[a-z0-9.!#$%&''*+/=?^_`{|}~-]+@gomezleemarketing\.com$' then
|
|
return jsonb_build_object('ok', false, 'error', 'Debes utilizar una cuenta corporativa de GomezLee Marketing.');
|
|
end if;
|
|
|
|
select access.full_name, access.role, access.is_active
|
|
into v_control_name, v_role, v_is_active
|
|
from public.glm_hub_authorized_users as access
|
|
where access.email = v_email
|
|
limit 1;
|
|
|
|
if found and v_is_active = false then
|
|
return jsonb_build_object('ok', false, 'error', 'Tu acceso al GLM Hub está deshabilitado. Contacta a IT Support.');
|
|
end if;
|
|
|
|
if coalesce(v_role, 'member') = 'admin' then
|
|
return jsonb_build_object('ok', false, 'error', 'Los administradores no necesitan solicitar acceso desde el Hub.');
|
|
end if;
|
|
|
|
v_name := coalesce(
|
|
nullif(btrim(v_control_name), ''),
|
|
nullif(btrim(auth.jwt() -> 'user_metadata' ->> 'full_name'), ''),
|
|
nullif(btrim(auth.jwt() -> 'user_metadata' ->> 'name'), ''),
|
|
split_part(v_email, '@', 1)
|
|
);
|
|
|
|
select app.name, app.category
|
|
into v_app_name, v_app_category
|
|
from public.glm_hub_apps as app
|
|
where app.id = p_app_id
|
|
and app.visibility = 'published'
|
|
limit 1;
|
|
|
|
if not found then
|
|
return jsonb_build_object('ok', false, 'error', 'La aplicación seleccionada ya no está publicada.');
|
|
end if;
|
|
|
|
if exists (
|
|
select 1
|
|
from public.glm_hub_access_requests as request
|
|
where request.requester_email = v_email
|
|
and request.app_id = p_app_id
|
|
and request.status = 'pending'
|
|
) then
|
|
return jsonb_build_object(
|
|
'ok', false,
|
|
'code', 'PENDING_EXISTS',
|
|
'error', 'Ya existe una solicitud pendiente para esta aplicación.'
|
|
);
|
|
end if;
|
|
|
|
insert into public.glm_hub_access_requests (
|
|
requester_user_id,
|
|
requester_name,
|
|
requester_email,
|
|
app_id,
|
|
app_name,
|
|
app_category
|
|
)
|
|
values (
|
|
v_user_id,
|
|
v_name,
|
|
v_email,
|
|
p_app_id,
|
|
v_app_name,
|
|
v_app_category
|
|
)
|
|
returning id into v_request_id;
|
|
|
|
return jsonb_build_object(
|
|
'ok', true,
|
|
'requestId', v_request_id,
|
|
'requesterName', v_name,
|
|
'requesterEmail', v_email,
|
|
'appName', v_app_name,
|
|
'appCategory', v_app_category
|
|
);
|
|
end;
|
|
$$;
|
|
|
|
alter function public.glm_hub_prepare_access_request(uuid) owner to postgres;
|
|
revoke all on function public.glm_hub_prepare_access_request(uuid) from public, anon;
|
|
grant execute on function public.glm_hub_prepare_access_request(uuid) to authenticated;
|
|
grant execute on function public.glm_hub_prepare_access_request(uuid) to service_role;
|
|
|
|
notify pgrst, 'reload schema';
|
|
|
|
commit;
|
|
|
|
-- ==========================================================================
|
|
-- OPERACIONES FUTURAS
|
|
-- ==========================================================================
|
|
|
|
-- HACER ADMINISTRADOR:
|
|
-- insert into public.glm_hub_authorized_users (email, full_name, role, is_active)
|
|
-- values ('usuario@gomezleemarketing.com', 'Nombre del usuario', 'admin', true)
|
|
-- on conflict (email) do update
|
|
-- set full_name = excluded.full_name, role = 'admin', is_active = true, updated_at = now();
|
|
|
|
-- DEVOLVER A USUARIO NORMAL:
|
|
-- delete from public.glm_hub_authorized_users
|
|
-- where email = 'usuario@gomezleemarketing.com';
|
|
|
|
-- BLOQUEAR USUARIO:
|
|
-- insert into public.glm_hub_authorized_users (email, full_name, role, is_active)
|
|
-- values ('usuario@gomezleemarketing.com', 'Nombre del usuario', 'member', false)
|
|
-- on conflict (email) do update
|
|
-- set full_name = excluded.full_name, role = 'member', is_active = false, updated_at = now();
|
|
|
|
-- DESBLOQUEAR USUARIO:
|
|
-- delete from public.glm_hub_authorized_users
|
|
-- where email = 'usuario@gomezleemarketing.com'
|
|
-- and role = 'member';
|