feat: add SUPERADMIN role (200) with full audit access
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions

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 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-03-13 11:20:25 +01:00
parent 8f37ef4ded
commit f960a4cf0d
2 changed files with 9 additions and 7 deletions

View File

@ -50,7 +50,8 @@ class SystemRole(IntEnum):
- EMPLOYEE (30): Pracownik firmy członkowskiej - może edytować dane firmy - 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 - 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) - 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) UNAFFILIATED = 10 # Niezrzeszony (firma spoza Izby)
MEMBER = 20 # Członek Norda bez firmy MEMBER = 20 # Członek Norda bez firmy
@ -58,6 +59,7 @@ class SystemRole(IntEnum):
MANAGER = 40 # Kadra zarządzająca firmy MANAGER = 40 # Kadra zarządzająca firmy
OFFICE_MANAGER = 50 # Kierownik biura Norda OFFICE_MANAGER = 50 # Kierownik biura Norda
ADMIN = 100 # Administrator portalu ADMIN = 100 # Administrator portalu
SUPERADMIN = 200 # Superadministrator - pełne prawa + audyty
@classmethod @classmethod
def choices(cls): def choices(cls):
@ -69,6 +71,7 @@ class SystemRole(IntEnum):
cls.MANAGER: 'Kadra Zarządzająca', cls.MANAGER: 'Kadra Zarządzająca',
cls.OFFICE_MANAGER: 'Kierownik Biura', cls.OFFICE_MANAGER: 'Kierownik Biura',
cls.ADMIN: 'Administrator', cls.ADMIN: 'Administrator',
cls.SUPERADMIN: 'Superadministrator',
} }
return [(role.value, labels[role]) for role in cls] return [(role.value, labels[role]) for role in cls]
@ -82,6 +85,7 @@ class SystemRole(IntEnum):
'MANAGER': cls.MANAGER, 'MANAGER': cls.MANAGER,
'OFFICE_MANAGER': cls.OFFICE_MANAGER, 'OFFICE_MANAGER': cls.OFFICE_MANAGER,
'ADMIN': cls.ADMIN, 'ADMIN': cls.ADMIN,
'SUPERADMIN': cls.SUPERADMIN,
} }
return mapping.get(value.upper(), cls.UNAFFILIATED) return mapping.get(value.upper(), cls.UNAFFILIATED)
@ -560,7 +564,7 @@ class User(Base, UserMixin):
""" """
self.role = new_role.name self.role = new_role.name
if sync_is_admin: 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): def set_company_role(self, new_role: CompanyRole):
"""Set the user's company role.""" """Set the user's company role."""

View File

@ -18,14 +18,12 @@ from functools import wraps
from flask import abort, flash, redirect, url_for, request from flask import abort, flash, redirect, url_for, request
from flask_login import current_user 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(): 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: if not current_user.is_authenticated:
return False 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) # Import role enums (lazy import to avoid circular dependencies)
def _get_system_role(): def _get_system_role():