forgottenpassword.py 4.6 KB

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