feat: Reseller-Rolle + SUPER_ADMIN-Mandantenübersicht
Mandantenfähigkeit ausgebaut: - Neue Rolle RESELLER (company_id NULL); companies.reseller_id + is_active - RLS-Erweiterung (Migration 0034): companies/users zusätzlich auf app.reseller_id gefenced → Reseller sieht/verwaltet DB-seitig nur eigene Firmen, keine personenbezogenen Zeit-/Abwesenheitsdaten (DSGVO: nur Verwaltung) - get_current_user setzt app.reseller_id + Bypass aus für RESELLER - tenant_service: Firma + Erst-Admin (Einladung), Übersicht mit Kennzahlen - Router /reseller/* (Self-Service) und /admin/* (SUPER_ADMIN: Mandanten + Reseller) - Login-Sperre bei deaktiviertem Mandanten - Frontend: TenantsPage (/admin/tenants), eigene ResellerCompaniesPage (/reseller), rollenbasierte Login-Weiterleitung, Nav "Mandanten" für SUPER_ADMIN - 4 neue Tests inkl. Cross-Reseller-RLS-Isolation; 172/172 grün Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -18,9 +18,16 @@ TestSessionLocal = async_sessionmaker(test_engine, class_=AsyncSession, expire_o
|
||||
_BYPASS = "COALESCE(current_setting('app.bypass_rls', true), 'off') = 'on'"
|
||||
_CID = "company_id = NULLIF(current_setting('app.company_id', true), '')::uuid"
|
||||
_IID = "id = NULLIF(current_setting('app.company_id', true), '')::uuid"
|
||||
_RID = "reseller_id = NULLIF(current_setting('app.reseller_id', true), '')::uuid"
|
||||
# Reseller darf User seiner eigenen Firmen verwalten (vgl. Migration 0034)
|
||||
_USER_RESELLER = (
|
||||
"company_id IN (SELECT id FROM companies WHERE "
|
||||
"reseller_id = NULLIF(current_setting('app.reseller_id', true), '')::uuid)"
|
||||
)
|
||||
|
||||
def _rls_using_cid(): return f"({_BYPASS} OR {_CID})"
|
||||
def _rls_using_iid(): return f"({_BYPASS} OR {_IID})"
|
||||
def _rls_using_cid(): return f"({_BYPASS} OR {_CID})"
|
||||
def _rls_using_iid(): return f"({_BYPASS} OR {_IID} OR {_RID})"
|
||||
def _rls_using_users(): return f"({_BYPASS} OR {_CID} OR {_USER_RESELLER})"
|
||||
def _rls_using_join(): return (
|
||||
f"({_BYPASS} OR user_id IN (SELECT id FROM users WHERE {_CID}))"
|
||||
)
|
||||
@@ -55,7 +62,8 @@ async def _apply_rls(conn) -> None:
|
||||
for sql in enable("companies", _rls_using_iid()):
|
||||
await conn.execute(text(sql))
|
||||
for table in _COMPANY_COL_TABLES:
|
||||
for sql in enable(table, _rls_using_cid()):
|
||||
using = _rls_using_users() if table == "users" else _rls_using_cid()
|
||||
for sql in enable(table, using):
|
||||
await conn.execute(text(sql))
|
||||
for table in _USER_JOIN_TABLES:
|
||||
for sql in enable(table, _rls_using_join()):
|
||||
|
||||
Reference in New Issue
Block a user