2017-12-08 21:31:53 +01:00
|
|
|
from datetime import timedelta
|
|
|
|
from itertools import chain
|
|
|
|
|
|
|
|
from django.db.models import Q
|
2017-12-08 21:54:04 +01:00
|
|
|
from django.forms import ChoiceField, Form, ModelForm
|
2017-12-08 21:31:53 +01:00
|
|
|
from django.utils import timezone
|
|
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from django.utils.translation import ungettext_lazy
|
2017-12-08 18:41:48 +01:00
|
|
|
|
|
|
|
from c3nav.control.models import UserPermissions
|
2017-12-10 15:23:53 +01:00
|
|
|
from c3nav.mapdata.forms import I18nModelFormMixin
|
2017-12-10 14:13:20 +01:00
|
|
|
from c3nav.mapdata.models.access import AccessPermissionToken, AccessPermissionTokenItem, AccessRestriction
|
2017-12-10 15:23:53 +01:00
|
|
|
from c3nav.site.models import Announcement
|
2017-12-08 18:41:48 +01:00
|
|
|
|
|
|
|
|
|
|
|
class UserPermissionsForm(ModelForm):
|
|
|
|
class Meta:
|
|
|
|
model = UserPermissions
|
|
|
|
exclude = ('user', )
|
2017-12-08 21:31:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
class AccessPermissionForm(Form):
|
|
|
|
def __init__(self, request, *args, **kwargs):
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
2017-12-14 23:35:18 +01:00
|
|
|
# remember author if this form is saved
|
2017-12-08 21:31:53 +01:00
|
|
|
self.author = request.user
|
|
|
|
|
2017-12-14 23:35:18 +01:00
|
|
|
# determine which access permissions the author can grant
|
2017-12-08 21:31:53 +01:00
|
|
|
if not request.user_permissions.access_all:
|
|
|
|
self.author_access_permissions = {
|
|
|
|
pk: expire_date for pk, expire_date in self.author.accesspermissions.filter(
|
|
|
|
Q(can_grant=True) & (Q(expire_date__isnull=True) | Q(expire_date__lt=timezone.now()))
|
|
|
|
).values_list('access_restriction_id', 'expire_date')
|
|
|
|
}
|
|
|
|
access_restrictions = AccessRestriction.objects.filter(
|
|
|
|
pk__in=self.author_access_permissions.keys()
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
self.author_access_permissions = {}
|
|
|
|
access_restrictions = AccessRestriction.objects.all()
|
|
|
|
|
|
|
|
self.access_restrictions = {
|
|
|
|
access_restriction.pk: access_restriction
|
|
|
|
for access_restriction in access_restrictions
|
|
|
|
}
|
|
|
|
|
|
|
|
self.access_restriction_choices = {
|
|
|
|
'all': self.access_restrictions.values(),
|
|
|
|
**{str(pk): (access_restriction, ) for pk, access_restriction in self.access_restrictions.items()}
|
|
|
|
}
|
|
|
|
|
2017-12-14 23:35:18 +01:00
|
|
|
# construct choice field for access permissions
|
2017-12-08 21:31:53 +01:00
|
|
|
choices = [('', _('choose permissions…')),
|
|
|
|
('all', ungettext_lazy('everything possible (%d permission)',
|
|
|
|
'everything possible (%d permissions)',
|
|
|
|
len(access_restrictions)) % len(access_restrictions))]
|
|
|
|
|
|
|
|
choices.append((_('Access Permissions'), tuple(
|
|
|
|
(str(pk), access_restriction.title)
|
|
|
|
for pk, access_restriction in self.access_restrictions.items()
|
|
|
|
)))
|
|
|
|
|
2017-12-08 21:54:04 +01:00
|
|
|
self.fields['access_restrictions'] = ChoiceField(choices=choices, required=True)
|
2017-12-08 21:31:53 +01:00
|
|
|
|
2017-12-14 23:35:18 +01:00
|
|
|
# construct choices for the expire field
|
2017-12-08 21:31:53 +01:00
|
|
|
expire_choices = [
|
|
|
|
('', _('never')),
|
|
|
|
]
|
|
|
|
for minutes in range(15, 60, 15):
|
|
|
|
expire_choices.append(
|
|
|
|
(str(minutes), ungettext_lazy('in %d minute', 'in %d minutes', minutes) % minutes))
|
|
|
|
|
|
|
|
for hours in chain(range(1, 6), range(6, 24, 6)):
|
|
|
|
expire_choices.append(
|
|
|
|
(str(hours*60), ungettext_lazy('in %d hour', 'in %d hours', hours) % hours)
|
|
|
|
)
|
|
|
|
expire_choices.insert(
|
|
|
|
5, (str(90), _('in 1½ hour'))
|
|
|
|
)
|
|
|
|
for days in range(1, 14):
|
|
|
|
expire_choices.append(
|
|
|
|
(str(days*24*60), ungettext_lazy('in %d day', 'in %d days', days) % days)
|
|
|
|
)
|
|
|
|
|
2017-12-08 21:54:04 +01:00
|
|
|
self.fields['expires'] = ChoiceField(required=False, initial='60', choices=expire_choices)
|
2017-12-08 21:31:53 +01:00
|
|
|
|
2017-12-14 23:35:18 +01:00
|
|
|
# if applicable, add field to grant pass on permissions
|
2017-12-08 21:31:53 +01:00
|
|
|
if request.user_permissions.access_all:
|
2017-12-08 21:54:04 +01:00
|
|
|
choices = [('0', '---')]*6 + [('1', _('can pass on'))] + [('0', '---')]*3
|
|
|
|
self.fields['can_grant'] = ChoiceField(required=False, initial='60', choices=choices)
|
2017-12-08 21:31:53 +01:00
|
|
|
|
|
|
|
def clean_access_restrictions(self):
|
|
|
|
data = self.cleaned_data['access_restrictions']
|
|
|
|
return self.access_restriction_choices[data]
|
|
|
|
|
|
|
|
def clean_expires(self):
|
|
|
|
data = self.cleaned_data['expires']
|
|
|
|
if data == '':
|
|
|
|
return None
|
|
|
|
return timezone.now()+timedelta(minutes=int(data))
|
|
|
|
|
|
|
|
def save(self, user):
|
|
|
|
self._save_code(self._create_code(), user)
|
|
|
|
|
2017-12-10 03:16:07 +01:00
|
|
|
def get_token(self):
|
2017-12-14 23:35:18 +01:00
|
|
|
# create an AccessPermissionToken from this form and return it
|
2017-12-08 21:31:53 +01:00
|
|
|
restrictions = []
|
|
|
|
for restriction in self.cleaned_data['access_restrictions']:
|
2017-12-10 14:13:20 +01:00
|
|
|
expire_date = self.cleaned_data['expires']
|
|
|
|
author_expire_date = self.author_access_permissions.get(restriction.pk)
|
2017-12-14 23:57:59 +01:00
|
|
|
# make sure that each permission is not granted for a longer time than the author has it
|
2017-12-10 14:13:20 +01:00
|
|
|
if author_expire_date is not None:
|
|
|
|
expire_date = author_expire_date if expire_date is None else min(expire_date, author_expire_date)
|
|
|
|
restrictions.append(AccessPermissionTokenItem(pk=restriction.pk, expire_date=expire_date,
|
|
|
|
title=restriction.title))
|
2017-12-10 03:16:07 +01:00
|
|
|
return AccessPermissionToken(author=self.author,
|
|
|
|
can_grant=self.cleaned_data.get('can_grant', '0') == '1',
|
|
|
|
restrictions=tuple(restrictions))
|
2017-12-10 15:23:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
class AnnouncementForm(I18nModelFormMixin, ModelForm):
|
|
|
|
class Meta:
|
|
|
|
model = Announcement
|
|
|
|
fields = ('text', 'active', 'active_until')
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.fields['active_until'].initial = timezone.now()
|