-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix API participation permissions, allow filtering by event type (#1249)
* correct handling of permissions on participation endpoint * add filter for event type on participation endpoint * add FilterSet, add tests
- Loading branch information
Showing
3 changed files
with
87 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from django_filters import DateTimeFilter, ModelChoiceFilter | ||
from django_filters.rest_framework import FilterSet | ||
from guardian.shortcuts import get_objects_for_user | ||
from rest_framework.filters import BaseFilterBackend | ||
|
||
from ephios.core.models import EventType, LocalParticipation | ||
|
||
|
||
class ParticipationPermissionFilter(BaseFilterBackend): | ||
def filter_queryset(self, request, queryset, view): | ||
events = get_objects_for_user(request.user, "core.view_event") | ||
return queryset.filter(shift__event__in=events) | ||
|
||
|
||
class ParticipationFilterSet(FilterSet): | ||
# we cannot use gettext_lazy as it breaks sphinxcontrib.openapi (https://github.com/sphinx-contrib/openapi/issues/153) | ||
event_type = ModelChoiceFilter( | ||
field_name="shift__event__type", label="event type", queryset=EventType.objects.all() | ||
) | ||
start_gte = DateTimeFilter(field_name="start_time", lookup_expr="gte", label="start time after") | ||
start_lte = DateTimeFilter( | ||
field_name="start_time", lookup_expr="lte", label="start time before" | ||
) | ||
end_gte = DateTimeFilter(field_name="end_time", lookup_expr="gte", label="end time after") | ||
end_lte = DateTimeFilter(field_name="end_time", lookup_expr="lte", label="end time before") | ||
|
||
class Meta: | ||
model = LocalParticipation | ||
fields = ["state"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
from django.urls import reverse | ||
from guardian.shortcuts import remove_perm | ||
|
||
from ephios.core.models import AbstractParticipation, LocalParticipation | ||
|
||
|
||
def test_participation_list_permissions(django_app, event, planner, groups, volunteer, manager): | ||
LocalParticipation.objects.create( | ||
user=volunteer, shift=event.shifts.first(), state=AbstractParticipation.States.CONFIRMED | ||
) | ||
response = django_app.get( | ||
reverse("api:user-participations-list", kwargs=dict(user=volunteer.pk)), | ||
user=planner, | ||
status=200, | ||
) | ||
assert event.title in response | ||
|
||
# make event invisible to volunteers | ||
_, planners, volunteers = groups | ||
remove_perm("view_event", planners, event) | ||
remove_perm("view_event", volunteers, event) | ||
remove_perm("view_event", planner, event) | ||
|
||
response = django_app.get( | ||
reverse("api:user-participations-list", kwargs=dict(user=volunteer.pk)), | ||
user=planner, | ||
status=200, | ||
) | ||
assert event.title not in response | ||
assert event.title in django_app.get( | ||
reverse("api:user-participations-list", kwargs=dict(user=volunteer.pk)), | ||
user=manager, | ||
status=200, | ||
) | ||
|
||
|
||
def test_participation_list_filter( | ||
django_app, event, planner, groups, volunteer, manager, training_event_type | ||
): | ||
LocalParticipation.objects.create( | ||
user=volunteer, shift=event.shifts.first(), state=AbstractParticipation.States.CONFIRMED | ||
) | ||
response = django_app.get( | ||
reverse("api:user-participations-list", kwargs=dict(user=volunteer.pk)), | ||
user=planner, | ||
status=200, | ||
) | ||
assert event.title in response | ||
|
||
response = django_app.get( | ||
f"{reverse('api:user-participations-list', kwargs=dict(user=volunteer.pk))}?event_type={training_event_type.pk}", | ||
user=planner, | ||
status=200, | ||
) | ||
assert event.title not in response |