added organization and improved layout

master
Simon Pirkelmann 2021-03-08 21:31:25 +01:00
parent f9eadc3c5a
commit 652a406461
3 changed files with 111 additions and 44 deletions

54
app.py
View File

@ -10,10 +10,11 @@ from flask_security.models import fsqla_v2 as fsqla
from flask_security.forms import LoginForm, Required, PasswordField from flask_security.forms import LoginForm, Required, PasswordField
from datetime import date from datetime import date
from door import Door from door import Door
door = Door('10.10.21.2') MQTT_BROKER = '10.10.21.2'
door = Door(MQTT_BROKER)
app = Flask(__name__) app = Flask(__name__)
@ -25,7 +26,7 @@ app.config['SECURITY_PASSWORD_SALT'] = os.environ.get("SECURITY_PASSWORD_SALT",
app.config['SECURITY_USER_IDENTITY_ATTRIBUTES'] = ('username', 'email') app.config['SECURITY_USER_IDENTITY_ATTRIBUTES'] = ('username', 'email')
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///admin.db'
# As of Flask-SQLAlchemy 2.4.0 it is easy to pass in options directly to the # As of Flask-SQLAlchemy 2.4.0 it is easy to pass in options directly to the
# underlying engine. This option makes sure that DB connections from the # underlying engine. This option makes sure that DB connections from the
# pool are still valid. Important for entire application since # pool are still valid. Important for entire application since
@ -69,10 +70,11 @@ def validate_valid_thru_date(form, field):
class TokenForm(FlaskForm): class TokenForm(FlaskForm):
name = StringField('Name', validators=[DataRequired()]) name = StringField('Name', validators=[DataRequired()])
email = EmailField('E-Mail', validators=[DataRequired()]) email = EmailField('E-Mail', validators=[DataRequired()])
organization = StringField('Organization', validators=[DataRequired()])
limit_validity = BooleanField('Gültigkeit begrenzen?') limit_validity = BooleanField('Gültigkeit begrenzen?')
valid_thru = DateField('Gültig bis', validators=[validate_valid_thru_date]) valid_thru = DateField('Gültig bis', validators=[validate_valid_thru_date])
active = BooleanField('Aktiv?') active = BooleanField('Aktiv?')
dsgvo = BooleanField('Einwilligung DSGVO erfragt?', validators=[DataRequired()]) dsgvo = BooleanField('Einwilligung Nutzungsbedingungen erfragt?', validators=[DataRequired()])
# Create a user to test with # Create a user to test with
@ -90,7 +92,7 @@ def door_lock():
@app.route('/tokens') @app.route('/tokens')
#@auth_required() @auth_required()
def list_tokens(): def list_tokens():
tokens = door.get_tokens() tokens = door.get_tokens()
assigned_tokens = {t: data for t, data in tokens.items() if not data['inactive']} assigned_tokens = {t: data for t, data in tokens.items() if not data['inactive']}
@ -99,7 +101,7 @@ def list_tokens():
@app.route('/register-token', methods=['GET', 'POST']) @app.route('/register-token', methods=['GET', 'POST'])
#@auth_required() @auth_required()
def register(): def register():
"""Register new token for locking and unlocking the door. """Register new token for locking and unlocking the door.
@ -120,6 +122,7 @@ def register():
session['token'] = door.get_most_recent_token()['token'] session['token'] = door.get_most_recent_token()['token']
session['name'] = form.name.data session['name'] = form.name.data
session['email'] = form.email.data session['email'] = form.email.data
session['organization'] = form.organization.data
if form.limit_validity.data: if form.limit_validity.data:
session['valid_thru'] = form.valid_thru.data.isoformat() session['valid_thru'] = form.valid_thru.data.isoformat()
else: else:
@ -131,7 +134,7 @@ def register():
@app.route('/edit-token/<token>', methods=['GET', 'POST']) @app.route('/edit-token/<token>', methods=['GET', 'POST'])
#@auth_required() @auth_required()
def edit_token(token): def edit_token(token):
"""Edit data in the token file (name, email, valid_thru date, active/inactive). """Edit data in the token file (name, email, valid_thru date, active/inactive).
@ -144,7 +147,7 @@ def edit_token(token):
token : str token : str
The token for which data should be edited. The token for which data should be edited.
""" """
form = TokenForm() form = TokenForm(request.form)
form.dsgvo.validators = [] # we skip the validation of the DSGVO checkbox here because we assume the user agreed form.dsgvo.validators = [] # we skip the validation of the DSGVO checkbox here because we assume the user agreed
# to it before # to it before
if request.method == 'GET': if request.method == 'GET':
@ -155,6 +158,8 @@ def edit_token(token):
form.active.data = not et['inactive'] form.active.data = not et['inactive']
form.name.data = et['name'] if et['name'] else '' form.name.data = et['name'] if et['name'] else ''
form.email.data = et['email'] if et['email'] else '' form.email.data = et['email'] if et['email'] else ''
form.organization.data = et['organization'] if et['organization'] else ''
# for the valid thru date we use today's date in case there is not valid date in the database # for the valid thru date we use today's date in case there is not valid date in the database
try: try:
form.valid_thru.data = date.fromisoformat(et['valid_thru']) form.valid_thru.data = date.fromisoformat(et['valid_thru'])
@ -167,21 +172,26 @@ def edit_token(token):
# flash an error message if the route is accessed with an invalid token # flash an error message if the route is accessed with an invalid token
flash(f'Ausgewaehlter Token {token} in Tokenfile nicht gefunden.') flash(f'Ausgewaehlter Token {token} in Tokenfile nicht gefunden.')
return redirect('/tokens') return redirect('/tokens')
elif request.method == 'POST' and form.validate(): elif request.method == 'POST':
# store data in session cookie if form.validate():
session['token'] = token # store data in session cookie
session['name'] = form.name.data session['token'] = token
session['email'] = form.email.data session['name'] = form.name.data
if form.limit_validity.data: session['organization'] = form.organization.data
session['valid_thru'] = form.valid_thru.data.isoformat() session['email'] = form.email.data
if form.limit_validity.data:
session['valid_thru'] = form.valid_thru.data.isoformat()
else:
session['valid_thru'] = ''
session['inactive'] = not form.active.data
return redirect(f'/store-token')
else: else:
session['valid_thru'] = '' return render_template('edit.html', token=token, form=form)
session['inactive'] = not form.active.data
return redirect(f'/store-token')
@app.route('/store-token') @app.route('/store-token')
#@auth_required() @auth_required()
def store_token(): def store_token():
"""Store token to the token file on disk. """Store token to the token file on disk.
@ -194,13 +204,13 @@ def store_token():
'email': session['email'], 'email': session['email'],
'valid_thru': session['valid_thru'], 'valid_thru': session['valid_thru'],
'inactive': session['inactive'], 'inactive': session['inactive'],
'organization': 'test_org'} 'organization': session['organization']}
door.store_tokens(tokens) door.store_tokens(tokens)
return redirect('/tokens') return redirect('/tokens')
@app.route('/delete-token', methods=['POST']) @app.route('/delete-token', methods=['POST'])
#@auth_required() @auth_required()
def delete_token(): def delete_token():
"""Delete the given token from the token file and store the new token file to disk """Delete the given token from the token file and store the new token file to disk
@ -218,7 +228,7 @@ def delete_token():
@app.route('/deactivate-token/<token>') @app.route('/deactivate-token/<token>')
#@auth_required() @auth_required()
def deactivate_token(token): def deactivate_token(token):
"""Deactivate access for the given token. This updates the token file on disk. """Deactivate access for the given token. This updates the token file on disk.

