umap/umap/decorators.py
Yohan Boniface 49f600adfa wip: refactor login flow
Instead of dealing with in JavaScript, let's do a more classic
HTTP flow.

The main flows work, but there is still at least one to deal with:
when editing a map without being logged in, the server may ask for
login, and in this case we should login THEN reissue the request,
so we need to interrupt the first request in some way,
otherwise the server will still answer with a 403, which is what
happens after this commit.
2024-02-05 07:22:53 +01:00

62 lines
2 KiB
Python

from functools import wraps
from django.conf import settings
from django.http import HttpResponseForbidden
from django.shortcuts import get_object_or_404
from django.urls import reverse_lazy
from .models import Map
from .views import simple_json_response
LOGIN_URL = getattr(settings, "LOGIN_URL", "login")
LOGIN_URL = reverse_lazy(LOGIN_URL) if not LOGIN_URL.startswith("/") else LOGIN_URL
def login_required_if_not_anonymous_allowed(view_func):
@wraps(view_func)
def wrapper(request, *args, **kwargs):
if (
not getattr(settings, "UMAP_ALLOW_ANONYMOUS", False)
and not request.user.is_authenticated
):
return simple_json_response(login_required=str(LOGIN_URL))
return view_func(request, *args, **kwargs)
return wrapper
def can_edit_map(view_func):
"""
Used for URLs dealing with editing the map.
"""
@wraps(view_func)
def wrapper(request, *args, **kwargs):
map_inst = get_object_or_404(Map, pk=kwargs["map_id"])
user = request.user
kwargs["map_inst"] = map_inst # Avoid rerequesting the map in the view
if map_inst.edit_status >= map_inst.EDITORS:
can_edit = map_inst.can_edit(user=user, request=request)
if not can_edit:
if map_inst.owner and not user.is_authenticated:
return simple_json_response(login_required=str(LOGIN_URL))
return HttpResponseForbidden()
return view_func(request, *args, **kwargs)
return wrapper
def can_view_map(view_func):
"""
Used for URLs dealing with viewing the map.
"""
@wraps(view_func)
def wrapper(request, *args, **kwargs):
map_inst = get_object_or_404(Map, pk=kwargs["map_id"])
kwargs["map_inst"] = map_inst # Avoid rerequesting the map in the view
if not map_inst.can_view(request):
return HttpResponseForbidden()
return view_func(request, *args, **kwargs)
return wrapper