diff --git a/back_latienda/urls.py b/back_latienda/urls.py index 91d5891..8349a64 100644 --- a/back_latienda/urls.py +++ b/back_latienda/urls.py @@ -36,6 +36,7 @@ urlpatterns = [ path('api/v1/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), path('api/v1/token/verify/', TokenVerifyView.as_view(), name='token_verify'), path('api/v1/user/change_password//', core_views.ChangeUserPasswordView.as_view(), name="change-password"), + path('api/v1/forgotten_password/', core_views.forgotten_password, name="forgotten-password"), path('api/v1/admin_stats/', core_views.admin_stats, name='admin-stats'), path('api/v1/load_coops/', core_views.load_coop_managers, name='coop-loader'), path('api/v1/load_products/', product_views.load_coop_products, name='product-loader'), diff --git a/core/utils.py b/core/utils.py index ae85804..fc06599 100644 --- a/core/utils.py +++ b/core/utils.py @@ -1,4 +1,6 @@ import logging +import random +import string from io import BytesIO from django.contrib.auth import get_user_model @@ -199,3 +201,7 @@ def coop_loader(csv_reader, request=None): logging.error(f"Could not parse {row}") return coop_counter, user_counter + +def generate_password(length): + result_str = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(length)) + return result_str \ No newline at end of file diff --git a/core/views.py b/core/views.py index 21634fa..2329dbd 100644 --- a/core/views.py +++ b/core/views.py @@ -15,6 +15,8 @@ from django.db import IntegrityError from django.contrib.gis.geos import Point, GEOSGeometry from django.shortcuts import redirect from django.conf import settings +from django.template.loader import render_to_string +from django.core.mail import EmailMessage from rest_framework import status from rest_framework import viewsets @@ -203,6 +205,42 @@ def activate_user(request, uidb64, token): else: return Response({"error": f"Tu token de verificacion no coincide con ningún usuario registrado"}, status=status.HTTP_406_NOT_ACCEPTABLE) +@api_view(['POST']) +@permission_classes([AllowAny,]) +def forgotten_password(request): + """Set new password for registered user and send email + """ + if 'email' not in request.data: + return Response({"error": "Missing parameter: email"}, status=400) + email = request.data['email'] + user = User.objects.get(email=email) + + if user: + try: + password = utils.generate_password(12) + print(password) + user.set_password(password) + user.save() + except: + return Response({'error': f"Could not set new password [{str(type(e))}]: {str(e)}"}, status=500) + + try: + message = render_to_string('forgotten_password.html', { + 'user': user, + 'password': password, + }) + subject = "[latienda.coop] Contraseña restablecida" + email = EmailMessage(subject, message, to=[email]) + email.content_subtype = "html" + email.send() + logging.info(f"Email sent to {email}") + except Exception as e: + return Response({'error': f"Could not send emails [{str(type(e))}]: {str(e)}"}, status=500) + + else: + return Response({'error': f"This email has no user related to it"}, status=404) + return Response() + @api_view(['GET',]) @permission_classes([IsAdminUser,]) diff --git a/templates/forgotten_password.html b/templates/forgotten_password.html new file mode 100644 index 0000000..27ea75a --- /dev/null +++ b/templates/forgotten_password.html @@ -0,0 +1,680 @@ + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ +
+ + + + +
+ + + + + + +
+ + + +
+
+
+ +
+
+ +
+ + + + + + +
+ +
+ + + + +
+
+ Contraseña restablecida +
+
+
+ +
+
+ +
+ + + + + + +
+ +
+ + + + + + + + +
+ + + + + + +
+
+

+ Hola {{ user.full_name }}, +

+ Se ha restablecido la contraseña para tu usuario. + A partir de ahora puedes entrar en LaTienda.COOP con la siguiente contraseña: +

+ {{password}} +
+ +

+
+
+ +
+
+ +
+ + + + + + +
+ +
+
+
+ +
+
+ + +
+ + + + +
+
+ 2021 La Tienda.coop +
+
+
+ + + + + +
+ + + +