diff options
Diffstat (limited to 'ogcp')
-rw-r--r-- | ogcp/cfg/ogcp.json | 2 | ||||
-rw-r--r-- | ogcp/forms/auth.py | 20 | ||||
-rw-r--r-- | ogcp/models.py | 5 | ||||
-rw-r--r-- | ogcp/templates/auth/login.html | 12 | ||||
-rw-r--r-- | ogcp/templates/base.html | 2 | ||||
-rw-r--r-- | ogcp/templates/nav.html | 18 | ||||
-rw-r--r-- | ogcp/views.py | 57 |
7 files changed, 116 insertions, 0 deletions
diff --git a/ogcp/cfg/ogcp.json b/ogcp/cfg/ogcp.json index 9e715d4..cff1cad 100644 --- a/ogcp/cfg/ogcp.json +++ b/ogcp/cfg/ogcp.json @@ -2,4 +2,6 @@ "IP": "127.0.0.1", "PORT": 8888, "API_TOKEN": "c3fe7bb0395747ec42a25df027585871" + "USER": "user", + "PASS": "pass" } diff --git a/ogcp/forms/auth.py b/ogcp/forms/auth.py new file mode 100644 index 0000000..8c84e84 --- /dev/null +++ b/ogcp/forms/auth.py @@ -0,0 +1,20 @@ +from wtforms import ( + Form, SubmitField, HiddenField, SelectField, BooleanField, IntegerField, + StringField, RadioField, PasswordField +) +from wtforms.validators import InputRequired +from flask_wtf import FlaskForm +from flask_babel import _ + +class LoginForm(FlaskForm): + user = StringField( + label=_('User'), + validators=[InputRequired()] + ) + pwd = PasswordField( + label=_('Password'), + validators=[InputRequired()] + ) + submit = SubmitField( + label=_('Login') + ) diff --git a/ogcp/models.py b/ogcp/models.py new file mode 100644 index 0000000..668c623 --- /dev/null +++ b/ogcp/models.py @@ -0,0 +1,5 @@ +from flask_login import UserMixin + +class User(UserMixin): + def get_id(self): + return 1 diff --git a/ogcp/templates/auth/login.html b/ogcp/templates/auth/login.html new file mode 100644 index 0000000..220f69e --- /dev/null +++ b/ogcp/templates/auth/login.html @@ -0,0 +1,12 @@ +{% extends 'base.html' %} +{% import "bootstrap/wtf.html" as wtf %} + +{% block content %} + +{{ wtf.quick_form(form, + method='post', + form_type='basic', + button_map={'submit':'primary'}, + extra_classes='p-5') }} + +{% endblock %} diff --git a/ogcp/templates/base.html b/ogcp/templates/base.html index 5f07fe7..3f55555 100644 --- a/ogcp/templates/base.html +++ b/ogcp/templates/base.html @@ -17,6 +17,8 @@ <div class="alert alert-info alert-dismissible fade show m-1" role="alert"> {% elif category == 'error' %} <div class="alert alert-danger alert-dismissible fade show m-1" role="alert"> + {% else %} + <div class="alert alert-warning alert-dismissible fade show m-1" role="alert"> {% endif %} {{ message }} <button type="button" class="close" data-dismiss="alert" aria-label="{{ _('Close') }}"> diff --git a/ogcp/templates/nav.html b/ogcp/templates/nav.html index 5147a37..d7741ca 100644 --- a/ogcp/templates/nav.html +++ b/ogcp/templates/nav.html @@ -9,9 +9,27 @@ <li class="nav-item active"> <a class="nav-link" href="{{ url_for('index') }}">{{ _('Home') }}<span class="sr-only">(current)</span></a> </li> + {% if current_user.is_authenticated %} <li class="nav-item"> <a class="nav-link" href="{{ url_for('scopes') }}">{{ _('Scopes') }}</a> </li> + {% endif %} + </ul> + + <ul class="nav navbar-nav navbar-right"> + {% if current_user.is_authenticated %} + + <li class="nav-item"> + <a class="btn btn-danger" href="{{ url_for('logout') }}">{{ _('Logout') }}</a> + </li> + + {% else %} + + <li class="nav-item"> + <a class="btn btn-primary" href="{{ url_for('login') }}">{{ _('Login') }}</a> + </li> + + {% endif %} </ul> </div> </nav> diff --git a/ogcp/views.py b/ogcp/views.py index 7502067..c7a05e7 100644 --- a/ogcp/views.py +++ b/ogcp/views.py @@ -5,6 +5,14 @@ from ogcp.forms.action_forms import ( WOLForm, PartitionForm, ClientDetailsForm, HardwareForm, SessionForm, ImageRestoreForm, ImageCreateForm, SoftwareForm, BootModeForm ) +from flask_login import ( + current_user, LoginManager, + login_user, logout_user, + login_required +) + +from ogcp.models import User +from ogcp.forms.auth import LoginForm from ogcp.og_server import OGServer from flask_babel import _ from ogcp import app @@ -33,6 +41,10 @@ PART_SCHEME_CODES = { 2: 'GPT' } +login_manager = LoginManager() +login_manager.init_app(app) +login_manager.login_view = 'login' + def validate_ips(ips, min_len=1, max_len=float('inf')): valid = True if len(ips) < min_len: @@ -74,6 +86,12 @@ def parse_scopes_from_tree(tree, scope_type): scopes += parse_scopes_from_tree(scope, scope_type) return scopes +@login_manager.user_loader +def load_user(user_id): + if user_id == 1: + return User() + return None + @app.before_request def load_config(): g.server = OGServer() @@ -90,7 +108,31 @@ def server_error(error): def index(): return render_template('base.html') +@app.route('/login', methods=['GET', 'POST']) +def login(): + form = LoginForm(request.form) + if request.method == 'POST' and form.validate(): + user = User() + form_user = request.form['user'] + pwd = request.form['pwd'] + if form_user != app.config['USER']: + flash(_('Incorrect user name')) + return render_template('auth/login.html', form=form) + if pwd != app.config['PASS']: + flash(_('Incorrect password')) + return render_template('auth/login.html', form=form) + login_user(user) + return redirect(url_for('scopes')) + return render_template('auth/login.html', form=LoginForm()) + +@app.route("/logout") +@login_required +def logout(): + logout_user() + return redirect(url_for('index')) + @app.route('/scopes/') +@login_required def scopes(): def add_state_and_ips(scope, clients): if 'ip' in scope: @@ -115,6 +157,7 @@ def scopes(): return render_template('scopes.html', scopes=scopes, clients=clients) @app.route('/action/poweroff', methods=['POST']) +@login_required def action_poweroff(): ips = parse_ips(request.form.to_dict()) payload = {'clients': list(ips)} @@ -122,6 +165,7 @@ def action_poweroff(): return redirect(url_for("scopes")) @app.route('/action/wol', methods=['GET', 'POST']) +@login_required def action_wol(): form = WOLForm(request.form) if request.method == 'POST' and form.validate(): @@ -140,6 +184,7 @@ def action_wol(): return redirect(url_for('scopes')) @app.route('/action/setup', methods=['GET']) +@login_required def action_setup_show(): ips = parse_ips(request.args.to_dict()) db_partitions = get_client_setup(ips) @@ -161,6 +206,7 @@ def action_setup_show(): return render_template('actions/setup.html', forms=forms) @app.route('/action/setup/modify', methods=['POST']) +@login_required def action_setup_modify(): form = PartitionForm(request.form) if form.validate(): @@ -208,6 +254,7 @@ def action_setup_modify(): return make_response("400 Bad Request", 400) @app.route('/action/setup/delete', methods=['POST']) +@login_required def action_setup_delete(): form = PartitionForm(request.form) if form.validate(): @@ -243,6 +290,7 @@ def action_setup_delete(): return make_response("400 Bad Request", 400) @app.route('/action/image/restore', methods=['GET', 'POST']) +@login_required def action_image_restore(): def search_image(images_list, image_id): for image in images_list: @@ -315,6 +363,7 @@ def action_image_restore(): return render_template('actions/image_restore.html', form=form) @app.route('/action/hardware', methods=['GET', 'POST']) +@login_required def action_hardware(): form = HardwareForm(request.form) if request.method == 'POST': @@ -335,6 +384,7 @@ def action_hardware(): hardware=hardware) @app.route('/action/software', methods=['GET', 'POST']) +@login_required def action_software(): form = SoftwareForm(request.form) if request.method == 'POST': @@ -374,6 +424,7 @@ def action_software(): return render_template('actions/software.html', form=form) @app.route('/action/session', methods=['GET', 'POST']) +@login_required def action_session(): form = SessionForm(request.form) if request.method == 'POST': @@ -400,6 +451,7 @@ def action_session(): return render_template('actions/session.html', form=form) @app.route('/action/client/info', methods=['GET']) +@login_required def action_client_info(): form = ClientDetailsForm() ips = parse_ips(request.args.to_dict()) @@ -437,6 +489,7 @@ def action_client_info(): return render_template('actions/client_details.html', form=form) @app.route('/action/client/add', methods=['GET', 'POST']) +@login_required def action_client_add(): form = ClientDetailsForm(request.form) if request.method == 'POST': @@ -472,6 +525,7 @@ def action_client_add(): return render_template('actions/client_details.html', form=form) @app.route('/action/mode', methods=['GET', 'POST']) +@login_required def action_mode(): form = BootModeForm(request.form) if request.method == 'POST': @@ -500,6 +554,7 @@ def action_mode(): @app.route('/action/image/create', methods=['GET', 'POST']) +@login_required def action_image_create(): form = ImageCreateForm(request.form) if request.method == 'POST': @@ -545,6 +600,7 @@ def action_image_create(): return render_template('actions/image_create.html', form=form) @app.route('/action/reboot', methods=['POST']) +@login_required def action_reboot(): ips = parse_ips(request.form.to_dict()) if not validate_ips(ips): @@ -559,6 +615,7 @@ def action_reboot(): return redirect(url_for("scopes")) @app.route('/action/refresh', methods=['POST']) +@login_required def action_refresh(): ips = parse_ips(request.form.to_dict()) if not validate_ips(ips): |