added organization and improved layout

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

36
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 datetime import date
from door import Door
door = Door('10.10.21.2')
MQTT_BROKER = '10.10.21.2'
door = Door(MQTT_BROKER)
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['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
# underlying engine. This option makes sure that DB connections from the
# pool are still valid. Important for entire application since
@ -69,10 +70,11 @@ def validate_valid_thru_date(form, field):
class TokenForm(FlaskForm):
name = StringField('Name', validators=[DataRequired()])
email = EmailField('E-Mail', validators=[DataRequired()])
organization = StringField('Organization', validators=[DataRequired()])
limit_validity = BooleanField('Gültigkeit begrenzen?')
valid_thru = DateField('Gültig bis', validators=[validate_valid_thru_date])
active = BooleanField('Aktiv?')
dsgvo = BooleanField('Einwilligung DSGVO erfragt?', validators=[DataRequired()])
dsgvo = BooleanField('Einwilligung Nutzungsbedingungen erfragt?', validators=[DataRequired()])
# Create a user to test with
@ -90,7 +92,7 @@ def door_lock():
@app.route('/tokens')
#@auth_required()
@auth_required()
def list_tokens():
tokens = door.get_tokens()
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'])
#@auth_required()
@auth_required()
def register():
"""Register new token for locking and unlocking the door.
@ -120,6 +122,7 @@ def register():
session['token'] = door.get_most_recent_token()['token']
session['name'] = form.name.data
session['email'] = form.email.data
session['organization'] = form.organization.data
if form.limit_validity.data:
session['valid_thru'] = form.valid_thru.data.isoformat()
else:
@ -131,7 +134,7 @@ def register():
@app.route('/edit-token/<token>', methods=['GET', 'POST'])
#@auth_required()
@auth_required()
def edit_token(token):
"""Edit data in the token file (name, email, valid_thru date, active/inactive).
@ -144,7 +147,7 @@ def edit_token(token):
token : str
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
# to it before
if request.method == 'GET':
@ -155,6 +158,8 @@ def edit_token(token):
form.active.data = not et['inactive']
form.name.data = et['name'] if et['name'] 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
try:
form.valid_thru.data = date.fromisoformat(et['valid_thru'])
@ -167,10 +172,12 @@ def edit_token(token):
# flash an error message if the route is accessed with an invalid token
flash(f'Ausgewaehlter Token {token} in Tokenfile nicht gefunden.')
return redirect('/tokens')
elif request.method == 'POST' and form.validate():
elif request.method == 'POST':
if form.validate():
# store data in session cookie
session['token'] = token
session['name'] = form.name.data
session['organization'] = form.organization.data
session['email'] = form.email.data
if form.limit_validity.data:
session['valid_thru'] = form.valid_thru.data.isoformat()
@ -178,10 +185,13 @@ def edit_token(token):
session['valid_thru'] = ''
session['inactive'] = not form.active.data
return redirect(f'/store-token')
else:
return render_template('edit.html', token=token, form=form)
@app.route('/store-token')
#@auth_required()
@auth_required()
def store_token():
"""Store token to the token file on disk.
@ -194,13 +204,13 @@ def store_token():
'email': session['email'],
'valid_thru': session['valid_thru'],
'inactive': session['inactive'],
'organization': 'test_org'}
'organization': session['organization']}
door.store_tokens(tokens)
return redirect('/tokens')
@app.route('/delete-token', methods=['POST'])
#@auth_required()
@auth_required()
def delete_token():
"""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>')
#@auth_required()
@auth_required()
def deactivate_token(token):
"""Deactivate access for the given token. This updates the token file on disk.

View File

@ -21,17 +21,39 @@
Token {{ token }} editieren:
</p>
<form method="POST">
<p>{{ form.csrf_token }}
<p>{{ form.name.label }} {{ form.name(size=20) }}</p>
<p>{{ form.email.label }} {{ form.email(size=20) }}</p>
<p>{{ form.limit_validity.label }} {{ form.limit_validity() }}</p>
<div id="valid_thru_dialog" {% if not form.limit_validity.data %}hidden{% endif %}>
<p>{{ form.valid_thru.label }} {{ form.valid_thru() }}</p>
</div>
<p>{{ form.active.label }} {{ form.active() }}</p>
<table>
{{ form.csrf_token }}
<tr>
<td>{{ form.name.label }}</td>
<td>{{ form.name(size=20) }}</td>
</tr>
<tr>
<td>{{ form.email.label }}</td>
<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: {% 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>
</div>
</body>
@ -39,7 +61,12 @@
<script>
$(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>

View File

@ -25,15 +25,40 @@
RaumnutzerIn registrieren:
</p>
<form method="POST">
<p>{{ form.csrf_token }}
<p>{{ form.name.label }} {{ form.name(size=20) }}</p>
<p>{{ form.email.label }} {{ form.email(size=20) }}</p>
<p>{{ form.limit_validity.label }} {{ form.limit_validity() }}</p>
<div id="valid_thru_dialog" {% if not form.limit_validity.data %}hidden{% endif %}>
<p>{{ form.valid_thru.label }} {{ form.valid_thru() }}</p>
</div>
<p>{{ form.dsgvo.label }} {{ form.dsgvo() }}</p>
<table>
{{ form.csrf_token }}
<tr>
<td>{{ form.name.label }}</td>
<td>{{ form.name(size=20) }}</td>
</tr>
<tr>
<td>{{ form.email.label }}</td>
<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>
</div>
{% else %}
@ -44,7 +69,12 @@
<script>
$(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>