forgottenpassword.py 4.7 KB

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