From 2d2f8bfbcded7d4bd8a914a0213b2e134b451f35 Mon Sep 17 00:00:00 2001 From: Arksine Date: Sat, 14 Nov 2020 15:53:42 -0500 Subject: [PATCH] authorization: fix issue cors issue when an error is detected Tornado clears the headers when an error is detected, "set_default_headers" must be overrridden so that errors are properly returned. Signed-off-by: Eric Callahan --- moonraker/app.py | 22 ++++++++++------------ moonraker/authorization.py | 34 +++++++++++++++++++++------------- moonraker/websockets.py | 7 ++++--- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/moonraker/app.py b/moonraker/app.py index 27ad0e6..a67a632 100644 --- a/moonraker/app.py +++ b/moonraker/app.py @@ -117,14 +117,15 @@ class MoonrakerApp: self.mutable_router = MutableRouter(self) app_handlers = [ (AnyMatches(), self.mutable_router), - (r"/websocket", WebSocket, {'main_app': self}), - (r"/api/version", EmulateOctoprintHandler, {'main_app': self})] + (r"/websocket", WebSocket), + (r"/api/version", EmulateOctoprintHandler)] self.app = tornado.web.Application( app_handlers, serve_traceback=debug, websocket_ping_interval=10, - websocket_ping_timeout=30) + websocket_ping_timeout=30, + parent=self) self.get_handler_delegate = self.app.get_handler_delegate # Register handlers @@ -165,7 +166,6 @@ class MoonrakerApp: f"Websocket: {', '.join(api_def.ws_methods)}") self.wsm.register_remote_handler(api_def) params = {} - params['main_app'] = self params['arg_parser'] = api_def.parser params['remote_callback'] = api_def.endpoint self.mutable_router.add_handler( @@ -182,7 +182,6 @@ class MoonrakerApp: if "http" in protocol: msg += f" - HTTP: ({' '.join(request_methods)}) {uri}" params = {} - params['main_app'] = self params['methods'] = request_methods params['arg_parser'] = api_def.parser params['callback'] = callback @@ -206,12 +205,11 @@ class MoonrakerApp: logging.info(f"Invalid file path: {file_path}") return logging.debug(f"Registering static file: ({pattern}) {file_path}") - params = {'main_app': self, 'path': file_path} + params = {'path': file_path} self.mutable_router.add_handler(pattern, FileRequestHandler, params) def register_upload_handler(self, pattern): - params = {'main_app': self} - self.mutable_router.add_handler(pattern, FileUploadHandler, params) + self.mutable_router.add_handler(pattern, FileUploadHandler, {}) def remove_handler(self, endpoint): api_def = self.api_cache.get(endpoint) @@ -260,8 +258,8 @@ class MoonrakerApp: # ***** Dynamic Handlers***** class RemoteRequestHandler(AuthorizedRequestHandler): - def initialize(self, main_app, remote_callback, arg_parser): - super(RemoteRequestHandler, self).initialize(main_app) + def initialize(self, remote_callback, arg_parser): + super(RemoteRequestHandler, self).initialize() self.remote_callback = remote_callback self.query_parser = arg_parser @@ -283,8 +281,8 @@ class RemoteRequestHandler(AuthorizedRequestHandler): self.finish({'result': result}) class LocalRequestHandler(AuthorizedRequestHandler): - def initialize(self, main_app, callback, methods, arg_parser): - super(LocalRequestHandler, self).initialize(main_app) + def initialize(self, callback, methods, arg_parser): + super(LocalRequestHandler, self).initialize() self.callback = callback self.methods = methods self.query_parser = arg_parser diff --git a/moonraker/authorization.py b/moonraker/authorization.py index 232796d..808fc36 100644 --- a/moonraker/authorization.py +++ b/moonraker/authorization.py @@ -207,17 +207,22 @@ class Authorization: self.prune_handler.stop() class AuthorizedRequestHandler(tornado.web.RequestHandler): - def initialize(self, main_app): - self.server = main_app.get_server() - self.auth = main_app.get_auth() - self.wsm = main_app.get_websocket_manager() - self.cors_enabled = False + def initialize(self): + app = self.settings['parent'] + self.server = app.get_server() + self.auth = app.get_auth() + self.wsm = app.get_websocket_manager() + + def set_default_headers(self): + origin = self.request.headers.get("Origin") + # it is necessary to look up the parent app here, + # as initialize() may not yet be called + auth = self.settings['parent'].get_auth() + self.cors_enabled = auth.check_cors(origin, self) def prepare(self): if not self.auth.check_authorized(self.request): raise tornado.web.HTTPError(401, "Unauthorized") - origin = self.request.headers.get("Origin") - self.cors_enabled = self.auth.check_cors(origin, self) def options(self, *args, **kwargs): # Enable CORS if configured @@ -244,17 +249,20 @@ class AuthorizedRequestHandler(tornado.web.RequestHandler): # Due to the way Python treats multiple inheritance its best # to create a separate authorized handler for serving files class AuthorizedFileHandler(tornado.web.StaticFileHandler): - def initialize(self, main_app, path, default_filename=None): + def initialize(self, path, default_filename=None): super(AuthorizedFileHandler, self).initialize(path, default_filename) - self.server = main_app.get_server() - self.auth = main_app.get_auth() - self.cors_enabled = False + app = self.settings['parent'] + self.server = app.get_server() + self.auth = app.get_auth() + + def set_default_headers(self): + origin = self.request.headers.get("Origin") + auth = self.settings['parent'].get_auth() + self.cors_enabled = auth.check_cors(origin, self) def prepare(self): if not self.auth.check_authorized(self.request): raise tornado.web.HTTPError(401, "Unauthorized") - origin = self.request.headers.get("Origin") - self.cors_enabled = self.auth.check_cors(origin, self) def options(self, *args, **kwargs): # Enable CORS if configured diff --git a/moonraker/websockets.py b/moonraker/websockets.py index d5b1636..4e4f2fa 100644 --- a/moonraker/websockets.py +++ b/moonraker/websockets.py @@ -273,9 +273,10 @@ class WebsocketManager: self.websockets = {} class WebSocket(WebSocketHandler): - def initialize(self, main_app): - self.auth = main_app.get_auth() - self.wsm = main_app.get_websocket_manager() + def initialize(self): + app = self.settings['parent'] + self.auth = app.get_auth() + self.wsm = app.get_websocket_manager() self.rpc = self.wsm.rpc self.uid = id(self)