Allow users to temporarily deactivate their accounts (#2324)
This commit is contained in:
parent
3ebd957d3d
commit
eae1866992
16 changed files with 333 additions and 39 deletions
|
@ -31,7 +31,7 @@ from .admin.user_admin import UserAdmin, UserAdminList
|
|||
from .preferences.change_password import ChangePassword
|
||||
from .preferences.edit_user import EditUser
|
||||
from .preferences.export import Export
|
||||
from .preferences.delete_user import DeleteUser
|
||||
from .preferences.delete_user import DeleteUser, DeactivateUser, ReactivateUser
|
||||
from .preferences.block import Block, unblock
|
||||
from .preferences.two_factor_auth import (
|
||||
Edit2FA,
|
||||
|
|
|
@ -6,12 +6,10 @@ from django.contrib.auth.decorators import login_required
|
|||
from django.shortcuts import redirect
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views import View
|
||||
from django.views.decorators.debug import sensitive_variables, sensitive_post_parameters
|
||||
|
||||
from bookwyrm import forms, models
|
||||
from bookwyrm.settings import DOMAIN
|
||||
from bookwyrm.views.helpers import set_language
|
||||
|
||||
|
||||
|
@ -40,19 +38,13 @@ class Login(View):
|
|||
return redirect("/")
|
||||
login_form = forms.LoginForm(request.POST)
|
||||
|
||||
localname = login_form.data.get("localname")
|
||||
|
||||
if "@" in localname: # looks like an email address to me
|
||||
try:
|
||||
username = models.User.objects.get(email=localname).username
|
||||
except models.User.DoesNotExist: # maybe it's a full username?
|
||||
username = localname
|
||||
else:
|
||||
username = f"{localname}@{DOMAIN}"
|
||||
# who do we think is trying to log in
|
||||
username = login_form.infer_username()
|
||||
password = login_form.data.get("password")
|
||||
|
||||
# perform authentication
|
||||
user = authenticate(request, username=username, password=password)
|
||||
|
||||
if user is not None:
|
||||
# if 2fa is set, don't log them in until they enter the right code
|
||||
if user.two_factor_auth:
|
||||
|
@ -76,14 +68,22 @@ class Login(View):
|
|||
|
||||
return set_language(user, redirect("/"))
|
||||
|
||||
# maybe the user is pending email confirmation
|
||||
if models.User.objects.filter(
|
||||
username=username, is_active=False, deactivation_reason="pending"
|
||||
).exists():
|
||||
user_attempt = models.User.objects.filter(
|
||||
username=username, is_active=False
|
||||
).first()
|
||||
if user_attempt and user_attempt.deactivation_reason == "pending":
|
||||
# maybe the user is pending email confirmation
|
||||
return redirect("confirm-email")
|
||||
if (
|
||||
user_attempt
|
||||
and user_attempt.allow_reactivation
|
||||
and user_attempt.check_password(password)
|
||||
):
|
||||
# maybe we want to reactivate an account?
|
||||
return redirect("prefs-reactivate")
|
||||
|
||||
# login errors
|
||||
login_form.non_field_errors = _("Username or password are incorrect")
|
||||
login_form.add_invalid_password_error()
|
||||
register_form = forms.RegisterForm()
|
||||
data = {"login_form": login_form, "register_form": register_form}
|
||||
return TemplateResponse(request, "landing/login.html", data)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
""" edit your own account """
|
||||
from django.contrib.auth import logout
|
||||
import time
|
||||
|
||||
from django.contrib.auth import login, logout
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views import View
|
||||
|
@ -23,7 +25,7 @@ class DeleteUser(View):
|
|||
return TemplateResponse(request, "preferences/delete_user.html", data)
|
||||
|
||||
def post(self, request):
|
||||
"""les get fancy with images"""
|
||||
"""There's no going back from this"""
|
||||
form = forms.DeleteUserForm(request.POST, instance=request.user)
|
||||
# idk why but I couldn't get check_password to work on request.user
|
||||
user = models.User.objects.get(id=request.user.id)
|
||||
|
@ -36,3 +38,49 @@ class DeleteUser(View):
|
|||
form.errors["password"] = ["Invalid password"]
|
||||
data = {"form": form, "user": request.user}
|
||||
return TemplateResponse(request, "preferences/delete_user.html", data)
|
||||
|
||||
|
||||
@method_decorator(login_required, name="dispatch")
|
||||
class DeactivateUser(View):
|
||||
"""deactivate user view"""
|
||||
|
||||
def post(self, request):
|
||||
"""You can reactivate"""
|
||||
request.user.deactivate()
|
||||
logout(request)
|
||||
return redirect("/")
|
||||
|
||||
|
||||
class ReactivateUser(View):
|
||||
"""now reactivate the user"""
|
||||
|
||||
def get(self, request):
|
||||
"""so you want to rejoin?"""
|
||||
if request.user.is_authenticated:
|
||||
return redirect("/")
|
||||
data = {"login_form": forms.LoginForm()}
|
||||
return TemplateResponse(request, "landing/reactivate.html", data)
|
||||
|
||||
def post(self, request):
|
||||
"""reactivate that baby"""
|
||||
login_form = forms.LoginForm(request.POST)
|
||||
|
||||
username = login_form.infer_username()
|
||||
password = login_form.data.get("password")
|
||||
user = get_object_or_404(models.User, username=username)
|
||||
|
||||
# we can't use "authenticate" because that requires an active user
|
||||
if not user.check_password(password):
|
||||
login_form.add_invalid_password_error()
|
||||
data = {"login_form": login_form}
|
||||
return TemplateResponse(request, "landing/reactivate.html", data)
|
||||
|
||||
# Correct password, do you need 2fa too?
|
||||
if user.two_factor_auth:
|
||||
request.session["2fa_user"] = user.username
|
||||
request.session["2fa_auth_time"] = time.time()
|
||||
return redirect("login-with-2fa")
|
||||
|
||||
user.reactivate()
|
||||
login(request, user)
|
||||
return redirect("/")
|
||||
|
|
|
@ -133,6 +133,9 @@ class LoginWith2FA(View):
|
|||
request, "two_factor_auth/two_factor_login.html", data
|
||||
)
|
||||
|
||||
# is this a reactivate? let's go for it
|
||||
if not user.is_active and user.allow_reactivation:
|
||||
user.reactivate()
|
||||
# log the user in - we are bypassing standard login
|
||||
login(request, user)
|
||||
user.update_active_date()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue