diff --git a/src/c3nav/mapdata/render/base.py b/src/c3nav/mapdata/render/base.py index ae2b1946..48c3c26f 100644 --- a/src/c3nav/mapdata/render/base.py +++ b/src/c3nav/mapdata/render/base.py @@ -29,7 +29,7 @@ def set_tile_access_cookie(request, response): access_permissions = AccessPermission.get_for_request(request) if access_permissions: - value = ','.join(str(i) for i in access_permissions)+':'+str(int(time.time())+60) + value = '-'.join(str(i) for i in access_permissions)+':'+str(int(time.time())+60) key = hashlib.sha1(settings.SECRET_TILE_KEY.encode()).digest() signed = base64.b64encode(hmac.new(key, msg=value.encode(), digestmod=hashlib.sha256).digest()).decode() response.set_cookie(settings.TILE_ACCESS_COOKIE_NAME, value+':'+signed, max_age=60) @@ -37,6 +37,30 @@ def set_tile_access_cookie(request, response): response.delete_cookie(settings.TILE_ACCESS_COOKIE_NAME) +def get_tile_access_cookie(request): + try: + cookie = request.COOKIES[settings.TILE_ACCESS_COOKIE_NAME] + except KeyError: + return set() + + try: + access_permissions, expire, signed = cookie.split(':') + except ValueError: + return set() + + value = access_permissions+':'+expire + + key = hashlib.sha1(settings.SECRET_TILE_KEY.encode()).digest() + signed_verify = base64.b64encode(hmac.new(key, msg=value.encode(), digestmod=hashlib.sha256).digest()).decode() + if signed != signed_verify: + return set() + + if int(expire) < time.time(): + return set() + + return set(int(i) for i in access_permissions.split('-')) + + class AltitudeAreaGeometries: def __init__(self, altitudearea=None, colors=None): if altitudearea is not None: diff --git a/src/c3nav/mapdata/views.py b/src/c3nav/mapdata/views.py index 6eacc09b..7413ff30 100644 --- a/src/c3nav/mapdata/views.py +++ b/src/c3nav/mapdata/views.py @@ -13,8 +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.base import get_render_level_ids, get_tile_access_cookie from c3nav.mapdata.render.svg import SVGRenderer @@ -43,9 +42,11 @@ def tile(request, level, zoom, x, y, format): if level not in get_render_level_ids(cache_key): raise Http404 + # decode access permissions + access_permissions = get_tile_access_cookie(request) + # init renderer - renderer = SVGRenderer(level, miny, minx, maxy, maxx, scale=2**zoom, - access_permissions=AccessPermission.get_for_request(request)) + renderer = SVGRenderer(level, miny, minx, maxy, maxx, scale=2**zoom, access_permissions=access_permissions) tile_cache_key = renderer.cache_key update_cache_key = renderer.update_cache_key @@ -109,6 +110,7 @@ def tile(request, level, zoom, x, y, format): response = HttpResponse(data, content_type) response['ETag'] = etag response['Cache-Control'] = 'no-cache' + response['Vary'] = 'Cookie' response['X-Access-Restrictions'] = ', '.join(str(s) for s in renderer.unlocked_access_restrictions) or '0' return response