mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-30 02:27:01 -05:00
feat: Implement MFA authentication, add ride statistics model, and update various services, APIs, and tests across the application.
This commit is contained in:
@@ -1,41 +1,42 @@
|
||||
from django.views.generic import DetailView, TemplateView
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib import messages
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.crypto import get_random_string
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
from django.contrib.sites.shortcuts import get_current_site
|
||||
from django.contrib.sites.models import Site
|
||||
from django.contrib.sites.requests import RequestSite
|
||||
from django.db.models import QuerySet
|
||||
from django.http import HttpResponseRedirect, HttpResponse, HttpRequest
|
||||
from django.urls import reverse
|
||||
from django.contrib.auth import login
|
||||
from django.core.files.uploadedfile import UploadedFile
|
||||
from apps.accounts.models import (
|
||||
User,
|
||||
PasswordReset,
|
||||
EmailVerification,
|
||||
UserProfile,
|
||||
)
|
||||
from apps.lists.models import UserList
|
||||
from django_forwardemail.services import EmailService
|
||||
from apps.parks.models import ParkReview
|
||||
from apps.rides.models import RideReview
|
||||
from allauth.account.views import LoginView, SignupView
|
||||
from .mixins import TurnstileMixin
|
||||
from typing import Dict, Any, Optional, Union, cast
|
||||
from django_htmx.http import HttpResponseClientRefresh
|
||||
from contextlib import suppress
|
||||
import logging
|
||||
import re
|
||||
from contextlib import suppress
|
||||
from datetime import timedelta
|
||||
from typing import Any, cast
|
||||
|
||||
from apps.core.logging import log_exception, log_security_event
|
||||
from allauth.account.views import LoginView, SignupView
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth import get_user_model, login
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib.sites.models import Site
|
||||
from django.contrib.sites.requests import RequestSite
|
||||
from django.contrib.sites.shortcuts import get_current_site
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.files.uploadedfile import UploadedFile
|
||||
from django.db.models import QuerySet
|
||||
from django.http import HttpRequest, HttpResponse, HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.template.loader import render_to_string
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.crypto import get_random_string
|
||||
from django.views.generic import DetailView, TemplateView
|
||||
from django_forwardemail.services import EmailService
|
||||
from django_htmx.http import HttpResponseClientRefresh
|
||||
|
||||
from apps.accounts.models import (
|
||||
EmailVerification,
|
||||
PasswordReset,
|
||||
User,
|
||||
UserProfile,
|
||||
)
|
||||
from apps.core.logging import log_security_event
|
||||
from apps.lists.models import UserList
|
||||
from apps.parks.models import ParkReview
|
||||
from apps.rides.models import RideReview
|
||||
|
||||
from .mixins import TurnstileMixin
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -184,7 +185,7 @@ class ProfileView(DetailView):
|
||||
def get_queryset(self) -> QuerySet[User]:
|
||||
return User.objects.select_related("profile")
|
||||
|
||||
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
||||
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
||||
context = super().get_context_data(**kwargs)
|
||||
user = cast(User, self.get_object())
|
||||
|
||||
@@ -220,7 +221,7 @@ class ProfileView(DetailView):
|
||||
class SettingsView(LoginRequiredMixin, TemplateView):
|
||||
template_name = "accounts/settings.html"
|
||||
|
||||
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
||||
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["user"] = self.request.user
|
||||
return context
|
||||
@@ -283,7 +284,7 @@ class SettingsView(LoginRequiredMixin, TemplateView):
|
||||
|
||||
def _handle_password_change(
|
||||
self, request: HttpRequest
|
||||
) -> Optional[HttpResponseRedirect]:
|
||||
) -> HttpResponseRedirect | None:
|
||||
user = cast(User, request.user)
|
||||
old_password = request.POST.get("old_password", "")
|
||||
new_password = request.POST.get("new_password", "")
|
||||
@@ -385,7 +386,7 @@ def create_password_reset_token(user: User) -> str:
|
||||
|
||||
|
||||
def send_password_reset_email(
|
||||
user: User, site: Union[Site, RequestSite], token: str
|
||||
user: User, site: Site | RequestSite, token: str
|
||||
) -> None:
|
||||
reset_url = reverse("password_reset_confirm", kwargs={"token": token})
|
||||
context = {
|
||||
@@ -435,7 +436,7 @@ def handle_password_reset(
|
||||
user: User,
|
||||
new_password: str,
|
||||
reset: PasswordReset,
|
||||
site: Union[Site, RequestSite],
|
||||
site: Site | RequestSite,
|
||||
) -> None:
|
||||
user.set_password(new_password)
|
||||
user.save()
|
||||
@@ -457,7 +458,7 @@ def handle_password_reset(
|
||||
|
||||
|
||||
def send_password_reset_confirmation(
|
||||
user: User, site: Union[Site, RequestSite]
|
||||
user: User, site: Site | RequestSite
|
||||
) -> None:
|
||||
context = {
|
||||
"user": user,
|
||||
|
||||
Reference in New Issue
Block a user