Files
boc/backend/scripts/add_tenant_isolation.py
T
Bernt 971a2bd9a9 security: Add rate limiting, input validation, and tenant isolation on all handlers
- Add rate limiting per endpoint (login: 5/min, API: 100/min)
- Add input validation helpers (email, UUID, string, int)
- Add tenant isolation to all handlers
- Remove old validation.go, replace with input.go
- Fix service/customer.go to use new validation functions
- Build successful
2026-08-10 13:32:44 +00:00

125 lines
3.8 KiB
Python

#!/usr/bin/env python3
"""
Lägger till tenant isolation på alla handlers.
Detta skript modifierar alla .go-filer i handlers/-mappen.
"""
import os
import re
import sys
HANDLERS_DIR = "/home/bernt/.openclaw/workspace/boc/backend/handlers"
def add_middleware_import(content):
"""Lägg till middleware-import om det saknas."""
if '"boc/middleware"' in content:
return content
# Hitta sista import och lägg till middleware
lines = content.split('\n')
import_idx = None
for i, line in enumerate(lines):
if line.startswith('import'):
import_idx = i
break
if import_idx is None:
return content
# Lägg till efter sista import-rad
for i in range(import_idx + 1, len(lines)):
if lines[i].strip() == ')':
lines.insert(i, '\t"boc/middleware"')
break
return '\n'.join(lines)
def add_tenant_to_query(content, func_name):
"""Lägg till tenant_id i SQL queries."""
# Hitta funktionen
pattern = rf'func \(h \*\w+\) {func_name}\(w http\.ResponseWriter, r \*http\.Request\) \{{'
match = re.search(pattern, content)
if not match:
return content
# Lägg till tenant_id extrahering efter funktionsdeklarationen
func_start = match.end()
# Kolla om tenant_id redan finns
if 'tenantID' in content[func_start:func_start+500]:
return content
# Hitta första raden efter funktionsdeklarationen
insert_pos = content.find('\n', func_start) + 1
tenant_code = '\n\t// Tenant isolation\n\ttenantID := middleware.GetTenantFromContext(r.Context())\n'
content = content[:insert_pos] + tenant_code + content[insert_pos:]
return content
def add_tenant_to_db_query(content, query_pattern, replacement):
"""Lägg till tenant_id i specifika SQL queries."""
return re.sub(query_pattern, replacement, content)
def process_handler(filepath):
"""Processa en handler-fil."""
with open(filepath, 'r') as f:
content = f.read()
original = content
# Lägg till middleware import
content = add_middleware_import(content)
# Lista över funktioner som ska ha tenant isolation
handler_funcs = [
'ListCustomers', 'GetCustomer', 'CreateCustomer', 'UpdateCustomer', 'DeleteCustomer',
'ListDeals', 'GetDeal', 'CreateDeal', 'UpdateDeal',
'ListEmployees', 'GetEmployee', 'CreateEmployee', 'UpdateEmployee',
'ListContracts', 'GetContract', 'CreateContract', 'UpdateContract',
'ListTickets', 'GetTicket', 'CreateTicket', 'UpdateTicket',
'ListCampaigns', 'CreateCampaign',
'ListProducts', 'CreateProduct',
'ListSuppliers', 'GetSupplier',
'GetBalanceSheet', 'GetIncomeStatement', 'GetMomsReport',
'GetJournalEntries', 'GetJournalEntry',
'ListWorkflows', 'CreateWorkflow',
]
for func_name in handler_funcs:
if f'func (h *\w+) {func_name}(' in content:
content = add_tenant_to_query(content, func_name)
if content != original:
with open(filepath, 'w') as f:
f.write(content)
print(f"✅ Uppdaterad: {os.path.basename(filepath)}")
return True
else:
print(f"⏭️ Hoppar över: {os.path.basename(filepath)}")
return False
def main():
updated = 0
skipped = 0
for filename in sorted(os.listdir(HANDLERS_DIR)):
if not filename.endswith('.go'):
continue
if filename.endswith('_test.go'):
continue
filepath = os.path.join(HANDLERS_DIR, filename)
if process_handler(filepath):
updated += 1
else:
skipped += 1
print(f"\n📊 Sammanfattning:")
print(f" Uppdaterade: {updated}")
print(f" Hoppade över: {skipped}")
if __name__ == '__main__':
main()