Files
DroneWars/frontend/views.py
Matteo Rosati 9587995354 simplify apps
2026-02-11 21:05:49 +01:00

114 lines
4.0 KiB
Python

from django.contrib import messages
from django.contrib.auth import authenticate
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.http import HttpRequest, HttpResponse
from django.shortcuts import redirect, render
from django.views.decorators.http import require_http_methods
from django_ratelimit.decorators import ratelimit
from game.models import UserProfile
def home(request):
return render(request, "frontend/home.html")
@ratelimit(key="ip", rate="5/m", method="POST", block=False)
@require_http_methods(["GET", "POST"])
def register(request: HttpRequest) -> HttpResponse:
user = getattr(request, "user", None)
if user and user.is_authenticated:
return redirect("home")
if getattr(request, "limited", False):
messages.error(request, "Too many attempts. Try again in a minute.")
if request.method == "POST" and not getattr(request, "limited", False):
email = str(request.POST.get("email", "")).strip().lower()
display_name = str(request.POST.get("display_name", "")).strip()
password = request.POST.get("password") or ""
password_confirm = request.POST.get("password_confirm") or ""
errors: list[str] = []
if not email:
errors.append("Email is required.")
else:
try:
validate_email(email)
except ValidationError:
errors.append("Enter a valid email address.")
if not display_name:
errors.append("Display name is required.")
if not password:
errors.append("Password is required.")
elif password != password_confirm:
errors.append("Passwords do not match.")
if email and User.objects.filter(username=email).exists():
errors.append("An account with that email already exists.")
if (
display_name
and UserProfile.objects.filter( # type: ignore[attr-defined]
display_name=display_name
).exists()
):
errors.append("That display name is already taken.")
if errors:
for error in errors:
messages.error(request, error)
else:
user = User.objects.create_user(
username=email, email=email, password=password
)
UserProfile.objects.filter(user=user).update( # type: ignore[attr-defined]
display_name=display_name
)
auth_login(request, user)
return redirect("home")
return render(request, "frontend/register.html")
@ratelimit(key="ip", rate="10/m", method="POST", block=False)
@require_http_methods(["GET", "POST"])
def login(request: HttpRequest) -> HttpResponse:
user = getattr(request, "user", None)
if user and user.is_authenticated:
return redirect("home")
if getattr(request, "limited", False):
messages.error(request, "Too many attempts. Try again in a minute.")
if request.method == "POST" and not getattr(request, "limited", False):
email = str(request.POST.get("email", "")).strip().lower()
password = request.POST.get("password") or ""
if not email or not password:
messages.error(request, "Email and password are required.")
else:
user = authenticate(request, username=email, password=password)
if user is None:
messages.error(request, "Invalid email or password.")
else:
auth_login(request, user)
return redirect("home")
return render(request, "frontend/login.html")
@require_http_methods(["GET", "POST"])
def logout(request: HttpRequest) -> HttpResponse:
if request.method == "POST":
auth_logout(request)
return redirect("home")
return render(request, "frontend/logout.html")