create and show access qr code
This commit is contained in:
parent
cca01e584a
commit
2a175aa43d
6 changed files with 98 additions and 4 deletions
9
src/c3nav/control/templates/control/access.html
Normal file
9
src/c3nav/control/templates/control/access.html
Normal 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 %}
|
25
src/c3nav/control/templates/control/access_qr.html
Normal file
25
src/c3nav/control/templates/control/access_qr.html
Normal 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 %}
|
|
@ -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> ·
|
||||
<a href="{% url 'control.users' %}">{% trans 'Users' %}</a>
|
||||
<a href="{% url 'control.users' %}">{% trans 'Users' %}</a> ·
|
||||
<a href="{% url 'control.access' %}">{% trans 'Access' %}</a>
|
||||
</p>
|
||||
</nav>
|
||||
{% endblock %}
|
||||
{% block subcontent %}
|
||||
{% endblock %}
|
||||
</main>
|
||||
|
|
|
@ -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'),
|
||||
]
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue