mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-08 15:37:27 -06:00
Fix number of mypy mistakes
CURA-5744
This commit is contained in:
parent
3ae223334f
commit
d0fc4878c2
5 changed files with 33 additions and 20 deletions
|
@ -16,7 +16,7 @@ from cura.OAuth2.Models import AuthenticationResponse, UserProfile, OAuth2Settin
|
|||
class AuthorizationHelpers:
|
||||
"""Class containing several helpers to deal with the authorization flow."""
|
||||
|
||||
def __init__(self, settings: "OAuth2Settings"):
|
||||
def __init__(self, settings: "OAuth2Settings") -> None:
|
||||
self._settings = settings
|
||||
self._token_url = "{}/token".format(self._settings.OAUTH_SERVER_URL)
|
||||
|
||||
|
@ -25,8 +25,7 @@ class AuthorizationHelpers:
|
|||
"""Get the OAuth2 settings object."""
|
||||
return self._settings
|
||||
|
||||
def getAccessTokenUsingAuthorizationCode(self, authorization_code: str, verification_code: str)->\
|
||||
Optional["AuthenticationResponse"]:
|
||||
def getAccessTokenUsingAuthorizationCode(self, authorization_code: str, verification_code: str)-> "AuthenticationResponse":
|
||||
"""
|
||||
Request the access token from the authorization server.
|
||||
:param authorization_code: The authorization code from the 1st step.
|
||||
|
@ -42,7 +41,7 @@ class AuthorizationHelpers:
|
|||
"scope": self._settings.CLIENT_SCOPES
|
||||
}))
|
||||
|
||||
def getAccessTokenUsingRefreshToken(self, refresh_token: str) -> Optional["AuthenticationResponse"]:
|
||||
def getAccessTokenUsingRefreshToken(self, refresh_token: str) -> AuthenticationResponse:
|
||||
"""
|
||||
Request the access token from the authorization server using a refresh token.
|
||||
:param refresh_token:
|
||||
|
@ -57,7 +56,7 @@ class AuthorizationHelpers:
|
|||
}))
|
||||
|
||||
@staticmethod
|
||||
def parseTokenResponse(token_response: "requests.request") -> Optional["AuthenticationResponse"]:
|
||||
def parseTokenResponse(token_response: requests.models.Response) -> AuthenticationResponse:
|
||||
"""
|
||||
Parse the token response from the authorization server into an AuthenticationResponse object.
|
||||
:param token_response: The JSON string data response from the authorization server.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import Optional, Callable
|
||||
from typing import Optional, Callable, Tuple, Dict, Any, List
|
||||
|
||||
from http.server import BaseHTTPRequestHandler
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
|
@ -49,16 +49,17 @@ class AuthorizationRequestHandler(BaseHTTPRequestHandler):
|
|||
# This will cause the server to shut down, so we do it at the very end of the request handling.
|
||||
self.authorization_callback(token_response)
|
||||
|
||||
def _handleCallback(self, query: dict) -> ("ResponseData", Optional["AuthenticationResponse"]):
|
||||
def _handleCallback(self, query: Dict[Any, List]) -> Tuple["ResponseData", Optional["AuthenticationResponse"]]:
|
||||
"""
|
||||
Handler for the callback URL redirect.
|
||||
:param query: Dict containing the HTTP query parameters.
|
||||
:return: HTTP ResponseData containing a success page to show to the user.
|
||||
"""
|
||||
if self._queryGet(query, "code"):
|
||||
code = self._queryGet(query, "code")
|
||||
if code:
|
||||
# If the code was returned we get the access token.
|
||||
token_response = self.authorization_helpers.getAccessTokenUsingAuthorizationCode(
|
||||
self._queryGet(query, "code"), self.verification_code)
|
||||
code, self.verification_code)
|
||||
|
||||
elif self._queryGet(query, "error_code") == "user_denied":
|
||||
# Otherwise we show an error message (probably the user clicked "Deny" in the auth dialog).
|
||||
|
@ -99,6 +100,6 @@ class AuthorizationRequestHandler(BaseHTTPRequestHandler):
|
|||
self.wfile.write(data)
|
||||
|
||||
@staticmethod
|
||||
def _queryGet(query_data: dict, key: str, default=None) -> Optional[str]:
|
||||
def _queryGet(query_data: Dict[Any, List], key: str, default=None) -> Optional[str]:
|
||||
"""Helper for getting values from a pre-parsed query string"""
|
||||
return query_data.get(key, [default])[0]
|
||||
|
|
|
@ -27,7 +27,7 @@ class AuthorizationService:
|
|||
# Emit signal when authentication failed.
|
||||
onAuthenticationError = Signal()
|
||||
|
||||
def __init__(self, preferences, settings: "OAuth2Settings"):
|
||||
def __init__(self, preferences, settings: "OAuth2Settings") -> None:
|
||||
self._settings = settings
|
||||
self._auth_helpers = AuthorizationHelpers(settings)
|
||||
self._auth_url = "{}/authorize".format(self._settings.OAUTH_SERVER_URL)
|
||||
|
@ -55,7 +55,7 @@ class AuthorizationService:
|
|||
Tries to parse the JWT if all the needed data exists.
|
||||
:return: UserProfile if found, otherwise None.
|
||||
"""
|
||||
if not self._auth_data:
|
||||
if not self._auth_data or self._auth_data.access_token is None:
|
||||
# If no auth data exists, we should always log in again.
|
||||
return None
|
||||
user_data = self._auth_helpers.parseJWT(self._auth_data.access_token)
|
||||
|
@ -63,10 +63,13 @@ class AuthorizationService:
|
|||
# If the profile was found, we return it immediately.
|
||||
return user_data
|
||||
# The JWT was expired or invalid and we should request a new one.
|
||||
if self._auth_data.refresh_token is None:
|
||||
return None
|
||||
self._auth_data = self._auth_helpers.getAccessTokenUsingRefreshToken(self._auth_data.refresh_token)
|
||||
if not self._auth_data:
|
||||
if not self._auth_data or self._auth_data.access_token is None:
|
||||
# The token could not be refreshed using the refresh token. We should login again.
|
||||
return None
|
||||
|
||||
return self._auth_helpers.parseJWT(self._auth_data.access_token)
|
||||
|
||||
def getAccessToken(self) -> Optional[str]:
|
||||
|
@ -78,16 +81,23 @@ class AuthorizationService:
|
|||
# We check if we can get the user profile.
|
||||
# If we can't get it, that means the access token (JWT) was invalid or expired.
|
||||
return None
|
||||
|
||||
if self._auth_data is None:
|
||||
return None
|
||||
|
||||
return self._auth_data.access_token
|
||||
|
||||
def refreshAccessToken(self) -> None:
|
||||
"""
|
||||
Refresh the access token when it expired.
|
||||
"""
|
||||
if self._auth_data is None or self._auth_data.refresh_token is None:
|
||||
Logger.log("w", "Unable to refresh acces token, since there is no refresh token.")
|
||||
return
|
||||
self._storeAuthData(self._auth_helpers.getAccessTokenUsingRefreshToken(self._auth_data.refresh_token))
|
||||
self.onAuthStateChanged.emit(logged_in=True)
|
||||
|
||||
def deleteAuthData(self):
|
||||
def deleteAuthData(self) -> None:
|
||||
"""Delete authentication data from preferences and locally."""
|
||||
self._storeAuthData()
|
||||
self.onAuthStateChanged.emit(logged_in=False)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
import threading
|
||||
from http.server import HTTPServer
|
||||
from typing import Optional, Callable
|
||||
from typing import Optional, Callable, Any
|
||||
|
||||
# As this module is specific for Cura plugins, we can rely on these imports.
|
||||
from UM.Logger import Logger
|
||||
|
@ -16,22 +16,22 @@ from cura.OAuth2.Models import AuthenticationResponse
|
|||
|
||||
class LocalAuthorizationServer:
|
||||
def __init__(self, auth_helpers: "AuthorizationHelpers",
|
||||
auth_state_changed_callback: "Callable[[AuthenticationResponse], any]",
|
||||
daemon: bool):
|
||||
auth_state_changed_callback: "Callable[[AuthenticationResponse], Any]",
|
||||
daemon: bool) -> None:
|
||||
"""
|
||||
: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[HTTPServer]
|
||||
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
|
||||
self._auth_helpers = auth_helpers
|
||||
self._auth_state_changed_callback = auth_state_changed_callback
|
||||
self._daemon = daemon
|
||||
|
||||
def start(self, verification_code: "str") -> None:
|
||||
def start(self, verification_code: str) -> None:
|
||||
"""
|
||||
Starts the local web server to handle the authorization callback.
|
||||
:param verification_code: The verification code part of the OAuth2 client identification.
|
||||
|
@ -42,6 +42,9 @@ class LocalAuthorizationServer:
|
|||
self._web_server.setVerificationCode(verification_code)
|
||||
return
|
||||
|
||||
if self._web_server_port is None:
|
||||
raise Exception("Unable to start server without specifying the port.")
|
||||
|
||||
Logger.log("d", "Starting local web server to handle authorization callback on port %s",
|
||||
self._web_server_port)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ class BaseModel:
|
|||
|
||||
# OAuth OAuth2Settings data template.
|
||||
class OAuth2Settings(BaseModel):
|
||||
CALLBACK_PORT = None # type: Optional[str]
|
||||
CALLBACK_PORT = None # type: Optional[int]
|
||||
OAUTH_SERVER_URL = None # type: Optional[str]
|
||||
CLIENT_ID = None # type: Optional[str]
|
||||
CLIENT_SCOPES = None # type: Optional[str]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue