forgottenpassword.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. from django.contrib import messages
  2. from django.contrib.auth import get_user_model
  3. from django.http import Http404
  4. from django.shortcuts import get_object_or_404, redirect, render
  5. from django.utils.translation import ugettext as _
  6. from django.views.decorators.debug import sensitive_post_parameters
  7. from misago.conf import settings
  8. from misago.core.mail import mail_user
  9. from misago.core.views import noscript
  10. from misago.users.bans import get_user_ban
  11. from misago.users.decorators import deflect_authenticated, deflect_banned_ips
  12. from misago.users.forms.auth import ResetPasswordForm, SetNewPasswordForm
  13. from misago.users.tokens import (make_password_reset_token,
  14. is_password_reset_token_valid)
  15. def reset_view(f):
  16. @deflect_authenticated
  17. @deflect_banned_ips
  18. def decorator(*args, **kwargs):
  19. return f(*args, **kwargs)
  20. return decorator
  21. @reset_view
  22. def request_reset(request):
  23. return noscript(request, **{
  24. 'title': _("Change forgotten password"),
  25. 'message': _("To change forgotten password enable JavaScript."),
  26. })
  27. form = ResetPasswordForm()
  28. if request.method == 'POST':
  29. form = ResetPasswordForm(request.POST)
  30. if form.is_valid():
  31. requesting_user = form.user_cache
  32. request.session['reset_password_link_sent_to'] = requesting_user.pk
  33. mail_subject = _("Change %(user)s password "
  34. "on %(forum_title)s forums")
  35. subject_formats = {'user': requesting_user.username,
  36. 'forum_title': settings.forum_name}
  37. mail_subject = mail_subject % subject_formats
  38. confirmation_token = make_password_reset_token(requesting_user)
  39. mail_user(request, requesting_user, mail_subject,
  40. 'misago/emails/change_password_form_link',
  41. {'confirmation_token': confirmation_token})
  42. return redirect('misago:reset_password_link_sent')
  43. return render(request, 'misago/forgottenpassword/request.html',
  44. {'form': form})
  45. @reset_view
  46. def link_sent(request):
  47. requesting_user_pk = request.session.get('reset_password_link_sent_to')
  48. if not requesting_user_pk:
  49. raise Http404()
  50. User = get_user_model()
  51. requesting_user = get_object_or_404(User.objects, pk=requesting_user_pk)
  52. return render(request, 'misago/forgottenpassword/link_sent.html',
  53. {'requesting_user': requesting_user})
  54. class ResetStopped(Exception):
  55. pass
  56. class ResetError(Exception):
  57. pass
  58. @sensitive_post_parameters()
  59. @reset_view
  60. def reset_password_form(request, user_id, token):
  61. User = get_user_model()
  62. requesting_user = get_object_or_404(User.objects, pk=user_id)
  63. try:
  64. if requesting_user.requires_activation_by_admin:
  65. message = _("%(user)s, administrator has to activate your "
  66. "account before you will be able to request "
  67. "new password.")
  68. message = message % {'user': requesting_user.username}
  69. raise ResetStopped(message)
  70. if requesting_user.requires_activation_by_user:
  71. message = _("%(user)s, you have to activate your account "
  72. "before you will be able to request new password.")
  73. message = message % {'user': requesting_user.username}
  74. raise ResetStopped(message)
  75. if get_user_ban(requesting_user):
  76. message = _("%(user)s, your account is banned "
  77. "and it's password can't be changed.")
  78. message = message % {'user': requesting_user.username}
  79. raise ResetError(message)
  80. if not is_password_reset_token_valid(requesting_user, token):
  81. message = _("%(user)s, your link is invalid. "
  82. "Try again or request new link.")
  83. message = message % {'user': requesting_user.username}
  84. raise ResetError(message)
  85. except ResetStopped as e:
  86. messages.info(request, e.args[0])
  87. return redirect('misago:index')
  88. except ResetError as e:
  89. messages.error(request, e.args[0])
  90. return redirect('misago:request_password_reset')
  91. form = SetNewPasswordForm()
  92. if request.method == 'POST':
  93. form = SetNewPasswordForm(request.POST)
  94. if form.is_valid():
  95. requesting_user.set_password(form.cleaned_data['new_password'])
  96. requesting_user.save(update_fields=['password'])
  97. message = _("%(user)s, your password has been changed.")
  98. message = message % {'user': requesting_user.username}
  99. messages.success(request, message)
  100. return redirect(settings.LOGIN_URL)
  101. return render(request, 'misago/forgottenpassword/reset_password_form.html',
  102. {'requesting_user': requesting_user, 'form': form})