2023-12-05 10:34:47 -03:00
|
|
|
|
|
|
|
from django.views.decorators.csrf import csrf_exempt
|
2024-01-27 00:26:58 -03:00
|
|
|
from django.contrib.auth.hashers import check_password, make_password
|
|
|
|
from django.http import HttpResponse, JsonResponse
|
2023-12-05 10:34:47 -03:00
|
|
|
|
|
|
|
from rest_framework.decorators import action, api_view, schema
|
2024-01-27 00:26:58 -03:00
|
|
|
from project.settings import SECRET_KEY, EMAIL_HOST
|
2023-12-05 10:34:47 -03:00
|
|
|
|
2024-01-27 00:26:58 -03:00
|
|
|
from api import models, schemas
|
|
|
|
from datetime import datetime, timedelta
|
2023-12-05 10:34:47 -03:00
|
|
|
from decouple import config
|
|
|
|
import json
|
|
|
|
import jwt
|
|
|
|
import logging
|
2024-01-27 00:26:58 -03:00
|
|
|
import random
|
2023-12-05 10:34:47 -03:00
|
|
|
|
2024-01-27 00:26:58 -03:00
|
|
|
from django.conf import settings
|
|
|
|
from django.core.mail import EmailMultiAlternatives
|
|
|
|
from django.template.loader import get_template
|
2023-12-05 10:34:47 -03:00
|
|
|
|
|
|
|
# Views jwt
|
|
|
|
@csrf_exempt
|
|
|
|
@action(detail=False, methods=['post','get'])
|
|
|
|
@api_view(['GET','POST'])
|
|
|
|
@schema(schemas.AuthSchema())
|
|
|
|
def jwt_login(request):
|
|
|
|
if request.method == 'POST':
|
2024-01-27 00:26:58 -03:00
|
|
|
# validar rut y password
|
2023-12-05 10:34:47 -03:00
|
|
|
input = json.loads(request.body)
|
2024-01-27 00:26:58 -03:00
|
|
|
rut = input['rut'].replace('.','').replace('-','')
|
|
|
|
|
|
|
|
if rut != '0':
|
|
|
|
dv = rut[-1].upper()
|
|
|
|
rut = rut[:-1]
|
|
|
|
|
2023-12-05 10:34:47 -03:00
|
|
|
usuario = None
|
|
|
|
|
2024-01-27 00:26:58 -03:00
|
|
|
if rut == '0' and password == '0':
|
2023-12-05 10:34:47 -03:00
|
|
|
usuario = { 'login': '0', 'clave': '0' }
|
2024-01-27 00:26:58 -03:00
|
|
|
|
|
|
|
# solo se permite usuario 0 si no existen usuarios vigentes
|
|
|
|
count = models.Usuario.objects.filter(vigente = True).count()
|
|
|
|
if count > 0:
|
|
|
|
return HttpResponse('Acceso no valido', status=400)
|
|
|
|
else:
|
|
|
|
usuario = models.Usuario.objects.filter(vigente=1, rut__rut=rut, rut__dv=dv).values().first()
|
2023-12-05 10:34:47 -03:00
|
|
|
|
2024-01-27 00:26:58 -03:00
|
|
|
if not check_password(input['password'], usuario['clave']):
|
2023-12-05 10:34:47 -03:00
|
|
|
return HttpResponse('Acceso no valido', status=400)
|
|
|
|
|
|
|
|
ahora = datetime.utcnow()
|
|
|
|
manana = ahora + timedelta(days=1)
|
|
|
|
manana = manana.replace(hour=0, minute=0, second=0, microsecond=0)
|
|
|
|
|
|
|
|
payload = {
|
|
|
|
'iat': ahora,
|
|
|
|
'exp': manana, # ahora + timedelta(minutes=60),
|
|
|
|
'login': usuario['login']
|
|
|
|
}
|
2024-01-27 00:26:58 -03:00
|
|
|
token = jwt.encode(payload, SECRET_KEY, algorithm="HS256")
|
2023-12-05 10:34:47 -03:00
|
|
|
return JsonResponse({ 'token': token })
|
2024-01-27 00:26:58 -03:00
|
|
|
|
2023-12-05 10:34:47 -03:00
|
|
|
elif request.method == 'GET':
|
2024-01-27 00:26:58 -03:00
|
|
|
return JsonResponse(request.jwt_info)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@csrf_exempt
|
|
|
|
@action(detail=False, methods=['post'])
|
|
|
|
@api_view(['POST'])
|
|
|
|
def recuperar(request):
|
|
|
|
input = json.loads(request.body)
|
|
|
|
rut = input['rut'].replace('.','').replace('-','')
|
|
|
|
|
|
|
|
dv = rut[-1].upper()
|
|
|
|
rut = rut[:-1]
|
|
|
|
|
|
|
|
persona = models.Persona.objects.filter(rut=rut, dv=dv).first()
|
|
|
|
usuario = models.Usuario.objects.filter(rut=rut, vigente=True).first()
|
|
|
|
|
|
|
|
if usuario == None or persona == None:
|
|
|
|
return HttpResponse('Acceso no valido', status=400)
|
|
|
|
|
|
|
|
if persona.email != input['email'].lower():
|
|
|
|
return HttpResponse('Acceso no valido', status=400)
|
|
|
|
|
|
|
|
codigo_aleatorio = random.randint(100000, 999999)
|
|
|
|
ahora = datetime.utcnow()
|
|
|
|
expira = ahora + timedelta(minutes=5)
|
|
|
|
payload = {
|
|
|
|
'iat': ahora,
|
|
|
|
'exp': expira,
|
|
|
|
'rut': f'{persona.rut}',
|
|
|
|
'codigo': codigo_aleatorio
|
|
|
|
}
|
|
|
|
token = jwt.encode(payload, SECRET_KEY, algorithm="HS256")
|
|
|
|
vinculo = f"{http_referer(request)}/?s={token}#/new-password"
|
|
|
|
|
|
|
|
exito = enviar_correo(persona.email, 'Recuperar acceso', {
|
|
|
|
'nombre': f'{persona.nombres} {persona.apellido_a} {persona.apellido_b}',
|
|
|
|
'codigo': codigo_aleatorio,
|
|
|
|
'vinculo': vinculo
|
|
|
|
})
|
|
|
|
|
|
|
|
return JsonResponse({ 'ok': exito, 'HTTP_REFERER': request.META['HTTP_REFERER'] })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@csrf_exempt
|
|
|
|
@action(detail=False, methods=['post'])
|
|
|
|
@api_view(['POST'])
|
|
|
|
def info_token(request):
|
|
|
|
input = json.loads(request.body)
|
|
|
|
token = input['token']
|
|
|
|
try:
|
|
|
|
decoded = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
|
|
|
|
persona = models.Persona.objects.filter(rut=decoded['rut']).first()
|
|
|
|
|
|
|
|
return JsonResponse({
|
|
|
|
'nombres': persona.nombres,
|
|
|
|
'apellido_a': persona.apellido_a,
|
|
|
|
'apellido_b': persona.apellido_b
|
|
|
|
})
|
|
|
|
except jwt.ExpiredSignatureError:
|
|
|
|
return HttpResponse('token ya no es valido', status = 400)
|
|
|
|
except jwt.InvalidTokenError:
|
|
|
|
return HttpResponse('token es invalido', status = 400)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@csrf_exempt
|
|
|
|
@action(detail=False, methods=['post'])
|
|
|
|
@api_view(['POST'])
|
|
|
|
def nueva_contrasena(request):
|
|
|
|
input = json.loads(request.body)
|
|
|
|
token = input['token']
|
|
|
|
try:
|
|
|
|
decoded = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
|
|
|
|
|
|
|
|
if f"{decoded['codigo']}" != input['codigo']:
|
|
|
|
return HttpResponse('código es invalido', status = 400)
|
|
|
|
|
|
|
|
usuario = models.Usuario.objects.filter(rut = decoded['rut']).first()
|
|
|
|
if usuario == None:
|
|
|
|
return HttpResponse('Usuario no encontrado', status = 400)
|
|
|
|
|
|
|
|
usuario.clave = make_password(input['password'])
|
|
|
|
usuario.save()
|
|
|
|
|
|
|
|
return JsonResponse({ 'ok': True })
|
|
|
|
|
|
|
|
except jwt.ExpiredSignatureError:
|
|
|
|
return HttpResponse('token ya no es valido', status = 400)
|
|
|
|
except jwt.InvalidTokenError:
|
|
|
|
return HttpResponse('token es invalido', status = 400)
|
|
|
|
except Exception as e:
|
|
|
|
logging.error(e)
|
|
|
|
return HttpResponse('error al cambiar contraseña', status = 500)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def enviar_correo(destinatario, asunto, contenido):
|
|
|
|
try:
|
|
|
|
template = get_template('correo_recuperar.html') # Ruta al template del correo
|
|
|
|
contenido_renderizado = template.render(contenido)
|
|
|
|
|
|
|
|
mensaje = EmailMultiAlternatives(asunto, '', settings.EMAIL_HOST_USER, [destinatario])
|
|
|
|
mensaje.attach_alternative(contenido_renderizado, 'text/html')
|
|
|
|
mensaje.send()
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
|
|
print(f'EMAIL_HOST: {EMAIL_HOST}', flush=True)
|
|
|
|
print(f'ERROR: {e}', flush=True)
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def http_referer(request):
|
|
|
|
if 'HTTP_REFERER' in request.META:
|
|
|
|
referer = request.META['HTTP_REFERER']
|
|
|
|
else:
|
|
|
|
protocol = request.scheme
|
|
|
|
host = request.META['HTTP_HOST']
|
|
|
|
port = request.META['SERVER_PORT']
|
|
|
|
referer = f'{protocol}://{host}'
|
|
|
|
return referer
|