Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions descope/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,22 @@ def refresh_token(self, refresh_token: str) -> dict:
resp = response.json()
return self._generate_auth_info(resp, refresh_token)

def exchange_access_key(self, access_key: str) -> dict:
uri = Auth._compose_exchange_access_key_url()
server_response = self.do_get(uri, None, None, access_key)

json = server_response.json()
response = {
"keyId": json.get("keyId", ""),
"exp": json.get("expiration", 0),
}

jwt = json.get("sessionJwt", "")
if jwt:
response[SESSION_TOKEN_NAME] = self._validate_token(jwt)

return response

@staticmethod
def _compose_exchange_params(code: str) -> dict:
return {"code": code}
Expand Down Expand Up @@ -460,3 +476,7 @@ def _validate_and_load_tokens(self, session_token: str, refresh_token: str) -> d
@staticmethod
def _compose_refresh_token_url() -> str:
return EndpointsV1.refreshTokenPath

@staticmethod
def _compose_exchange_access_key_url() -> str:
return EndpointsV1.exchangeAuthAccessKeyPath
3 changes: 3 additions & 0 deletions descope/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class EndpointsV1:
logoutPath = "/v1/auth/logoutall"
mePath = "/v1/auth/me"

# accesskey
exchangeAuthAccessKeyPath = "/v1/auth/accesskey/exchange"

# otp
signUpAuthOTPPath = "/v1/auth/otp/signup"
signInAuthOTPPath = "/v1/auth/otp/signin"
Expand Down
15 changes: 15 additions & 0 deletions descope/descope_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,18 @@ def refresh_token(self, refresh_token: str) -> dict:
AuthException: Exception is raised if session is not authorized or another error occurs
"""
return self._auth.refresh_token(refresh_token)

def exchange_access_key(self, access_key: str) -> dict:
"""
Return a new session token for the given access key

Args:
access_key (str): The access key

Return value (dict): returns the session token from the server together with the expiry and key id
(sessionToken:dict, keyId:str, expiration:int)

Raise:
AuthException: Exception is raised if access key is not valid or another error occurs
"""
return self._auth.exchange_access_key(access_key)
13 changes: 13 additions & 0 deletions tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,19 @@ def test_refresh_token(self):
dummy_refresh_token,
)

def test_exchange_access_key(self):
dummy_access_key = "dummy access key"
auth = Auth(self.dummy_project_id, self.public_key_dict)

# Test fail flow
with patch("requests.get") as mock_request:
mock_request.return_value.ok = False
self.assertRaises(
AuthException,
auth.exchange_access_key,
dummy_access_key,
)


if __name__ == "__main__":
unittest.main()