From 7e60ac14e7cb020b501bd1be2aac6785a8a11be8 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 1 Dec 2022 01:41:17 +0300 Subject: [PATCH 1/5] Add support for sync credentials --- .../azure_identity_access_token_provider.py | 27 +++++++++++++------ .../azure_identity_authentication_provider.py | 5 ++-- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/kiota_authentication_azure/azure_identity_access_token_provider.py b/kiota_authentication_azure/azure_identity_access_token_provider.py index 5f5ad5c..cdf8914 100644 --- a/kiota_authentication_azure/azure_identity_access_token_provider.py +++ b/kiota_authentication_azure/azure_identity_access_token_provider.py @@ -1,10 +1,14 @@ -from typing import TYPE_CHECKING, Dict, List, Optional +import inspect +from typing import TYPE_CHECKING, Dict, List, Optional, Union from urllib.parse import urlparse +from azure.core.credentials import TokenCredential +from azure.core.credentials_async import AsyncTokenCredential from kiota_abstractions.authentication import AccessTokenProvider, AllowedHostsValidator -if TYPE_CHECKING: - from azure.core.credentials_async import AsyncTokenCredential +# if TYPE_CHECKING: +# from azure.core.credentials import TokenCredential +# from azure.core.credentials_async import AsyncTokenCredential class AzureIdentityAccessTokenProvider(AccessTokenProvider): @@ -13,7 +17,7 @@ class AzureIdentityAccessTokenProvider(AccessTokenProvider): def __init__( self, - credentials: "AsyncTokenCredential", + credentials: Union[TokenCredential, AsyncTokenCredential], options: Optional[Dict], scopes: List[str] = ['https://graph.microsoft.com/.default'], allowed_hosts: List[str] = [ @@ -45,11 +49,18 @@ async def get_authorization_token(self, uri: str) -> str: parsed_url = urlparse(uri) if not parsed_url.scheme == 'https': raise Exception("Only https is supported") + #async credentials + if inspect.iscoroutinefunction(self._credentials.get_token): + if self._options: + result = await self._credentials.get_token(*self._scopes, **self._options) + result = await self._credentials.get_token(*self._scopes) + await self._credentials.close() #type: ignore + # sync credentials + else: + if self._options: + result = self._credentials.get_token(*self._scopes, **self._options) + result = self._credentials.get_token(*self._scopes) - if self._options: - result = await self._credentials.get_token(*self._scopes, **self._options) - result = await self._credentials.get_token(*self._scopes) - await self._credentials.close() if result and result.token: return result.token return "" diff --git a/kiota_authentication_azure/azure_identity_authentication_provider.py b/kiota_authentication_azure/azure_identity_authentication_provider.py index 1414025..c2cfca4 100644 --- a/kiota_authentication_azure/azure_identity_authentication_provider.py +++ b/kiota_authentication_azure/azure_identity_authentication_provider.py @@ -1,10 +1,11 @@ -from typing import TYPE_CHECKING, Dict, List, Optional +from typing import TYPE_CHECKING, Dict, List, Optional, Union from kiota_abstractions.authentication import BaseBearerTokenAuthenticationProvider from .azure_identity_access_token_provider import AzureIdentityAccessTokenProvider if TYPE_CHECKING: + from azure.core.credentials import TokenCredential from azure.core.credentials_async import AsyncTokenCredential @@ -12,7 +13,7 @@ class AzureIdentityAuthenticationProvider(BaseBearerTokenAuthenticationProvider) def __init__( self, - credentials: "AsyncTokenCredential", + credentials: Union["TokenCredential", "AsyncTokenCredential"], options: Optional[Dict] = None, scopes: List[str] = ['https://graph.microsoft.com/.default'], allowed_hosts: List[str] = [ From d0d6009ee467c00705685bbf88304b2a6cd1a602 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 1 Dec 2022 01:41:35 +0300 Subject: [PATCH 2/5] Update tests --- tests/helpers.py | 7 ++++- ...st_azure_identity_access_token_provider.py | 27 ++++++++++++------- ..._azure_identity_authentication_provider.py | 7 ++--- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/tests/helpers.py b/tests/helpers.py index 9a1f757..e99ea40 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -6,7 +6,12 @@ class DummyToken: token: str -class DummyAzureTokenCredential(): +class DummySyncAzureTokenCredential(): + + def get_token(self, *args): + return DummyToken(token="This is a dummy token") + +class DummyAsyncAzureTokenCredential(): async def get_token(self, *args): return DummyToken(token="This is a dummy token") diff --git a/tests/test_azure_identity_access_token_provider.py b/tests/test_azure_identity_access_token_provider.py index 879c1cb..9a75fee 100644 --- a/tests/test_azure_identity_access_token_provider.py +++ b/tests/test_azure_identity_access_token_provider.py @@ -4,8 +4,7 @@ from kiota_authentication_azure.azure_identity_access_token_provider import ( AzureIdentityAccessTokenProvider, ) - -from .helpers import DummyAzureTokenCredential +from .helpers import DummyAsyncAzureTokenCredential, DummySyncAzureTokenCredential def test_invalid_instantiation_without_credentials(): @@ -14,17 +13,19 @@ def test_invalid_instantiation_without_credentials(): def test_valid_instantiation_without_options(): - token_provider = AzureIdentityAccessTokenProvider(DummyAzureTokenCredential(), None) + token_provider = AzureIdentityAccessTokenProvider(DummyAsyncAzureTokenCredential(), None) assert not token_provider._options def test_invalid_instatiation_without_scopes(): with pytest.raises(Exception): - token_provider = AzureIdentityAccessTokenProvider(DummyAzureTokenCredential(), None, None) + token_provider = AzureIdentityAccessTokenProvider( + DummyAsyncAzureTokenCredential(), None, None + ) def test_get_allowed_hosts_validator(): - token_provider = AzureIdentityAccessTokenProvider(DummyAzureTokenCredential(), None) + token_provider = AzureIdentityAccessTokenProvider(DummySyncAzureTokenCredential(), None) validator = token_provider.get_allowed_hosts_validator() hosts = validator.get_allowed_hosts() assert isinstance(validator, AllowedHostsValidator) @@ -36,9 +37,17 @@ def test_get_allowed_hosts_validator(): @pytest.mark.asyncio -async def test_get_authorization_token(): +async def test_get_authorization_token_async(): + + token_provider = AzureIdentityAccessTokenProvider(DummyAsyncAzureTokenCredential(), None) + token = await token_provider.get_authorization_token('https://graph.microsoft.com') + assert token == "This is a dummy token" + + +@pytest.mark.asyncio +async def test_get_authorization_token_sync(): - token_provider = AzureIdentityAccessTokenProvider(DummyAzureTokenCredential(), None) + token_provider = AzureIdentityAccessTokenProvider(DummySyncAzureTokenCredential(), None) token = await token_provider.get_authorization_token('https://graph.microsoft.com') assert token == "This is a dummy token" @@ -46,7 +55,7 @@ async def test_get_authorization_token(): @pytest.mark.asyncio async def test_get_authorization_token_invalid_url(): - token_provider = AzureIdentityAccessTokenProvider(DummyAzureTokenCredential(), None) + token_provider = AzureIdentityAccessTokenProvider(DummyAsyncAzureTokenCredential(), None) token = await token_provider.get_authorization_token('https://example.com') assert token == "" @@ -54,5 +63,5 @@ async def test_get_authorization_token_invalid_url(): @pytest.mark.asyncio async def test_get_authorization_token_invalid_scheme(): with pytest.raises(Exception): - token_provider = AzureIdentityAccessTokenProvider(DummyAzureTokenCredential(), None) + token_provider = AzureIdentityAccessTokenProvider(DummySyncAzureTokenCredential(), None) token = await token_provider.get_authorization_token('http://graph.microsoft.com') diff --git a/tests/test_azure_identity_authentication_provider.py b/tests/test_azure_identity_authentication_provider.py index ef65ddc..e9a98f5 100644 --- a/tests/test_azure_identity_authentication_provider.py +++ b/tests/test_azure_identity_authentication_provider.py @@ -1,12 +1,9 @@ import pytest from kiota_abstractions.request_information import RequestInformation - from kiota_authentication_azure.azure_identity_authentication_provider import ( AzureIdentityAuthenticationProvider, ) - -from .helpers import DummyAzureTokenCredential - +from .helpers import DummyAsyncAzureTokenCredential, DummySyncAzureTokenCredential def test_invalid_instantiation_without_credentials(): with pytest.raises(Exception): @@ -15,7 +12,7 @@ def test_invalid_instantiation_without_credentials(): @pytest.mark.asyncio async def test_valid_instantiation_without_options(): - auth_provider = AzureIdentityAuthenticationProvider(DummyAzureTokenCredential()) + auth_provider = AzureIdentityAuthenticationProvider(DummyAsyncAzureTokenCredential()) request_info = RequestInformation() request_info.url = "https://graph.microsoft.com" await auth_provider.authenticate_request(request_info) From f91a116406c8a22536bc546822f455109f4b248b Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 1 Dec 2022 01:41:49 +0300 Subject: [PATCH 3/5] Bump package version --- kiota_authentication_azure/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kiota_authentication_azure/_version.py b/kiota_authentication_azure/_version.py index 31d99c0..8e3d668 100644 --- a/kiota_authentication_azure/_version.py +++ b/kiota_authentication_azure/_version.py @@ -1 +1 @@ -VERSION: str = '0.1.1' +VERSION: str = '0.2.0' From f49448c0499d69ccab5a0818676059d604b9cbf2 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 1 Dec 2022 01:43:10 +0300 Subject: [PATCH 4/5] Code formattng --- .../azure_identity_access_token_provider.py | 2 +- tests/helpers.py | 1 + tests/test_azure_identity_authentication_provider.py | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/kiota_authentication_azure/azure_identity_access_token_provider.py b/kiota_authentication_azure/azure_identity_access_token_provider.py index cdf8914..0b9b104 100644 --- a/kiota_authentication_azure/azure_identity_access_token_provider.py +++ b/kiota_authentication_azure/azure_identity_access_token_provider.py @@ -54,7 +54,7 @@ async def get_authorization_token(self, uri: str) -> str: if self._options: result = await self._credentials.get_token(*self._scopes, **self._options) result = await self._credentials.get_token(*self._scopes) - await self._credentials.close() #type: ignore + await self._credentials.close() #type: ignore # sync credentials else: if self._options: diff --git a/tests/helpers.py b/tests/helpers.py index e99ea40..82e84e4 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -11,6 +11,7 @@ class DummySyncAzureTokenCredential(): def get_token(self, *args): return DummyToken(token="This is a dummy token") + class DummyAsyncAzureTokenCredential(): async def get_token(self, *args): diff --git a/tests/test_azure_identity_authentication_provider.py b/tests/test_azure_identity_authentication_provider.py index e9a98f5..f929572 100644 --- a/tests/test_azure_identity_authentication_provider.py +++ b/tests/test_azure_identity_authentication_provider.py @@ -5,6 +5,7 @@ ) from .helpers import DummyAsyncAzureTokenCredential, DummySyncAzureTokenCredential + def test_invalid_instantiation_without_credentials(): with pytest.raises(Exception): auth_provider = AzureIdentityAuthenticationProvider(None) From 58fd36099b27e0f18ab593f86e606515ff688c98 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 1 Dec 2022 01:51:53 +0300 Subject: [PATCH 5/5] Remove commented code --- .../azure_identity_access_token_provider.py | 4 ---- tests/test_azure_identity_access_token_provider.py | 1 + tests/test_azure_identity_authentication_provider.py | 2 ++ 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/kiota_authentication_azure/azure_identity_access_token_provider.py b/kiota_authentication_azure/azure_identity_access_token_provider.py index 0b9b104..32d0fd4 100644 --- a/kiota_authentication_azure/azure_identity_access_token_provider.py +++ b/kiota_authentication_azure/azure_identity_access_token_provider.py @@ -6,10 +6,6 @@ from azure.core.credentials_async import AsyncTokenCredential from kiota_abstractions.authentication import AccessTokenProvider, AllowedHostsValidator -# if TYPE_CHECKING: -# from azure.core.credentials import TokenCredential -# from azure.core.credentials_async import AsyncTokenCredential - class AzureIdentityAccessTokenProvider(AccessTokenProvider): """Access token provider that leverages the Azure Identity library to retrieve an access token. diff --git a/tests/test_azure_identity_access_token_provider.py b/tests/test_azure_identity_access_token_provider.py index 9a75fee..000dde2 100644 --- a/tests/test_azure_identity_access_token_provider.py +++ b/tests/test_azure_identity_access_token_provider.py @@ -4,6 +4,7 @@ from kiota_authentication_azure.azure_identity_access_token_provider import ( AzureIdentityAccessTokenProvider, ) + from .helpers import DummyAsyncAzureTokenCredential, DummySyncAzureTokenCredential diff --git a/tests/test_azure_identity_authentication_provider.py b/tests/test_azure_identity_authentication_provider.py index f929572..22a6610 100644 --- a/tests/test_azure_identity_authentication_provider.py +++ b/tests/test_azure_identity_authentication_provider.py @@ -1,8 +1,10 @@ import pytest from kiota_abstractions.request_information import RequestInformation + from kiota_authentication_azure.azure_identity_authentication_provider import ( AzureIdentityAuthenticationProvider, ) + from .helpers import DummyAsyncAzureTokenCredential, DummySyncAzureTokenCredential