added guide for token registration
|
@ -2,6 +2,7 @@ import paho.mqtt.client as mqtt
|
||||||
import socket
|
import socket
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import logging
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
class DoorHandle:
|
class DoorHandle:
|
||||||
def __init__(self, token_file, mqtt_host, mqtt_port=1883, nfc_socket='/tmp/nfc.sock', logger=None):
|
def __init__(self, token_file, mqtt_host, mqtt_port=1883, nfc_socket='/tmp/nfc.sock', logger=None):
|
||||||
|
@ -53,6 +54,7 @@ class DoorHandle:
|
||||||
self.encoder_position = int(msg.payload)
|
self.encoder_position = int(msg.payload)
|
||||||
elif msg.topic == 'door/token/last_invalid':
|
elif msg.topic == 'door/token/last_invalid':
|
||||||
timestamp, token = msg.payload.decode().split(";")
|
timestamp, token = msg.payload.decode().split(";")
|
||||||
|
timestamp = datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S')
|
||||||
self.last_invalid = {'timestamp': timestamp, 'token': token}
|
self.last_invalid = {'timestamp': timestamp, 'token': token}
|
||||||
|
|
||||||
def get_tokens(self):
|
def get_tokens(self):
|
||||||
|
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 4.4 KiB |
BIN
imaginaerraum_door_admin/static/token.png
Normal file
After Width: | Height: | Size: 89 KiB |
|
@ -5,13 +5,37 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if not token.vars %}
|
|
||||||
<div class="d-grid gap-3">
|
<div class="d-grid gap-3">
|
||||||
<div class="p-2 bg-light border">
|
<div class="p-2 bg-light border">
|
||||||
Letzter gelesener unregistrierter Token: {{ token['token'] }} <br>
|
<h2>Anleitung zur Schlüsselregistrierung</h2>
|
||||||
Gelesen: {{ token['timestamp']}}
|
<ol>
|
||||||
|
<li>RFID-Token bereithalten (liegen im Regal im hinteren Raum)<br>
|
||||||
|
<img src="static/token.png" title="Token" alt="Token"><br>
|
||||||
|
Wichtig: Der RFID-Token darf nicht bereits registriert sein. Falls ein Token neu beschrieben werden soll,
|
||||||
|
muss zunächst die bestehende Registrierung gelöscht werden.</li>
|
||||||
|
<li>RFID-Token einmal von außen an das Lesegerät an der Tür halten. Danach diese Seite neu laden.</li>
|
||||||
|
<li>Im Feld weiter unten erscheint die ID des Token. Außerdem wird die Uhrzeit des Lesevorgangs angezeigt.
|
||||||
|
Diese bitte überprüfen, damit nicht versehentlich ein falscher Token registriert wird.</li>
|
||||||
|
<li>Wenn alles passt, kann der Token registiert werden. Hierzu im Registierungsfeld Namen,
|
||||||
|
Organisationszugehörigkeit (z.B. imaginärraum o. TransitionHaus) und eine E-Mail-Adresse zur
|
||||||
|
Kontaktaufnahme angeben. Optional kann die Gültigkeitsdauer des Tokens begrenzt werden.
|
||||||
|
Zusätzlich muss angegeben werden, dass der/die NutzerIn über die Nutzungsbedingungen aufgeklärt wurde
|
||||||
|
und diesen zustimmt.
|
||||||
|
</li>
|
||||||
|
<li>Achtung: Der Token funktioniert nicht sofort, sondern muss erst explizit aktiviert werden!
|
||||||
|
Dazu in der <a href="{{ url_for('list_tokens') }}">Token-Übersicht</a> auf das Bearbeiten-Symbol
|
||||||
|
(<img src="static/edit.png" title="Editieren" alt="Edit">) klicken und den Haken bei "Aktiv?" setzen.
|
||||||
|
</li>
|
||||||
|
<li>Jetzt kann der Token verwendet werden.</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
{% if 'token' in token and 'timestamp' in token %}
|
||||||
|
<div class="alert alert-success" role="alert">
|
||||||
|
<h4 class="alert-heading">Unregistrierter Token gelesen:</h4>
|
||||||
|
<p>Token ID: {{ token['token'] }}</p>
|
||||||
|
<hr>
|
||||||
|
<p class="mb-0">Zeitstempel: {{ token['timestamp']}}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="p-2 bg-light border">
|
<div class="p-2 bg-light border">
|
||||||
<h3>RaumnutzerIn registrieren:</h3>
|
<h3>RaumnutzerIn registrieren:</h3>
|
||||||
|
@ -54,7 +78,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
Keine unregistrierten Tokens in MQTT Nachrichten. Bitte Token scannen und die Seite neu laden.
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<p>Keine unregistrierten Tokens in MQTT Nachrichten. </p>
|
||||||
|
<p>Bitte Token scannen und die Seite neu laden.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -23,7 +23,7 @@ from pathlib import Path
|
||||||
import logging
|
import logging
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from datetime import date
|
from datetime import date, datetime, timedelta
|
||||||
from .door_handle import DoorHandle
|
from .door_handle import DoorHandle
|
||||||
|
|
||||||
|
|
||||||
|
@ -503,12 +503,20 @@ def create_application(config):
|
||||||
If the route is called via POST the provided form data is checked and if the check succeeds the /store-token route
|
If the route is called via POST the provided form data is checked and if the check succeeds the /store-token route
|
||||||
will be called which adds the new token to the database.
|
will be called which adds the new token to the database.
|
||||||
"""
|
"""
|
||||||
|
token = door.get_most_recent_token()
|
||||||
|
|
||||||
|
recent_token = {}
|
||||||
|
if {'token', 'timestamp'}.issubset(set(token.keys())):
|
||||||
|
if token['timestamp'] >= datetime.now() - timedelta(minutes=10):
|
||||||
|
recent_token = token
|
||||||
|
|
||||||
form = TokenForm()
|
form = TokenForm()
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
# set default valid thru date to today to make sure form validity check passes
|
# set default valid thru date to today to make sure form validity check passes
|
||||||
# (will not be used if limited validity is disabled)
|
# (will not be used if limited validity is disabled)
|
||||||
form.valid_thru.data = date.today()
|
form.valid_thru.data = date.today()
|
||||||
return render_template('register.html', token=door.get_most_recent_token(), form=form)
|
|
||||||
|
return render_template('register.html', token=recent_token, form=form)
|
||||||
elif request.method == 'POST' and form.validate():
|
elif request.method == 'POST' and form.validate():
|
||||||
# store data in session cookie
|
# store data in session cookie
|
||||||
session['token'] = door.get_most_recent_token()['token']
|
session['token'] = door.get_most_recent_token()['token']
|
||||||
|
@ -522,7 +530,7 @@ def create_application(config):
|
||||||
session['inactive'] = not form.active.data
|
session['inactive'] = not form.active.data
|
||||||
return redirect('/store-token')
|
return redirect('/store-token')
|
||||||
else:
|
else:
|
||||||
return render_template('register.html', token=door.get_most_recent_token(), form=form)
|
return render_template('register.html', token=recent_token, form=form)
|
||||||
|
|
||||||
@app.route('/edit-token/<token>', methods=['GET', 'POST'])
|
@app.route('/edit-token/<token>', methods=['GET', 'POST'])
|
||||||
@roles_required('admin')
|
@roles_required('admin')
|
||||||
|
|