diff options
Diffstat (limited to 'cura/OAuth2/LocalAuthorizationServer.py')
-rw-r--r-- | cura/OAuth2/LocalAuthorizationServer.py | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/cura/OAuth2/LocalAuthorizationServer.py b/cura/OAuth2/LocalAuthorizationServer.py index 0e4e491e46..ac14b00985 100644 --- a/cura/OAuth2/LocalAuthorizationServer.py +++ b/cura/OAuth2/LocalAuthorizationServer.py @@ -1,6 +1,6 @@ # Copyright (c) 2020 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. - +import sys import threading from typing import Any, Callable, Optional, TYPE_CHECKING @@ -20,18 +20,23 @@ if TYPE_CHECKING: class LocalAuthorizationServer: - ## The local LocalAuthorizationServer takes care of the oauth2 callbacks. - # Once the flow is completed, this server should be closed down again by - # calling stop() - # \param auth_helpers An instance of the authorization helpers class. - # \param auth_state_changed_callback A callback function to be called when - # the authorization state changes. - # \param daemon Whether the server thread should be run in daemon mode. - # Note: Daemon threads are abruptly stopped at shutdown. Their resources - # (e.g. open files) may never be released. def __init__(self, auth_helpers: "AuthorizationHelpers", auth_state_changed_callback: Callable[["AuthenticationResponse"], Any], daemon: bool) -> None: + """The local LocalAuthorizationServer takes care of the oauth2 callbacks. + + Once the flow is completed, this server should be closed down again by calling + :py:meth:`cura.OAuth2.LocalAuthorizationServer.LocalAuthorizationServer.stop()` + + :param auth_helpers: An instance of the authorization helpers class. + :param auth_state_changed_callback: A callback function to be called when the authorization state changes. + :param daemon: Whether the server thread should be run in daemon mode. + + .. note:: + + Daemon threads are abruptly stopped at shutdown. Their resources (e.g. open files) may never be released. + """ + self._web_server = None # type: Optional[AuthorizationRequestServer] self._web_server_thread = None # type: Optional[threading.Thread] self._web_server_port = auth_helpers.settings.CALLBACK_PORT @@ -39,10 +44,13 @@ class LocalAuthorizationServer: self._auth_state_changed_callback = auth_state_changed_callback self._daemon = daemon - ## Starts the local web server to handle the authorization callback. - # \param verification_code The verification code part of the OAuth2 client identification. - # \param state The unique state code (to ensure that the request we get back is really from the server. def start(self, verification_code: str, state: str) -> None: + """Starts the local web server to handle the authorization callback. + + :param verification_code: The verification code part of the OAuth2 client identification. + :param state: The unique state code (to ensure that the request we get back is really from the server. + """ + if self._web_server: # If the server is already running (because of a previously aborted auth flow), we don't have to start it. # We still inject the new verification code though. @@ -63,18 +71,37 @@ class LocalAuthorizationServer: self._web_server.setState(state) # Start the server on a new thread. - self._web_server_thread = threading.Thread(None, self._web_server.serve_forever, daemon = self._daemon) + self._web_server_thread = threading.Thread(None, self._serve_forever, daemon = self._daemon) self._web_server_thread.start() - ## Stops the web server if it was running. It also does some cleanup. def stop(self) -> None: + """Stops the web server if it was running. It also does some cleanup.""" + Logger.log("d", "Stopping local oauth2 web server...") if self._web_server: try: - self._web_server.server_close() + self._web_server.shutdown() except OSError: # OS error can happen if the socket was already closed. We really don't care about that case. pass self._web_server = None self._web_server_thread = None + + def _serve_forever(self) -> None: + """ + If the platform is windows, this function calls the serve_forever function of the _web_server, catching any + OSErrors that may occur in the thread, thus making the reported message more log-friendly. + If it is any other platform, it just calls the serve_forever function immediately. + + :return: None + """ + if self._web_server: + if sys.platform == "win32": + try: + self._web_server.serve_forever() + except OSError as e: + Logger.warning(str(e)) + else: + # Leave the default behavior in non-windows platforms + self._web_server.serve_forever() |