usercp.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. from django.contrib import messages
  2. from django.contrib.auth import update_session_auth_hash
  3. from django.db import IntegrityError, transaction
  4. from django.http import Http404
  5. from django.shortcuts import redirect, render as django_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.markup import Editor
  11. from misago.users.decorators import deny_guests
  12. from misago.users.forms.usercp import (ChangeForumOptionsForm,
  13. EditSignatureForm,
  14. ChangeUsernameForm,
  15. ChangeEmailPasswordForm)
  16. from misago.users.signatures import set_user_signature
  17. from misago.users.sites import usercp
  18. from misago.users.changedcredentials import (cache_new_credentials,
  19. get_new_credentials)
  20. from misago.users.namechanges import UsernameChanges
  21. def render(request, template, context=None):
  22. context = context or {}
  23. context['pages'] = usercp.get_pages(request)
  24. for page in context['pages']:
  25. if page['is_active']:
  26. context['active_page'] = page
  27. break
  28. return django_render(request, template, context)
  29. @deny_guests
  30. def change_forum_options(request):
  31. form = ChangeForumOptionsForm(instance=request.user)
  32. if request.method == 'POST':
  33. form = ChangeForumOptionsForm(request.POST, instance=request.user)
  34. if form.is_valid():
  35. form.save()
  36. message = _("Your forum options have been changed.")
  37. messages.success(request, message)
  38. return redirect('misago:usercp_change_forum_options')
  39. return render(request, 'misago/usercp/change_forum_options.html',
  40. {'form': form})
  41. @deny_guests
  42. def edit_signature(request):
  43. if not request.user.acl['can_have_signature']:
  44. raise Http404()
  45. form = EditSignatureForm(instance=request.user)
  46. if not request.user.is_signature_banned and request.method == 'POST':
  47. form = EditSignatureForm(request.POST, instance=request.user)
  48. if form.is_valid():
  49. set_user_signature(request.user, form.cleaned_data['signature'])
  50. request.user.save(update_fields=['signature', 'signature_parsed',
  51. 'signature_checksum'])
  52. if form.cleaned_data['signature']:
  53. messages.success(request, _("Your signature has been edited."))
  54. else:
  55. message = _("Your signature has been cleared.")
  56. messages.success(request, message)
  57. return redirect('misago:usercp_edit_signature')
  58. acl = request.user.acl
  59. editor = Editor(form['signature'],
  60. allow_blocks=acl['allow_signature_blocks'],
  61. allow_links=acl['allow_signature_links'],
  62. allow_images=acl['allow_signature_images'])
  63. return render(request, 'misago/usercp/edit_signature.html',
  64. {'form': form, 'editor': editor})
  65. @deny_guests
  66. @transaction.atomic()
  67. def change_username(request):
  68. namechanges = UsernameChanges(request.user)
  69. form = ChangeUsernameForm()
  70. if request.method == 'POST' and namechanges.left:
  71. form = ChangeUsernameForm(request.POST, user=request.user)
  72. if form.is_valid():
  73. request.user.set_username(form.cleaned_data['new_username'])
  74. request.user.save(update_fields=['username', 'username_slug'])
  75. message = _("Your username has been changed.")
  76. messages.success(request, message)
  77. return redirect('misago:usercp_change_username')
  78. return render(request, 'misago/usercp/change_username.html', {
  79. 'form': form,
  80. 'changes_left': namechanges.left,
  81. 'next_change_on': namechanges.next_on
  82. })
  83. @sensitive_post_parameters()
  84. @deny_guests
  85. def change_email_password(request):
  86. form = ChangeEmailPasswordForm()
  87. if request.method == 'POST':
  88. form = ChangeEmailPasswordForm(request.POST, user=request.user)
  89. if form.is_valid():
  90. new_email = ''
  91. new_password = ''
  92. # Store original data
  93. old_email = request.user.email
  94. old_password = request.user.password
  95. # Assign new creds to user temporarily
  96. if form.cleaned_data['new_email']:
  97. request.user.set_email(form.cleaned_data['new_email'])
  98. new_email = request.user.email
  99. if form.cleaned_data['new_password']:
  100. request.user.set_password(form.cleaned_data['new_password'])
  101. new_password = request.user.password
  102. request.user.email = old_email
  103. request.user.password = old_password
  104. credentials_token = cache_new_credentials(
  105. request.user, new_email, new_password)
  106. mail_subject = _("Confirm changes to %(username)s account "
  107. "on %(forum_title)s forums")
  108. subject_formats = {'username': request.user.username,
  109. 'forum_title': settings.forum_name}
  110. mail_subject = mail_subject % subject_formats
  111. if new_email:
  112. # finally override email before sending message
  113. request.user.email = new_email
  114. mail_user(request, request.user, mail_subject,
  115. 'misago/emails/change_email_password',
  116. {'credentials_token': credentials_token})
  117. message = _("E-mail was sent to %(email)s with a link that "
  118. "you have to click to confirm changes.")
  119. messages.info(request, message % {'email': request.user.email})
  120. return redirect('misago:usercp_change_email_password')
  121. return render(request, 'misago/usercp/change_email_password.html',
  122. {'form': form})
  123. @deny_guests
  124. def confirm_email_password_change(request, token):
  125. new_credentials = get_new_credentials(request.user, token)
  126. if not new_credentials:
  127. messages.error(request, _("Confirmation link is invalid."))
  128. else:
  129. changes_made = []
  130. if new_credentials['email']:
  131. request.user.set_email(new_credentials['email'])
  132. changes_made.extend(['email', 'email_hash'])
  133. if new_credentials['password']:
  134. request.user.password = new_credentials['password']
  135. update_session_auth_hash(request, request.user)
  136. changes_made.append('password')
  137. try:
  138. request.user.save(update_fields=changes_made)
  139. message = _("Changes in e-mail and password have been saved.")
  140. messages.success(request, message)
  141. except IntegrityError:
  142. messages.error(request, _("Confirmation link is invalid."))
  143. return redirect('misago:usercp_change_email_password')