1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
import json
from django.utils import timezone
from datetime import timedelta
from django.shortcuts import render
from django.contrib.auth import logout
from django.conf import settings
from django.http import HttpResponse
from authentication.utils import (
get_redirect_uri,
get_discord_user,
update_user_discord_info,
)
class AuthMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# Skip authentication if the path contains "admin", "static", or is not a view
if (
"admin" in request.path
or "auth" in request.path
or "favicon.ico" in request.path
or request.path.startswith(settings.STATIC_URL) # Exclude static files
or not hasattr(request, "user")
):
response = self.get_response(request)
return response
if (
not request.user.is_authenticated
or not request.user.discord_id
or not request.user.discord_access_token
):
logout(request)
request.session["next"] = request.get_full_path()
return render(request, "messages/unauthorized.html", {"redirect_uri": get_redirect_uri()})
# Check the verification cookie
verification_cookie = request.COOKIES.get("guild_verified")
if verification_cookie:
try:
cookie_data = json.loads(verification_cookie)
verified_at = timezone.datetime.fromisoformat(
cookie_data["verified_at"]
)
if timezone.now() > verified_at + timedelta(hours=24):
verification_cookie = None
except (json.JSONDecodeError, ValueError):
verification_cookie = None
else:
verification_cookie = None
pass
if not verification_cookie or not self._is_authorized(request):
user = get_discord_user(
access_token=request.user.discord_access_token,
token_type=request.user.discord_token_type,
)
if not user["is_authorized"]:
logout(request)
request.session["next"] = request.get_full_path()
response = render(request, "messages/unauthorized.html", {"redirect_uri": get_redirect_uri()})
response.delete_cookie("guild_verified") # Ensure cookie is removed
return response
update_user_discord_info(user)
# Set the verification cookie
response = self.get_response(request)
response.set_cookie(
"guild_verified",
json.dumps({"verified_at": timezone.now().isoformat()}),
max_age=24 * 60 * 60 if not user["rate_limited"] else 60 * 60, # 24 hours or 1 hour if rate limited
httponly=True, # Cookie cannot be accessed via JavaScript
secure=True, # Ensure cookie is sent over HTTPS
)
return response
response = self.get_response(request)
return response
def _is_authorized(self, request):
# Check if the user is authorized based on the current cookie or session
# This function should ideally be a lightweight check
return True
|