232 lines
No EOL
7.4 KiB
Python
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) |