Added Cambios Permisos y Modulos

This commit is contained in:
fjrodriguez
2023-11-13 11:45:10 -06:00
parent ac80bf6a45
commit 61cf354a79
13 changed files with 772 additions and 49 deletions

View File

@@ -439,6 +439,8 @@ class CancelaTimbre(APIView):
BitacoraErrores.objects.create(level=2, message=msn, traceback=traceback.format_exc(), view='Sistemas.CancelaTimbre') BitacoraErrores.objects.create(level=2, message=msn, traceback=traceback.format_exc(), view='Sistemas.CancelaTimbre')
return Response({'Error':f'{ex}','isError':True}) return Response({'Error':f'{ex}','isError':True})
class add_timbre(APIView): class add_timbre(APIView):
pass pass

View File

@@ -1,9 +1,164 @@
from typing import Any
from django.contrib import admin from django.contrib import admin
from . models import Sistemas_por_cliente_A24, ClientesA24, DeviceA24 from .models import *
from django.contrib.sessions.models import Session
from django.contrib.auth.models import User
from django.utils import timezone
from datetime import timedelta
from django.db.models import Q
class SessionAdmin(admin.ModelAdmin):
list_display=['get_username','session_key','session_data','expire_date']
readonly_fields = ['display_session_data', 'get_username']
def display_session_data(self,obj):
session_data =obj.get_decoded()
formatted_data = "\n".join([f"{key}: {value}" for key, value in session_data.items()])
return formatted_data
display_session_data.shoort_description= "Session Data"
def get_username(self,obj):
session_data=obj.get_decoded()
user_id=session_data.get('_auth_user_id')
try:
user=User.objects.get(id=user_id)
return user.username
except User.DoesNotExist:
return "Usuario inexistente"
get_username.short_description = 'Nombre Usuario'
def delete_expired_sessions(self,request,queryset):
now =timezone.now()
one_day_ago = now- timedelta(days=1)
expired_sessions = queryset.filter(expire_date__lte=one_day_ago)
expired_sessions.delete()
delete_expired_sessions.short_description = 'Eliminar Sessiones caducas'
def get_queryset(self,request):
now =timezone.now()
one_day_ago = now- timedelta(days=1)
current_session = request.session.session_key
queryset = super().get_queryset(request)#.filter(expire_date__gte=one_day_ago)
#queryset.exclude(session_key=current_session)
return queryset
class Device_A24_Admin(admin.ModelAdmin): class Device_A24_Admin(admin.ModelAdmin):
list_display = ['clienteA24', 'dataBase','username','sistema','MAC','deviceName'] list_display = ['clienteA24', 'dataBase','username','sistema','MAC','deviceName']
class ActiveTokenSession_Admin(admin.ModelAdmin):
list_display = ['start_time', 'last_time', 'has_expired']
class SuspensionPermisoInline(admin.TabularInline):
model = SuspensionPermiso
extra = 1
def get_formset(self, request, obj=None, **kwargs):
# Utiliza el objeto 'obj' (el módulo actual) para filtrar el queryset
formset = super().get_formset(request, obj, **kwargs)
if obj:
print('SDL',obj.modulo.permisos.all())
formset.form.base_fields['permiso'].queryset = obj.modulo.permisos.all()
return formset
class SuspensionModuloInline(admin.TabularInline):
model = SuspensionModulo
class SuspensionModuloAdmin(admin.ModelAdmin):
list_display = ['modulo','suspendido','supension_modPerm_id']
inlines=[SuspensionPermisoInline]
class Suspension_Modulos_Permisos_ClienteAdmin(admin.ModelAdmin):
inlines = [SuspensionModuloInline]
def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)
for modulo in obj.suspensionmodulo_set.all():
for permiso in modulo.modulo.permisos.all():
permObj,created=SuspensionPermiso.objects.get_or_create(
suspension_modulo=modulo,
permiso=permiso,
)
admin.site.register(Permisos_A24)
admin.site.register(Modulo)
admin.site.register(SuspensionModulo,SuspensionModuloAdmin)
admin.site.register(Suspension_Modulos_Permisos_Cliente, Suspension_Modulos_Permisos_ClienteAdmin)
# class Permisos_A24_Admin(admin.ModelAdmin):
# list_display =['nombre']
# search_fields = ['nombre']
# class Modulo_Admin(admin.ModelAdmin):
# list_display=('nombre','sistema_cliente'
# #,'lista_permisos'
# )
# filter_horizontal = ['permisos']
# class SuspensionPermisoInline(admin.TabularInline):
# model = SuspensionPermiso
# extra = 1 # Puedes ajustar esto según tus necesidades
# class SuspensionModuloInline(admin.TabularInline):
# model = SuspensionModulo
# extra = 1 # Ajusta según tus necesidades
# class SuspensionModulo_Admin(admin.ModelAdmin):
# list_display=['modulo','cliente_nombre','dispositivo','custom_suspendido']
# search_fields = ['dispositivo__clienteA24__Nombre', 'dispositivo__clienteA24__RFC']
# def cliente_nombre(self, obj):
# return f'{obj.dispositivo.clienteA24.Nombre}({obj.dispositivo.clienteA24.RFC})' \
# if obj.dispositivo and obj.dispositivo.clienteA24 else "N/A"
# cliente_nombre.short_description = 'Nombre del Cliente(RFC)' # Puedes personalizar el encabezado si lo deseas
# def custom_suspendido(self,obj):
# return "Sí" if obj.suspendido else "No"
# custom_suspendido.short_description = 'Suspendido'
# class ModuloInline(admin.TabularInline):
# model = Modulo
# extra =1
# autocomplete_fields = ['permisos']
# class Sistema_x_ClienteAdmin(admin.ModelAdmin):
# inlines = [ModuloInline]
# search_fields = ['modulos__nombre', 'modulos__permisos__nombre']
# list_filter =('modulo__permisos__nombre',)
# class Device_A24_Admin2(admin.ModelAdmin):
# inlines = [SuspensionPermisoInline, SuspensionModuloInline]
# admin.site.register(SuspensionPermiso)
# admin.site.register(SuspensionModulo,SuspensionModulo_Admin)
# admin.site.register(Permisos_A24,Permisos_A24_Admin)
# admin.site.register(Modulo,Modulo_Admin)
admin.site.register(Sistemas_por_cliente_A24) admin.site.register(Sistemas_por_cliente_A24)
admin.site.register(ClientesA24) admin.site.register(ClientesA24)
admin.site.register(DeviceA24, Device_A24_Admin) admin.site.register(DeviceA24, Device_A24_Admin)
admin.site.register(ActiveTokenSession, ActiveTokenSession_Admin)
admin.site.register(Session, SessionAdmin)

