API Auth: Respect staff sessions

This commit is contained in:
Raphael Michel
2019-04-26 16:24:13 +02:00
parent 2bc0dd6076
commit cc4602c308
2 changed files with 27 additions and 5 deletions

View File

@@ -1,7 +1,8 @@
from rest_framework.permissions import SAFE_METHODS, BasePermission from rest_framework.permissions import SAFE_METHODS, BasePermission
from pretix.api.models import OAuthAccessToken from pretix.api.models import OAuthAccessToken
from pretix.base.models import Device, Event from pretix.base.models import Device, Event, User
from pretix.base.models.auth import SuperuserPermissionSet
from pretix.base.models.organizer import Organizer, TeamAPIToken from pretix.base.models.organizer import Organizer, TeamAPIToken
from pretix.helpers.security import ( from pretix.helpers.security import (
SessionInvalid, SessionReauthRequired, assert_session_valid, SessionInvalid, SessionReauthRequired, assert_session_valid,
@@ -37,9 +38,12 @@ class EventPermission(BasePermission):
slug=request.resolver_match.kwargs['event'], slug=request.resolver_match.kwargs['event'],
organizer__slug=request.resolver_match.kwargs['organizer'], organizer__slug=request.resolver_match.kwargs['organizer'],
).select_related('organizer').first() ).select_related('organizer').first()
if not request.event or not perm_holder.has_event_permission(request.event.organizer, request.event): if not request.event or not perm_holder.has_event_permission(request.event.organizer, request.event, request=request):
return False return False
request.organizer = request.event.organizer request.organizer = request.event.organizer
if isinstance(perm_holder, User) and perm_holder.has_active_staff_session(request.session.session_key):
request.eventpermset = SuperuserPermissionSet()
else:
request.eventpermset = perm_holder.get_event_permission_set(request.organizer, request.event) request.eventpermset = perm_holder.get_event_permission_set(request.organizer, request.event)
if required_permission and required_permission not in request.eventpermset: if required_permission and required_permission not in request.eventpermset:
@@ -49,8 +53,11 @@ class EventPermission(BasePermission):
request.organizer = Organizer.objects.filter( request.organizer = Organizer.objects.filter(
slug=request.resolver_match.kwargs['organizer'], slug=request.resolver_match.kwargs['organizer'],
).first() ).first()
if not request.organizer or not perm_holder.has_organizer_permission(request.organizer): if not request.organizer or not perm_holder.has_organizer_permission(request.organizer, request=request):
return False return False
if isinstance(perm_holder, User) and perm_holder.has_active_staff_session(request.session.session_key):
request.orgapermset = SuperuserPermissionSet()
else:
request.orgapermset = perm_holder.get_organizer_permission_set(request.organizer) request.orgapermset = perm_holder.get_organizer_permission_set(request.organizer)
if required_permission and required_permission not in request.orgapermset: if required_permission and required_permission not in request.orgapermset:

View File

@@ -2,6 +2,7 @@ import time
import pytest import pytest
from django.test import override_settings from django.test import override_settings
from django.utils.timezone import now
from pretix.base.models import Organizer from pretix.base.models import Organizer
@@ -442,3 +443,17 @@ def test_token_org_subresources_permission_not_allowed(token_client, team, organ
assert resp.status_code == 403 assert resp.status_code == 403
else: else:
assert resp.status_code in (404, 403) assert resp.status_code in (404, 403)
@pytest.mark.django_db
@pytest.mark.parametrize("url", event_urls)
def test_event_staff_requires_staff_session(user_client, organizer, team, event, url, user):
team.delete()
user.is_staff = True
user.save()
resp = user_client.get('/api/v1/organizers/{}/events/{}/{}'.format(organizer.slug, event.slug, url[1]))
assert resp.status_code == 403
user.staffsession_set.create(date_start=now(), session_key=user_client.session.session_key)
resp = user_client.get('/api/v1/organizers/{}/events/{}/{}'.format(organizer.slug, event.slug, url[1]))
assert resp.status_code == 200