implement access permissions

This commit is contained in:
Laura Klünder 2017-10-24 22:45:57 +02:00
parent 7c44a9d74f
commit 10da4f3bb6
3 changed files with 29 additions and 8 deletions

View file

@ -1,6 +1,8 @@
from django.conf import settings
from django.core.cache import cache
from django.db import models
from django.db.models import Q
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from c3nav.mapdata.models.base import SerializableMixin, TitledMixin
@ -36,6 +38,24 @@ class AccessPermission(models.Model):
default_related_name = 'accesspermissions'
unique_together = (('user', 'access_restriction'), )
@staticmethod
def user_access_permission_key(user):
return 'mapdata:user_access_permission:%d' % user.pk
@classmethod
def get_for_request(cls, request):
if not request.user.is_authenticated:
return set()
cache_key = cls.user_access_permission_key(request.user)
access_restriction_ids = cache.get(cache_key, None)
if access_restriction_ids is None:
access_restriction_ids = set(request.user.accesspermissions.filter(
Q(expire_date__isnull=True) | Q(expire_date__lt=timezone.now())
).values_list('access_restriction_id', flat=True))
cache.set(cache_key, access_restriction_ids, 120)
return access_restriction_ids
class AccessRestrictionMixin(SerializableMixin, models.Model):
access_restriction = models.ForeignKey(AccessRestriction, null=True, blank=True,
@ -55,6 +75,7 @@ class AccessRestrictionMixin(SerializableMixin, models.Model):
@classmethod
def q_for_request(cls, request, prefix='', allow_none=False):
if (request is None and allow_none) or (request.user.is_authenticated and request.user.is_superuser):
if request is None and allow_none:
return Q()
return Q(**{prefix + 'access_restriction__isnull': True})
return (Q(**{prefix+'access_restriction__isnull': True}) |
Q(**{prefix+'access_restriction__in': AccessPermission.get_for_request(request)}))

View file

@ -11,14 +11,14 @@ from c3nav.mapdata.utils.svg import SVGImage
class SVGRenderer:
def __init__(self, level, miny, minx, maxy, maxx, scale=1, user=None):
def __init__(self, level, miny, minx, maxy, maxx, scale=1, access_permissions=None):
self.level = level
self.miny = miny
self.minx = minx
self.maxy = maxy
self.maxx = maxx
self.scale = scale
self.user = user
self.access_permissions = access_permissions
@cached_property
def bbox(self):
@ -50,9 +50,7 @@ class SVGRenderer:
@cached_property
def unlocked_access_restrictions(self):
# todo access_restriction
return set(access_restriction for access_restriction in self.affected_access_restrictions
if self.user is not None and self.user.is_superuser)
return self.affected_access_restrictions & self.access_permissions
@cached_property
def access_cache_key(self):

View file

@ -13,6 +13,7 @@ from shapely.geometry import box
from c3nav.mapdata.cache import MapHistory
from c3nav.mapdata.middleware import no_language
from c3nav.mapdata.models import Level, MapUpdate, Source
from c3nav.mapdata.models.access import AccessPermission
from c3nav.mapdata.render.base import get_render_level_ids
from c3nav.mapdata.render.svg import SVGRenderer
@ -43,7 +44,8 @@ def tile(request, level, zoom, x, y, format):
raise Http404
# init renderer
renderer = SVGRenderer(level, miny, minx, maxy, maxx, scale=2**zoom, user=request.user)
renderer = SVGRenderer(level, miny, minx, maxy, maxx, scale=2**zoom,
access_permissions=AccessPermission.get_for_request(request))
tile_cache_key = renderer.cache_key
update_cache_key = renderer.update_cache_key