Browse Source

Calculate expiry date to determine if token refresh is needed

ChrisTerBeke 6 years ago
parent
commit
05c4b6012e

+ 0 - 1
cura/API/Account.py

@@ -57,7 +57,6 @@ class Account(QObject):
 
     def initialize(self) -> None:
         self._authorization_service.initialize(self._application.getPreferences())
-
         self._authorization_service.onAuthStateChanged.connect(self._onLoginStateChanged)
         self._authorization_service.onAuthenticationError.connect(self._onLoginStateChanged)
         self._authorization_service.loadAuthDataFromPreferences()

+ 6 - 3
cura/OAuth2/AuthorizationHelpers.py

@@ -1,10 +1,11 @@
 # Copyright (c) 2018 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
+from datetime import datetime
 import json
 import random
 from hashlib import sha512
 from base64 import b64encode
-from typing import Dict, Optional
+from typing import Optional
 
 import requests
 
@@ -75,7 +76,8 @@ class AuthorizationHelpers:
                                       access_token=token_data["access_token"],
                                       refresh_token=token_data["refresh_token"],
                                       expires_in=token_data["expires_in"],
-                                      scope=token_data["scope"])
+                                      scope=token_data["scope"],
+                                      received_at=datetime.now())
 
     #   Calls the authentication API endpoint to get the token data.
     #   \param access_token: The encoded JWT token.
@@ -99,7 +101,8 @@ class AuthorizationHelpers:
         return UserProfile(
             user_id = user_data["user_id"],
             username = user_data["username"],
-            profile_image_url = user_data.get("profile_image_url", "")
+            profile_image_url = user_data.get("profile_image_url", ""),
+            generated_at = datetime.now()
         )
 
     @staticmethod

+ 0 - 1
cura/OAuth2/AuthorizationRequestHandler.py

@@ -9,7 +9,6 @@ from cura.OAuth2.Models import AuthenticationResponse, ResponseData, HTTP_STATUS
 
 if TYPE_CHECKING:
     from cura.OAuth2.Models import ResponseStatus
-    from cura.OAuth2.AuthorizationHelpers import AuthorizationHelpers
 
 
 #   This handler handles all HTTP requests on the local web server.

+ 11 - 9
cura/OAuth2/AuthorizationService.py

@@ -2,6 +2,7 @@
 # Cura is released under the terms of the LGPLv3 or higher.
 import json
 import webbrowser
+from datetime import timedelta, datetime
 from typing import Optional, TYPE_CHECKING
 from urllib.parse import urlencode
 import requests.exceptions
@@ -51,11 +52,12 @@ class AuthorizationService:
     #   \return UserProfile if a user is logged in, None otherwise.
     #   \sa _parseJWT
     def getUserProfile(self) -> Optional["UserProfile"]:
-        try:
-            self._user_profile = self._parseJWT()
-        except requests.exceptions.ConnectionError:
-            # Unable to get connection, can't login.
-            return None
+        if not self._user_profile:
+            try:
+                self._user_profile = self._parseJWT()
+            except requests.exceptions.ConnectionError:
+                # Unable to get connection, can't login.
+                return None
 
         if not self._user_profile and self._auth_data:
             # If there is still no user profile from the JWT, we have to log in again.
@@ -87,10 +89,10 @@ class AuthorizationService:
 
     #   Get the access token as provided by the response data.
     def getAccessToken(self) -> Optional[str]:
-        if not self.getUserProfile():
-            # 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.
-            # In that case we try to refresh the access token.
+        # Check if the current access token is expired and refresh it if that is the case.
+        creation_date = self._auth_data.received_at or datetime(2000, 1, 1)
+        expiry_date = creation_date + timedelta(seconds = float(self._auth_data.expires_in))
+        if datetime.now() > expiry_date:
             self.refreshAccessToken()
 
         if self._auth_data is None:

+ 2 - 1
cura/OAuth2/Models.py

@@ -1,6 +1,6 @@
 # Copyright (c) 2018 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
-
+from datetime import datetime
 from typing import Optional
 
 
@@ -38,6 +38,7 @@ class AuthenticationResponse(BaseModel):
     expires_in = None  # type: Optional[str]
     scope = None  # type: Optional[str]
     err_message = None  # type: Optional[str]
+    received_at = None  # type: Optional[datetime]
 
 
 # Response status template.