View File

@@ -0,0 +1,26 @@
# Generated by Django 4.1.3 on 2023-10-18 21:11
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('authtoken', '0003_tokenproxy'),
('IMMEX', '0002_devicea24'),
]
operations = [
migrations.CreateModel(
name='ActiveTokenSession',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('start_time', models.DateTimeField(default=django.utils.timezone.now)),
('last_time', models.DateTimeField(default=django.utils.timezone.now)),
('has_expired', models.BooleanField(default=False)),
('token', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='authtoken.token')),
],
),
]

View File

@@ -0,0 +1,62 @@
# Generated by Django 4.1.3 on 2023-10-19 14:46
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('IMMEX', '0003_activetokensession'),
]
operations = [
migrations.CreateModel(
name='Modulo',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nombre', models.CharField(max_length=100)),
],
),
migrations.CreateModel(
name='Permisos_A24',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nombre', models.CharField(max_length=100)),
],
),
migrations.CreateModel(
name='Suspension_Modulos_Permisos_Cliente',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sistema_cliente', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='IMMEX.sistemas_por_cliente_a24')),
],
),
migrations.CreateModel(
name='SuspensionModulo',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('suspendido', models.BooleanField(default=False)),
('modulo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='IMMEX.modulo')),
('supension_modPerm_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='IMMEX.suspension_modulos_permisos_cliente')),
],
),
migrations.CreateModel(
name='SuspensionPermiso',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('permiso', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='IMMEX.permisos_a24')),
('suspension_modulo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='IMMEX.suspensionmodulo')),
],
),
migrations.AddField(
model_name='modulo',
name='permisos',
field=models.ManyToManyField(to='IMMEX.permisos_a24'),
),
migrations.AddField(
model_name='modulo',
name='sistema_cliente',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='IMMEX.sistemas_por_cliente_a24'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.1.3 on 2023-10-19 15:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('IMMEX', '0004_modulo_permisos_a24_and_more'),
]
operations = [
migrations.AddField(
model_name='suspensionpermiso',
name='suspendido',
field=models.BooleanField(default=False),
),
]

View File

@@ -0,0 +1,17 @@
# Generated by Django 4.1.3 on 2023-10-19 15:43
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('IMMEX', '0005_suspensionpermiso_suspendido'),
]
operations = [
migrations.RemoveField(
model_name='modulo',
name='sistema_cliente',
),
]

View File

