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.authorize_admins('default') def token(): user_session = UserSession(session) # return jsonify(user_session.userinfo) return jsonify(access_token=user_session.access_token, id_token=user_session.id_token, userinfo=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/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 = sorted(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/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)