|
| 1 | +import logging |
1 | 2 | from datetime import timedelta
|
| 3 | +from inspect import isawaitable |
2 | 4 |
|
| 5 | +from django.http import HttpRequest |
| 6 | +from django.utils.decorators import sync_and_async_middleware |
3 | 7 | from django.utils.timezone import now
|
4 | 8 |
|
| 9 | +from asgiref.sync import iscoroutinefunction, sync_to_async |
| 10 | +from gqlauth.core.middlewares import USER_OR_ERROR_KEY, UserOrError |
| 11 | +from gqlauth.core.middlewares import django_jwt_middleware as _django_jwt_middleware |
| 12 | +from gqlauth.core.types_ import GQLAuthError, GQLAuthErrors |
| 13 | +from whitenoise.middleware import WhiteNoiseMiddleware |
| 14 | + |
5 | 15 | from hub.models import UserProperties
|
6 | 16 |
|
| 17 | +logger = logging.getLogger(__name__) |
7 | 18 |
|
8 |
| -class RecordLastSeenMiddleware: |
9 |
| - one_day = timedelta(hours=24) |
10 | 19 |
|
11 |
| - def __init__(self, get_response): |
12 |
| - self.get_response = get_response |
| 20 | +@sync_and_async_middleware |
| 21 | +def record_last_seen_middleware(get_response): |
| 22 | + one_day = timedelta(hours=24) |
13 | 23 |
|
14 |
| - def __call__(self, request): |
| 24 | + def process_request(request): |
15 | 25 | if request.user.is_authenticated:
|
16 | 26 | user = request.user
|
17 |
| - if not hasattr(user, "userproperties"): |
18 |
| - UserProperties.objects.create(user=user) |
19 |
| - |
| 27 | + props = UserProperties.objects.get_or_create(user=user) |
20 | 28 | last_seen = request.session.get("last_seen", None)
|
21 |
| - |
22 |
| - yesterday = now().replace(hour=0, minute=0) - self.one_day |
23 |
| - |
| 29 | + yesterday = now().replace(hour=0, minute=0) - one_day |
24 | 30 | if last_seen is None or last_seen < yesterday.timestamp():
|
25 |
| - props = user.userproperties |
26 | 31 | props.last_seen = now()
|
27 | 32 | request.session["last_seen"] = props.last_seen.timestamp()
|
28 | 33 | props.save()
|
29 | 34 |
|
30 |
| - response = self.get_response(request) |
| 35 | + if iscoroutinefunction(get_response): |
| 36 | + async def middleware(request: HttpRequest): |
| 37 | + await sync_to_async(process_request)(request) |
| 38 | + return await get_response(request) |
| 39 | + |
| 40 | + else: |
| 41 | + def middleware(request: HttpRequest): |
| 42 | + process_request(request) |
| 43 | + return get_response(request) |
| 44 | + |
| 45 | + return middleware |
| 46 | + |
| 47 | + |
| 48 | +@sync_and_async_middleware |
| 49 | +def async_whitenoise_middleware(get_response): |
| 50 | + def logic(request): |
| 51 | + return WhiteNoiseMiddleware(get_response)(request) |
| 52 | + |
| 53 | + if iscoroutinefunction(get_response): |
| 54 | + async def middleware(request: HttpRequest): |
| 55 | + response = logic(request) |
| 56 | + if isawaitable(response): |
| 57 | + response = await response |
| 58 | + return response |
| 59 | + |
| 60 | + else: |
| 61 | + def middleware(request: HttpRequest): |
| 62 | + return logic(request) |
| 63 | + |
| 64 | + return middleware |
| 65 | + |
| 66 | + |
| 67 | +@sync_and_async_middleware |
| 68 | +def django_jwt_middleware(get_response): |
| 69 | + """ |
| 70 | + Wrap the gqlauth jwt middleware in an exception |
| 71 | + handler (initially added because if a user is |
| 72 | + deleted, the middleware throws an error, |
| 73 | + causing a 500 instead of a 403). |
| 74 | + """ |
| 75 | + gqlauth_middleware = _django_jwt_middleware(get_response) |
| 76 | + |
| 77 | + def exception_handler(error: Exception, request: HttpRequest): |
| 78 | + logger.warning(f"Gqlauth middleware error: {error}") |
| 79 | + user_or_error = UserOrError() |
| 80 | + user_or_error.error = GQLAuthError(code=GQLAuthErrors.UNAUTHENTICATED) |
| 81 | + setattr(request, USER_OR_ERROR_KEY, user_or_error) |
| 82 | + |
| 83 | + if iscoroutinefunction(get_response): |
| 84 | + async def middleware(request: HttpRequest): |
| 85 | + try: |
| 86 | + return await gqlauth_middleware(request) |
| 87 | + except Exception: |
| 88 | + exception_handler(request) |
| 89 | + return await get_response(request) |
| 90 | + |
| 91 | + else: |
| 92 | + def middleware(request: HttpRequest): |
| 93 | + try: |
| 94 | + return gqlauth_middleware(request) |
| 95 | + except Exception as e: |
| 96 | + exception_handler(request) |
| 97 | + return get_response(request) |
31 | 98 |
|
32 |
| - return response |
| 99 | + return middleware |
0 commit comments