@@ -626,7 +626,7 @@ def username(self, username: Optional[str]) -> None:
626
626
if self .session is not None :
627
627
access_token = self .token_backend .get_access_token (username = username )
628
628
if access_token is not None :
629
- self .session . headers . update ({ "Authorization" : f"Bearer { access_token } " } )
629
+ self .update_session_auth_header ( access_token = access_token [ "secret" ] )
630
630
else :
631
631
# if we can't find an access token for the current user, then remove the auth header from the session
632
632
if "Authorization" in self .session .headers :
@@ -806,8 +806,7 @@ def request_token(
806
806
807
807
# Update the session headers if the session exists
808
808
if self .session is not None :
809
- access_token = result ["access_token" ]
810
- self .session .headers .update ({"Authorization" : f"Bearer { access_token } " })
809
+ self .update_session_auth_header (access_token = result ["access_token" ])
811
810
812
811
if store_token :
813
812
self .token_backend .save_token ()
@@ -878,80 +877,92 @@ def get_naive_session(self) -> Session:
878
877
879
878
return naive_session
880
879
881
- def refresh_token (self ) -> bool :
882
- """
883
- Refresh the OAuth authorization token.
884
- This will be called automatically when the access token
885
- expires, however, you can manually call this method to
886
- request a new refresh token.
887
-
888
- :return bool: Success / Failure
889
- """
890
- if self .session is None :
891
- self .session = self .get_session (load_token = True )
880
+ def update_session_auth_header (self , access_token : Optional [str ] = None ) -> None :
881
+ """ Will update the internal request session auth header with an access token"""
882
+ if access_token is None :
883
+ # try to get the access_token from the backend
884
+ access_token_dict = self .token_backend .get_access_token (
885
+ username = self .username
886
+ ) or {}
887
+ access_token = access_token_dict .get ("secret" )
888
+ if access_token is None :
889
+ # at this point this is an error.
890
+ raise RuntimeError ("Tried to update the session auth header but no access "
891
+ "token was provided nor found in the token backend." )
892
+ log .debug ("New access token set into session auth header" )
893
+ self .session .headers .update (
894
+ {"Authorization" : f"Bearer { access_token } " }
895
+ )
892
896
897
+ def _try_refresh_token (self ) -> bool :
898
+ """Internal method to check try to update the refresh token"""
899
+ # first we check if we can acquire a new refresh token
893
900
token_refreshed = False
894
-
895
901
if (
896
902
self .token_backend .token_is_long_lived (username = self .username )
897
903
or self .auth_flow_type == "credentials"
898
904
):
899
- should_rt = self .token_backend .should_refresh_token (self )
905
+ # then we ask the token backend if we should refresh the token
906
+ log .debug ("Asking the token backend if we should refresh the token" )
907
+ should_rt = self .token_backend .should_refresh_token (con = self , username = self .username )
908
+ log .debug (f"Token Backend answered { should_rt } " )
900
909
if should_rt is True :
901
910
# The backend has checked that we can refresh the token
902
- log .debug ("Refreshing access token" )
903
-
904
- # This will set the connection scopes from the scopes set in the stored refresh or access token
905
- scopes = self .token_backend .get_token_scopes (
906
- username = self .username , remove_reserved = True
907
- )
908
-
909
- result = self .msal_client .acquire_token_silent_with_error (
910
- scopes = scopes ,
911
- account = self .msal_client .get_accounts (username = self .username )[0 ],
912
- )
913
- if result is None :
914
- raise RuntimeError ("There is no refresh token to refresh" )
915
- elif "error" in result :
916
- raise RuntimeError (
917
- f'Refresh token operation failed: { result ["error" ]} '
918
- )
919
- elif "access_token" in result :
920
- # refresh done, update authorization header
921
- token_refreshed = True
922
- self .session .headers .update (
923
- {"Authorization" : f'Bearer { result ["access_token" ]} ' }
924
- )
925
- log .debug (
926
- f"New oauth token fetched by refresh method for username: { self .username } "
927
- )
911
+ return self .refresh_token ()
928
912
elif should_rt is False :
929
- # the token was refreshed by another instance and updated into this instance,
930
- # so: update the session token and retry the request again
931
- access_token = self .token_backend .get_access_token (
932
- username = self .username
933
- )
934
- if access_token :
935
- self .session .headers .update (
936
- {"Authorization" : f'Bearer { access_token ["secret" ]} ' }
937
- )
938
- else :
939
- raise RuntimeError (
940
- "Can't get access token refreshed by another instance."
941
- )
913
+ # The token was refreshed by another instance and 'should_refresh_token' has updated it into the
914
+ # backend cache. So, update the session token and retry the request again
915
+ self .update_session_auth_header ()
916
+ return True
942
917
else :
943
- # the refresh was performed by the token backend.
944
- pass
918
+ # the refresh was performed by the token backend, and it has updated all the data
919
+ return True
945
920
else :
946
921
log .error (
947
- ' You can not refresh an access token that has no " refresh_token" available.'
948
- ' Include " offline_access" permission to get a " refresh_token"'
922
+ " You can not refresh an access token that has no ' refresh_token' available."
923
+ " Include ' offline_access' permission to get a ' refresh_token'."
949
924
)
950
925
return False
951
926
952
- if token_refreshed and self .store_token_after_refresh :
953
- self .token_backend .save_token ()
954
- return True
927
+ def refresh_token (self ) -> bool :
928
+ """
929
+ Refresh the OAuth authorization token.
930
+ This will be called automatically when the access token
931
+ expires, however, you can manually call this method to
932
+ request a new refresh token.
933
+
934
+ :return bool: Success / Failure
935
+ """
936
+ log .debug ("Refreshing access token" )
937
+
938
+ if self .session is None :
939
+ self .session = self .get_session (load_token = True )
940
+
941
+ # This will set the connection scopes from the scopes set in the stored refresh or access token
942
+ scopes = self .token_backend .get_token_scopes (
943
+ username = self .username , remove_reserved = True
944
+ )
945
+
946
+ # call the refresh!
947
+ result = self .msal_client .acquire_token_silent_with_error (
948
+ scopes = scopes ,
949
+ account = self .msal_client .get_accounts (username = self .username )[0 ],
950
+ )
951
+ if result is None :
952
+ raise RuntimeError ("There is no refresh token to refresh" )
953
+ elif "error" in result :
954
+ raise RuntimeError (f"Refresh token operation failed: { result ['error' ]} " )
955
+ elif "access_token" in result :
956
+ log .debug (
957
+ f"New oauth token fetched by refresh method for username: { self .username } "
958
+ )
959
+ # refresh done, update authorization header
960
+ self .update_session_auth_header (access_token = result ["access_token" ])
961
+
962
+ if self .store_token_after_refresh :
963
+ self .token_backend .save_token ()
964
+ return True
965
+ return False
955
966
956
967
def _check_delay (self ) -> None :
957
968
"""Checks if a delay is needed between requests and sleeps if True"""
@@ -1117,7 +1128,8 @@ def oauth_request(self, url: str, method: str, **kwargs) -> Response:
1117
1128
except TokenExpiredError as e :
1118
1129
# refresh and try again the request!
1119
1130
try :
1120
- if self .refresh_token ():
1131
+ # try to refresh the token and/or follow token backend answer on 'should_refresh_token'
1132
+ if self ._try_refresh_token ():
1121
1133
return self ._internal_request (self .session , url , method , ** kwargs )
1122
1134
else :
1123
1135
raise e
0 commit comments