2021-03-08 16:49:10 +00:00
|
|
|
""" class views for password management """
|
2021-01-12 16:48:31 +00:00
|
|
|
from django.contrib.auth import login
|
|
|
|
from django.core.exceptions import PermissionDenied
|
|
|
|
from django.shortcuts import redirect
|
|
|
|
from django.template.response import TemplateResponse
|
2021-08-17 21:35:28 +00:00
|
|
|
from django.utils.translation import gettext_lazy as _
|
2021-01-12 16:48:31 +00:00
|
|
|
from django.views import View
|
|
|
|
|
|
|
|
from bookwyrm import models
|
|
|
|
from bookwyrm.emailing import password_reset_email
|
|
|
|
|
|
|
|
|
|
|
|
# pylint: disable= no-self-use
|
|
|
|
class PasswordResetRequest(View):
|
2021-04-26 16:15:42 +00:00
|
|
|
"""forgot password flow"""
|
2021-03-08 16:49:10 +00:00
|
|
|
|
2021-01-12 16:48:31 +00:00
|
|
|
def get(self, request):
|
2021-04-26 16:15:42 +00:00
|
|
|
"""password reset page"""
|
2021-01-12 16:48:31 +00:00
|
|
|
return TemplateResponse(
|
|
|
|
request,
|
2021-10-16 17:00:31 +00:00
|
|
|
"landing/password_reset_request.html",
|
2021-01-12 16:48:31 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
def post(self, request):
|
2021-04-26 16:15:42 +00:00
|
|
|
"""create a password reset token"""
|
2021-03-08 16:49:10 +00:00
|
|
|
email = request.POST.get("email")
|
2021-01-12 16:48:31 +00:00
|
|
|
try:
|
2021-09-27 16:29:13 +00:00
|
|
|
user = models.User.viewer_aware_objects(request.user).get(
|
|
|
|
email=email, email__isnull=False
|
|
|
|
)
|
2021-01-12 16:48:31 +00:00
|
|
|
except models.User.DoesNotExist:
|
2021-03-21 19:06:20 +00:00
|
|
|
data = {"error": _("No user with that email address was found.")}
|
2021-10-16 17:00:31 +00:00
|
|
|
return TemplateResponse(
|
|
|
|
request, "landing/password_reset_request.html", data
|
|
|
|
)
|
2021-01-12 16:48:31 +00:00
|
|
|
|
|
|
|
# remove any existing password reset cods for this user
|
|
|
|
models.PasswordReset.objects.filter(user=user).all().delete()
|
|
|
|
|
|
|
|
# create a new reset code
|
|
|
|
code = models.PasswordReset.objects.create(user=user)
|
|
|
|
password_reset_email(code)
|
2021-10-06 23:33:07 +00:00
|
|
|
data = {"message": _(f"A password reset link was sent to {email}")}
|
2021-10-16 17:00:31 +00:00
|
|
|
return TemplateResponse(request, "landing/password_reset_request.html", data)
|
2021-01-12 16:48:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
class PasswordReset(View):
|
2021-04-26 16:15:42 +00:00
|
|
|
"""set new password"""
|
2021-03-08 16:49:10 +00:00
|
|
|
|
2021-01-12 16:48:31 +00:00
|
|
|
def get(self, request, code):
|
2021-04-26 16:15:42 +00:00
|
|
|
"""endpoint for sending invites"""
|
2021-01-12 16:48:31 +00:00
|
|
|
if request.user.is_authenticated:
|
2021-03-08 16:49:10 +00:00
|
|
|
return redirect("/")
|
2021-01-12 16:48:31 +00:00
|
|
|
try:
|
|
|
|
reset_code = models.PasswordReset.objects.get(code=code)
|
|
|
|
if not reset_code.valid():
|
2021-09-27 22:57:22 +00:00
|
|
|
raise PermissionDenied()
|
2021-01-12 16:48:31 +00:00
|
|
|
except models.PasswordReset.DoesNotExist:
|
2021-09-27 22:57:22 +00:00
|
|
|
raise PermissionDenied()
|
2021-01-12 16:48:31 +00:00
|
|
|
|
2021-10-16 17:00:31 +00:00
|
|
|
return TemplateResponse(request, "landing/password_reset.html", {"code": code})
|
2021-01-12 16:48:31 +00:00
|
|
|
|
|
|
|
def post(self, request, code):
|
2021-04-26 16:15:42 +00:00
|
|
|
"""allow a user to change their password through an emailed token"""
|
2021-01-12 16:48:31 +00:00
|
|
|
try:
|
2021-03-08 16:49:10 +00:00
|
|
|
reset_code = models.PasswordReset.objects.get(code=code)
|
2021-01-12 16:48:31 +00:00
|
|
|
except models.PasswordReset.DoesNotExist:
|
2021-03-08 16:49:10 +00:00
|
|
|
data = {"errors": ["Invalid password reset link"]}
|
2021-10-16 17:00:31 +00:00
|
|
|
return TemplateResponse(request, "landing/password_reset.html", data)
|
2021-01-12 16:48:31 +00:00
|
|
|
|
|
|
|
user = reset_code.user
|
|
|
|
|
2021-03-08 16:49:10 +00:00
|
|
|
new_password = request.POST.get("password")
|
|
|
|
confirm_password = request.POST.get("confirm-password")
|
2021-01-12 16:48:31 +00:00
|
|
|
|
|
|
|
if new_password != confirm_password:
|
2021-03-08 16:49:10 +00:00
|
|
|
data = {"errors": ["Passwords do not match"]}
|
2021-10-16 17:00:31 +00:00
|
|
|
return TemplateResponse(request, "landing/password_reset.html", data)
|
2021-01-12 16:48:31 +00:00
|
|
|
|
|
|
|
user.set_password(new_password)
|
2021-08-03 19:33:48 +00:00
|
|
|
user.save(broadcast=False, update_fields=["password"])
|
2021-01-12 16:48:31 +00:00
|
|
|
login(request, user)
|
|
|
|
reset_code.delete()
|
2021-03-08 16:49:10 +00:00
|
|
|
return redirect("/")
|