gmao/app_new/lib_ext/permissions.py
2026-08-14 16:02:25 +00:00

232 lines
No EOL
7.4 KiB
Python

"""Gestion des permissions et accès par rôle."""
"""Gestion des permissions et accès par rôle."""
from functools import wraps
from flask import abort, current_app
from flask_login import current_user
import os
class Permission:
"""Définition des permissions de l'application."""
# Permissions de base
VIEW_DASHBOARD = 'dashboard:view'
CREATE_INTERVENTION = 'intervention:create'
VIEW_INTERVENTIONS = 'intervention:view'
EDIT_INTERVENTIONS = 'intervention:edit'
DELETE_INTERVENTIONS = 'intervention:delete'
# Permissions équipements
VIEW_EQUIPMENTS = 'equipment:view'
CREATE_EQUIPMENTS = 'equipment:create'
EDIT_EQUIPMENTS = 'equipment:edit'
DELETE_EQUIPMENTS = 'equipment:delete'
# Permissions planning
VIEW_PLANNING = 'planning:view'
CREATE_PLANNING = 'planning:create'
EDIT_PLANNING = 'planning:edit'
# Permissions ENT
VIEW_ENT = 'ent:view'
CONFIG_ENT = 'ent:config'
MANAGE_ENT_MESSAGES = 'ent:manage'
# Permissions administratives
VIEW_USERS = 'user:view'
CREATE_USERS = 'user:create'
EDIT_USERS = 'user:edit'
DELETE_USERS = 'user:delete'
VIEW_ADMIN = 'admin:view'
# Permission de modification du code (admin seulement)
EDIT_CODE = 'code:edit'
# Permissions entreprises et pièces
VIEW_COMPANIES = 'company:view'
CREATE_COMPANIES = 'company:create'
EDIT_COMPANIES = 'company:edit'
DELETE_COMPANIES = 'company:delete'
VIEW_PARTS = 'part:view'
CREATE_PARTS = 'part:create'
EDIT_PARTS = 'part:edit'
DELETE_PARTS = 'part:delete'
class RolePermission:
"""Définition des permissions par rôle."""
# Rôle administrateur (accès à tout)
ADMIN = {
Permission.VIEW_DASHBOARD,
Permission.CREATE_INTERVENTION,
Permission.VIEW_INTERVENTIONS,
Permission.EDIT_INTERVENTIONS,
Permission.DELETE_INTERVENTIONS,
Permission.VIEW_EQUIPMENTS,
Permission.CREATE_EQUIPMENTS,
Permission.EDIT_EQUIPMENTS,
Permission.DELETE_EQUIPMENTS,
Permission.VIEW_PLANNING,
Permission.CREATE_PLANNING,
Permission.EDIT_PLANNING,
Permission.VIEW_ENT,
Permission.CONFIG_ENT,
Permission.MANAGE_ENT_MESSAGES,
Permission.VIEW_USERS,
Permission.CREATE_USERS,
Permission.EDIT_USERS,
Permission.DELETE_USERS,
Permission.VIEW_ADMIN,
Permission.VIEW_COMPANIES,
Permission.CREATE_COMPANIES,
Permission.EDIT_COMPANIES,
Permission.DELETE_COMPANIES,
Permission.VIEW_PARTS,
Permission.CREATE_PARTS,
Permission.EDIT_PARTS,
Permission.DELETE_PARTS,
Permission.EDIT_CODE, # Permission de modification du code
}
# Rôle technicien (peut voir et gérer les interventions, voir les équipements)
TECHNICIAN = {
Permission.VIEW_DASHBOARD,
Permission.CREATE_INTERVENTION,
Permission.VIEW_INTERVENTIONS,
Permission.EDIT_INTERVENTIONS,
Permission.VIEW_EQUIPMENTS,
Permission.VIEW_PLANNING,
Permission.VIEW_ENT,
}
# Rôle chef d'établissement (peut voir et gérer les interventions, planning, voir les données)
CHEF = {
Permission.VIEW_DASHBOARD,
Permission.CREATE_INTERVENTION,
Permission.VIEW_INTERVENTIONS,
Permission.EDIT_INTERVENTIONS,
Permission.VIEW_EQUIPMENTS,
Permission.VIEW_PLANNING,
Permission.CREATE_PLANNING,
Permission.VIEW_ENT,
}
# Rôle demandeur (peut voir le dashboard, créer des interventions, voir les équipements)
DEMANDEUR = {
Permission.VIEW_DASHBOARD,
Permission.CREATE_INTERVENTION,
Permission.VIEW_INTERVENTIONS,
Permission.VIEW_EQUIPMENTS,
Permission.VIEW_PLANNING,
}
def get_role_permissions(role):
"""Retourne les permissions pour un rôle donné."""
role_permissions_map = {
'admin': RolePermission.ADMIN,
'technicien': RolePermission.TECHNICIAN,
'chef': RolePermission.CHEF,
'demandeur': RolePermission.DEMANDEUR,
}
return role_permissions_map.get(role, set())
def permission_required(permission):
"""Décorateur pour vérifier une permission spécifique."""
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.is_authenticated:
abort(401)
if current_user.role == 'admin':
return f(*args, **kwargs)
user_permissions = get_role_permissions(current_user.role)
if permission not in user_permissions:
current_app.logger.warning(
f"User {current_user.username} (role: {current_user.role}) "
f"tried to access {permission} which is not allowed"
)
abort(403)
return f(*args, **kwargs)
return decorated_function
return decorator
def any_permission_required(*permissions):
"""Décorateur pour vérifier qu'au moins une permission parmi les listées est présente."""
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.is_authenticated:
abort(401)
if current_user.role == 'admin':
return f(*args, **kwargs)
user_permissions = get_role_permissions(current_user.role)
# Vérifier si l'utilisateur a au moins une des permissions requises
has_permission = any(perm in user_permissions for perm in permissions)
if not has_permission:
current_app.logger.warning(
f"User {current_user.username} (role: {current_user.role}) "
f"tried to access {permissions} but none are allowed"
)
abort(403)
return f(*args, **kwargs)
return decorated_function
return decorator
def role_required(role):
"""Décorateur pour vérifier le rôle exact."""
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.is_authenticated:
abort(401)
if current_user.role != role:
current_app.logger.warning(
f"User {current_user.username} (role: {current_user.role}) "
f"tried to access endpoint requiring {role} role"
)
abort(403)
return f(*args, **kwargs)
return decorated_function
return decorator
def has_permission(permission):
"""Macro template pour vérifier une permission dans les templates."""
if not current_user.is_authenticated:
return False
if current_user.role == 'admin':
return True
user_permissions = get_role_permissions(current_user.role)
return permission in user_permissions
def get_user_permissions(user=None):
"""Retourne les permissions d'un utilisateur (ou de l'utilisateur courant)."""
if user is None:
if not current_user.is_authenticated:
return set()
user = current_user
if user.role == 'admin':
return RolePermission.ADMIN
return get_role_permissions(user.role)