From d5eaf699a7dd5215403b626762b68cd09bc846b5 Mon Sep 17 00:00:00 2001 From: Roberto Hueso Gómez Date: Fri, 4 Sep 2020 11:09:44 +0200 Subject: Add WoL action This action can be applied on one or multiple scopes. This implementation use Flask-WTF as a way to build and valdiate forms. As a side effect, this adds CSRF protection to all forms. --- ogcp/__init__.py | 8 ++++++++ ogcp/forms/action_forms.py | 10 ++++++++++ ogcp/templates/actions/wol.html | 11 +++++++++++ ogcp/templates/scopes.html | 9 ++++++--- ogcp/views.py | 15 +++++++++++++++ requirements.txt | 5 +++++ 6 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 ogcp/forms/action_forms.py create mode 100644 ogcp/templates/actions/wol.html diff --git a/ogcp/__init__.py b/ogcp/__init__.py index 1fda3f1..58ba0c3 100644 --- a/ogcp/__init__.py +++ b/ogcp/__init__.py @@ -1,6 +1,14 @@ +from flask_wtf.csrf import CSRFProtect +from flask_bootstrap import Bootstrap from flask_babel import Babel from flask import Flask +from os import urandom + app = Flask(__name__) babel = Babel(app) +csrf = CSRFProtect(app) +bootstrap = Bootstrap(app) + +app.secret_key = urandom(16) import ogcp.views diff --git a/ogcp/forms/action_forms.py b/ogcp/forms/action_forms.py new file mode 100644 index 0000000..d6416bd --- /dev/null +++ b/ogcp/forms/action_forms.py @@ -0,0 +1,10 @@ +from wtforms import Form, SubmitField, HiddenField, SelectField +from flask_wtf import FlaskForm +from flask_babel import _ + +class WOLForm(FlaskForm): + ips = HiddenField() + wol_type = SelectField(label=_('Type'), + choices=[('broadcast', 'Broadcast'), + ('unicast', 'Unicast')]) + submit = SubmitField(label=_('Submit')) diff --git a/ogcp/templates/actions/wol.html b/ogcp/templates/actions/wol.html new file mode 100644 index 0000000..27bb3d3 --- /dev/null +++ b/ogcp/templates/actions/wol.html @@ -0,0 +1,11 @@ +{% extends 'base.html' %} +{% import "bootstrap/wtf.html" as wtf %} + +{% block content %} + +{{ wtf.quick_form(form, + action=url_for('action_wol'), + method='post', + button_map={'submit': 'primary'}) }} + +{% endblock %} diff --git a/ogcp/templates/scopes.html b/ogcp/templates/scopes.html index 4603f04..4b9ff28 100644 --- a/ogcp/templates/scopes.html +++ b/ogcp/templates/scopes.html @@ -21,7 +21,8 @@ {% block content %} -
+ + {{ print_scopes_tree(scopes["scope"]) }}
diff --git a/ogcp/views.py b/ogcp/views.py index 9d44b55..92e91b2 100644 --- a/ogcp/views.py +++ b/ogcp/views.py @@ -1,4 +1,5 @@ from flask import g, render_template, url_for, request, jsonify, make_response +from ogcp.forms.action_forms import WOLForm from ogcp.og_server import OGServer from flask_babel import _ from ogcp import app @@ -49,6 +50,20 @@ def action_poweroff(): g.server.post('/poweroff', payload) return make_response("200 OK", 200) +@app.route('/action/wol', methods=['GET', 'POST']) +def action_wol(): + form = WOLForm(request.form) + if request.method == 'POST' and form.validate(): + wol_type = form.wol_type.data + ips = parse_ips(request.form.to_dict()) + payload = {'type': wol_type, 'clients': list(ips)} + g.server.post('/wol', payload) + return make_response("200 OK", 200) + else: + ips = parse_ips(request.args.to_dict()) + form.ips.data = " ".join(ips) + return render_template('actions/wol.html', form=form) + @app.route('/action/reboot', methods=['POST']) def action_reboot(): ips = parse_ips(request.form.to_dict()) diff --git a/requirements.txt b/requirements.txt index 7f77a3c..aba7d15 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,8 +2,11 @@ Babel==2.8.0 certifi==2020.6.20 chardet==3.0.4 click==7.1.2 +dominate==2.5.2 Flask==1.1.2 Flask-Babel==2.0.0 +Flask-Bootstrap==3.3.7.1 +Flask-WTF==0.14.3 idna==2.10 itsdangerous==1.1.0 Jinja2==2.11.2 @@ -11,4 +14,6 @@ MarkupSafe==1.1.1 pytz==2020.1 requests==2.24.0 urllib3==1.25.10 +visitor==0.1.3 Werkzeug==1.0.1 +WTForms==2.3.3 -- cgit v1.2.3-18-g5258