Source code for samlab.dashboard.server

# Copyright 2018, National Technology & Engineering Solutions of Sandia, LLC
# (NTESS).  Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
# Government retains certain rights in this software.

import functools
import os
import uuid

import arrow
import flask
import flask_socketio
import werkzeug.routing


# Setup the web server.
application = flask.Flask(__name__)
application.secret_key = os.urandom(24)
socketio = flask_socketio.SocketIO(application, json=flask.json)

[docs]class AllowConverter(werkzeug.routing.BaseConverter): def __init__(self, map, *items): werkzeug.routing.BaseConverter.__init__(self, map) self.items = items
[docs] def to_python(self, value): if value not in self.items: raise werkzeug.routing.ValidationError() return value
application.url_map.converters["allow"] = AllowConverter
[docs]class ExcludeConverter(werkzeug.routing.BaseConverter): def __init__(self, map, *items): werkzeug.routing.BaseConverter.__init__(self, map) self.items = items
[docs] def to_python(self, value): if value in self.items: raise werkzeug.routing.ValidationError() return value
application.url_map.converters["exclude"] = ExcludeConverter ################################################################################## # Authentication and permissions sessions = {}
[docs]def require_auth(f): @functools.wraps(f) def decorated(*args, **kwargs): # Validate an existing session. if "sid" in flask.session: sid = flask.session["sid"] if sid in sessions: session = sessions[sid] if session["remote-ip"] == flask.request.remote_addr: elapsed = arrow.utcnow() - session["last-request"] if elapsed.total_seconds() < application.config["session-timeout"]: session["last-request"] = arrow.utcnow() # Handle the request return f(*args, **kwargs) del sessions[sid] del flask.session["sid"] # No existing session, so authenticate the user. if application.config["credentials"](flask.request.authorization): # Create a new session. flask.session["sid"] = uuid.uuid4() sessions[flask.session["sid"]] = { "last-request": arrow.utcnow(), "remote-ip": flask.request.remote_addr, } # Handle the request return f(*args, **kwargs) # Prompt the user for their credentials. return application.config["authentication"]() return decorated
[docs]def require_permissions(permissions): if not application.config["acl"](flask.request.authorization, permissions): flask.abort(flask.make_response(flask.jsonify(message="You don't have the necessary permissions."), 403))