bookwyrm/bookwyrm/views/landing/register.py

162 lines
5.5 KiB
Python
Raw Normal View History

2021-03-08 16:49:10 +00:00
""" class views for login/register views """
2024-04-01 19:50:31 +00:00
import zoneinfo
from django.contrib.auth import login
2021-01-12 16:19:08 +00:00
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404, redirect
2021-01-12 16:08:43 +00:00
from django.template.response import TemplateResponse
2021-09-07 22:03:15 +00:00
from django.utils.decorators import method_decorator
2021-01-12 16:08:43 +00:00
from django.views import View
from django.views.decorators.debug import sensitive_variables, sensitive_post_parameters
2021-01-12 16:08:43 +00:00
2021-08-06 22:38:37 +00:00
from bookwyrm import emailing, forms, models
2021-08-06 23:24:57 +00:00
from bookwyrm.settings import DOMAIN
2021-01-12 16:08:43 +00:00
2021-08-06 23:24:57 +00:00
# pylint: disable=no-self-use
class Register(View):
2021-04-26 16:15:42 +00:00
"""register a user"""
2021-03-08 16:49:10 +00:00
2021-09-18 22:08:02 +00:00
def get(self, request): # pylint: disable=unused-argument
"""whether or not you're logged in, just go to the home view"""
return redirect("/")
@sensitive_variables("password")
2021-09-07 22:03:15 +00:00
@method_decorator(sensitive_post_parameters("password"))
2021-01-12 16:19:08 +00:00
def post(self, request):
2021-04-26 16:15:42 +00:00
"""join the server"""
2021-08-06 23:24:57 +00:00
settings = models.SiteSettings.get()
# no registration allowed when the site is being installed
if settings.install_mode:
raise PermissionDenied()
2021-08-06 23:24:57 +00:00
if not settings.allow_registration:
2021-03-08 16:49:10 +00:00
invite_code = request.POST.get("invite_code")
2021-01-12 16:19:08 +00:00
if not invite_code:
2021-09-27 22:57:22 +00:00
raise PermissionDenied()
2021-01-12 16:19:08 +00:00
invite = get_object_or_404(models.SiteInvite, code=invite_code)
if not invite.valid():
2021-09-27 22:57:22 +00:00
raise PermissionDenied()
2021-01-12 16:19:08 +00:00
else:
invite = None
form = forms.RegisterForm(request.POST)
if not form.is_valid():
2022-02-17 19:25:11 +00:00
data = {
"login_form": forms.LoginForm(),
"register_form": form,
"invite": invite,
"valid": invite.valid() if invite else True,
}
if invite:
return TemplateResponse(request, "landing/invite.html", data)
return TemplateResponse(request, "landing/login.html", data)
2021-01-12 16:19:08 +00:00
2021-03-08 16:49:10 +00:00
localname = form.data["localname"].strip()
email = form.data["email"]
password = form.data["password"]
try:
2024-04-01 19:50:31 +00:00
preferred_timezone = zoneinfo.ZoneInfo(
form.data.get("preferred_timezone", "")
)
except (ValueError, zoneinfo.ZoneInfoNotFoundError):
preferred_timezone = zoneinfo.ZoneInfo("UTC")
2021-01-12 16:19:08 +00:00
# make sure the email isn't blocked as spam
email_domain = email.split("@")[-1]
if models.EmailBlocklist.objects.filter(domain=email_domain).exists():
# treat this like a successful registration, but don't do anything
return redirect("confirm-email")
2021-09-18 18:32:00 +00:00
username = f"{localname}@{DOMAIN}"
2021-01-12 16:19:08 +00:00
user = models.User.objects.create_user(
2021-08-06 22:38:37 +00:00
username,
email,
password,
localname=localname,
local=True,
2023-07-16 12:53:46 +00:00
allow_reactivation=settings.require_confirm_email,
2021-08-06 23:24:57 +00:00
deactivation_reason="pending" if settings.require_confirm_email else None,
is_active=not settings.require_confirm_email,
preferred_timezone=preferred_timezone,
2021-03-08 16:49:10 +00:00
)
2021-01-12 16:19:08 +00:00
if invite:
invite.times_used += 1
2021-04-02 00:19:29 +00:00
invite.invitees.add(user)
2021-01-12 16:19:08 +00:00
invite.save()
2021-08-06 23:24:57 +00:00
if settings.require_confirm_email:
2021-08-06 22:38:37 +00:00
emailing.email_confirmation_email(user)
return redirect("confirm-email")
2021-01-12 16:19:08 +00:00
login(request, user)
2021-04-01 19:46:38 +00:00
return redirect("get-started-profile")
2021-08-06 23:24:57 +00:00
class ConfirmEmailCode(View):
"""confirm email address"""
def get(self, request, code): # pylint: disable=unused-argument
"""you got the code! good work"""
settings = models.SiteSettings.get()
if request.user.is_authenticated:
2021-08-06 23:24:57 +00:00
return redirect("/")
if not settings.require_confirm_email:
return redirect("login")
2021-08-06 23:24:57 +00:00
# look up the user associated with this code
2021-08-07 00:23:44 +00:00
try:
user = models.User.objects.get(
confirmation_code=code, deactivation_reason="pending"
)
2021-08-07 00:23:44 +00:00
except models.User.DoesNotExist:
2021-08-07 00:39:22 +00:00
return TemplateResponse(
request, "confirm_email/confirm_email.html", {"valid": False}
)
2021-08-06 23:24:57 +00:00
# update the user
user.reactivate()
2021-08-06 23:24:57 +00:00
# direct the user to log in
return redirect("login", confirmed="confirmed")
2021-08-07 00:23:44 +00:00
class ConfirmEmail(View):
"""enter code to confirm email address"""
def get(self, request): # pylint: disable=unused-argument
"""you need a code! keep looking"""
settings = models.SiteSettings.get()
if request.user.is_authenticated or not settings.require_confirm_email:
return redirect("/")
2021-08-07 00:39:22 +00:00
return TemplateResponse(
request, "confirm_email/confirm_email.html", {"valid": True}
)
2021-08-07 00:23:44 +00:00
def post(self, request):
"""same as clicking the link"""
code = request.POST.get("code")
return ConfirmEmailCode().get(request, code)
2021-08-07 00:39:22 +00:00
2022-03-19 19:00:16 +00:00
class ResendConfirmEmail(View):
"""you probably didn't get the email because celery is slow but you can try this"""
2022-03-19 19:08:57 +00:00
def get(self, request):
2022-03-19 19:00:16 +00:00
"""resend link landing page"""
return TemplateResponse(request, "confirm_email/resend.html")
2022-03-19 19:00:16 +00:00
def post(self, request):
"""resend confirmation link"""
email = request.POST.get("email")
try:
user = models.User.objects.get(email=email)
emailing.email_confirmation_email(user)
2022-03-19 19:00:16 +00:00
except models.User.DoesNotExist:
pass
2022-03-19 19:00:16 +00:00
return TemplateResponse(
request, "confirm_email/confirm_email.html", {"valid": True}
)