diff --git a/src/c3nav/access/apply.py b/src/c3nav/access/apply.py index dff49186..03c0cf7f 100644 --- a/src/c3nav/access/apply.py +++ b/src/c3nav/access/apply.py @@ -1,4 +1,5 @@ from django.conf import settings +from django.db.models import Q from c3nav.mapdata.inclusion import get_maybe_invisible_areas_names from c3nav.mapdata.utils.cache import get_packages_cached @@ -28,8 +29,15 @@ def can_access_package(request, package): return request.c3nav_full_access or package.name in get_unlocked_packages_names(request) -def filter_queryset_by_access(request, queryset): - return queryset if request.c3nav_full_access else queryset.filter(package__in=get_unlocked_packages(request)) +def filter_queryset_by_access(request, queryset, filter_location_inclusion=False): + return queryset if request.c3nav_full_access else queryset.filter(package__in=get_public_packages()) + + +def filter_arealocations_by_access(request, queryset): + if request.c3nav_full_access: + return queryset + return queryset.filter(Q(Q(package__in=get_public_packages()), ~Q(routing_inclusion='needs_permission')) | + Q(name__in=request.c3nav_access_list)) def get_visible_areas(request): diff --git a/src/c3nav/mapdata/api.py b/src/c3nav/mapdata/api.py index 6868f7dc..6e5caa83 100644 --- a/src/c3nav/mapdata/api.py +++ b/src/c3nav/mapdata/api.py @@ -9,7 +9,7 @@ from rest_framework.decorators import detail_route from rest_framework.response import Response from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet -from c3nav.access.apply import filter_queryset_by_access, get_unlocked_packages_names +from c3nav.access.apply import filter_arealocations_by_access, filter_queryset_by_access, get_unlocked_packages_names from c3nav.mapdata.models import GEOMETRY_MAPITEM_TYPES, AreaLocation, Level, LocationGroup, Package, Source from c3nav.mapdata.models.geometry import DirectedLineGeometryMapItemWithLevel from c3nav.mapdata.search import get_location @@ -159,16 +159,17 @@ class SourceViewSet(CachedReadOnlyViewSetMixin, ReadOnlyModelViewSet): return response -class LocationViewSet(CachedReadOnlyViewSetMixin, ViewSet): +class LocationViewSet(ViewSet): """ List and retrieve locations + Dont cache this, because it depends on access_list """ lookup_field = 'name' include_package_access = True def list(self, request, **kwargs): locations = [] - locations += sorted(filter_queryset_by_access(request, AreaLocation.objects.filter(can_search=True)), + locations += sorted(filter_arealocations_by_access(request, AreaLocation.objects.filter(can_search=True)), key=AreaLocation.get_sort_key, reverse=True) locations += list(filter_queryset_by_access(request, LocationGroup.objects.filter(can_search=True))) return Response([location.to_location_json() for location in locations]) diff --git a/src/c3nav/mapdata/search.py b/src/c3nav/mapdata/search.py index 932ef297..145ab616 100644 --- a/src/c3nav/mapdata/search.py +++ b/src/c3nav/mapdata/search.py @@ -2,7 +2,7 @@ import re from django.db.models import Q -from c3nav.access.apply import filter_queryset_by_access +from c3nav.access.apply import filter_arealocations_by_access, filter_queryset_by_access from c3nav.mapdata.models import AreaLocation, LocationGroup from c3nav.mapdata.models.locations import PointLocation from c3nav.mapdata.utils.cache import get_levels_cached @@ -18,9 +18,10 @@ def get_location(request, name): return PointLocation(level=level, x=int(match.group('x'))/100, y=int(match.group('y'))/100) if name.startswith('g:'): - return filter_queryset_by_access(request, LocationGroup.objects.filter(name=name[2:], can_search=True)).first() + queryset = LocationGroup.objects.filter(Q(name=name[2:], can_search=True)) + return filter_queryset_by_access(request, queryset).first() - return filter_queryset_by_access(request, AreaLocation.objects.filter(name=name, can_search=True)).first() + return filter_arealocations_by_access(request, AreaLocation.objects.filter(name=name, can_search=True)).first() def filter_words(queryset, words): @@ -40,7 +41,7 @@ def search_location(request, search): queryset = AreaLocation.objects.filter(can_seach=True) if isinstance(location, AreaLocation): queryset.exclude(name=location.name) - results += sorted(filter_words(filter_queryset_by_access(request, queryset), words), + results += sorted(filter_words(filter_arealocations_by_access(request, queryset), words), key=AreaLocation.get_sort_key, reverse=True) queryset = LocationGroup.objects.filter(can_seach=True)