144 lines
No EOL
4.9 KiB
Python
144 lines
No EOL
4.9 KiB
Python
from functools import wraps
|
|
from django.http import HttpResponseForbidden
|
|
from django.shortcuts import get_object_or_404
|
|
from django.utils.translation import gettext as _
|
|
|
|
from controls.models import Control
|
|
from projects.models import ProjectUserAccess
|
|
from common.models import UserThematics
|
|
|
|
def user_can_view_control(user, control):
|
|
if hasattr(user, "config") and user.config.roles.filter(name__in=['admin', 'top_manager']).exists():
|
|
return True
|
|
|
|
if control.control_author == user:
|
|
return True
|
|
|
|
if hasattr(control, "visibility") and control.visibility == 'private':
|
|
return user == control.control_author
|
|
|
|
if hasattr(control, "visibility") and control.visibility == 'intern' and ((not hasattr(user, "config")) or user.config.is_intern == False):
|
|
return False
|
|
|
|
if control.project:
|
|
has_project_access = ProjectUserAccess.objects.filter(project=control.project, user=user, can_view=True).exists()
|
|
if has_project_access:
|
|
return True
|
|
# Fallback thématique : les contrôles privés sont déjà gérés plus haut ;
|
|
# les non-internes sont bloqués à l'étape visibility=='intern' ci-dessus.
|
|
# Un interne ayant accès à l'une des thématiques du contrôle peut donc le voir.
|
|
if control.thematics.exists() and hasattr(user, "config") and user.config.is_intern:
|
|
return UserThematics.objects.filter(
|
|
user_config=user.config,
|
|
thematic__in=control.thematics.all(),
|
|
can_view_interventions=True
|
|
).exists()
|
|
return False
|
|
|
|
if control.thematics.exists() and hasattr(user, "config") and user.config.is_intern:
|
|
return UserThematics.objects.filter(
|
|
user_config=user.config,
|
|
thematic__in=control.thematics.all(),
|
|
can_view_interventions=True
|
|
).exists()
|
|
|
|
return False
|
|
|
|
|
|
def control_view_required(view_func):
|
|
@wraps(view_func)
|
|
def _wrapped_view(request, control_id, *args, **kwargs):
|
|
control = get_object_or_404(Control, id=control_id)
|
|
|
|
if user_can_view_control(request.user, control):
|
|
return view_func(request, control_id, *args, **kwargs)
|
|
|
|
return HttpResponseForbidden(_("Vous n'êtes pas autorisé à accéder à ce contrôle."))
|
|
|
|
return _wrapped_view
|
|
|
|
|
|
def user_can_add_control(user):
|
|
if hasattr(user, "config") and user.config.roles.filter(name__in=['admin', 'manager', 'controller']).exists():
|
|
return True
|
|
|
|
return False
|
|
|
|
def control_add_required(view_func):
|
|
@wraps(view_func)
|
|
def _wrapped_view(request, *args, **kwargs):
|
|
if user_can_add_control(request.user):
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
return HttpResponseForbidden(_("Vous n'êtes pas autorisé à ajouter un contrôle."))
|
|
|
|
return _wrapped_view
|
|
|
|
|
|
|
|
def user_can_change_control(user, control):
|
|
if not hasattr(user, "config"):
|
|
return False
|
|
|
|
if user.config.roles.filter(name__in=["admin"]).exists():
|
|
return True
|
|
|
|
if not control.shared_edition:
|
|
return user == control.control_author
|
|
|
|
# 1. L'utilisateur doit avoir un rôle suffisant
|
|
has_permission_role = (
|
|
hasattr(user, "config") and
|
|
user.config.roles.filter(name__in=["manager", "controller"]).exists()
|
|
)
|
|
|
|
# 2. L'utilisateur doit pouvoir voir ce contrôle
|
|
can_view = user_can_view_control(user, control)
|
|
|
|
return has_permission_role and can_view
|
|
|
|
def control_change_required(view_func):
|
|
@wraps(view_func)
|
|
def _wrapped_view(request, control_id, *args, **kwargs):
|
|
control = get_object_or_404(Control, id=control_id)
|
|
|
|
if user_can_change_control(request.user, control):
|
|
return view_func(request, control_id, *args, **kwargs)
|
|
|
|
return HttpResponseForbidden(_("Vous n'êtes pas autorisé à modifier ce contrôle."))
|
|
|
|
return _wrapped_view
|
|
|
|
|
|
# ============================================================================
|
|
# Guards pour les fichiers privés (private_media)
|
|
# ============================================================================
|
|
|
|
def guard_control_report_document(obj, user):
|
|
"""
|
|
Guard pour ControlReport.document.
|
|
L'utilisateur doit pouvoir voir le contrôle associé.
|
|
"""
|
|
if not user.is_authenticated:
|
|
return False
|
|
return user_can_view_control(user, obj.control)
|
|
|
|
|
|
def guard_control_reference_plan(obj, user):
|
|
"""
|
|
Guard pour ControlReferencePlan.plan.
|
|
L'utilisateur doit pouvoir voir le contrôle associé.
|
|
"""
|
|
if not user.is_authenticated:
|
|
return False
|
|
return user_can_view_control(user, obj.control)
|
|
|
|
|
|
def guard_remark_image_file(obj, user):
|
|
"""
|
|
Guard pour RemarkImage.file et thumbnail.
|
|
L'utilisateur doit pouvoir voir le contrôle associé à la remarque.
|
|
"""
|
|
if not user.is_authenticated:
|
|
return False
|
|
return user_can_view_control(user, obj.remark.control) |