feature/rbac permisos y roles implementados

This commit is contained in:
2026-05-21 07:54:59 -06:00
parent 9bbed42cf3
commit a318b70324
38 changed files with 2596 additions and 901 deletions

View File

@@ -25,15 +25,14 @@ class VucemUpdateSerializer(VucemSerializer):
class Meta(VucemSerializer.Meta):
fields = VucemSerializer.Meta.fields
from .models import Vucem, CredencialesImportador
from core.permissions import IsSameOrganizationDeveloper
from rest_framework import mixins
from core.permissions import (
IsSameOrganization,
IsSameOrganizationDeveloper,
IsSameOrganizationAndAdmin,
IsSuperUser,
IsSameOrganizationAndInAllowedGroups
IsSameOrganizationAndInAllowedGroups,
get_org_context,
is_internal_service_request,
require_permission,
user_has_permission,
)
class CustomVucemPagination(PageNumberPagination):
@@ -53,8 +52,6 @@ class CustomVucemPagination(PageNumberPagination):
# Create your views here.
class VucemView(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated , (IsSuperUser | IsSameOrganization | IsSameOrganizationAndAdmin | IsSameOrganizationDeveloper )]
queryset = Vucem.objects.all()
pagination_class = CustomVucemPagination
filterset_fields = ['organizacion', 'patente', 'usuario', 'is_importador', 'acusecove', 'acuseedocument', 'is_active']
@@ -68,27 +65,45 @@ class VucemView(viewsets.ModelViewSet):
return VucemSerializer
def get_permissions(self):
if self.action in ['create', 'update', 'partial_update', 'destroy']:
return [IsAuthenticated(), IsSameOrganizationAndInAllowedGroups()]
return super().get_permissions()
perms = {
'list': 'vucem.view',
'retrieve': 'vucem.view',
'create': 'vucem.manage',
'update': 'vucem.manage',
'partial_update': 'vucem.manage',
'destroy': 'vucem.manage',
'download_cer': 'vucem.view',
'download_key': 'vucem.view',
}
codename = perms.get(self.action, 'vucem.view')
return [IsAuthenticated(), require_permission(codename)()]
def get_queryset(self):
# Verificar que el usuario esté autenticado y tenga organización
if not self.request.user.is_authenticated:
return self.queryset.none()
queryset = self.queryset
if is_internal_service_request(self.request):
queryset = self.queryset.all()
importador_rfc = self.request.query_params.get('importador')
if importador_rfc:
queryset = queryset.filter(usuarios_importadores__rfc__rfc=importador_rfc).distinct()
return queryset
if self.request.user.is_superuser:
queryset = queryset.all()
elif not hasattr(self.request.user, 'organizacion') or not self.request.user.organizacion:
return queryset.none()
elif self.request.user.groups.filter(name='Importador').exists():
queryset = queryset.filter(organizacion=self.request.user.organizacion, usuario__in=self.request.user.rfc.all())
if not user_has_permission(self.request.user, 'vucem.view'):
return self.queryset.none()
org = get_org_context(self.request.user)
if not org:
return self.queryset.none()
if self.request.user.is_importador:
queryset = self.queryset.filter(
organizacion=org,
usuario__in=self.request.user.rfc.all(),
)
else:
queryset = queryset.filter(organizacion=self.request.user.organizacion)
queryset = self.queryset.filter(organizacion=org)
# Filtro por importador (RFC)
importador_rfc = self.request.query_params.get('importador')
if importador_rfc:
queryset = queryset.filter(usuarios_importadores__rfc__rfc=importador_rfc).distinct()
@@ -96,54 +111,37 @@ class VucemView(viewsets.ModelViewSet):
return queryset
def perform_create(self, serializer):
if not self.request.user.is_authenticated or not hasattr(self.request.user, 'organizacion'):
raise ValueError("El usuario debe estar autenticado y tener una organización asignada.")
if self.request.user.is_superuser:
organizacion_id = self.request.data.get('organizacion_id')
if not organizacion_id:
raise ValueError("Los superusuarios deben especificar una organización")
try:
# Importa el modelo Organizacion
# from ..organization.models import Organizacion
organizacion = Organizacion.objects.get(id=organizacion_id)
except Organizacion.DoesNotExist:
raise ValueError({"organizacion": "Organización no encontrada"})
serializer.save(
organizacion=organizacion,
created_by=self.request.user,
updated_by=self.request.user
)
return
else:
serializer.save(
organizacion=self.request.user.organizacion,
created_by=self.request.user,
updated_by=self.request.user
)
return
if is_internal_service_request(self.request):
serializer.save(updated_by=self.request.user)
return
org = get_org_context(self.request.user)
if not org:
raise ValueError("El usuario debe tener una organización activa para crear credenciales VUCEM.")
serializer.save(
organizacion=org,
created_by=self.request.user,
updated_by=self.request.user,
)
def perform_update(self, serializer):
if not self.request.user.is_authenticated or not hasattr(self.request.user, 'organizacion'):
raise ValueError("El usuario debe estar autenticado y tener una organización asignada.")
if is_internal_service_request(self.request):
instance = self.get_object()
serializer.save(
created_by=instance.created_by,
updated_by=self.request.user,
)
return
org = get_org_context(self.request.user)
if not org:
raise ValueError("El usuario debe tener una organización activa para modificar credenciales VUCEM.")
instance = self.get_object()
if self.request.user.is_superuser:
serializer.save(
created_by=instance.created_by,
updated_by=self.request.user
)
return
else:
serializer.save(
organizacion=self.request.user.organizacion,
created_by=instance.created_by,
updated_by=self.request.user
)
return
serializer.save(
organizacion=org,
created_by=instance.created_by,
updated_by=self.request.user,
)
@action(detail=True, methods=["get"], permission_classes=[IsAuthenticated])
@action(detail=True, methods=["get"])
def download_cer(self, request, pk=None):
vucem = self.get_object()
if not vucem.cer:
@@ -164,7 +162,7 @@ class VucemView(viewsets.ModelViewSet):
return response
@action(detail=True, methods=["get"], permission_classes=[IsAuthenticated])
@action(detail=True, methods=["get"])
def download_key(self, request, pk=None):
vucem = self.get_object()
if not vucem.key:
@@ -194,7 +192,6 @@ class VucemView(viewsets.ModelViewSet):
class CredencialesImportadorViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
queryset = CredencialesImportador.objects.all()
serializer_class = CredencialesImportadorSimpleSerializer
filterset_fields = ['organizacion', 'vucem', 'rfc']
@@ -205,27 +202,34 @@ class CredencialesImportadorViewSet(viewsets.ModelViewSet):
my_tags = ['Credenciales por Importador']
def get_permissions(self):
if self.action in ['create', 'update', 'partial_update', 'destroy']:
return [IsAuthenticated()]
return super().get_permissions()
perms = {
'list': 'vucem.view',
'retrieve': 'vucem.view',
'create': 'vucem.manage',
'update': 'vucem.manage',
'partial_update': 'vucem.manage',
'destroy': 'vucem.manage',
}
codename = perms.get(self.action, 'vucem.view')
return [IsAuthenticated(), require_permission(codename)()]
def get_queryset(self):
if self.request.user.is_superuser:
# Si es superusuario, devolver todos los registros
return self.queryset.all()
# Verificar que el usuario esté autenticado y tenga organización
if not self.request.user.is_authenticated or not hasattr(self.request.user, 'organizacion'):
if not self.request.user.is_authenticated:
return self.queryset.none()
queryset = self.queryset.filter(organizacion=self.request.user.organizacion)
return queryset
if is_internal_service_request(self.request):
return self.queryset.all()
if not user_has_permission(self.request.user, 'vucem.view'):
return self.queryset.none()
org = get_org_context(self.request.user)
if not org:
return self.queryset.none()
return self.queryset.filter(organizacion=org)
def perform_create(self, serializer):
if not self.request.user.is_authenticated or not hasattr(self.request.user, 'organizacion'):
raise ValueError("El usuario debe estar autenticado y tener una organización asignada.")
serializer.save(organizacion=self.request.user.organizacion)
return
if is_internal_service_request(self.request):
serializer.save()
return
org = get_org_context(self.request.user)
if not org:
raise ValueError("El usuario debe tener una organización activa.")
serializer.save(organizacion=org)