@@ -2,7 +2,7 @@ from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from Sistemas.models import Sistema from Sistemas.models import Sistema
from rest_framework.authtoken.models import Token from rest_framework.authtoken.models import Token
from django.utils import timezone
import re import re
class ClientesA24(models.Model): class ClientesA24(models.Model):
@@ -21,7 +21,7 @@ class Sistemas_por_cliente_A24(models.Model):
cliente = models.ForeignKey(ClientesA24, related_name='cliente_spc_IMMEX', on_delete=models.CASCADE) cliente = models.ForeignKey(ClientesA24, related_name='cliente_spc_IMMEX', on_delete=models.CASCADE)
num_licencias= models.IntegerField(default=1) num_licencias= models.IntegerField(default=1)
def __str__(self): def __str__(self):
return f'{self.cliente.Nombre}' return f'{self.cliente.Nombre}, {self.id_sistema.nombre_sistema} '
class Meta: class Meta:
ordering= ('-cliente','id_sistema') ordering= ('-cliente','id_sistema')
unique_together = ('id_sistema', 'cliente') unique_together = ('id_sistema', 'cliente')
@@ -46,7 +46,7 @@ class DeviceA24(models.Model):
def generate_username(self,client, device_name, mac_address): def generate_username(self,client, device_name, mac_address):
"""""" """"""
username_ = f"SCAII_{client.RFC}_{device_name}_{mac_address}" username_ = f"IMMEX_{client.RFC}_{device_name}_{mac_address}"
username_ = re.sub(r'\W+', '', username_) username_ = re.sub(r'\W+', '', username_)
if User.objects.filter(username=username_).exists(): if User.objects.filter(username=username_).exists():
@@ -64,4 +64,53 @@ class DeviceA24(models.Model):
super().save(*args, **kwargs) super().save(*args, **kwargs)
def __str__(self): def __str__(self):
return f'{self.username}' return f'{self.username}'
class ActiveTokenSession(models.Model):
token = models.ForeignKey(Token, on_delete=models.CASCADE, db_index=True)
start_time = models.DateTimeField(default=timezone.now)
last_time = models.DateTimeField(default=timezone.now)
has_expired = models.BooleanField(default=False)
def is_expired(self, expiration_minutes):
expiration_time = self.start_time + timezone.timedelta(minutes=expiration_minutes)
return expiration_time < timezone.now()
##--------------------------PERMISOS
class Permisos_A24(models.Model):
nombre= models.CharField(max_length=100)
def __str__(self) -> str:
return f'{self.nombre}'
class Modulo(models.Model):
nombre = models.CharField(max_length=100)
#sistema_cliente = models.ForeignKey(Sistemas_por_cliente_A24, on_delete=models.CASCADE)
permisos = models.ManyToManyField(Permisos_A24)
def __str__(self) -> str:
return f'{self.nombre}'
class Suspension_Modulos_Permisos_Cliente(models.Model):
sistema_cliente = models.ForeignKey(Sistemas_por_cliente_A24, on_delete=models.CASCADE)
def __str__(self) -> str:
return f'{self.sistema_cliente} {self.sistema_cliente.id_sistema.nombre_sistema}'
class SuspensionModulo(models.Model):
supension_modPerm_id = models.ForeignKey(Suspension_Modulos_Permisos_Cliente, on_delete=models.CASCADE)
modulo = models.ForeignKey(Modulo, on_delete=models.CASCADE)
suspendido = models.BooleanField(default=False)
def __str__(self) -> str:
return f'{self.modulo}'
class SuspensionPermiso(models.Model):
suspension_modulo = models.ForeignKey(SuspensionModulo, on_delete=models.CASCADE)
permiso = models.ForeignKey(Permisos_A24, on_delete=models.CASCADE)
suspendido = models.BooleanField(default=False)
def __str__(self) -> str:
return f'{self.permiso}'

111
IMMEX/permissions.py Normal file
View File

@@ -0,0 +1,111 @@
from rest_framework.permissions import BasePermission
from .models import ActiveTokenSession,Sistemas_por_cliente_A24,SuspensionModulo
from django.utils import timezone
class TokenCheckSession(BasePermission):
message = 'NO'
def has_permission(self,request, view):
print('FROM TokenCheckSession : ')
sistema = request.META.get('HTTP_SISTEMA','')
mac = request.META.get('HTTP_MAC','')
RFC = request.META.get('HTTP_RFC','')
modulo = request.META.get('HTTP_MODULO','')
permiso= request.META.get('HTTP_PERMISO','')
active_session, created = ActiveTokenSession.objects.get_or_create(token=request.user.auth_token)
sistema_cliente = Sistemas_por_cliente_A24.objects.filter(id_sistema__nombre_sistema=sistema,cliente__RFC=RFC).first()
if sistema_cliente is None:
self.message +=f';El sistema:{sistema}, no se encuentra dado de alta para el RFC:{RFC}'
return False
modulo_ids = sistema_cliente.suspension_modulos_permisos_cliente_set.filter(suspensionmodulo__modulo__nombre=modulo).first()
if modulo_ids is None:
self.message +=f";El modulo:{modulo}, no se encuentra dado de alta para el RFC:{RFC} enviado"
return False
for modulo in modulo_ids.suspensionmodulo_set.filter(modulo__nombre=modulo):
if modulo.suspendido:
self.message +=f';El modulo:{modulo} se encuentra suspendido para el RFC:{RFC}'
return False
if modulo.suspensionpermiso_set.filter(permiso__nombre=permiso).first() is None:
self.message += f';El permiso:{permiso} en el modulo:{modulo} no esta dado de alta para el RFC:{RFC}'
return False
inner_sistema = active_session.token.devicea24_set.first().sistema.nombre_sistema == sistema
inner_mac = active_session.token.devicea24_set.first().MAC == mac
expiro = active_session.is_expired(1)
if not (inner_sistema and inner_mac):
self.message+=";no se agregó código de máquina y/o sistema correctamente"
if expiro:
self.message+=";la session expiro"
if active_session.token.devicea24_set.first() is None:
self.message +=';Device not Found'
return False
#print(expiro , inner_sistema , inner_mac)
if not (inner_sistema and inner_mac):
self.message+=";no se agregó código de máquina y/o sistema correctamente"
return False
active_session.last_time=timezone.now()
active_session.has_expired =True if expiro else False
active_session.save()
return False if expiro else True
class ActiveTokenSessionPerm(BasePermission):
message = 'NO'
def has_permission(self,request, view):
authorization = request.META.get('HTTP_AUTHORIZATION','')
sistema = request.META.get('HTTP_SISTEMA','')
mac = request.META.get('HTTP_MAC','')
if 'Token' in authorization:
active_session, created = ActiveTokenSession.objects.get_or_create(token=request.user.auth_token)
#print(active_session.is_expired(1))
#verifica que este el DeviceA24 dado de alta
if active_session.token.devicea24_set.first() is None:
self.message +=';Device not Found'
return False
#print(active_session.token.devicea24_set.first().sistema.nombre_sistema)
inner_mac = active_session.token.devicea24_set.first().MAC
if mac != inner_mac:
self.message +=f';El Codigo de maquina `{mac}` proporcionado para esta licencia no es igual al registrado para este equipo `{inner_mac}`'
return False
inner_sistema= active_session.token.devicea24_set.first().sistema.nombre_sistema
if sistema != inner_sistema:
self.message +=f';El Sistema `{sistema}` proporcionado para esta licencia no es igual al registrado para este equipo `{inner_sistema}`'
return False
if created: #si el registro es recien creado la session es valida
return True
#si la session esta expidara la renueva
print('expirooo',active_session.is_expired(1))
if active_session.is_expired(1):
active_session.start_time = timezone.now()
active_session.last_time=timezone.now()
active_session.has_expired =False
active_session.save()
return True
# if active_session.has_expired:
# self.message += ';La Session ha expidado'
# return False
# else:
# active_session.last_time=timezone.now()
# active_session.save()
# return True
# si no encuentra el Header[Authorization] con Token no deja entrar
return False