View File

@ -21,17 +21,39 @@
Token {{ token }} editieren: Token {{ token }} editieren:
</p> </p>
<form method="POST"> <form method="POST">
<p>{{ form.csrf_token }} <table>
<p>{{ form.name.label }} {{ form.name(size=20) }}</p> {{ form.csrf_token }}
<p>{{ form.email.label }} {{ form.email(size=20) }}</p> <tr>
<p>{{ form.limit_validity.label }} {{ form.limit_validity() }}</p> <td>{{ form.name.label }}</td>
<td>{{ form.name(size=20) }}</td>
<div id="valid_thru_dialog" {% if not form.limit_validity.data %}hidden{% endif %}> </tr>
<p>{{ form.valid_thru.label }} {{ form.valid_thru() }}</p> <tr>
</div> <td>{{ form.email.label }}</td>
<p>{{ form.active.label }} {{ form.active() }}</p> <td>{{ form.email(size=20) }}</td>
</tr>
<input type="submit" value="Speichern"> <tr>
<td>{{ form.organization.label }}</td>
<td>{{ form.organization(size=20) }}</td>
</tr>
<tr>
<td>{{ form.limit_validity.label }}</td>
<td> {{ form.limit_validity() }}</td>
</tr>
<tr id="valid_thru_row" style="display: {% if form.limit_validity.data %}table-row{% else %}none{% endif %}">
<td>{{ form.valid_thru.label }} </td>
<td>{{ form.valid_thru() }}</td>
</tr>
<tr>
<td>{{ form.active.label }}</td>
<td> {{ form.active() }}</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="Speichern">
</td>
</tr>
</table>
</form> </form>
</div> </div>
</body> </body>
@ -39,7 +61,12 @@
<script> <script>
$(function () { $(function () {
$("#limit_validity").on("click", function () { $("#limit_validity").on("click", function () {
$("#valid_thru_dialog").toggle(this.checked); if (this.checked) {
$("#valid_thru_row").css("display", "table-row")
}
else {
$("#valid_thru_row").css("display", "none")
}
}); });
}); });
</script> </script>

