diff --git a/apiserver/apiserver/api/serializers.py b/apiserver/apiserver/api/serializers.py index b7c0868..07617f9 100644 --- a/apiserver/apiserver/api/serializers.py +++ b/apiserver/apiserver/api/serializers.py @@ -7,7 +7,7 @@ from rest_framework import serializers from rest_framework.exceptions import ValidationError from rest_framework.validators import UniqueValidator from rest_auth.registration.serializers import RegisterSerializer -from rest_auth.serializers import PasswordChangeSerializer +from rest_auth.serializers import PasswordChangeSerializer, PasswordResetSerializer from rest_auth.serializers import UserDetailsSerializer import re @@ -431,6 +431,12 @@ class MyPasswordChangeSerializer(PasswordChangeSerializer): super().save() +class MyPasswordResetSerializer(PasswordResetSerializer): + def validate_email(self, email): + if not User.objects.filter(email=email).exists(): + raise ValidationError('Not found.') + return super().validate_email(email) + class MemberCountSerializer(serializers.ModelSerializer): class Meta: diff --git a/apiserver/apiserver/api/views.py b/apiserver/apiserver/api/views.py index 4c48c35..504ac7e 100644 --- a/apiserver/apiserver/api/views.py +++ b/apiserver/apiserver/api/views.py @@ -12,7 +12,7 @@ from rest_framework import viewsets, views, mixins, generics, exceptions from rest_framework.decorators import action, api_view from rest_framework.permissions import BasePermission, IsAuthenticated, SAFE_METHODS, IsAuthenticatedOrReadOnly from rest_framework.response import Response -from rest_auth.views import PasswordChangeView +from rest_auth.views import PasswordChangeView, PasswordResetView from rest_auth.registration.views import RegisterView from fuzzywuzzy import fuzz, process from collections import OrderedDict @@ -525,6 +525,9 @@ class PasswordChangeView(PasswordChangeView): permission_classes = [AllowMetadata | IsAuthenticated] serializer_class = serializers.MyPasswordChangeSerializer +class PasswordResetView(PasswordResetView): + serializer_class = serializers.MyPasswordResetSerializer + @api_view() def null_view(request): diff --git a/apiserver/apiserver/settings.py b/apiserver/apiserver/settings.py index 104c59c..7e533b2 100644 --- a/apiserver/apiserver/settings.py +++ b/apiserver/apiserver/settings.py @@ -258,7 +258,12 @@ OLD_PASSWORD_FIELD_ENABLED = True LOGOUT_ON_PASSWORD_CHANGE = False ACCOUNT_PRESERVE_USERNAME_CASING = False -EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +if not secrets.EMAIL_USER or not secrets.EMAIL_PASS: + logger.info('Logging outgoing emails to console') + EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +else: + EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' + EMAIL_HOST = 'smtp-relay.gmail.com' EMAIL_PORT = '587' EMAIL_HOST_USER = secrets.EMAIL_USER diff --git a/apiserver/apiserver/urls.py b/apiserver/apiserver/urls.py index 32dc1f7..38d0b97 100644 --- a/apiserver/apiserver/urls.py +++ b/apiserver/apiserver/urls.py @@ -31,6 +31,7 @@ urlpatterns = [ path('', include(router.urls)), path(ADMIN_ROUTE, admin.site.urls), path('api-auth/', include('rest_framework.urls')), + url(r'^password/reset/$', views.PasswordResetView.as_view(), name='rest_password_reset'), url(r'^password-reset/confirm/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', views.null_view, name='password_reset_confirm'), url(r'^rest-auth/', include('rest_auth.urls')), url(r'^registration/', views.RegistrationView.as_view(), name='rest_name_register'),