create and show access qr code

This commit is contained in:
Laura Klünder 2017-12-10 03:49:21 +01:00
parent cca01e584a
commit 2a175aa43d
6 changed files with 98 additions and 4 deletions

View file

@ -0,0 +1,9 @@
{% extends 'control/base.html' %}
{% load i18n %}
{% block heading %}{% trans 'Access Permissions' %}{% endblock %}
{% block subcontent %}
{% trans 'Generate QR Code' as button_label %}
{% include 'control/fragment_access_permissions_form.html' with button_label=button_label %}
{% endblock %}

View file

@ -0,0 +1,25 @@
{% extends 'control/base.html' %}
{% load i18n %}
{% block heading %}{% trans 'Access Permission QR Code' %}{% endblock %}
{% block addattributes %} style="text-align: center;"{% endblock %}
{% block menu %}{% endblock %}
{% block subcontent %}
<p>
{% trans 'Scan this QR code to get access permissions:' %}
</p>
<p>
<img src="/qr/access/{{ token }}">
</p>
<p>
{{ absolute_url }}
</p>
<p>
<a href="{% url 'control.access' %}">« {% trans 'back' %}</a>
</p>
<script type="text/javascript">
window.setTimeout(function() { window.location.reload(); }, 3000);
</script>
{% endblock %}

View file

@ -6,15 +6,18 @@
{% block header_title_url %}{% url 'control.index' %}{% endblock %}
{% block content %}
<main class="control">
<main class="control"{% block addattributes %}{% endblock %}>
{% include 'site/fragment_messages.html' %}
<h2>{% block heading %}{% endblock %}</h2>
{% block menu %}
<nav>
<p>
<a href="{% url 'control.index' %}">{% trans 'Overview' %}</a> &middot;
<a href="{% url 'control.users' %}">{% trans 'Users' %}</a>
<a href="{% url 'control.users' %}">{% trans 'Users' %}</a> &middot;
<a href="{% url 'control.access' %}">{% trans 'Access' %}</a>
</p>
</nav>
{% endblock %}
{% block subcontent %}
{% endblock %}
</main>

View file

@ -1,9 +1,11 @@
from django.conf.urls import url
from c3nav.control.views import main_index, user_detail, user_list
from c3nav.control.views import grant_access, grant_access_qr, main_index, user_detail, user_list
urlpatterns = [
url(r'^users/$', user_list, name='control.users'),
url(r'^users/(?P<user>\d+)/$', user_detail, name='control.users.detail'),
url(r'^access/$', grant_access, name='control.access'),
url(r'^access/qr/(?P<token>[^/]+)', grant_access_qr, name='control.access.qr'),
url(r'^$', main_index, name='control.index'),
]

View file

@ -5,13 +5,15 @@ from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied
from django.core.paginator import Paginator
from django.db import transaction
from django.db.models import Prefetch
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from c3nav.control.forms import AccessPermissionForm, UserPermissionsForm
from c3nav.control.models import UserPermissions
from c3nav.mapdata.models.access import AccessPermission
from c3nav.mapdata.models.access import AccessPermission, AccessPermissionToken
def control_panel_view(func):
@ -112,3 +114,53 @@ def user_detail(request, user):
})
return render(request, 'control/user.html', ctx)
@login_required
@control_panel_view
def grant_access(request):
if request.method == 'POST' and request.POST.get('submit_access_permissions'):
form = AccessPermissionForm(request=request, data=request.POST)
if form.is_valid():
token = form.get_token()
token.save()
return redirect(reverse('control.access.qr', kwargs={'token': token.id}))
else:
form = AccessPermissionForm(request=request)
ctx = {
'access_permission_form': form
}
return render(request, 'control/access.html', ctx)
@login_required
@control_panel_view
def grant_access_qr(request, token):
with transaction.atomic():
token = AccessPermissionToken.objects.select_for_update().get(id=token, author=request.user)
if token.redeemed:
messages.success(_('Access successfully granted!'))
token = None
elif not token.unlimited:
try:
latest = AccessPermissionToken.objects.filter(author=request.user).latest('valid_until')
except AccessPermissionToken.DoesNotExist:
token = None
else:
if latest.id != token.id:
token = None
if token is None:
messages.error(_('You can only display your most recently created token.'))
if token is None:
redirect('control.access')
token.bump()
token.save()
return render(request, 'control/access_qr.html', {
'token': token.id,
'absolute_url': request.build_absolute_uri('/access/qr/%s' % token.id)
})

View file

@ -78,6 +78,9 @@ class AccessPermissionToken(models.Model):
if self.pk:
self.save()
def bump(self):
self.valid_until = default_valid_until()
class AccessPermission(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)