View File

@ -25,15 +25,40 @@
RaumnutzerIn registrieren: RaumnutzerIn registrieren:
</p> </p>
<form method="POST"> <form method="POST">
<p>{{ form.csrf_token }} <table>
<p>{{ form.name.label }} {{ form.name(size=20) }}</p> {{ form.csrf_token }}
<p>{{ form.email.label }} {{ form.email(size=20) }}</p> <tr>
<p>{{ form.limit_validity.label }} {{ form.limit_validity() }}</p> <td>{{ form.name.label }}</td>
<div id="valid_thru_dialog" {% if not form.limit_validity.data %}hidden{% endif %}> <td>{{ form.name(size=20) }}</td>
<p>{{ form.valid_thru.label }} {{ form.valid_thru() }}</p> </tr>
</div> <tr>
<p>{{ form.dsgvo.label }} {{ form.dsgvo() }}</p> <td>{{ form.email.label }}</td>
<input type="submit" value="Abschicken"> <td>{{ form.email(size=20) }}</td>
</tr>
<tr>
<td>{{ form.organization.label }}</td>
<td>{{ form.organization(size=20) }}</td>
</tr>
<tr>
<td>{{ form.limit_validity.label }}</td>
<td> {{ form.limit_validity() }}</td>
</tr>
<tr id="valid_thru_row" style="display: none">
<td>{{ form.valid_thru.label }} </td>
<td>{{ form.valid_thru() }}</td>
</tr>
<tr>
<td>{{ form.dsgvo.label }} </td>
<td> {{ form.dsgvo() }}</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="Abschicken">
</td>
</tr>
</table>
</form> </form>
</div> </div>
{% else %} {% else %}
@ -44,7 +69,12 @@
<script> <script>
$(function () { $(function () {
$("#limit_validity").on("click", function () { $("#limit_validity").on("click", function () {
$("#valid_thru_dialog").toggle(this.checked); if (this.checked) {
$("#valid_thru_row").css("display", "table-row")
}
else {
$("#valid_thru_row").css("display", "none")
}
}); });
}); });
</script> </script>