View File

@@ -1,10 +1,22 @@
from rest_framework import serializers from rest_framework import serializers
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from allauth.account.models import EmailAddress from allauth.account.models import EmailAddress
from django.contrib.auth.models import Permission
from Sistemas.models import Sistema from Sistemas.models import Sistema
from .models import ClientesA24, Sistemas_por_cliente_A24, DeviceA24 from .models import ClientesA24, Sistemas_por_cliente_A24, DeviceA24,Modulo
class CustomPermissionSerializer(serializers.ModelSerializer):
activo = serializers.BooleanField(read_only=True)
class Meta:
model = Permission
fields = '__all__'
class ModulosSerializer(serializers.ModelSerializer):
class Meta:
model=Modulo
fields = '__all__'
depth =1
class Sistema_A24_PKRF(serializers.PrimaryKeyRelatedField): class Sistema_A24_PKRF(serializers.PrimaryKeyRelatedField):
def to_internal_value(self,data): def to_internal_value(self,data):
@@ -12,7 +24,7 @@ class Sistema_A24_PKRF(serializers.PrimaryKeyRelatedField):
return Sistema.objects.get(nombre_sistema=data) return Sistema.objects.get(nombre_sistema=data)
except Sistema.DoesNotExist: except Sistema.DoesNotExist:
raise serializers.ValidationError("Sistema no existe") raise serializers.ValidationError("Sistema no existe")
class ClientA24_PKRF(serializers.PrimaryKeyRelatedField): class ClientA24_PKRF(serializers.PrimaryKeyRelatedField):
def to_internal_value(self,data): def to_internal_value(self,data):
try: try:
@@ -39,17 +51,29 @@ class ClientesA24Serailizer(serializers.ModelSerializer):
model =ClientesA24 model =ClientesA24
fields = ('pk','RFC', 'Nombre','Activo','fecha_baja',) fields = ('pk','RFC', 'Nombre','Activo','fecha_baja',)
class DeviceA24_admin_Serialiazer(serializers.ModelSerializer):
clienteA24 = serializers.SerializerMethodField()
sistema = serializers.SerializerMethodField()
class Meta:
model = DeviceA24
fields = '__all__'
def get_clienteA24(self, obj):
return obj.clienteA24.RFC if obj.clienteA24.RFC else ""
def get_sistema(self,obj):
return obj.sistema.nombre_sistema if obj.sistema.nombre_sistema else ""
class SerialiazerA24(serializers.ModelSerializer): class SerialiazerA24(serializers.ModelSerializer):
clienteA24 = ClientA24_PKRF(queryset=ClientesA24.objects.all()) clienteA24 = ClientA24_PKRF(queryset=ClientesA24.objects.all())
sistema = Sistema_A24_PKRF(queryset=Sistema.objects.all()) sistema = Sistema_A24_PKRF(queryset=Sistema.objects.all())
token = serializers.CharField(read_only=True) token = serializers.CharField(read_only=True)
class Meta: class Meta:
model = DeviceA24 model = DeviceA24
fields= ('clienteA24', 'deviceName', 'deviceOS', 'deviceIP', 'token', 'sistema', 'MAC', 'dataBase',) fields= ('clienteA24', 'deviceName', 'deviceOS', 'deviceIP', 'token', 'sistema', 'MAC', 'dataBase',)
def create(self, validated_data): def create(self, validated_data):
# Extraer los datos obligatorios de la solicitud # Extraer los datos obligatorios de la solicitud
clienteA24 = validated_data['clienteA24'] clienteA24 = validated_data['clienteA24']

View File

