修改过时文档,优化文档内容
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
-- =====================================================================================
|
||||
-- RPC: notify-worker safe recipients lookup (RLS-safe)
|
||||
--
|
||||
-- 背景:
|
||||
-- - public.ml_orders 已开启 RLS,PostgREST 在未携带可解码 JWT 时,auth.uid() 为 NULL,
|
||||
-- 直接 SELECT 会被策略过滤为 0 行,导致 notify-worker 报 “order not found for waybill”。
|
||||
-- - 在一些自托管场景中,Authorization: Bearer <service_role JWT> 可能因 JWT_SECRET 不一致被 PostgREST 拒绝(401 PGRST301)。
|
||||
--
|
||||
-- 方案:
|
||||
-- - 提供 SECURITY DEFINER 的 RPC:只返回订单的收件人映射(user_id / merchant_id)。
|
||||
-- - 通过请求头 x-notify-worker-token 做显式鉴权(避免把表全局 SELECT 放开)。
|
||||
--
|
||||
-- 使用:
|
||||
-- - notify-worker 调用 POST /rest/v1/rpc/notify_get_order_recipients
|
||||
-- 并携带 header: x-notify-worker-token: <NOTIFY_WORKER_RPC_TOKEN>
|
||||
-- =====================================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.notify_get_order_recipients(
|
||||
p_order_id UUID DEFAULT NULL,
|
||||
p_order_no TEXT DEFAULT NULL
|
||||
)
|
||||
RETURNS TABLE (
|
||||
id UUID,
|
||||
order_no VARCHAR,
|
||||
user_id UUID,
|
||||
merchant_id UUID
|
||||
)
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
SET search_path = public
|
||||
AS $func$
|
||||
DECLARE
|
||||
headers_json JSON;
|
||||
token TEXT;
|
||||
expected_token TEXT;
|
||||
BEGIN
|
||||
-- 1) 读取请求头 token(PostgREST 会把 headers 放入 GUC request.headers)
|
||||
expected_token := current_setting('app.notify_worker_token', true);
|
||||
headers_json := NULLIF(current_setting('request.headers', true), '')::json;
|
||||
IF headers_json IS NOT NULL THEN
|
||||
token := headers_json->>'x-notify-worker-token';
|
||||
END IF;
|
||||
|
||||
IF expected_token IS NULL OR expected_token = '' THEN
|
||||
RAISE EXCEPTION 'server misconfigured: app.notify_worker_token is not set';
|
||||
END IF;
|
||||
|
||||
IF token IS NULL OR token <> expected_token THEN
|
||||
RAISE EXCEPTION 'permission denied: invalid x-notify-worker-token';
|
||||
END IF;
|
||||
|
||||
-- 2) 参数校验
|
||||
IF (p_order_id IS NULL OR p_order_id::text = '') AND (p_order_no IS NULL OR btrim(p_order_no) = '') THEN
|
||||
RAISE EXCEPTION 'p_order_id or p_order_no must be provided';
|
||||
END IF;
|
||||
|
||||
-- 3) 返回映射(SECURITY DEFINER 可绕过 RLS;只返回最小必要字段)
|
||||
RETURN QUERY
|
||||
SELECT o.id, o.order_no, o.user_id, o.merchant_id
|
||||
FROM public.ml_orders o
|
||||
WHERE (p_order_id IS NOT NULL AND o.id = p_order_id)
|
||||
OR (p_order_no IS NOT NULL AND o.order_no = p_order_no)
|
||||
LIMIT 1;
|
||||
END;
|
||||
$func$;
|
||||
|
||||
-- 默认收紧:撤销 PUBLIC,按需授予 anon/authenticated/service_role 执行权限。
|
||||
REVOKE ALL ON FUNCTION public.notify_get_order_recipients(UUID, TEXT) FROM PUBLIC;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'anon') THEN
|
||||
GRANT EXECUTE ON FUNCTION public.notify_get_order_recipients(UUID, TEXT) TO anon;
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'authenticated') THEN
|
||||
GRANT EXECUTE ON FUNCTION public.notify_get_order_recipients(UUID, TEXT) TO authenticated;
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'service_role') THEN
|
||||
GRANT EXECUTE ON FUNCTION public.notify_get_order_recipients(UUID, TEXT) TO service_role;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
COMMIT;
|
||||
Reference in New Issue
Block a user