diff --git a/src/c3nav/control/admin.py b/src/c3nav/control/admin.py index 90cc0984..d3471447 100644 --- a/src/c3nav/control/admin.py +++ b/src/c3nav/control/admin.py @@ -1,6 +1,7 @@ from django.contrib import admin from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.models import User +from django.urls import reverse from django.utils.translation import ugettext_lazy as _ from c3nav.control.models import UserPermissions diff --git a/src/c3nav/control/forms.py b/src/c3nav/control/forms.py index f0005283..2c9f1f72 100644 --- a/src/c3nav/control/forms.py +++ b/src/c3nav/control/forms.py @@ -1,3 +1,8 @@ +import binascii +import hashlib +import hmac +import json +import time from datetime import timedelta from itertools import chain @@ -118,6 +123,23 @@ class AccessPermissionForm(Form): can_grant=self.cleaned_data.get('can_grant', '0') == '1', restrictions=tuple(restrictions)) + def get_signed_data(self, key=None): + if not self.author.permissions.api_secret: + raise ValueError('Author has no api secret.') + data = { + 'id': self.data['access_restrictions'], + 'time': int(time.time()), + 'valid_until': int(self.cleaned_data['expires'].strftime('%s')), + 'author': self.author.pk, + } + if key is not None: + data['key'] = key + data = json.dumps(data, separators=(',', ':')) + signature = hmac.new(self.author.permissions.api_secret.encode(), + msg=data.encode(), + digestmod=hashlib.sha256).digest() + return '%s:%s' % (data, binascii.b2a_base64(signature).strip().decode()) + class AnnouncementForm(I18nModelFormMixin, ModelForm): class Meta: diff --git a/src/c3nav/control/views.py b/src/c3nav/control/views.py index 5406673c..d36857bd 100644 --- a/src/c3nav/control/views.py +++ b/src/c3nav/control/views.py @@ -1,6 +1,7 @@ import string from functools import wraps +from django.conf import settings from django.contrib import messages from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User @@ -162,6 +163,8 @@ def grant_access(request): if form.is_valid(): token = form.get_token() token.save() + if settings.DEBUG and request.user_permissions.api_secret: + print(form.get_signed_data()) return redirect(reverse('control.access.qr', kwargs={'token': token.token})) else: form = AccessPermissionForm(request=request)