Commit cefc6716 authored by Sebastian Böhm's avatar Sebastian Böhm
Browse files

add flask-security

parent cbed3616
......@@ -164,6 +164,11 @@ CPU_LOAD_SVC_MAX_TARGET_LOAD=0.75
# web
WEB_HOSTNAME=localhost
FLASK_WEB_USER=
FLASK_WEB_PASSWORD=
FLASK_SECRET_KEY=
FLASK_SECURITY_PASSWORD_SALT=
FLASK_SQLITE_DB_PATH=sqlite:///../../flask-db.db
```
......
......@@ -29,7 +29,7 @@ if __name__=="__main__":
message_broker = MessageBroker(consumer_queue, publisher_queue, cpu_load_svc)
try:
logging.info('Please press any key to interrupt...')
logging.info('Start Edge-IoT Simulator...')
publisher.start()
temperature_svc.start()
cpu_load_svc.start()
......
import os
import threading
import logging
from flask import Flask, render_template, redirect, url_for, request, Response
from werkzeug.serving import make_server
from core.temperature_svc import TemperatureUnits
from flask import Flask, render_template_string
from flask_sqlalchemy import SQLAlchemy
from flask_security import Security, SQLAlchemyUserDatastore, auth_required, hash_password
from flask_security.models import fsqla_v2 as fsqla
logging.basicConfig(format='%(asctime)s %(module)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.DEBUG)
class WebApp(threading.Thread):
......@@ -11,33 +18,73 @@ class WebApp(threading.Thread):
def __init__(self, publisher, temperature_svc, cpu_load_svc):
threading.Thread.__init__(self)
app = self.create_app(publisher, temperature_svc, cpu_load_svc)
self.srv = make_server('0.0.0.0', 5000, app)
self.srv = make_server('0.0.0.0', 5000, app, ssl_context='adhoc')
self.ctx = app.app_context()
self.ctx.push()
self.logger = logging.getLogger(__name__)
def create_app(self, publisher, temperature_svc, cpu_load_svc):
app = Flask(__name__)
app.config['DEBUG'] = True
# Generate a nice key using secrets.token_urlsafe()
app.config['SECRET_KEY'] = os.getenv("FLASK_SECRET_KEY")
app.config['SECURITY_PASSWORD_SALT'] = os.getenv("FLASK_SECURITY_PASSWORD_SALT")
# Use an in-memory db
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('FLASK_SQLITE_DB_PATH')
app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {
"pool_pre_ping": True,
}
# Create database connection object
db = SQLAlchemy(app)
# Define models
fsqla.FsModels.set_db_info(db)
class Role(db.Model, fsqla.FsRoleMixin):
pass
class User(db.Model, fsqla.FsUserMixin):
pass
# Setup Flask-Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
# Create a user to test with
@app.before_first_request
def create_user():
db.create_all()
if not user_datastore.find_user(email=os.getenv('FLASK_WEB_USER')):
user_datastore.create_user(email=os.getenv('FLASK_WEB_USER'), password=hash_password(os.getenv('FLASK_WEB_PASSWORD')))
db.session.commit()
@app.route("/")
@auth_required()
def index():
return render_template('dashboard.html', TemperatureMeasurement=temperature_svc.get_temperature(TemperatureUnits.celsius.name), MqttStatistics=publisher.get_mqtt_statistics())
@app.route("/temperature")
@auth_required()
def get_temperature():
return temperature_svc.get_temperature(TemperatureUnits.celsius.name).to_string()
@app.route("/cpu-load", methods=["POST"])
@auth_required()
def create_cpu_load_job():
form_data = request.form
cpu_load_svc.create_cpu_load_job(int(form_data.get('duration')), float(form_data.get('target_load')))
return redirect('/cpu-load')
@app.route("/cpu-load", methods=["GET"])
@auth_required()
def get_cpu_load():
return render_template('cpu-load.html', CPULoadJobHistory=cpu_load_svc.get_cpu_load_job_history())
@app.route("/cpu-load/<id>", methods=["DELETE"])
@auth_required()
def terminate_cpu_load_job(id):
cpu_load_svc.delete_cpu_load_job_by_id(id)
return Response(status=200)
......
......@@ -14,7 +14,7 @@
<div class="container px-4">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="/dashboard">Edge-IoT Simulator</a>
<a class="navbar-brand" href="/">Edge-IoT Simulator</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
......@@ -28,6 +28,9 @@
</li>
</ul>
</div>
<form class="form-inline" action="/logout">
<button class="btn btn-outline-danger" type="submit">Logout</button>
</form>
</div>
</nav>
<div class="row gx-5">
......
......@@ -14,7 +14,7 @@
<div class="container px-4">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Edge-IoT Simulator</a>
<a class="navbar-brand" href="/">Edge-IoT Simulator</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
......@@ -28,6 +28,9 @@
</li>
</ul>
</div>
<form class="form-inline" action="/logout">
<button class="btn btn-outline-danger" type="submit">Logout</button>
</form>
</div>
</nav>
<div class="row gx-5">
......
File added
autopep8==1.6.0
bcrypt==3.2.0
bidict==0.21.4
blinker==1.4
cffi==1.15.0
click==8.0.3
cpu-load-generator==1.2.0
dnspython==2.1.0
email-validator==1.1.3
Flask==2.0.2
Flask-Login==0.5.0
Flask-Mail==0.9.1
Flask-MQTT==1.1.1
Flask-Principal==0.4.0
Flask-Security-Too==4.1.2
Flask-SocketIO==5.1.1
Flask-SQLAlchemy==2.5.1
Flask-WTF==1.0.0
gevent==21.8.0
gevent-websocket==0.10.1
greenlet==1.1.2
idna==3.3
install==1.3.4
itsdangerous==2.0.1
Jinja2==3.0.3
MarkupSafe==2.0.1
paho-mqtt==1.6.1
passlib==1.7.4
pi==0.1.2
psutil==5.8.0
pycodestyle==2.8.0
pycparser==2.21
python-dotenv==0.19.1
python-engineio==4.3.0
python-socketio==5.4.1
six==1.16.0
SQLAlchemy==1.4.27
SQLAlchemy-Utils==0.37.9
toml==0.10.2
Werkzeug==2.0.2
WTForms==3.0.0
zope.event==4.5.0
zope.interface==5.4.0
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment