Repository navigation
Expand file tree
/
Copy pathsupabase_rls_security.sql
More file actions
240 lines (194 loc) · 12.8 KB
/
Copy pathsupabase_rls_security.sql
File metadata and controls
240 lines (194 loc) · 12.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
-- ══════════════════════════════════════════════════════════
-- SEGURANÇA: Row Level Security (RLS) — PS Gestão e Capital
-- Proteção no nível do BANCO DE DADOS
-- Mesmo com bug no frontend, dados NUNCA vazam
-- ══════════════════════════════════════════════════════════
-- 1. FUNÇÃO AUXILIAR: verifica se o usuário é admin
CREATE OR REPLACE FUNCTION is_admin()
RETURNS BOOLEAN AS $$
SELECT EXISTS (
SELECT 1 FROM users
WHERE id = auth.uid() AND role = 'adm'
);
$$ LANGUAGE SQL SECURITY DEFINER STABLE;
-- 2. FUNÇÃO AUXILIAR: retorna IDs das empresas que o usuário pode acessar
CREATE OR REPLACE FUNCTION user_company_ids()
RETURNS SETOF UUID AS $$
SELECT company_id FROM user_companies WHERE user_id = auth.uid()
$$ LANGUAGE SQL SECURITY DEFINER STABLE;
-- ══════════════════════════════════════════════════════════
-- 3. COMPANIES — usuário só vê empresas vinculadas
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "companies_select" ON companies;
DROP POLICY IF EXISTS "companies_all" ON companies;
DROP POLICY IF EXISTS "allow_all" ON companies;
CREATE POLICY "companies_select" ON companies FOR SELECT USING (
is_admin() OR id IN (SELECT user_company_ids())
);
CREATE POLICY "companies_insert" ON companies FOR INSERT WITH CHECK (is_admin());
CREATE POLICY "companies_update" ON companies FOR UPDATE USING (is_admin());
CREATE POLICY "companies_delete" ON companies FOR DELETE USING (is_admin());
ALTER TABLE companies ENABLE ROW LEVEL SECURITY;
ALTER TABLE companies FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 4. OMIE_IMPORTS — dados financeiros protegidos
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all" ON omie_imports;
DROP POLICY IF EXISTS "omie_imports_select" ON omie_imports;
CREATE POLICY "omie_imports_select" ON omie_imports FOR SELECT USING (
is_admin() OR company_id IN (SELECT user_company_ids())
);
CREATE POLICY "omie_imports_insert" ON omie_imports FOR INSERT WITH CHECK (
is_admin() OR company_id IN (SELECT user_company_ids())
);
CREATE POLICY "omie_imports_update" ON omie_imports FOR UPDATE USING (
is_admin() OR company_id IN (SELECT user_company_ids())
);
ALTER TABLE omie_imports ENABLE ROW LEVEL SECURITY;
ALTER TABLE omie_imports FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 5. FICHAS TÉCNICAS
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all_ft" ON fichas_tecnicas;
DROP POLICY IF EXISTS "ft_select" ON fichas_tecnicas;
CREATE POLICY "ft_select" ON fichas_tecnicas FOR SELECT USING (
is_admin() OR company_id IN (SELECT user_company_ids())
);
CREATE POLICY "ft_modify" ON fichas_tecnicas FOR ALL USING (
is_admin() OR company_id IN (SELECT user_company_ids())
);
ALTER TABLE fichas_tecnicas ENABLE ROW LEVEL SECURITY;
ALTER TABLE fichas_tecnicas FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 6. FICHA ITENS (via ficha_id → fichas_tecnicas)
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all_fi" ON ficha_itens;
CREATE POLICY "fi_all" ON ficha_itens FOR ALL USING (
is_admin() OR ficha_id IN (
SELECT id FROM fichas_tecnicas WHERE company_id IN (SELECT user_company_ids())
)
);
ALTER TABLE ficha_itens ENABLE ROW LEVEL SECURITY;
ALTER TABLE ficha_itens FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 7. ORÇAMENTO
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all_orc" ON orcamento;
CREATE POLICY "orc_all" ON orcamento FOR ALL USING (
is_admin() OR company_id IN (SELECT user_company_ids())
);
ALTER TABLE orcamento ENABLE ROW LEVEL SECURITY;
ALTER TABLE orcamento FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 8. BALANÇO PATRIMONIAL
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all" ON balanco_patrimonial;
CREATE POLICY "bp_all" ON balanco_patrimonial FOR ALL USING (
is_admin() OR company_id IN (SELECT user_company_ids())
);
ALTER TABLE balanco_patrimonial ENABLE ROW LEVEL SECURITY;
ALTER TABLE balanco_patrimonial FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 9. FINANCIAMENTOS
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all" ON financiamentos;
CREATE POLICY "fin_all" ON financiamentos FOR ALL USING (
is_admin() OR company_id IN (SELECT user_company_ids())
);
ALTER TABLE financiamentos ENABLE ROW LEVEL SECURITY;
ALTER TABLE financiamentos FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 10. BUSINESS LINES
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all" ON business_lines;
DROP POLICY IF EXISTS "allow_all" ON business_line_config;
CREATE POLICY "bl_all" ON business_lines FOR ALL USING (
is_admin() OR company_id IN (SELECT user_company_ids())
);
CREATE POLICY "blc_all" ON business_line_config FOR ALL USING (
is_admin() OR company_id IN (SELECT user_company_ids())
);
ALTER TABLE business_lines ENABLE ROW LEVEL SECURITY;
ALTER TABLE business_lines FORCE ROW LEVEL SECURITY;
ALTER TABLE business_line_config ENABLE ROW LEVEL SECURITY;
ALTER TABLE business_line_config FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 11. CONCILIAÇÃO CARTÃO
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all_cc" ON conciliacao_cartao;
DROP POLICY IF EXISTS "allow_all_ci2" ON conciliacao_itens;
CREATE POLICY "cc_all" ON conciliacao_cartao FOR ALL USING (
is_admin() OR company_id IN (SELECT user_company_ids())
);
CREATE POLICY "ci_all" ON conciliacao_itens FOR ALL USING (
is_admin() OR conciliacao_id IN (
SELECT id FROM conciliacao_cartao WHERE company_id IN (SELECT user_company_ids())
)
);
ALTER TABLE conciliacao_cartao ENABLE ROW LEVEL SECURITY;
ALTER TABLE conciliacao_cartao FORCE ROW LEVEL SECURITY;
ALTER TABLE conciliacao_itens ENABLE ROW LEVEL SECURITY;
ALTER TABLE conciliacao_itens FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 12. USER_COMPANIES — usuário só vê seus próprios vínculos
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all" ON user_companies;
CREATE POLICY "uc_select" ON user_companies FOR SELECT USING (
is_admin() OR user_id = auth.uid()
);
CREATE POLICY "uc_modify" ON user_companies FOR ALL USING (is_admin());
ALTER TABLE user_companies ENABLE ROW LEVEL SECURITY;
ALTER TABLE user_companies FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 13. USERS — cada um vê só a si, admin vê todos
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all" ON users;
CREATE POLICY "users_select" ON users FOR SELECT USING (
is_admin() OR id = auth.uid()
);
CREATE POLICY "users_modify" ON users FOR ALL USING (
is_admin() OR id = auth.uid()
);
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE users FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 14. SUGESTÕES — todos podem criar, admin gerencia
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all" ON sugestoes;
CREATE POLICY "sug_select" ON sugestoes FOR SELECT USING (
is_admin() OR user_id = auth.uid()
);
CREATE POLICY "sug_insert" ON sugestoes FOR INSERT WITH CHECK (true);
CREATE POLICY "sug_update" ON sugestoes FOR UPDATE USING (
is_admin() OR user_id = auth.uid()
);
ALTER TABLE sugestoes ENABLE ROW LEVEL SECURITY;
ALTER TABLE sugestoes FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 15. INVITES — só admin
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all" ON invites;
CREATE POLICY "inv_select" ON invites FOR SELECT USING (is_admin());
CREATE POLICY "inv_insert" ON invites FOR INSERT WITH CHECK (is_admin());
CREATE POLICY "inv_modify" ON invites FOR ALL USING (is_admin());
ALTER TABLE invites ENABLE ROW LEVEL SECURITY;
ALTER TABLE invites FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- 16. COMPANY GROUPS + ORGANIZATIONS — admin vê todos
-- ══════════════════════════════════════════════════════════
DROP POLICY IF EXISTS "allow_all" ON company_groups;
DROP POLICY IF EXISTS "allow_all" ON organizations;
CREATE POLICY "cg_select" ON company_groups FOR SELECT USING (true);
CREATE POLICY "cg_modify" ON company_groups FOR ALL USING (is_admin());
CREATE POLICY "org_all" ON organizations FOR ALL USING (is_admin());
ALTER TABLE company_groups ENABLE ROW LEVEL SECURITY;
ALTER TABLE company_groups FORCE ROW LEVEL SECURITY;
ALTER TABLE organizations ENABLE ROW LEVEL SECURITY;
ALTER TABLE organizations FORCE ROW LEVEL SECURITY;
-- ══════════════════════════════════════════════════════════
-- VERIFICAÇÃO: conferir que tudo está ativo
-- ══════════════════════════════════════════════════════════
SELECT tablename, rowsecurity
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY tablename;