show qr code with token
This commit is contained in:
parent
281f01b8a0
commit
fa68e3999d
8 changed files with 50 additions and 9 deletions
|
@ -90,6 +90,12 @@ class AccessToken(models.Model):
|
|||
return None
|
||||
return reverse('access.activate', kwargs={'pk': self.pk, 'secret': self.secret})
|
||||
|
||||
@property
|
||||
def qr_url(self):
|
||||
if self.activated:
|
||||
return None
|
||||
return reverse('access.qr', kwargs={'pk': self.pk, 'secret': self.secret})
|
||||
|
||||
@staticmethod
|
||||
def create_secret():
|
||||
return get_random_string(42, string.ascii_letters + string.digits)
|
||||
|
|
|
@ -38,3 +38,7 @@ footer {
|
|||
min-height: 29px;
|
||||
line-height:29px;
|
||||
}
|
||||
|
||||
.token img {
|
||||
width:100%;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
{% load i18n %}
|
||||
|
||||
<p>
|
||||
<a href="{{ token.activation_url }}" class="btn btn-default btn-block">{% trans 'Activate token on this device' %}</a>
|
||||
</p>
|
||||
<div class="token">
|
||||
<p>
|
||||
<img src="{{ token.qr_url }}">
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{ token.activation_url }}" class="btn btn-default btn-block">{% trans 'Activate token on this device' %}</a>
|
||||
</p>
|
||||
<p>
|
||||
{% blocktrans %}
|
||||
This link QR Code / Link only works once. If you want access on multiple devices, you need multiple tokens.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
<td>
|
||||
{% if not token.is_expired %}
|
||||
<button class="btn btn-xs btn-danger" type="submit" name="expire" value="{{ token.id }}">{% trans 'Expire' %}</button>
|
||||
{% if not token.activated or 1 %}
|
||||
{% if not token.activated %}
|
||||
<a href="{% url 'access.user.token' user=user.id token=token.id %}" class="btn btn-xs btn-success" type="submit" name="activate" value="{{ token.id }}">{% trans 'Activate' %}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
from django.conf.urls import url
|
||||
from django.contrib.auth import views as auth_views
|
||||
|
||||
from c3nav.access.views import activate_token, dashboard, prove, show_user_token, user_detail, user_list
|
||||
from c3nav.access.views import activate_token, dashboard, prove, show_user_token, token_qr, user_detail, user_list
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', dashboard, name='access.dashboard'),
|
||||
url(r'^prove/$', prove, name='access.prove'),
|
||||
url(r'^activate/(?P<pk>[0-9]+):(?P<secret>[a-zA-Z0-9]+)/$', activate_token, name='access.activate'),
|
||||
url(r'^qr/(?P<pk>[0-9]+):(?P<secret>[a-zA-Z0-9]+).png$', token_qr, name='access.qr'),
|
||||
url(r'^users/$', user_list, name='access.users'),
|
||||
url(r'^users/(?P<page>[0-9]+)/$', user_list, name='access.users'),
|
||||
url(r'^user/(?P<pk>[0-9]+)/$', user_detail, name='access.user'),
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
from collections import OrderedDict
|
||||
|
||||
import qrcode
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
|
||||
from django.db import transaction
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse
|
||||
|
||||
from c3nav.access.apply import get_nonpublic_packages
|
||||
from c3nav.access.forms import AccessTokenForm
|
||||
|
@ -79,6 +82,23 @@ def activate_token(request, pk, secret):
|
|||
})
|
||||
|
||||
|
||||
def token_qr(request, pk, secret):
|
||||
get_object_or_404(AccessToken, expired=False, activated=False, id=pk, secret=secret)
|
||||
|
||||
qr = qrcode.QRCode(
|
||||
version=1,
|
||||
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
||||
box_size=10,
|
||||
border=4,
|
||||
)
|
||||
qr.add_data(request.build_absolute_uri(reverse('access.activate', kwargs={'pk': pk, 'secret': secret})))
|
||||
qr.make(fit=True)
|
||||
|
||||
response = HttpResponse(content_type='image/png')
|
||||
qr.make_image().save(response, 'PNG')
|
||||
return response
|
||||
|
||||
|
||||
@login_required(login_url='/access/login/')
|
||||
def user_list(request, page=1):
|
||||
queryset = AccessUser.objects.all()
|
||||
|
@ -138,9 +158,9 @@ def user_detail(request, pk):
|
|||
@login_required(login_url='/access/login/')
|
||||
def show_user_token(request, user, token):
|
||||
user = get_object_or_404(AccessUser, id=user)
|
||||
token = get_object_or_404(AccessToken, user=user, id=token, activated=False)
|
||||
token = get_object_or_404(AccessToken, user=user, id=token)
|
||||
|
||||
return render(request, 'access/user_token.html', {
|
||||
'user': user,
|
||||
'tokens': token,
|
||||
'token': token,
|
||||
})
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import mimetypes
|
||||
from calendar import timegm
|
||||
from datetime import timedelta
|
||||
|
||||
|
@ -236,7 +235,7 @@ def map_image(request, area, level):
|
|||
if if_modified_since != last_update:
|
||||
return HttpResponseNotModified()
|
||||
|
||||
response = HttpResponse(content_type=mimetypes.guess_type(img)[0])
|
||||
response = HttpResponse(content_type='image/png')
|
||||
for chunk in File(open(img, 'rb')).chunks():
|
||||
response.write(chunk)
|
||||
|
||||
|
|
|
@ -10,3 +10,4 @@ requests>=2.11,<2.12
|
|||
Pillow>=3.4.2,<3.5
|
||||
matplotlib>=1.5.3,<1.6
|
||||
scipy>=0.18.1,<0.19
|
||||
qrcode>=5.3,<5.4
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue