more stuff about access and footer
This commit is contained in:
parent
4421d1a3e8
commit
e6255c8ecd
17 changed files with 97 additions and 68 deletions
31
src/c3nav/access/apply.py
Normal file
31
src/c3nav/access/apply.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
from django.conf import settings
|
||||
|
||||
from c3nav.mapdata.utils.cache import get_packages_cached
|
||||
|
||||
|
||||
def get_public_packages():
|
||||
packages_cached = get_packages_cached()
|
||||
return [packages_cached[name] for name in settings.PUBLIC_PACKAGES]
|
||||
|
||||
|
||||
def get_nonpublic_packages():
|
||||
packages_cached = get_packages_cached()
|
||||
return [package for name, package in packages_cached.items() if name not in settings.PUBLIC_PACKAGES]
|
||||
|
||||
|
||||
def get_unlocked_packages(request, packages_cached=None):
|
||||
return tuple(get_packages_cached().values()) if request.c3nav_full_access else get_public_packages()
|
||||
|
||||
|
||||
def get_unlocked_packages_names(request, packages_cached=None):
|
||||
if request.c3nav_full_access:
|
||||
return get_packages_cached().keys()
|
||||
return settings.PUBLIC_PACKAGES
|
||||
|
||||
|
||||
def can_access_package(request, package):
|
||||
return request.c3nav_full_access or package.name in get_unlocked_packages_names(request)
|
||||
|
||||
|
||||
def filter_queryset_by_package_access(request, queryset):
|
||||
return queryset if request.c3nav_full_access else queryset.filter(package__in=get_unlocked_packages(request))
|
|
@ -17,6 +17,9 @@ class AccessTokenMiddleware:
|
|||
request.c3nav_access = None
|
||||
request.c3nav_new_access = False
|
||||
|
||||
request.c3nav_full_access = False
|
||||
request.c3nav_access_list = None
|
||||
|
||||
access_cookie = request.COOKIES.get('c3nav_access')
|
||||
if access_cookie and re.match(r'^[0-9]+:[a-zA-Z0-9]+$', access_cookie):
|
||||
pk, secret = access_cookie.split(':')
|
||||
|
@ -31,6 +34,9 @@ class AccessTokenMiddleware:
|
|||
request.c3nav_access = access_instance.access_token
|
||||
request.c3nav_access.instances.filter(creation_date__lt=access_instance.creation_date).delete()
|
||||
|
||||
request.c3nav_full_access = request.c3nav_access.full_access
|
||||
request.c3nav_access_list = request.c3nav_access.permissions_list
|
||||
|
||||
response = self.get_response(request)
|
||||
|
||||
if request.c3nav_access is not None:
|
||||
|
|
|
@ -7,6 +7,7 @@ from django.db.models import Q
|
|||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.crypto import get_random_string
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
|
@ -65,6 +66,14 @@ class AccessToken(models.Model):
|
|||
verbose_name = _('Access Token')
|
||||
verbose_name_plural = _('Access Tokens')
|
||||
|
||||
@cached_property
|
||||
def permissions_list(self):
|
||||
return self.permissions.split(';')
|
||||
|
||||
@cached_property
|
||||
def full_access(self):
|
||||
return ':full' in self.permissions_list
|
||||
|
||||
@property
|
||||
def activation_url(self):
|
||||
if self.activated:
|
||||
|
|
|
@ -4,9 +4,9 @@ from django.contrib.auth.decorators import login_required
|
|||
from django.db import transaction
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
|
||||
from c3nav.access.apply import get_nonpublic_packages
|
||||
from c3nav.access.models import AccessToken, AccessUser
|
||||
from c3nav.editor.hosters import get_hoster_for_package
|
||||
from c3nav.mapdata.permissions import get_nonpublic_packages
|
||||
|
||||
|
||||
@login_required(login_url='/access/login/')
|
||||
|
@ -54,7 +54,7 @@ def prove(request):
|
|||
else:
|
||||
user = AccessUser.objects.create(user_url=user_id)
|
||||
|
||||
token = user.new_token(permissions=':all', description='automatically created')
|
||||
token = user.new_token(permissions=':full', description='automatically created')
|
||||
return render(request, 'access/prove.html', context={
|
||||
'hosters': hosters,
|
||||
'success': True,
|
||||
|
|
|
@ -9,8 +9,8 @@ from django.forms.widgets import HiddenInput
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
from shapely.geometry.geo import mapping
|
||||
|
||||
from c3nav.access.apply import get_unlocked_packages
|
||||
from c3nav.mapdata.models import Package
|
||||
from c3nav.mapdata.permissions import get_unlocked_packages
|
||||
|
||||
|
||||
class MapitemFormMixin(ModelForm):
|
||||
|
|
|
@ -6,12 +6,12 @@ from django.http.response import Http404
|
|||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.utils import translation
|
||||
|
||||
from c3nav.access.apply import can_access_package, filter_queryset_by_package_access
|
||||
from c3nav.editor.hosters import get_hoster_for_package, hosters
|
||||
from c3nav.mapdata.models import AreaLocation
|
||||
from c3nav.mapdata.models.base import MAPITEM_TYPES
|
||||
from c3nav.mapdata.models.package import Package
|
||||
from c3nav.mapdata.packageio.write import json_encode
|
||||
from c3nav.mapdata.permissions import can_access_package, filter_queryset_by_package_access
|
||||
|
||||
|
||||
def list_mapitemtypes(request, level):
|
||||
|
|
|
@ -9,10 +9,10 @@ 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_package_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.models.locations import get_location
|
||||
from c3nav.mapdata.permissions import filter_queryset_by_package_access, get_unlocked_packages_names
|
||||
from c3nav.mapdata.serializers.main import LevelSerializer, PackageSerializer, SourceSerializer
|
||||
from c3nav.mapdata.utils.cache import (CachedReadOnlyViewSetMixin, cache_mapdata_api_response, get_levels_cached,
|
||||
get_packages_cached)
|
||||
|
|
|
@ -3,8 +3,8 @@ from collections import OrderedDict
|
|||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from c3nav.access.apply import can_access_package
|
||||
from c3nav.mapdata.models import AreaLocation, LocationGroup
|
||||
from c3nav.mapdata.permissions import can_access_package
|
||||
|
||||
|
||||
def get_default_include_avoid():
|
||||
|
|
|
@ -86,7 +86,7 @@ class LevelGeometries():
|
|||
self.level = level
|
||||
self.only_public = only_public
|
||||
|
||||
from c3nav.mapdata.permissions import get_public_packages
|
||||
from c3nav.access.apply import get_public_packages
|
||||
self.public_packages = get_public_packages()
|
||||
|
||||
def query(self, name):
|
||||
|
|
|
@ -8,12 +8,12 @@ from django.db.models import Q
|
|||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from c3nav.access.apply import filter_queryset_by_package_access
|
||||
from c3nav.mapdata.fields import JSONField
|
||||
from c3nav.mapdata.lastupdate import get_last_mapdata_update
|
||||
from c3nav.mapdata.models import Level
|
||||
from c3nav.mapdata.models.base import MapItem
|
||||
from c3nav.mapdata.models.geometry import GeometryMapItemWithLevel
|
||||
from c3nav.mapdata.permissions import filter_queryset_by_package_access
|
||||
from c3nav.mapdata.utils.cache import get_levels_cached
|
||||
|
||||
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from rest_framework.exceptions import PermissionDenied
|
||||
from rest_framework.permissions import BasePermission
|
||||
from shapely.geometry import box
|
||||
|
||||
from c3nav.mapdata.models import Source
|
||||
from c3nav.mapdata.utils.cache import get_packages_cached
|
||||
from c3nav.mapdata.utils.misc import get_dimensions
|
||||
|
||||
|
||||
def get_public_packages():
|
||||
packages_cached = get_packages_cached()
|
||||
return [packages_cached[name] for name in settings.PUBLIC_PACKAGES]
|
||||
|
||||
|
||||
def get_nonpublic_packages():
|
||||
packages_cached = get_packages_cached()
|
||||
return [package for name, package in packages_cached.items() if name not in settings.PUBLIC_PACKAGES]
|
||||
|
||||
|
||||
def get_unlocked_packages_names(request, packages_cached=None):
|
||||
if packages_cached is None:
|
||||
packages_cached = get_packages_cached()
|
||||
if settings.DIRECT_EDITING:
|
||||
return packages_cached.keys()
|
||||
return set(settings.PUBLIC_PACKAGES) | set(request.session.get('unlocked_packages', ()))
|
||||
|
||||
|
||||
def get_unlocked_packages(request, packages_cached=None):
|
||||
if packages_cached is None:
|
||||
packages_cached = get_packages_cached()
|
||||
names = get_unlocked_packages_names(request, packages_cached=packages_cached)
|
||||
return tuple(packages_cached[name] for name in names if name in packages_cached)
|
||||
|
||||
|
||||
def can_access_package(request, package):
|
||||
return settings.DEBUG or package.name in get_unlocked_packages_names(request)
|
||||
|
||||
|
||||
def filter_queryset_by_package_access(request, queryset):
|
||||
return queryset if settings.DIRECT_EDITING else queryset.filter(package__in=get_unlocked_packages(request))
|
||||
|
||||
|
||||
def get_public_private_area(level):
|
||||
width, height = get_dimensions()
|
||||
everything = box(0, 0, width, height)
|
||||
public_area = level.public_geometries.areas_and_doors
|
||||
private_area = everything.difference(public_area)
|
||||
return public_area, private_area
|
||||
|
||||
|
||||
class LockedMapFeatures(BasePermission):
|
||||
def has_object_permission(self, request, view, obj):
|
||||
if isinstance(obj, Source):
|
||||
if not can_access_package(request, obj.package):
|
||||
raise PermissionDenied(_('This Source belongs to a package you don\'t have access to.'))
|
||||
return True
|
|
@ -62,7 +62,7 @@ class CachedReadOnlyViewSetMixin():
|
|||
include_package_access = False
|
||||
|
||||
def _get_unlocked_packages_ids(self, request):
|
||||
from c3nav.mapdata.permissions import get_unlocked_packages
|
||||
from c3nav.access.apply import get_unlocked_packages
|
||||
return ','.join(str(i) for i in sorted(package.id for package in get_unlocked_packages(request)))
|
||||
|
||||
def _get_add_cache_key(self, request, add_cache_key=''):
|
||||
|
|
|
@ -2,6 +2,7 @@ import os
|
|||
|
||||
from django.conf import settings
|
||||
from django.db.models import Max, Min
|
||||
from shapely.geometry import box
|
||||
|
||||
from c3nav.mapdata.models import Package
|
||||
from c3nav.mapdata.utils.cache import cache_result
|
||||
|
@ -25,3 +26,11 @@ def get_render_dimensions():
|
|||
def get_render_path(filetype, level, mode, public):
|
||||
return os.path.join(settings.RENDER_ROOT,
|
||||
'%s%s-level-%s.%s' % (('public-' if public else ''), mode, level, filetype))
|
||||
|
||||
|
||||
def get_public_private_area(level):
|
||||
width, height = get_dimensions()
|
||||
everything = box(0, 0, width, height)
|
||||
public_area = level.public_geometries.areas_and_doors
|
||||
private_area = everything.difference(public_area)
|
||||
return public_area, private_area
|
||||
|
|
|
@ -10,8 +10,9 @@ from scipy.sparse.csgraph._shortest_path import shortest_path
|
|||
from scipy.sparse.csgraph._tools import csgraph_from_dense
|
||||
from shapely.geometry import CAP_STYLE, JOIN_STYLE, LineString
|
||||
|
||||
from c3nav.mapdata.permissions import get_public_packages, get_public_private_area
|
||||
from c3nav.access.apply import get_public_packages
|
||||
from c3nav.mapdata.utils.geometry import assert_multilinestring, assert_multipolygon
|
||||
from c3nav.mapdata.utils.misc import get_public_private_area
|
||||
from c3nav.routing.point import GraphPoint
|
||||
from c3nav.routing.room import GraphRoom
|
||||
from c3nav.routing.utils.base import get_nearest_point
|
||||
|
|
|
@ -264,3 +264,8 @@ circle.pos {
|
|||
background-repeat:no-repeat;
|
||||
background-position:center;
|
||||
}
|
||||
|
||||
|
||||
footer {
|
||||
text-align:center;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
{% load static %}
|
||||
{% load compress %}
|
||||
{% load i18n %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
@ -19,6 +21,27 @@
|
|||
<h1>c3nav</h1>
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
<footer>
|
||||
<a href="https://github.com/c3nav/c3nav">GitHub</a>
|
||||
- <a href="https://twitter.com/c3nav">Twitter</a>
|
||||
– <a href="{% url 'editor.index' %}">{% trans 'Editor' %}</a>
|
||||
– <a href="/api/">{% trans 'API' %}</a>
|
||||
{% if full_access or access_list %}
|
||||
<br><small>
|
||||
{% if full_access %}
|
||||
{% trans 'full access unlocked' %}
|
||||
{% else %}
|
||||
{{ access_list }}
|
||||
{% blocktrans count count=access_list|length %}
|
||||
one area unlocked
|
||||
{% plural %}
|
||||
{{ count }} areas unlocked
|
||||
{% endblocktrans %}
|
||||
{% endif %}
|
||||
</small>
|
||||
{% endif %}
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
{% compress js %}
|
||||
|
|
|
@ -65,6 +65,9 @@ def main(request, location=None, origin=None, destination=None):
|
|||
'destination': destination,
|
||||
'mode': mode,
|
||||
'active_field': active_field,
|
||||
|
||||
'full_access': request.c3nav_full_access,
|
||||
'access_list': request.c3nav_access_list,
|
||||
}
|
||||
|
||||
width, height = get_dimensions()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue