From 58ebd3bc0f00c532e97e9a5571471ffab87934ba Mon Sep 17 00:00:00 2001 From: AL-LCL Date: Fri, 19 May 2023 10:39:49 +0200 Subject: GOD-VIEW --- server/web.py | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 server/web.py (limited to 'server/web.py') diff --git a/server/web.py b/server/web.py new file mode 100644 index 0000000..2cc4c3b --- /dev/null +++ b/server/web.py @@ -0,0 +1,139 @@ +''' + Handles everything related to the GUI, + exposing the necessary functionality. + Taking care of logging & middleware. + + Verified: 2021 February 8 + * Follows PEP8 + * Tested Platforms + * Windows 10 + * Third Party Modules + * eel +''' + +from server.state import ServerStatic, Dynamic +from server.helper import ServerHelper +from server.settings import Settings +from server.error import ServerError +from server.console import Console +from shared.helper import Helper +from shared.state import Static + +import traceback +import bottle +import eel + + +class Web: + + @staticmethod + @eel.expose + def clients_eel(): + return [[key, value.data] for key, value + in Dynamic.CLIENTS.items()] + + @staticmethod + @eel.expose + def session_eel(): + return list(Dynamic.SESSION) + + @staticmethod + @eel.expose + def help_eel(): + return ServerStatic.GUI_HELP + + @staticmethod + @eel.expose + def host_eel(): + return ServerStatic.HOST + + +class Gui: + + @staticmethod + @ServerError.thread + def start(): + eel.init(ServerStatic.GUI_DIR) + + if ServerStatic.WEB_GUI: + Gui.__execute_start(False) + else: + try: + Gui.__execute_start('chrome') + except EnvironmentError: + Console.log(traceback.format_exc(), + log_type=ServerStatic.TRACEBACK) + + Console.printf(Helper.join( + 'Chrome browser is not installed', + 'Converting to web GUI instance' + ), Static.INFO, newline=True) + + ServerStatic.WEB_GUI = True + Gui.__execute_start(False) + + @staticmethod + def __execute_start(mode): + eel.start(ServerStatic.GUI_PAGE, + mode=mode, + host=Static.IP, + port=ServerStatic.GUI_PORT, + app=Gui.__load_middleware(), + size=ServerStatic.WINDOW_SIZE, + close_callback=lambda *_: None) + + @staticmethod + def __load_middleware(): + bottle_instance = bottle.default_app() + bottle_instance.install(Middleware.verify) + bottle_instance.install(bottle.auth_basic(Middleware.login)) + + # CONSTANT : logout path is GUI dependant + @bottle_instance.route('/logout') + def _(): bottle.abort(401, 'Access denied') + + return bottle_instance + + +class Middleware: + + __IP_PROXY = ('REMOTE_ADDR', + 'HTTP_X_FORWARDED_FOR') + + @staticmethod + def verify(callback): + def wrapper(*args, **kwargs): + if Settings.GUI_WHITELIST: + normal, proxy = ServerHelper.keys(bottle.request.environ, + Middleware.__IP_PROXY) + gui_whitelist = Settings.GUI_WHITELIST.split(',') + + if normal in gui_whitelist or proxy in gui_whitelist: + return callback(*args, **kwargs) + else: + Console.log('Blocked: {} [{}/{}]\n'.format( + bottle.request.url, normal, proxy + ), Static.DANGER, ServerStatic.HTTP) + + bottle.abort(401, 'Access denied') + else: + return callback(*args, **kwargs) + + return wrapper + + @staticmethod + def login(username, password): + if (username == Settings.GUI_USERNAME and + password == Settings.GUI_PASSWORD): + Middleware.__resource(True) + return True + else: + Middleware.__resource(False) + return False + + @staticmethod + def __resource(success): + Console.log('Resource Request: {} [{}/{}]\n'.format( + bottle.request.url, *ServerHelper.keys(bottle.request.environ, + Middleware.__IP_PROXY) + ), Static.SUCCESS if success else Static.DANGER, ServerStatic.HTTP) -- cgit v1.2.3