From 382e693fc85bd015725bacdab36be9d5cf7287b1 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 3 Sep 2014 00:05:06 -0600 Subject: [PATCH] Added authentication handler for basic auth check --- gns3server/handlers/auth_handler.py | 71 ++++++++++++++++++++++++++ gns3server/handlers/version_handler.py | 4 +- gns3server/server.py | 18 +++++-- 3 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 gns3server/handlers/auth_handler.py diff --git a/gns3server/handlers/auth_handler.py b/gns3server/handlers/auth_handler.py new file mode 100644 index 00000000..0bedb40b --- /dev/null +++ b/gns3server/handlers/auth_handler.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2014 GNS3 Technologies Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Simple file upload & listing handler. +""" + + +import os +import tornado.web + +import logging +log = logging.getLogger(__name__) + +class GNS3BaseHandler(tornado.web.RequestHandler): + def get_current_user(self): + user = self.get_secure_cookie("user") + if not user: + return None + + if self.settings['required_user'] == user.decode("utf-8"): + return user + +class LoginHandler(tornado.web.RequestHandler): + def get(self): + self.write('
' + 'Name: ' + 'Password: ' + '' + '
') + + try: + redirect_to = self.get_argument("next") + self.set_secure_cookie("login_success_redirect_to", redirect_to) + except tornado.web.MissingArgumentError: + pass + + def post(self): + + user = self.get_argument("name") + password = self.get_argument("password") + + if self.settings['required_user'] == user and self.settings['required_pass'] == password: + self.set_secure_cookie("user", user) + auth_status = "successful" + else: + self.set_secure_cookie("user", "None") + auth_status = "failure" + + log.info("Authentication attempt %s: %s" %(auth_status, user)) + + try: + redirect_to = self.get_secure_cookie("login_success_redirect_to") + except tornado.web.MissingArgumentError: + redirect_to = "/" + + self.redirect(redirect_to) \ No newline at end of file diff --git a/gns3server/handlers/version_handler.py b/gns3server/handlers/version_handler.py index c85aa31c..3b338bd2 100644 --- a/gns3server/handlers/version_handler.py +++ b/gns3server/handlers/version_handler.py @@ -16,11 +16,13 @@ # along with this program. If not, see . import tornado.web +from .auth_handler import GNS3BaseHandler from ..version import __version__ -class VersionHandler(tornado.web.RequestHandler): +class VersionHandler(GNS3BaseHandler): + @tornado.web.authenticated def get(self): response = {'version': __version__} self.write(response) diff --git a/gns3server/server.py b/gns3server/server.py index 2bc4a893..275123ad 100644 --- a/gns3server/server.py +++ b/gns3server/server.py @@ -34,12 +34,15 @@ import tornado.web import tornado.autoreload import pkg_resources from os.path import expanduser +import base64 +import uuid from pkg_resources import parse_version from .config import Config from .handlers.jsonrpc_websocket import JSONRPCWebSocket from .handlers.version_handler import VersionHandler from .handlers.file_upload_handler import FileUploadHandler +from .handlers.auth_handler import LoginHandler from .builtins.server_version import server_version from .builtins.interfaces import interfaces from .modules import MODULES @@ -47,12 +50,12 @@ from .modules import MODULES import logging log = logging.getLogger(__name__) - class Server(object): # built-in handlers handlers = [(r"/version", VersionHandler), - (r"/upload", FileUploadHandler)] + (r"/upload", FileUploadHandler), + (r"/login", LoginHandler)] def __init__(self, host, port, ipc=False): @@ -160,6 +163,15 @@ class Server(object): Starts the Tornado web server and ZeroMQ server. """ + # FIXME: debug mode! + settings = { + "debug":True, + "cookie_secret": base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes), + "login_url": "/login", + "required_user" : "test123", + "required_pass" : "test456", + } + router = self._create_zmq_router() # Add our JSON-RPC Websocket handler to Tornado self.handlers.extend([(r"/", JSONRPCWebSocket, dict(zmq_router=router))]) @@ -169,7 +181,7 @@ class Server(object): templates_dir = pkg_resources.resource_filename("gns3server", "templates") tornado_app = tornado.web.Application(self.handlers, template_path=templates_dir, - debug=True) # FIXME: debug mode! + **settings) # FIXME: debug mode! try: print("Starting server on {}:{} (Tornado v{}, PyZMQ v{}, ZMQ v{})".format(self._host,