From facaaed9eba0855d7ae4a2a082d8431a66eeb690 Mon Sep 17 00:00:00 2001 From: Andrea Mistrali Date: Wed, 24 Jul 2024 17:10:30 +0200 Subject: [PATCH] Fix for exit node --- .gitignore | 2 - TODO.md | 1 + app/views/main.py | 131 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 app/views/main.py diff --git a/.gitignore b/.gitignore index d12bc41..f80ec6b 100644 --- a/.gitignore +++ b/.gitignore @@ -264,7 +264,5 @@ tags # End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,linux,python,vim # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) -main.py .flaskenv docker.env - diff --git a/TODO.md b/TODO.md index 8b26d21..98b3363 100644 --- a/TODO.md +++ b/TODO.md @@ -1,3 +1,4 @@ - try to use a datatable for routes, with grouping - API keys management; - Tag management on nodes; +- custom bootstrap build, with our own colors and fonts; diff --git a/app/views/main.py b/app/views/main.py new file mode 100644 index 0000000..6c24737 --- /dev/null +++ b/app/views/main.py @@ -0,0 +1,131 @@ +#SUKA +import logging +import datetime +import os +from flask import current_app +from flask import render_template, Blueprint, request +from flask import redirect, session, url_for +from app import auth + +# from ..lib import username + +from flask import jsonify +from flask_pyoidc.user_session import UserSession + +from hsapi_client import Node, User, Route, PreAuthKey +from hsapi_client.preauthkeys import v1ListPreAuthKeyRequest + + +log = logging.getLogger() + +main_blueprint = Blueprint( + 'main', __name__, url_prefix=os.getenv('APPLICATION_ROOT', '/')) + + +@main_blueprint.route('/health', methods=['GET']) +def health(): + return jsonify(dict(status="OK", version=current_app.config['APP_VERSION'])) + + +@main_blueprint.route('/', methods=['GET', 'POST']) +@auth.access_control('default') +def index(): + user_session = UserSession(session) + hs_user = user_session.userinfo['email'].split('@')[0] + userNodeList = [n for n in Node().list().nodes if n.user.name == hs_user] + return render_template('index.html', + userNodeList=userNodeList, + session=user_session) + + +@main_blueprint.route('/token', methods=['GET', 'POST']) +@auth.access_control('default') +def token(): + user_session = UserSession(session) + return jsonify(user_session.userinfo) + + +@main_blueprint.route('/logout') +@auth.oidc_logout +def logout(): + return redirect(url_for('main.index')) + + +@main_blueprint.route('/nodes', methods=['GET']) +@auth.authorize_admins('default') +def nodes(): + nodelist = Node().list() + return render_template('nodes.html', + nodes=nodelist.nodes) + + +@main_blueprint.route('/node/', methods=['GET']) +@auth.authorize_admins('default') +def node(nodeId): + # There is a bug in HS api with retrieving a single node + # and we added a workaround to hsapi, so node.get() returns a + # v1Node object instead of v1NodeResponse, so we access directly + # `node`, instead of `node.node` + node = Node().get(nodeId) + routes = Node().routes(nodeId) + isExitNode = any( + (r for r in routes.routes if r.prefix.endswith('/0') and r.enabled)) + return render_template("node.html", + routes=routes.routes, + isExitNode=isExitNode, + node=node) + + +@main_blueprint.route('/users', methods=['GET']) +@auth.authorize_admins('default') +def users(): + userList = User().list() + # Get online status of devices of the user + online = {} + nodeList = Node().list() + for user in userList.users: + userNodeList = [n for n in nodeList.nodes if n.user.name == user.name] + online[user.name] = any(map(lambda x: x.online, userNodeList)) + + return render_template('users.html', + users=userList.users, + online=online) + + +@main_blueprint.route('/user/', methods=['GET']) +@auth.authorize_admins('default') +def user(userName): + user = User().get(userName) + userNodeList = [n for n in Node().list().nodes if n.user.name == userName] + + preauthkeyreq = v1ListPreAuthKeyRequest(user=userName) + preauthKeys = PreAuthKey().list(preauthkeyreq) + + defaultExpiry = datetime.datetime.now() + datetime.timedelta(days=7) + expStr = defaultExpiry.strftime('%Y-%m-%dT%H:%M') + + return render_template("user.html", + user=user.user, + defaultExpiry=expStr, + preauthKeys=preauthKeys.preAuthKeys, + userNodeList=userNodeList) + + +@main_blueprint.route('/routes', methods=['GET']) +@auth.authorize_admins('default') +def routes(): + routes = Route().list() + + prefixes = set( + (r.prefix for r in routes.routes if not r.prefix.endswith('/0'))) + + exitNodes = [r.node for r in routes.routes if r.prefix.endswith( + '/0') and r.enabled] + + final = {} + for prefix in prefixes: + rrp = [x for x in routes.routes if x.prefix == prefix] + final[prefix] = sorted(rrp, key=lambda x: x.isPrimary, reverse=True) + return render_template("routes.html", + exitNodes=exitNodes, + routes=final)