# /opt/docker/dev/service_finder/backend/app/scripts/seed_org_roles.py """ 🌱 RBAC Phase 1: Seed the fleet.org_roles table. Az audit kimutatta, hogy a fleet.org_roles tábla ÜRES. Ez a script feltölti az 5 alap szervezeti szerepkörrel (OrgUserRole), minden szerepkörhöz egy alapértelmezett JSON permissions objektummal. Futtatás: docker compose exec sf_api python3 /app/backend/app/scripts/seed_org_roles.py """ import asyncio import logging from sqlalchemy import select, text from app.db.session import AsyncSessionLocal from app.models.marketplace.organization import OrgRole logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s]: %(message)s') logger = logging.getLogger("Seed-OrgRoles") # ────────────────────────────────────────────── # ALAPÉRTELMEZETT PERMISSIONS (JSON) SZEREPKÖRÖNKÉNT # ────────────────────────────────────────────── ORG_ROLE_PERMISSIONS = { "OWNER": { "can_manage_organization": True, "can_manage_members": True, "can_manage_vehicles": True, "can_add_expense": True, "can_approve_expense": True, "can_view_financials": True, "can_manage_branches": True, "can_transfer_ownership": True, "can_delete_organization": False, "can_invite_members": True, "can_remove_members": True, "can_edit_settings": True, }, "ADMIN": { "can_manage_organization": False, "can_manage_members": True, "can_manage_vehicles": True, "can_add_expense": True, "can_approve_expense": True, "can_view_financials": True, "can_manage_branches": True, "can_transfer_ownership": False, "can_delete_organization": False, "can_invite_members": True, "can_remove_members": True, "can_edit_settings": True, }, "ACCOUNTANT": { "can_manage_organization": False, "can_manage_members": False, "can_manage_vehicles": False, "can_add_expense": True, "can_approve_expense": True, "can_view_financials": True, "can_manage_branches": False, "can_transfer_ownership": False, "can_delete_organization": False, "can_invite_members": False, "can_remove_members": False, "can_edit_settings": False, }, "DRIVER": { "can_manage_organization": False, "can_manage_members": False, "can_manage_vehicles": False, "can_add_expense": True, "can_approve_expense": False, "can_view_financials": False, "can_manage_branches": False, "can_transfer_ownership": False, "can_delete_organization": False, "can_invite_members": False, "can_remove_members": False, "can_edit_settings": False, }, "VIEWER": { "can_manage_organization": False, "can_manage_members": False, "can_manage_vehicles": False, "can_add_expense": False, "can_approve_expense": False, "can_view_financials": True, "can_manage_branches": False, "can_transfer_ownership": False, "can_delete_organization": False, "can_invite_members": False, "can_remove_members": False, "can_edit_settings": False, }, } ORG_ROLE_DESCRIPTIONS = { "OWNER": "Teljes jogkörrel rendelkező tulajdonos. Minden funkcióhoz hozzáfér, kivéve a szervezet törlését.", "ADMIN": "Teljes körű adminisztrátor. Kezelheti a tagokat, járműveket, költségeket és beállításokat.", "ACCOUNTANT": "Pénzügyi szerepkör. Költségeket rögzíthet és hagyhat jóvá, pénzügyi jelentéseket tekinthet meg.", "DRIVER": "Sofőr szerepkör. Költségeket rögzíthet, de nem hagyhat jóvá. Járműveket nem kezelhet.", "VIEWER": "Csak olvasási jogosultság. Pénzügyi adatokat megtekinthet, de semmit nem módosíthat.", } ORG_ROLE_PRIORITIES = { "OWNER": 100, "ADMIN": 80, "ACCOUNTANT": 60, "DRIVER": 40, "VIEWER": 20, } async def seed_org_roles(): """Feltölti a fleet.org_roles táblát az 5 alap szerepkörrel.""" async with AsyncSessionLocal() as db: logger.info("🔍 Ellenőrzöm a fleet.org_roles tábla tartalmát...") # Ellenőrizzük, hogy vannak-e már rekordok result = await db.execute(select(OrgRole)) existing = result.scalars().all() if existing: logger.info(f"✅ A fleet.org_roles tábla már tartalmaz {len(existing)} rekordot.") logger.info("📋 Meglévő szerepkörök:") for role in existing: logger.info(f" - {role.name_key} (priority: {role.priority})") # Ellenőrizzük, hogy hiányzik-e valamelyik existing_keys = {r.name_key for r in existing} missing = set(ORG_ROLE_PERMISSIONS.keys()) - existing_keys if missing: logger.info(f"➕ Hiányzó szerepkörök: {missing}") else: logger.info("✅ Minden alap szerepkör jelen van.") logger.info("🌱 Feltöltöm a fleet.org_roles táblát...") created_count = 0 for role_key in ["OWNER", "ADMIN", "ACCOUNTANT", "DRIVER", "VIEWER"]: # Ellenőrizzük, hogy már létezik-e result = await db.execute( select(OrgRole).where(OrgRole.name_key == role_key) ) existing_role = result.scalar_one_or_none() if existing_role: logger.info(f" ⏭️ {role_key} már létezik, kihagyva.") continue new_role = OrgRole( name_key=role_key, display_name=role_key.capitalize(), description=ORG_ROLE_DESCRIPTIONS.get(role_key, ""), is_system=True, priority=ORG_ROLE_PRIORITIES.get(role_key, 0), is_active=True, permissions=ORG_ROLE_PERMISSIONS.get(role_key, {}), ) db.add(new_role) created_count += 1 logger.info(f" ✅ {role_key} létrehozva (priority: {new_role.priority})") if created_count > 0: await db.commit() logger.info(f"✅ Sikeresen létrehozva {created_count} új szerepkör.") # ── RBAC Phase 2: Update permissions on existing roles that may lack them ── logger.info("🔄 Ellenőrzöm a meglévő szerepkörök permissions mezőjét...") result = await db.execute(select(OrgRole)) all_roles = result.scalars().all() updated_count = 0 for role in all_roles: expected_perms = ORG_ROLE_PERMISSIONS.get(role.name_key, {}) if role.permissions != expected_perms: role.permissions = expected_perms updated_count += 1 logger.info(f" ✅ {role.name_key} permissions frissítve") if updated_count > 0: await db.commit() logger.info(f"✅ {updated_count} szerepkör permissions mezője frissítve.") else: logger.info("ℹ️ Minden szerepkör permissions mezője naprakész.") # Végeredmény kiírása result = await db.execute( select(OrgRole).order_by(OrgRole.priority.desc()) ) all_roles = result.scalars().all() logger.info(f"\n📊 A fleet.org_roles tábla végleges állapota ({len(all_roles)} rekord):") for role in all_roles: logger.info(f" - {role.name_key:12s} | priority: {role.priority:3d} | active: {role.is_active} | system: {role.is_system}") logger.info(f" Permissions: {ORG_ROLE_PERMISSIONS.get(role.name_key, {})}") async def main(): logger.info("=" * 60) logger.info("🌱 RBAC Phase 1: OrgRole Seed Script") logger.info("=" * 60) await seed_org_roles() logger.info("=" * 60) logger.info("✅ Seed befejeződött.") logger.info("=" * 60) if __name__ == "__main__": asyncio.run(main())