From f960a4cf0d23d4f29daf58a41fe58446cc97ed76 Mon Sep 17 00:00:00 2001 From: Maciej Pienczyn Date: Fri, 13 Mar 2026 11:20:25 +0100 Subject: [PATCH] feat: add SUPERADMIN role (200) with full audit access Replace hardcoded email check for audit panels with role-based SUPERADMIN check. ADMIN retains all management capabilities but SUPERADMIN adds access to technical audits (SEO, IT, GBP, Social, Access Control). Co-Authored-By: Claude Opus 4.6 --- database.py | 8 ++++++-- utils/decorators.py | 8 +++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/database.py b/database.py index 2e9386c..4dbbd80 100644 --- a/database.py +++ b/database.py @@ -50,7 +50,8 @@ class SystemRole(IntEnum): - EMPLOYEE (30): Pracownik firmy członkowskiej - może edytować dane firmy - MANAGER (40): Kadra zarządzająca - pełna kontrola firmy + zarządzanie użytkownikami - OFFICE_MANAGER (50): Kierownik biura Norda - panel admina (bez użytkowników) - - ADMIN (100): Administrator portalu - pełne prawa + - ADMIN (100): Administrator portalu - zarządzanie treścią i użytkownikami + - SUPERADMIN (200): Superadministrator - pełne prawa + audyty techniczne """ UNAFFILIATED = 10 # Niezrzeszony (firma spoza Izby) MEMBER = 20 # Członek Norda bez firmy @@ -58,6 +59,7 @@ class SystemRole(IntEnum): MANAGER = 40 # Kadra zarządzająca firmy OFFICE_MANAGER = 50 # Kierownik biura Norda ADMIN = 100 # Administrator portalu + SUPERADMIN = 200 # Superadministrator - pełne prawa + audyty @classmethod def choices(cls): @@ -69,6 +71,7 @@ class SystemRole(IntEnum): cls.MANAGER: 'Kadra Zarządzająca', cls.OFFICE_MANAGER: 'Kierownik Biura', cls.ADMIN: 'Administrator', + cls.SUPERADMIN: 'Superadministrator', } return [(role.value, labels[role]) for role in cls] @@ -82,6 +85,7 @@ class SystemRole(IntEnum): 'MANAGER': cls.MANAGER, 'OFFICE_MANAGER': cls.OFFICE_MANAGER, 'ADMIN': cls.ADMIN, + 'SUPERADMIN': cls.SUPERADMIN, } return mapping.get(value.upper(), cls.UNAFFILIATED) @@ -560,7 +564,7 @@ class User(Base, UserMixin): """ self.role = new_role.name if sync_is_admin: - self.is_admin = (new_role == SystemRole.ADMIN) + self.is_admin = (new_role >= SystemRole.ADMIN) def set_company_role(self, new_role: CompanyRole): """Set the user's company role.""" diff --git a/utils/decorators.py b/utils/decorators.py index 78d3498..4344516 100644 --- a/utils/decorators.py +++ b/utils/decorators.py @@ -18,14 +18,12 @@ from functools import wraps from flask import abort, flash, redirect, url_for, request from flask_login import current_user -# Audit access restriction — only this user sees SEO/IT/GBP/Social audits -AUDIT_OWNER_EMAIL = 'maciej.pienczyn@inpi.pl' - def is_audit_owner(): - """True only for the designated audit owner.""" + """True for SUPERADMIN users — full access to audits and technical panels.""" if not current_user.is_authenticated: return False - return current_user.email == AUDIT_OWNER_EMAIL + from database import SystemRole + return current_user.has_role(SystemRole.SUPERADMIN) # Import role enums (lazy import to avoid circular dependencies) def _get_system_role():