access restrictions can be set to public to make them available to everyone (even not logged in users)

public access restrictions do not count to the unlocked areas count
This commit is contained in:
Gwendolyn 2023-12-20 23:56:32 +01:00
parent 8a3d3bc18f
commit 1d4703f86f
4 changed files with 53 additions and 18 deletions

View file

@ -308,7 +308,7 @@ def create_editor_form(editor_model):
'level_change_description', 'base_mapdata_accessible', 'can_report_missing',
'label_settings', 'label_override', 'min_zoom', 'max_zoom', 'font_size',
'allow_levels', 'allow_spaces', 'allow_areas', 'allow_pois', 'allow_dynamic_locations',
'left', 'top', 'right', 'bottom']
'left', 'top', 'right', 'bottom', 'public']
field_names = [field.name for field in editor_model._meta.get_fields() if not field.one_to_many]
existing_fields = [name for name in possible_fields if name in field_names]

View file

@ -0,0 +1,24 @@
# Generated by Django 4.2.7 on 2023-12-20 22:25
import c3nav.mapdata.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0092_accesspermission_by_group'),
]
operations = [
migrations.RenameField(
model_name='accessrestriction',
old_name='open',
new_name='public',
),
migrations.AlterField(
model_name='accessrestriction',
name='public',
field=models.BooleanField(default=False, verbose_name='public'),
),
]

View file

@ -20,7 +20,7 @@ class AccessRestriction(TitledMixin, models.Model):
"""
An access restriction
"""
open = models.BooleanField(default=False, verbose_name=_('open'))
public = models.BooleanField(default=False, verbose_name=_('public'))
groups = models.ManyToManyField('mapdata.AccessRestrictionGroup', verbose_name=_('Groups'), blank=True)
class Meta:
@ -41,6 +41,26 @@ class AccessRestriction(TitledMixin, models.Model):
def q_for_request(cls, request):
return Q(pk__in=AccessPermission.get_for_request(request))
@staticmethod
def get_all() -> set[int]:
cache_key = 'all_access_restrictions:%s' % MapUpdate.current_cache_key()
access_restriction_ids = cache.get(cache_key, None)
if access_restriction_ids is None:
access_restriction_ids = set(AccessRestriction.objects.values_list('pk', flat=True))
cache.set(cache_key, access_restriction_ids, 300)
return access_restriction_ids
@staticmethod
def get_all_public() -> set[int]:
cache_key = 'public_access_restrictions:%s' % MapUpdate.current_cache_key()
access_restriction_ids = cache.get(cache_key, None)
if access_restriction_ids is None:
access_restriction_ids = set(AccessRestriction.objects.filter(public=True)
.values_list('pk', flat=True))
cache.set(cache_key, access_restriction_ids, 300)
return access_restriction_ids
class AccessRestrictionGroup(TitledMixin, models.Model):
"""
@ -59,7 +79,7 @@ class AccessRestrictionGroup(TitledMixin, models.Model):
def q_for_request(cls, request):
if request.user.is_authenticated and request.user.is_superuser:
return Q()
all_permissions = AccessPermission.get_all_access_restrictions()
all_permissions = AccessRestriction.get_all()
permissions = AccessPermission.get_for_request(request)
# now we filter out groups where the user doesn't have a permission for all members
filter_perms = all_permissions - permissions
@ -184,7 +204,7 @@ class AccessPermission(models.Model):
return {}
if request.user_permissions.grant_all_access:
return {pk: None for pk in cls.get_all_access_restrictions()}
return {pk: None for pk in AccessRestriction.get_all()}
result = tuple(
cls.queryset_for_user(request.user, can_grant).select_related(
@ -208,22 +228,13 @@ class AccessPermission(models.Model):
}
return permissions
@staticmethod
def get_all_access_restrictions() -> set[int]:
cache_key = 'all_access_restrictions:%s' % MapUpdate.current_cache_key()
access_restriction_ids = cache.get(cache_key, None)
if access_restriction_ids is None:
access_restriction_ids = set(AccessRestriction.objects.values_list('pk', flat=True))
cache.set(cache_key, access_restriction_ids, 300)
return access_restriction_ids
@classmethod
def get_for_request(cls, request) -> set[int]:
if not request or not request.user.is_authenticated:
return set()
return AccessRestriction.get_all_public()
if request.user_permissions.grant_all_access:
return cls.get_all_access_restrictions()
return AccessRestriction.get_all()
cache_key = cls.user_access_permission_key(request.user.pk)
access_restriction_ids = cache.get(cache_key, None)
@ -234,7 +245,7 @@ class AccessPermission(models.Model):
expire_date = min((e for e in permissions.values() if e), default=timezone.now()+timedelta(seconds=120))
cache.set(cache_key, access_restriction_ids, max(0.0, (expire_date-timezone.now()).total_seconds()))
return set(access_restriction_ids)
return set(access_restriction_ids) | AccessRestriction.get_all_public()
@classmethod
def cache_key_for_request(cls, request, with_update=True):

View file

@ -3,12 +3,12 @@ from django.utils.functional import lazy
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy
from c3nav.mapdata.models.access import AccessPermission
from c3nav.mapdata.models.access import AccessPermission, AccessRestriction
from c3nav.mapdata.models.locations import Position
def get_user_data(request):
permissions = AccessPermission.get_for_request(request)
permissions = AccessPermission.get_for_request(request) - AccessRestriction.get_all_public()
result = {
'logged_in': bool(request.user.is_authenticated),
'allow_editor': can_access_editor(request),