From 3dc2371725386262a7002a8df73517b41724c6c1 Mon Sep 17 00:00:00 2001 From: Zambom Date: Mon, 26 Dec 2016 18:17:32 -0200 Subject: [PATCH] Password recovery implementation --- amadeus/templates/recover_pass_email_template.html | 14 ++------------ users/forms.py | 12 +++++++++++- users/templates/users/new_password.html | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ users/urls.py | 2 +- users/views.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 5 files changed, 145 insertions(+), 24 deletions(-) create mode 100644 users/templates/users/new_password.html diff --git a/amadeus/templates/recover_pass_email_template.html b/amadeus/templates/recover_pass_email_template.html index 9b99948..f8da341 100644 --- a/amadeus/templates/recover_pass_email_template.html +++ b/amadeus/templates/recover_pass_email_template.html @@ -1,15 +1,6 @@ -{% extends 'base.html' %} {% load i18n %} -{% block nav %} -{% endblock %} - -{% block breadcrumbs %} -{% endblock %} - -{% block sidebar %} -{% endblock sidebar %} {% autoescape off %} @@ -18,10 +9,9 @@ {% trans "Please go to the following page and choose a new password:" %} {% block reset_link %} - {{ domain }}{% url 'users:reset_password_confirm' uidb64=uid token=token %} - + {{ domain }} {% endblock %} {% blocktrans %}The {{ site_name }} team{% endblocktrans %} -{% endautoescape %} \ No newline at end of file +{% endautoescape %} diff --git a/users/forms.py b/users/forms.py index 23b8658..9c28521 100644 --- a/users/forms.py +++ b/users/forms.py @@ -197,4 +197,14 @@ class PassResetRequest(forms.Form): except ValidationError: self._errors['email'] = [_('You must insert an email address')] - return ValueError \ No newline at end of file + return ValueError + +class SetPasswordForm(Validation): + is_edit = False + + new_password = forms.CharField(label=_('New Password'), widget = forms.PasswordInput(render_value=True), required = True) + password2 = forms.CharField(label = _('Confirm Password'), widget = forms.PasswordInput(render_value=True), required = True) + + class Meta: + model = User + fields = [] \ No newline at end of file diff --git a/users/templates/users/new_password.html b/users/templates/users/new_password.html new file mode 100644 index 0000000..e6c282a --- /dev/null +++ b/users/templates/users/new_password.html @@ -0,0 +1,83 @@ +{% extends 'base.html' %} + +{% load static i18n %} +{% load widget_tweaks %} + +{% block nav %} +{% endblock %} + +{% block breadcrumbs %} +{% endblock %} + +{% block sidebar %} +{% endblock sidebar %} + +{% block content %} +
+
+
+ +
+
+
+
+
+ {% if messages %} + {% for message in messages %} + + {% endfor %} + {% endif %} +
+
+
+
+

{% trans 'Set new password' %}

+
+
+ +
+ {% csrf_token %} + {% for field in form %} +
+
+ {% if field.field.required %} + + {% else %} + + {% endif %} + {% render_field field class='form-control' %} + {{ field.help_text }} + {% if field.errors %} + + {% endif %} +
+
+ {% endfor %} +
+
+
+ +
+ +
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/users/urls.py b/users/urls.py index 41f05f6..c345ebe 100644 --- a/users/urls.py +++ b/users/urls.py @@ -8,7 +8,7 @@ urlpatterns = [ url(r'^logout/$', auth_views.logout, {'next_page': 'users:login'}, name='logout'), url(r'^signup/$', views.RegisterUser.as_view(), name = 'signup'), url(r'^forgot_password/$', views.ForgotPassword.as_view(), name = 'forgot_pass'), - url(r'^reset_password_confirm/(?P[0-9A-Za-z]+)-(?P.+)/$', views.ForgotPassword.as_view(), name = 'reset_password_confirm'), + url(r'^reset_password_confirm/(?P[0-9A-Za-z]+)-(?P.+)/$', views.PasswordResetConfirmView.as_view(), name = 'reset_password_confirm'), url(r'^$', views.UsersListView.as_view(), name = 'manage'), url(r'^create/$', views.CreateView.as_view(), name = 'create'), url(r'^edit/(?P[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/$', views.UpdateView.as_view(), name='update'), diff --git a/users/views.py b/users/views.py index e05f3d7..6b679ce 100644 --- a/users/views.py +++ b/users/views.py @@ -10,7 +10,7 @@ from rolepermissions.shortcuts import assign_role from rolepermissions.verifications import has_role from .models import User -from .forms import RegisterUserForm, ProfileForm, UserForm, ChangePassForm, PassResetRequest +from .forms import RegisterUserForm, ProfileForm, UserForm, ChangePassForm, PassResetRequest, SetPasswordForm #RECOVER PASS IMPORTS from django.contrib.auth.tokens import default_token_generator @@ -27,11 +27,6 @@ from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnl # ================ ADMIN ======================= - - - - - # class View(LoginRequiredMixin, generic.DetailView): # #login_url = reverse_lazy("core:home") @@ -367,13 +362,16 @@ class ForgotPassword(generic.FormView): if users.exists(): for user in users: + uid = urlsafe_base64_encode(force_bytes(user.pk)) + token = default_token_generator.make_token(user) + c = { + 'request': request, + 'title': _('Recover Password'), 'email': user.email, - 'domain': 'amadeus.com.br', #or your domain + 'domain': request.build_absolute_uri(reverse("users:reset_password_confirm", kwargs = {'uidb64': uid, 'token':token})), #or your domain 'site_name': 'Amadeus', - 'uid': urlsafe_base64_encode(force_bytes(user.pk)), 'user': user, - 'token': default_token_generator.make_token(user), 'protocol': 'http', } @@ -388,7 +386,7 @@ class ForgotPassword(generic.FormView): send_mail(subject, email, settings.DEFAULT_FROM_EMAIL , [user.email], fail_silently=False) result = self.form_valid(form) - messages.success(request, _("An email has been sent to the informed address. Please check its inbox to continue reseting password.")) + messages.success(request, _("Soon you'll receive an email with instructions to set your new password. If you don't receive it in 24 hours, please check your spam box.")) return result @@ -397,6 +395,46 @@ class ForgotPassword(generic.FormView): return result +class PasswordResetConfirmView(generic.FormView): + template_name = "users/new_password.html" + success_url = reverse_lazy('users:login') + form_class = SetPasswordForm + + def get_context_data(self, **kwargs): + context = super(PasswordResetConfirmView, self).get_context_data(**kwargs) + context['title'] = _('Reset Password') + + return context + + def post(self, request, uidb64=None, token=None, *arg, **kwargs): + form = self.get_form() + + assert uidb64 is not None and token is not None + + try: + uid = urlsafe_base64_decode(uidb64) + user = User._default_manager.get(pk=uid) + except (TypeError, ValueError, OverflowError, User.DoesNotExist): + user = None + + if user is not None and default_token_generator.check_token(user, token): + if form.is_valid(): + new_password = form.cleaned_data['new_password'] + + user.set_password(new_password) + user.save() + + messages.success(request, 'Password reset successfully.') + + return self.form_valid(form) + else: + messages.error(request, 'We were not able to reset your password.') + return self.form_invalid(form) + else: + messages.error(request,'The reset password link is no longer valid.') + return self.form_invalid(form) + + def login(request): context = {} context['title'] = _('Log In') -- libgit2 0.21.2