83 lines
2.6 KiB
Python
Executable File
83 lines
2.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import uuid
|
|
import sqlite3
|
|
from datetime import datetime
|
|
from flask import Flask, request, render_template
|
|
from flask_uuid import FlaskUUID
|
|
from flask_qrcode import QRcode
|
|
from flask_socketio import SocketIO
|
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
|
|
|
# WIP: use sockets to broadcast when a hit to the expected uuid has been
|
|
# received, so that connected clients (the Chromium public browser) can
|
|
# refresh the qr code and update the list of users
|
|
# https://flask-socketio.readthedocs.io
|
|
|
|
app = Flask(__name__)
|
|
FlaskUUID(app)
|
|
QRcode(app)
|
|
app.config['SECRET_KEY'] = '53a8373e7ae652cd38beba15454b1dc4'
|
|
#app = ProxyFix(app, x_for=1, x_host=1)
|
|
app.wsgi_app = ProxyFix(app.wsgi_app)
|
|
socketio = SocketIO(app, async_mode=None)
|
|
|
|
def get_db_connection():
|
|
conn = sqlite3.connect('database.db')
|
|
conn.row_factory = sqlite3.Row
|
|
return conn
|
|
|
|
@app.route('/')
|
|
def show_qr_and_list():
|
|
# TODO: reject direct connections to server; allow access only via proxy
|
|
conn = get_db_connection()
|
|
data = conn.execute('SELECT * FROM hits ORDER BY id DESC LIMIT 10').fetchall()
|
|
conn.close()
|
|
|
|
# TODO: store next_uuid in a queue, and remove it once it's used. Accept only ids
|
|
# from the queue
|
|
next_uuid = uuid.uuid1()
|
|
return render_template("template.html",
|
|
next_uuid=str(next_uuid),
|
|
hits=data)
|
|
|
|
@app.route('/<uuid:id>')
|
|
def catch_uuids(id):
|
|
ua = request.headers.get('Remote-User')
|
|
# TODO: Check directly with Authelia using https://auth.agofer.net/api/verify
|
|
time = datetime.now().strftime("%A %Y-%m-%d %H:%M:%S")
|
|
error = None
|
|
data = []
|
|
conn = get_db_connection()
|
|
existing = conn.execute(
|
|
'SELECT * FROM hits WHERE uuid = ?', (str(id),)).fetchone()
|
|
if not ua:
|
|
error = 'NO_USERNAME'
|
|
elif id.fields[5] != uuid.getnode():
|
|
error = 'DIFFERENT_NODE'
|
|
elif existing:
|
|
error = 'ALREADY_USED'
|
|
else:
|
|
conn.execute("INSERT INTO hits (uuid, user) VALUES (?, ?)", (str(id), ua))
|
|
conn.commit()
|
|
socketio.emit('qr_used', {'data': (time, ua, str(id))})
|
|
|
|
data = conn.execute(
|
|
'SELECT * FROM hits WHERE user = ? ORDER BY id DESC LIMIT 10', (ua,)
|
|
).fetchall()
|
|
conn.close()
|
|
|
|
return render_template('thanks.html', user=ua, time=time, error=error, hits=data)
|
|
|
|
@socketio.on('message')
|
|
def handle_message(data):
|
|
print('received message: ' + data)
|
|
|
|
@socketio.on('my_event')
|
|
def handle_my_custom_event(json):
|
|
print('received json: ' + str(json))
|
|
|
|
if __name__ == '__main__':
|
|
#app.run(host='0.0.0.0')
|
|
socketio.run(app, host='0.0.0.0')
|