Skip to content

Commit 3a25e0c

Browse files
Fix billing records RLS
1 parent e3ec646 commit 3a25e0c

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
-- Drop the overly broad existing policy
2+
DROP POLICY IF EXISTS "Users can view their billing records" ON public.billing_records;
3+
4+
-- Create more granular and secure RLS policies for billing_records
5+
CREATE POLICY "Users can view their own billing records"
6+
ON public.billing_records
7+
FOR SELECT
8+
TO authenticated
9+
USING (auth.uid() = user_id);
10+
11+
-- System can create billing records (for automated processing)
12+
CREATE POLICY "System can create billing records"
13+
ON public.billing_records
14+
FOR INSERT
15+
TO authenticated
16+
WITH CHECK (auth.uid() = user_id);
17+
18+
-- Only allow updates to specific non-sensitive fields and only by record owner
19+
CREATE POLICY "Users can update limited billing record fields"
20+
ON public.billing_records
21+
FOR UPDATE
22+
TO authenticated
23+
USING (auth.uid() = user_id)
24+
WITH CHECK (
25+
auth.uid() = user_id AND
26+
-- Prevent modification of critical financial data
27+
OLD.total_revenue = NEW.total_revenue AND
28+
OLD.commission_amount = NEW.commission_amount AND
29+
OLD.fee_amount = NEW.fee_amount AND
30+
OLD.stripe_charge_id = NEW.stripe_charge_id AND
31+
OLD.campaign_id = NEW.campaign_id AND
32+
OLD.created_at = NEW.created_at
33+
);
34+
35+
-- No deletion of billing records for audit trail integrity
36+
CREATE POLICY "Billing records cannot be deleted"
37+
ON public.billing_records
38+
FOR DELETE
39+
TO authenticated
40+
USING (false);
41+
42+
-- Create security audit function for billing record access
43+
CREATE OR REPLACE FUNCTION public.log_billing_access(record_id uuid, access_type text)
44+
RETURNS void
45+
LANGUAGE plpgsql
46+
SECURITY DEFINER
47+
SET search_path = public
48+
AS $$
49+
BEGIN
50+
-- Log financial data access for security monitoring
51+
PERFORM public.log_security_event(
52+
'billing_record_access',
53+
auth.uid(),
54+
jsonb_build_object(
55+
'record_id', record_id,
56+
'access_type', access_type,
57+
'timestamp', now()
58+
)
59+
);
60+
END;
61+
$$;
62+
63+
-- Create function to validate billing record ownership before sensitive operations
64+
CREATE OR REPLACE FUNCTION public.validate_billing_record_ownership(record_id uuid)
65+
RETURNS boolean
66+
LANGUAGE plpgsql
67+
SECURITY DEFINER
68+
SET search_path = public
69+
AS $$
70+
DECLARE
71+
record_owner uuid;
72+
BEGIN
73+
SELECT user_id INTO record_owner
74+
FROM billing_records
75+
WHERE id = record_id;
76+
77+
RETURN (record_owner = auth.uid());
78+
END;
79+
$$;

0 commit comments

Comments
 (0)