@@ -1,5 +1,10 @@
from django.urls import path from django.urls import path, include
from . import views from . import views
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'permisos', views.PermissionListCreateAPIView)
router.register(r'modulos',views.ModulosListCreateAPIView)
urlpatterns = [ urlpatterns = [
path('', views.Sistemas_xCliente_IMMEX_ListView.as_view(), name='sistemasXcli_IMMEX'), path('', views.Sistemas_xCliente_IMMEX_ListView.as_view(), name='sistemasXcli_IMMEX'),
@@ -14,5 +19,11 @@ urlpatterns = [
path('api/clientes/', views.ClientesA24List.as_view(),name='api_IMMEX_Clientes'), path('api/clientes/', views.ClientesA24List.as_view(),name='api_IMMEX_Clientes'),
path('api/clientes/detail/<int:pk>/', views.ClientesA24Detail.as_view(),name='api_IMMEX_Cliente_detail'), path('api/clientes/detail/<int:pk>/', views.ClientesA24Detail.as_view(),name='api_IMMEX_Cliente_detail'),
path('api/admin/devices/', views.DeviceA24List.as_view(), name='api_admin_IMMEX_device-detail'),
path('api/admin/devices/<int:pk>/', views.DeviceA24Detail.as_view(), name='api_admin_IMMEX_device-detail'),
path('api/admin/', include(router.urls)),
path('api/checar_permisos/',views.ChecarPermisos.as_view(), name='api_ChecarPermisos'),
] ]

View File

@@ -6,10 +6,16 @@ from django.core.mail import send_mail
from django.views.generic.edit import CreateView from django.views.generic.edit import CreateView
from django.views.generic.list import ListView from django.views.generic.list import ListView
from django.contrib import messages from django.contrib import messages
from django.db.models import Case, When, Value, BooleanField
from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import login
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.utils import timezone from django.utils import timezone
# Imports de Django REST framework # Imports de Django REST framework
from rest_framework import viewsets
from rest_framework.authentication import TokenAuthentication, BasicAuthentication from rest_framework.authentication import TokenAuthentication, BasicAuthentication
from rest_framework.views import APIView from rest_framework.views import APIView
@@ -19,23 +25,32 @@ from rest_framework.response import Response
from rest_framework import status from rest_framework import status
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.pagination import PageNumberPagination from rest_framework.pagination import PageNumberPagination
from rest_framework import generics from rest_framework import generics
# Imports de allauth # Imports de allauth
from allauth.account.models import EmailConfirmation, EmailAddress from allauth.account.models import EmailConfirmation, EmailAddress
from allauth.account.forms import SignupForm from allauth.account.forms import SignupForm
# Imports de tus modelos y serializadores # Imports de tus modelos y serializadores
from .models import Sistemas_por_cliente_A24, ClientesA24, DeviceA24 from .permissions import ActiveTokenSessionPerm, TokenCheckSession
from .models import Sistemas_por_cliente_A24, ClientesA24, DeviceA24, ActiveTokenSession, Modulo
from Sistemas.models import Sistema, BitacoraErrores from Sistemas.models import Sistema, BitacoraErrores
from Sistemas.permissions import ItsAdminToken, HasAuthorizationHeader, CheckPermiso from Sistemas.permissions import ItsAdminToken, HasAuthorizationHeader, CheckPermiso
from .forms import ClienteForm_IMMEX from .forms import ClienteForm_IMMEX
from .serializers import ClientesA24Serailizer, SerialiazerA24, SignupSerializer, Sistema_Serializer, Sistema_Por_Cliente_Serializer from .serializers import (ClientesA24Serailizer, SerialiazerA24, SignupSerializer,
Sistema_Serializer, Sistema_Por_Cliente_Serializer,
DeviceA24_admin_Serialiazer, CustomPermissionSerializer,
ModulosSerializer
)
# Otras bibliotecas y módulos # Otras bibliotecas y módulos
import urllib.parse import urllib.parse
import traceback import traceback
import json import json
from io import StringIO
import csv
class Sistemas_xCliente_IMMEX_ListView(UserPassesTestMixin,LoginRequiredMixin, ListView): class Sistemas_xCliente_IMMEX_ListView(UserPassesTestMixin,LoginRequiredMixin, ListView):
model = Sistemas_por_cliente_A24 model = Sistemas_por_cliente_A24
@@ -85,11 +100,35 @@ class ClientesIMMEX_CreateView(CreateView):
else: else:
return response return response
"""---------API VIEWS---------""" """---------API VIEWS---------"""
class ChecarPermisos(APIView):
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated, HasAuthorizationHeader, TokenCheckSession]
def get(self,request):
if 'Response-Type' not in request.headers:
Response({"ACCESO":"OK"})
else:
ct= request.headers['Response-Type']
response = Response("ACCESS:OK", content_type=ct)
return response
class LoginIMMEX(APIView): class LoginIMMEX(APIView):
authentication_classes = [TokenAuthentication] authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated, HasAuthorizationHeader] permission_classes = [IsAuthenticated, HasAuthorizationHeader, ActiveTokenSessionPerm]
def get(self,request):
if 'Response-Type' not in request.headers:
return Response({'username':request.user.username})
else:
print(request.headers['Response-Type'])
ct= request.headers['Response-Type']
response = Response("ACCESS:OK", content_type=ct)
return response
def post(self, request): def post(self, request):
try: try:
username = request.data.get('username') username = request.data.get('username')
@@ -119,7 +158,8 @@ class LoginIMMEX(APIView):
class RegistroUsuarios(APIView): class RegistroUsuarios(APIView):
permission_classes = [ItsAdminToken] authentication_classes = (BasicAuthentication, TokenAuthentication, )
permission_classes=[IsAuthenticated,ItsAdminToken]
def post(self,request, *args, **kwargs): def post(self,request, *args, **kwargs):
try: try:
@@ -156,7 +196,9 @@ class RegistroUsuarios(APIView):
) )
class Check_IMMEX_RFC(APIView): class Check_IMMEX_RFC(APIView):
"""Verifica que el cliente pueda Timbrar""" """Verifica que el cliente pueda Timbrar"""
permission_classes = [IsAuthenticated,ItsAdminToken]
authentication_classes = (BasicAuthentication, TokenAuthentication, )
permission_classes=[IsAuthenticated]
def post(self,request,*args, **kwargs): def post(self,request,*args, **kwargs):
rfc= request.data.get('RFC') rfc= request.data.get('RFC')
@@ -174,6 +216,8 @@ class Check_IMMEX_RFC(APIView):
except Exception as E: except Exception as E:
return Response({'Error':f'check_RFC:{E} RFC:{rfc}','isError':True}) return Response({'Error':f'check_RFC:{E} RFC:{rfc}','isError':True})
class RegisterIMMEX_Device_APIView(APIView): class RegisterIMMEX_Device_APIView(APIView):
"""Register IMMEX Devices """Register IMMEX Devices
se manda el siguiente JSON se manda el siguiente JSON
@@ -189,34 +233,32 @@ class RegisterIMMEX_Device_APIView(APIView):
este es un ejemplo, el clienteA24 y sistema deben ser nombres validos para este es un ejemplo, el clienteA24 y sistema deben ser nombres validos para
sus tablas en IMMEX, es decir deben estar dados de alta en AS Admin en IMMEX sus tablas en IMMEX, es decir deben estar dados de alta en AS Admin en IMMEX
""" """
permissions_classes=[IsAuthenticated, ItsAdminToken] #authentication_classes = (BasicAuthentication, TokenAuthentication, )
#permission_classes=[ItsAdminToken]
def post(self,request): def post(self,request):
try: try:
serializer = SerialiazerA24(data=request.data, context={'request':request}) serializer = SerialiazerA24(data=request.data, context={'request':request})
if serializer.is_valid(): if serializer.is_valid():
instance =serializer.save() instance =serializer.save()
token = instance.token.key token = instance.token.key
return Response({'token':token}, status=status.HTTP_201_CREATED) if 'Response-Type' not in request.headers:
return Response({'token':token}, status=status.HTTP_201_CREATED)
else:
response = Response(instance.token.key, content_type='text/plain')
return response
else: else:
return Response({'Error':f'{serializer.errors}','isError':True}, status=status.HTTP_200_OK) return Response({'Error':f'{serializer.errors}','isError':True}, status=status.HTTP_200_OK)
except Exception as ex: except Exception as ex:
data_json = json.dumps(request.data) data_json = json.dumps(request.data)
traceback_info = f'{data_json}\n{traceback.format_exc()}' traceback_info = f'{data_json}\n{traceback.format_exc()}'
BitacoraErrores.objects.create(level=2, message=str(ex), traceback=traceback_info, BitacoraErrores.objects.create(level=2, message=str(ex), traceback=traceback_info,
view='IMMEX.RegisterIMMEX_Device_APIView') view='IMMEX.RegisterIMMEX_Device_APIView')
return Response({'Error':f'{ex}','isError':True}, status=status.HTTP_200_OK) return Response({'Error':f'{ex}','isError':True}, status=status.HTTP_200_OK)
class Sistemas_IMMEX_List_APIView(APIView):
def get(self, request):
sistemas = Sistema.objects.all()
serializer = Sistema_Serializer(sistemas,many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
class Sistema_por_cliente_APIView(APIView):
def get(self, request): def get(self, request):
nombre_sistema = request.query_params.get('nombre_sistema') nombre_sistema = request.query_params.get('nombre_sistema')
cliente_rfc = request.query_params.get('cliente_rfc') cliente_rfc = request.query_params.get('cliente_rfc')
@@ -224,7 +266,7 @@ class Sistema_por_cliente_APIView(APIView):
MAC = request.query_params.get('MAC') MAC = request.query_params.get('MAC')
sistemas_por_cliente = Sistemas_por_cliente_A24.objects.all() sistemas_por_cliente = Sistemas_por_cliente_A24.objects.all()
if nombre_sistema: if nombre_sistema:
sistemas_por_cliente = sistemas_por_cliente.filter(id_sistema__nombre_sistema=nombre_sistema) sistemas_por_cliente = sistemas_por_cliente.filter(id_sistema__nombre_sistema=nombre_sistema)
@@ -232,7 +274,71 @@ class Sistema_por_cliente_APIView(APIView):
sistemas_por_cliente = sistemas_por_cliente.filter(cliente__RFC=cliente_rfc) sistemas_por_cliente = sistemas_por_cliente.filter(cliente__RFC=cliente_rfc)
dispositivos = DeviceA24.objects.filter(sistema__nombre_sistema=nombre_sistema, clienteA24__RFC=cliente_rfc) dispositivos = DeviceA24.objects.filter(sistema__nombre_sistema=nombre_sistema, clienteA24__RFC=cliente_rfc)
print('dispositivos:',dispositivos)
serializer = Sistema_Por_Cliente_Serializer(sistemas_por_cliente, many=True,
context={'request': request})
data=serializer.data
for item in data:
del item['id_sistema']
del item['cliente']
if 'Response-Type' not in request.headers:
return Response(data, status=status.HTTP_200_OK)
else:
print(request.headers['Response-Type'])
csv_buffer = StringIO()
writer = csv.DictWriter(csv_buffer, fieldnames=serializer.child.fields.keys())
# Escribe los encabezados del CSV
#writer.writeheader()
# Escribe los datos en el CSV
for row in data:
writer.writerow(row)
# Coloca el puntero del archivo al principio del archivo
csv_buffer.seek(0)
# Lee la cadena CSV desde el objeto StringIO y devuelve como respuesta HTTP
csv_data = csv_buffer.getvalue()
print(csv_data)
csv_data = csv_data.replace("\r\n", "")
response = Response(csv_data, content_type='text/csv')
return response
class Sistemas_IMMEX_List_APIView(APIView):
authentication_classes = (BasicAuthentication, TokenAuthentication, )
permission_classes=[IsAuthenticated]
def get(self, request):
sistemas = Sistema.objects.all()
serializer = Sistema_Serializer(sistemas,many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
class Sistema_por_cliente_APIView(APIView):
authentication_classes = (BasicAuthentication, TokenAuthentication, )
permission_classes=[IsAuthenticated]
def get(self, request):
nombre_sistema = request.query_params.get('nombre_sistema')
cliente_rfc = request.query_params.get('cliente_rfc')
db = request.query_params.get('db')
MAC = request.query_params.get('MAC')
sistemas_por_cliente = Sistemas_por_cliente_A24.objects.all()
if nombre_sistema:
sistemas_por_cliente = sistemas_por_cliente.filter(id_sistema__nombre_sistema=nombre_sistema)
if cliente_rfc:
sistemas_por_cliente = sistemas_por_cliente.filter(cliente__RFC=cliente_rfc)
dispositivos = DeviceA24.objects.filter(sistema__nombre_sistema=nombre_sistema, clienteA24__RFC=cliente_rfc)
serializer = Sistema_Por_Cliente_Serializer(sistemas_por_cliente, many=True, serializer = Sistema_Por_Cliente_Serializer(sistemas_por_cliente, many=True,
context={'request': request}) context={'request': request})
data=serializer.data data=serializer.data
@@ -240,7 +346,8 @@ class Sistema_por_cliente_APIView(APIView):
del item['id_sistema'] del item['id_sistema']
del item['cliente'] del item['cliente']
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request): def post(self, request):
try: try:
context = { context = {
@@ -258,22 +365,20 @@ class Sistema_por_cliente_APIView(APIView):
data_json = json.dumps(request.data) data_json = json.dumps(request.data)
traceback_info = f'{data_json}\n{traceback.format_exc()}' traceback_info = f'{data_json}\n{traceback.format_exc()}'
BitacoraErrores.objects.create(level=2, message=str(ex), traceback=traceback_info, BitacoraErrores.objects.create(level=2, message=str(ex), traceback=traceback_info, \
view='IMMEX.Sistema_por_cliente_APIView') view='IMMEX.Sistema_por_cliente_APIView')
return Response({'Error':f'{ex}','isError':True}, status=status.HTTP_200_OK) return Response({'Error':f'{ex}','isError':True}, status=status.HTTP_200_OK)
#CRUD Clientes IMMEX #CRUD Clientes IMMEX
class MyPage(PageNumberPagination): class MyPage(PageNumberPagination):
page_size = 100 page_size =1
page_size_query_param = 'page_size' page_size_query_param = 'page_size'
max_page_size = 100 max_page_size = 1
class ClientesA24List(generics.ListCreateAPIView): class ClientesA24List(generics.ListCreateAPIView):
authentication_classes = (BasicAuthentication, TokenAuthentication, ) authentication_classes = (BasicAuthentication, TokenAuthentication, )
permission_classes=[IsAuthenticated,CheckPermiso] permission_classes=[ItsAdminToken]
@@ -302,8 +407,8 @@ class ClientesA24List(generics.ListCreateAPIView):
class ClientesA24Detail(APIView): class ClientesA24Detail(APIView):
authentication_classes = [TokenAuthentication] authentication_classes = (BasicAuthentication, TokenAuthentication, )
permission_classes = [IsAuthenticated, HasAuthorizationHeader] permission_classes=[ ItsAdminToken]
def get_object(self, pk): def get_object(self, pk):
try: try:
@@ -334,3 +439,145 @@ class ClientesA24Detail(APIView):
cliente.delete() cliente.delete()
return Response({"pk":pk},status=status.HTTP_200_OK) return Response({"pk":pk},status=status.HTTP_200_OK)
#-----ADMIN AREA
class DeviceA24List(generics.ListCreateAPIView):
#queryset = DeviceA24.objects.all()
serializer_class = DeviceA24_admin_Serialiazer
pagination_class = MyPage
authentication_classes = (BasicAuthentication, TokenAuthentication, )
permission_classes=[ ItsAdminToken]
def get_queryset(self):
queryset = DeviceA24.objects.all()
# Filtrar por clienteA24 si se proporciona como parámetro de consulta
clienteA24 = self.request.query_params.get('clienteA24')
if clienteA24:
queryset = queryset.filter(clienteA24__RFC__icontains=clienteA24)
# # Aplicar ordenación si se proporciona como parámetro de consulta
# ordering = self.request.query_params.get('ordering')
# if ordering:
# queryset = queryset.order_by(ordering)
return queryset
class DeviceA24Detail(generics.RetrieveUpdateDestroyAPIView):
queryset = DeviceA24.objects.all()
serializer_class = DeviceA24_admin_Serialiazer
authentication_classes = (BasicAuthentication, TokenAuthentication, )
permission_classes=[ ItsAdminToken]
# Método para recuperar un registro
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data)
# Método para actualizar un registro
def update(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
# Método para eliminar un registro
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
instance.delete()
return Response(status=204)
# Método para listar registros (opcional, dependiendo de tus necesidades)
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
class PermissionListCreateAPIView(viewsets.ModelViewSet):
queryset = Permission.objects.all()
# Asegúrate de tener un serializer adecuado
serializer_class = CustomPermissionSerializer
authentication_classes = (BasicAuthentication, TokenAuthentication, )
permission_classes=[ ItsAdminToken]
def get_queryset(self):
app_label = self.request.query_params.get('app_label')
user_id = self.request.query_params.get('user_id')
queryset = Permission.objects.all()
if app_label:
content_types = ContentType.objects.filter(app_label=app_label)
queryset = queryset.filter(content_type__in=content_types)
if user_id:
param_user = User.objects.get(id=user_id)
# Anotamos los permisos con True si el usuario los tiene, False en caso contrario
queryset = queryset.annotate(
activo=Case(
When(user=param_user, then=Value(True)),
default=Value(False),
output_field=BooleanField()
)
)
return queryset
def list(self, request, *args, **kwargs):
# Obtén la lista de permisos
queryset = self.get_queryset()
serializer = self.get_serializer(queryset, many=True)
# Agrega datos personalizados a la respuesta
data = {
"status": "success",
"message": "Lista de permisos recuperada exitosamente",
"data": serializer.data
}
return Response(data, status=status.HTTP_200_OK)
def create(self, request, *args, **kwargs):
# Obtén el ID del usuario del JSON de la solicitud
user_id = request.data.get('user_id')
try:
# Recupera el usuario por su ID
user = User.objects.get(id=user_id)
# Obtén la lista de permisos del JSON de la solicitud
permissions_data = request.data.get('permissions', [])
for perm_data in permissions_data:
# Recupera el ID del permiso de cada objeto en la lista
permission_id = perm_data.get('id')
print(permission_id)
try:
# Recupera el permiso por su ID
permission = Permission.objects.get(id=permission_id)
# Asigna el permiso al usuario
user.user_permissions.add(permission)
except Permission.DoesNotExist:
return Response({"error": f"El permiso con ID {permission_id} no existe"}, status=status.HTTP_400_BAD_REQUEST)
return Response({"message": "Permisos asignados correctamente al usuario"}, status=status.HTTP_201_CREATED)
except User.DoesNotExist:
return Response({"error": "El usuario no existe"}, status=status.HTTP_400_BAD_REQUEST)
class ModulosListCreateAPIView(viewsets.ModelViewSet):
queryset = Modulo.objects.all()
pagination_class = MyPage
serializer_class = ModulosSerializer
def get_queryset(self):
queryset = Modulo.objects.all()
return queryset

View File

@@ -1,5 +1,5 @@
from django.contrib import admin from django.contrib import admin
from .models import Sistema, sistemas_por_cliente, Device,DeviceHistory, BitacoraErrores from .models import Sistema, sistemas_por_cliente, Device,DeviceHistory, BitacoraErrores
class BitacoraErroresAdmin(admin.ModelAdmin): class BitacoraErroresAdmin(admin.ModelAdmin):
list_display = ['level', 'message','timestamp'] list_display = ['level', 'message','timestamp']
@@ -27,4 +27,4 @@ admin.site.register(BitacoraErrores,BitacoraErroresAdmin)
admin.site.register(Sistema,Sistema_Admin) admin.site.register(Sistema,Sistema_Admin)
admin.site.register(sistemas_por_cliente,SPC) admin.site.register(sistemas_por_cliente,SPC)
admin.site.register(Device,DeviceAdmin) admin.site.register(Device,DeviceAdmin)
admin.site.register(DeviceHistory,DeviceHistoryAdmin) admin.site.register(DeviceHistory,DeviceHistoryAdmin)

View File

@@ -4,6 +4,7 @@ from django.contrib.auth.models import Permission
class HasAuthorizationHeader(BasePermission): class HasAuthorizationHeader(BasePermission):
def has_permission(self, request, view): def has_permission(self, request, view):
return 'Authorization' in request.headers return 'Authorization' in request.headers
class ItsAdminToken(BasePermission): class ItsAdminToken(BasePermission):
@@ -18,19 +19,19 @@ class CheckPermiso(BasePermission):
def has_permission(self, request, view): def has_permission(self, request, view):
user = request.user user = request.user
print(user) #print(user)
permiso= request.META.get('HTTP_PERMISSION') permiso= request.META.get('HTTP_PERMISSION')
print('permiso',permiso) print('permiso',permiso)
print('es staff: ',user.is_staff) #print('es staff: ',user.is_staff)
print('su: ',user.is_superuser) #print('su: ',user.is_superuser)
print('Permisos:', user.user_permissions.filter(codename = permiso)) #print('Permisos:', user.user_permissions.filter(codename = permiso))
print(user.has_perm(permiso)) print(user.has_perm(permiso))
print('Grupos',user.groups.all()) #print('Grupos',user.groups.all())
if user.is_staff: if user.is_staff:
return True return True
if user.is_superuser: if user.is_superuser:
return True return True
if user.has_perm(permiso):
return True
return True return False