From 7e3509bbc55a30e5118bd554e180c585ae15d163 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Mon, 10 Jul 2023 10:06:22 -0700 Subject: [PATCH 01/21] wip; Update sync credentials --- .../azure-identity/azure/identity/_credentials/default.py | 7 +++++-- .../azure/identity/_credentials/environment.py | 5 ++++- .../azure/identity/_credentials/managed_identity.py | 7 ++++++- .../azure/identity/_credentials/shared_cache.py | 6 +++++- .../azure-identity/azure/identity/_credentials/vscode.py | 4 +++- .../azure/identity/_internal/get_token_mixin.py | 6 +++++- 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/default.py b/sdk/identity/azure-identity/azure/identity/_credentials/default.py index 8e188d028f33..57f6cbe6ba0d 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/default.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/default.py @@ -4,7 +4,7 @@ # ------------------------------------ import logging import os -from typing import List, TYPE_CHECKING, Any, cast +from typing import List, TYPE_CHECKING, Any, Optional, cast from azure.core.credentials import AccessToken from .._constants import EnvironmentVariables @@ -195,7 +195,9 @@ def __init__(self, **kwargs: Any) -> None: # pylint: disable=too-many-statement super(DefaultAzureCredential, self).__init__(*credentials) - def get_token(self, *scopes: str, **kwargs) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -204,6 +206,7 @@ def get_token(self, *scopes: str, **kwargs) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py index abd4675c9526..6d482916afd6 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py @@ -120,7 +120,9 @@ def close(self) -> None: self.__exit__() @log_get_token("EnvironmentCredential") - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -129,6 +131,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py index 52d0a00cc538..d54c55e3d3f6 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py @@ -108,7 +108,9 @@ def close(self) -> None: self.__exit__() @log_get_token("ManagedIdentityCredential") - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -117,6 +119,9 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: not used by this credential; any value provided will be ignored. + :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken :raises ~azure.identity.CredentialUnavailableError: managed identity isn't available in the hosting environment diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py index 3e78c9a42bac..35aa0eb7ce14 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py @@ -52,7 +52,9 @@ def close(self) -> None: self.__exit__() @log_get_token("SharedTokenCacheCredential") - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Get an access token for `scopes` from the shared cache. If no access token is cached, attempt to acquire one using a cached refresh token. @@ -64,8 +66,10 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str claims: additional claims required in the token, such as those returned in a resource provider's claims challenge following an authorization failure + :keyword str tenant_id: not used by this credential; any value provided will be ignored. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. + :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken :raises ~azure.identity.CredentialUnavailableError: the cache is unavailable or contains insufficient user diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py index f73b7832e972..19c80f947517 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py @@ -140,7 +140,9 @@ def close(self) -> None: self.__exit__() @log_get_token("VSCodeCredential") - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Request an access token for `scopes` as the user currently signed in to Visual Studio Code. This method is called automatically by Azure SDK clients. diff --git a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py index ebfdd2effc35..5c898dfc9a64 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py @@ -53,7 +53,9 @@ def _should_refresh(self, token: AccessToken) -> bool: return False return True - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -62,8 +64,10 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. + :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken :raises CredentialUnavailableError: the credential is unable to attempt authentication because it lacks From 9321c878b16c0f13953f1aecc9fec45bc2f5c7c8 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Tue, 18 Jul 2023 17:50:14 -0700 Subject: [PATCH 02/21] Correctly handle claims/tenant_id --- .../azure/identity/_credentials/chained.py | 10 +++++-- .../azure/identity/_credentials/default.py | 2 ++ .../identity/_credentials/environment.py | 3 +++ .../identity/_credentials/managed_identity.py | 3 +++ .../identity/_credentials/shared_cache.py | 4 ++- .../azure/identity/_credentials/vscode.py | 2 ++ .../azure/identity/_internal/__init__.py | 2 ++ .../identity/_internal/get_token_mixin.py | 3 +++ .../azure/identity/_internal/utils.py | 26 ++++++++++++++++++- 9 files changed, 51 insertions(+), 4 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py index 5a6a2046629a..0d7757f477dc 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py @@ -8,7 +8,7 @@ from azure.core.credentials import AccessToken from .. import CredentialUnavailableError -from .._internal import within_credential_chain +from .._internal import get_token_request_additions, within_credential_chain if TYPE_CHECKING: from azure.core.credentials import TokenCredential @@ -69,7 +69,9 @@ def close(self) -> None: """Close the transport session of each credential in the chain.""" self.__exit__() - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: # pylint:disable=unused-argument + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Request a token from each chained credential, in order, returning the first token received. This method is called automatically by Azure SDK clients. @@ -77,11 +79,15 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: # pylint:disab :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken :raises ~azure.core.exceptions.ClientAuthenticationError: no credential in the chain provided a token """ + additions = get_token_request_additions(claims, tenant_id) + kwargs.update(additions) within_credential_chain.set(True) history = [] for credential in self.credentials: diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/default.py b/sdk/identity/azure-identity/azure/identity/_credentials/default.py index 57f6cbe6ba0d..8624db8bab74 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/default.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/default.py @@ -214,6 +214,8 @@ def get_token( :raises ~azure.core.exceptions.ClientAuthenticationError: authentication failed. The exception has a `message` attribute listing each authentication attempt and its error message. """ + additions = get_token_request_additions(claims, tenant_id) + kwargs.update(additions) if self._successful_credential: token = self._successful_credential.get_token(*scopes, **kwargs) _LOGGER.info( diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py index 6d482916afd6..5a014ea14298 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py @@ -9,6 +9,7 @@ from .. import CredentialUnavailableError from .._constants import EnvironmentVariables +from .._internal import get_token_request_additions from .._internal.decorators import log_get_token from .certificate import CertificateCredential from .client_secret import ClientSecretCredential @@ -138,6 +139,8 @@ def get_token( :raises ~azure.identity.CredentialUnavailableError: environment variable configuration is incomplete """ + additions = get_token_request_additions(claims, tenant_id) + kwargs.update(additions) if not self._credential: message = ( "EnvironmentCredential authentication unavailable. Environment variables are not fully configured.\n" diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py index d54c55e3d3f6..955c3df5ef07 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py @@ -9,6 +9,7 @@ from azure.core.credentials import AccessToken from .. import CredentialUnavailableError from .._constants import EnvironmentVariables +from .._internal import get_token_request_additions from .._internal.decorators import log_get_token if TYPE_CHECKING: @@ -127,6 +128,8 @@ def get_token( :raises ~azure.identity.CredentialUnavailableError: managed identity isn't available in the hosting environment """ + additions = get_token_request_additions(claims, tenant_id) + kwargs.update(additions) if not self._credential: raise CredentialUnavailableError( message="No managed identity endpoint found. \n" diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py index 35aa0eb7ce14..24e8f98076a7 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py @@ -8,7 +8,7 @@ from .silent import SilentAuthenticationCredential from .. import CredentialUnavailableError from .._constants import DEVELOPER_SIGN_ON_CLIENT_ID -from .._internal import AadClient, AadClientBase +from .._internal import AadClient, AadClientBase, get_token_request_additions from .._internal.decorators import log_get_token from .._internal.shared_token_cache import NO_TOKEN, SharedTokenCacheBase @@ -77,6 +77,8 @@ def get_token( :raises ~azure.core.exceptions.ClientAuthenticationError: authentication failed. The error's ``message`` attribute gives a reason. """ + additions = get_token_request_additions(claims, tenant_id) + kwargs.update(additions) return self._credential.get_token(*scopes, **kwargs) @staticmethod diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py index 19c80f947517..efa8494ddfab 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py @@ -156,6 +156,8 @@ def get_token( :raises ~azure.identity.CredentialUnavailableError: the credential cannot retrieve user details from Visual Studio Code """ + additions = get_token_request_additions(claims, tenant_id) + kwargs.update(additions) if self._unavailable_reason: error_message = ( self._unavailable_reason + "\n" diff --git a/sdk/identity/azure-identity/azure/identity/_internal/__init__.py b/sdk/identity/azure-identity/azure/identity/_internal/__init__.py index 6bfab45e7dd5..1c300ad45534 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/__init__.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/__init__.py @@ -10,6 +10,7 @@ from .interactive import InteractiveCredential from .utils import ( get_default_authority, + get_token_request_additions, normalize_authority, resolve_tenant, validate_tenant_id, @@ -44,6 +45,7 @@ def _scopes_to_resource(*scopes) -> str: "AuthCodeRedirectServer", "AadClientCertificate", "get_default_authority", + "get_token_request_additions", "InteractiveCredential", "normalize_authority", "resolve_tenant", diff --git a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py index 5c898dfc9a64..e36286060853 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py @@ -10,6 +10,7 @@ from azure.core.credentials import AccessToken from .utils import within_credential_chain from .._constants import DEFAULT_REFRESH_OFFSET, DEFAULT_TOKEN_REFRESH_RETRY_DELAY +from .._internal import get_token_request_additions _LOGGER = logging.getLogger(__name__) @@ -78,6 +79,8 @@ def get_token( if not scopes: raise ValueError('"get_token" requires at least one scope') + additions = get_token_request_additions(claims, tenant_id) + kwargs.update(additions) try: token = self._acquire_token_silently(*scopes, **kwargs) if not token: diff --git a/sdk/identity/azure-identity/azure/identity/_internal/utils.py b/sdk/identity/azure-identity/azure/identity/_internal/utils.py index 0bb176e19d25..f867608f3bc7 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/utils.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/utils.py @@ -5,7 +5,7 @@ import os import logging from contextvars import ContextVar -from typing import List, Optional +from typing import Dict, List, Optional from urllib.parse import urlparse @@ -43,6 +43,30 @@ def get_default_authority() -> str: return normalize_authority(authority) +def get_token_request_additions(claims: Optional[str], tenant_id: Optional[str]) -> Dict[str, str]: + """Return a dictionary that **kwargs can be updated with in a get_token method. + + This method centralizes the logic of pulling keyword-only arguments out of get_token requests so that they're not + erroneously sent through to the pipeline if unspecified. + + :param claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure + :type claims: str or None + :param tenant_id: optional tenant to include in the token request + :type tenant_id: str or None + + :return: A dictionary containing each parameter as a key, mapped to its value, if the parameter has a non-None value + :rtype: dict + """ + + additions = {} + if claims is not None: + additions["claims"] = claims + if tenant_id is not None: + additions["tenant_id"] = tenant_id + return additions + + VALID_TENANT_ID_CHARACTERS = frozenset("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789" + "-.") From 0866d7e09fb2f00b08a6c17df23acf2c3bc96315 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Wed, 19 Jul 2023 11:25:00 -0700 Subject: [PATCH 03/21] Pass params through plainly --- .../azure/identity/_credentials/chained.py | 6 ++--- .../azure/identity/_credentials/default.py | 6 ++--- .../identity/_credentials/environment.py | 5 +--- .../identity/_credentials/managed_identity.py | 5 +--- .../identity/_credentials/shared_cache.py | 6 ++--- .../azure/identity/_credentials/vscode.py | 6 ++--- .../azure/identity/_internal/__init__.py | 2 -- .../identity/_internal/get_token_mixin.py | 9 +++---- .../azure/identity/_internal/utils.py | 24 ------------------- 9 files changed, 13 insertions(+), 56 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py index 0d7757f477dc..5ff3fcdd37b2 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py @@ -8,7 +8,7 @@ from azure.core.credentials import AccessToken from .. import CredentialUnavailableError -from .._internal import get_token_request_additions, within_credential_chain +from .._internal import within_credential_chain if TYPE_CHECKING: from azure.core.credentials import TokenCredential @@ -86,13 +86,11 @@ def get_token( :rtype: ~azure.core.credentials.AccessToken :raises ~azure.core.exceptions.ClientAuthenticationError: no credential in the chain provided a token """ - additions = get_token_request_additions(claims, tenant_id) - kwargs.update(additions) within_credential_chain.set(True) history = [] for credential in self.credentials: try: - token = credential.get_token(*scopes, **kwargs) + token = credential.get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) _LOGGER.info("%s acquired a token from %s", self.__class__.__name__, credential.__class__.__name__) self._successful_credential = credential return token diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/default.py b/sdk/identity/azure-identity/azure/identity/_credentials/default.py index 8624db8bab74..f9740e52c98e 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/default.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/default.py @@ -214,15 +214,13 @@ def get_token( :raises ~azure.core.exceptions.ClientAuthenticationError: authentication failed. The exception has a `message` attribute listing each authentication attempt and its error message. """ - additions = get_token_request_additions(claims, tenant_id) - kwargs.update(additions) if self._successful_credential: - token = self._successful_credential.get_token(*scopes, **kwargs) + token = self._successful_credential.get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) _LOGGER.info( "%s acquired a token from %s", self.__class__.__name__, self._successful_credential.__class__.__name__ ) return token within_dac.set(True) - token = super(DefaultAzureCredential, self).get_token(*scopes, **kwargs) + token = super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) within_dac.set(False) return token diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py index 5a014ea14298..c07a58d92146 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py @@ -9,7 +9,6 @@ from .. import CredentialUnavailableError from .._constants import EnvironmentVariables -from .._internal import get_token_request_additions from .._internal.decorators import log_get_token from .certificate import CertificateCredential from .client_secret import ClientSecretCredential @@ -139,8 +138,6 @@ def get_token( :raises ~azure.identity.CredentialUnavailableError: environment variable configuration is incomplete """ - additions = get_token_request_additions(claims, tenant_id) - kwargs.update(additions) if not self._credential: message = ( "EnvironmentCredential authentication unavailable. Environment variables are not fully configured.\n" @@ -148,4 +145,4 @@ def get_token( "this issue." ) raise CredentialUnavailableError(message=message) - return self._credential.get_token(*scopes, **kwargs) + return self._credential.get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py index 955c3df5ef07..400a7f7a4487 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py @@ -9,7 +9,6 @@ from azure.core.credentials import AccessToken from .. import CredentialUnavailableError from .._constants import EnvironmentVariables -from .._internal import get_token_request_additions from .._internal.decorators import log_get_token if TYPE_CHECKING: @@ -128,8 +127,6 @@ def get_token( :raises ~azure.identity.CredentialUnavailableError: managed identity isn't available in the hosting environment """ - additions = get_token_request_additions(claims, tenant_id) - kwargs.update(additions) if not self._credential: raise CredentialUnavailableError( message="No managed identity endpoint found. \n" @@ -137,4 +134,4 @@ def get_token( "Visit https://aka.ms/azsdk/python/identity/managedidentitycredential/troubleshoot to " "troubleshoot this issue." ) - return self._credential.get_token(*scopes, **kwargs) + return self._credential.get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py index 24e8f98076a7..01dc1020b8d1 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py @@ -8,7 +8,7 @@ from .silent import SilentAuthenticationCredential from .. import CredentialUnavailableError from .._constants import DEVELOPER_SIGN_ON_CLIENT_ID -from .._internal import AadClient, AadClientBase, get_token_request_additions +from .._internal import AadClient, AadClientBase from .._internal.decorators import log_get_token from .._internal.shared_token_cache import NO_TOKEN, SharedTokenCacheBase @@ -77,9 +77,7 @@ def get_token( :raises ~azure.core.exceptions.ClientAuthenticationError: authentication failed. The error's ``message`` attribute gives a reason. """ - additions = get_token_request_additions(claims, tenant_id) - kwargs.update(additions) - return self._credential.get_token(*scopes, **kwargs) + return self._credential.get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) @staticmethod def supported() -> bool: diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py index efa8494ddfab..c25b515afe37 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py @@ -156,8 +156,6 @@ def get_token( :raises ~azure.identity.CredentialUnavailableError: the credential cannot retrieve user details from Visual Studio Code """ - additions = get_token_request_additions(claims, tenant_id) - kwargs.update(additions) if self._unavailable_reason: error_message = ( self._unavailable_reason + "\n" @@ -167,11 +165,11 @@ def get_token( raise CredentialUnavailableError(message=error_message) if within_dac.get(): try: - token = super(VisualStudioCodeCredential, self).get_token(*scopes, **kwargs) + token = super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) return token except ClientAuthenticationError as ex: raise CredentialUnavailableError(message=ex.message) from ex - return super(VisualStudioCodeCredential, self).get_token(*scopes, **kwargs) + return super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) def _acquire_token_silently(self, *scopes: str, **kwargs: Any) -> Optional[AccessToken]: self._client = cast(AadClient, self._client) diff --git a/sdk/identity/azure-identity/azure/identity/_internal/__init__.py b/sdk/identity/azure-identity/azure/identity/_internal/__init__.py index 1c300ad45534..6bfab45e7dd5 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/__init__.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/__init__.py @@ -10,7 +10,6 @@ from .interactive import InteractiveCredential from .utils import ( get_default_authority, - get_token_request_additions, normalize_authority, resolve_tenant, validate_tenant_id, @@ -45,7 +44,6 @@ def _scopes_to_resource(*scopes) -> str: "AuthCodeRedirectServer", "AadClientCertificate", "get_default_authority", - "get_token_request_additions", "InteractiveCredential", "normalize_authority", "resolve_tenant", diff --git a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py index e36286060853..e5960687c517 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py @@ -10,7 +10,6 @@ from azure.core.credentials import AccessToken from .utils import within_credential_chain from .._constants import DEFAULT_REFRESH_OFFSET, DEFAULT_TOKEN_REFRESH_RETRY_DELAY -from .._internal import get_token_request_additions _LOGGER = logging.getLogger(__name__) @@ -79,17 +78,15 @@ def get_token( if not scopes: raise ValueError('"get_token" requires at least one scope') - additions = get_token_request_additions(claims, tenant_id) - kwargs.update(additions) try: - token = self._acquire_token_silently(*scopes, **kwargs) + token = self._acquire_token_silently(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) if not token: self._last_request_time = int(time.time()) - token = self._request_token(*scopes, **kwargs) + token = self._request_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) elif self._should_refresh(token): try: self._last_request_time = int(time.time()) - token = self._request_token(*scopes, **kwargs) + token = self._request_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) except Exception: # pylint:disable=broad-except pass _LOGGER.log( diff --git a/sdk/identity/azure-identity/azure/identity/_internal/utils.py b/sdk/identity/azure-identity/azure/identity/_internal/utils.py index f867608f3bc7..c349dc45ee50 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/utils.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/utils.py @@ -43,30 +43,6 @@ def get_default_authority() -> str: return normalize_authority(authority) -def get_token_request_additions(claims: Optional[str], tenant_id: Optional[str]) -> Dict[str, str]: - """Return a dictionary that **kwargs can be updated with in a get_token method. - - This method centralizes the logic of pulling keyword-only arguments out of get_token requests so that they're not - erroneously sent through to the pipeline if unspecified. - - :param claims: additional claims required in the token, such as those returned in a resource provider's - claims challenge following an authorization failure - :type claims: str or None - :param tenant_id: optional tenant to include in the token request - :type tenant_id: str or None - - :return: A dictionary containing each parameter as a key, mapped to its value, if the parameter has a non-None value - :rtype: dict - """ - - additions = {} - if claims is not None: - additions["claims"] = claims - if tenant_id is not None: - additions["tenant_id"] = tenant_id - return additions - - VALID_TENANT_ID_CHARACTERS = frozenset("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789" + "-.") From 6f0952efb706c84e13bbd52757eb2f2df180785f Mon Sep 17 00:00:00 2001 From: mccoyp Date: Wed, 19 Jul 2023 18:03:07 -0700 Subject: [PATCH 04/21] Update mock assertions --- .../azure/identity/_internal/utils.py | 2 +- .../tests/test_chained_credential.py | 2 +- .../tests/test_get_token_mixin.py | 20 +++++++++---------- .../tests/test_vscode_credential.py | 4 +++- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_internal/utils.py b/sdk/identity/azure-identity/azure/identity/_internal/utils.py index c349dc45ee50..0bb176e19d25 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/utils.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/utils.py @@ -5,7 +5,7 @@ import os import logging from contextvars import ContextVar -from typing import Dict, List, Optional +from typing import List, Optional from urllib.parse import urlparse diff --git a/sdk/identity/azure-identity/tests/test_chained_credential.py b/sdk/identity/azure-identity/tests/test_chained_credential.py index db6da5dc80c7..2d74ef9538e3 100644 --- a/sdk/identity/azure-identity/tests/test_chained_credential.py +++ b/sdk/identity/azure-identity/tests/test_chained_credential.py @@ -102,7 +102,7 @@ def test_raises_for_unexpected_error(): def test_returns_first_token(): expected_token = Mock() - first_credential = Mock(get_token=lambda _: expected_token) + first_credential = Mock(get_token=lambda _, **__: expected_token) second_credential = Mock(get_token=Mock()) aggregate = ChainedTokenCredential(first_credential, second_credential) diff --git a/sdk/identity/azure-identity/tests/test_get_token_mixin.py b/sdk/identity/azure-identity/tests/test_get_token_mixin.py index 62931fdc082a..0deee7ec8a9d 100644 --- a/sdk/identity/azure-identity/tests/test_get_token_mixin.py +++ b/sdk/identity/azure-identity/tests/test_get_token_mixin.py @@ -40,8 +40,8 @@ def test_no_cached_token(): credential = MockCredential() token = credential.get_token(SCOPE) - credential.acquire_token_silently.assert_called_once_with(SCOPE) - credential.request_token.assert_called_once_with(SCOPE) + credential.acquire_token_silently.assert_called_once_with(SCOPE, claims=None, tenant_id=None) + credential.request_token.assert_called_once_with(SCOPE, claims=None, tenant_id=None) assert token.token == MockCredential.NEW_TOKEN.token @@ -61,7 +61,7 @@ def test_token_acquisition_failure(): with pytest.raises(Exception): credential.get_token(SCOPE) assert credential.request_token.call_count == i + 1 - credential.request_token.assert_called_with(SCOPE) + credential.request_token.assert_called_with(SCOPE, claims=None, tenant_id=None) def test_expired_token(): @@ -71,8 +71,8 @@ def test_expired_token(): credential = MockCredential(cached_token=AccessToken(CACHED_TOKEN, now - 1)) token = credential.get_token(SCOPE) - credential.acquire_token_silently.assert_called_once_with(SCOPE) - credential.request_token.assert_called_once_with(SCOPE) + credential.acquire_token_silently.assert_called_once_with(SCOPE, claims=None, tenant_id=None) + credential.request_token.assert_called_once_with(SCOPE, claims=None, tenant_id=None) assert token.token == MockCredential.NEW_TOKEN.token @@ -82,7 +82,7 @@ def test_cached_token_outside_refresh_window(): credential = MockCredential(cached_token=AccessToken(CACHED_TOKEN, time.time() + DEFAULT_REFRESH_OFFSET + 1)) token = credential.get_token(SCOPE) - credential.acquire_token_silently.assert_called_once_with(SCOPE) + credential.acquire_token_silently.assert_called_once_with(SCOPE, claims=None, tenant_id=None) assert credential.request_token.call_count == 0 assert token.token == CACHED_TOKEN @@ -93,8 +93,8 @@ def test_cached_token_within_refresh_window(): credential = MockCredential(cached_token=AccessToken(CACHED_TOKEN, time.time() + DEFAULT_REFRESH_OFFSET - 1)) token = credential.get_token(SCOPE) - credential.acquire_token_silently.assert_called_once_with(SCOPE) - credential.request_token.assert_called_once_with(SCOPE) + credential.acquire_token_silently.assert_called_once_with(SCOPE, claims=None, tenant_id=None) + credential.request_token.assert_called_once_with(SCOPE, claims=None, tenant_id=None) assert token.token == MockCredential.NEW_TOKEN.token @@ -109,5 +109,5 @@ def test_retry_delay(): for i in range(4): token = credential.get_token(SCOPE) assert token.token == CACHED_TOKEN - credential.acquire_token_silently.assert_called_with(SCOPE) - credential.request_token.assert_called_once_with(SCOPE) + credential.acquire_token_silently.assert_called_with(SCOPE, claims=None, tenant_id=None) + credential.request_token.assert_called_once_with(SCOPE, claims=None, tenant_id=None) diff --git a/sdk/identity/azure-identity/tests/test_vscode_credential.py b/sdk/identity/azure-identity/tests/test_vscode_credential.py index 324223e1bae9..0c2715bab939 100644 --- a/sdk/identity/azure-identity/tests/test_vscode_credential.py +++ b/sdk/identity/azure-identity/tests/test_vscode_credential.py @@ -157,7 +157,9 @@ def test_redeem_token(): credential = get_credential(_client=mock_client) token = credential.get_token("scope") assert token is expected_token - mock_client.obtain_token_by_refresh_token.assert_called_with(("scope",), expected_value) + mock_client.obtain_token_by_refresh_token.assert_called_with( + ("scope",), expected_value, claims=None, tenant_id=None + ) assert mock_client.obtain_token_by_refresh_token.call_count == 1 From b37643aa7dc31a3a0c275b7c5580f1625de1ceef Mon Sep 17 00:00:00 2001 From: mccoyp Date: Fri, 21 Jul 2023 15:54:15 -0700 Subject: [PATCH 05/21] Update sync credentials --- .../azure/identity/_credentials/application.py | 13 +++++++++---- .../identity/_credentials/authorization_code.py | 7 +++++-- .../azure/identity/_credentials/azd_cli.py | 11 +++++++++-- .../azure/identity/_credentials/azure_cli.py | 11 +++++++++-- .../azure/identity/_credentials/azure_powershell.py | 11 +++++++++-- .../azure/identity/_credentials/shared_cache.py | 8 ++++++-- .../azure/identity/_credentials/silent.py | 6 ++++-- .../azure/identity/_internal/interactive.py | 10 ++++++---- .../identity/_internal/managed_identity_base.py | 6 ++++-- .../tests/test_interactive_credential.py | 2 +- 10 files changed, 62 insertions(+), 23 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/application.py b/sdk/identity/azure-identity/azure/identity/_credentials/application.py index 42d46835f228..aab1f60a2566 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/application.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/application.py @@ -4,7 +4,7 @@ # ------------------------------------ import logging import os -from typing import Any +from typing import Any, Optional from azure.core.credentials import AccessToken from .chained import ChainedTokenCredential @@ -63,7 +63,9 @@ def __init__(self, **kwargs: Any) -> None: ManagedIdentityCredential(client_id=managed_identity_client_id, **kwargs), ) - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -71,16 +73,19 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: not used by this credential; any value provided will be ignored. + :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken :raises ~azure.core.exceptions.ClientAuthenticationError: authentication failed. The exception has a `message` attribute listing each authentication attempt and its error message. """ if self._successful_credential: - token = self._successful_credential.get_token(*scopes, **kwargs) + token = self._successful_credential.get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) _LOGGER.info( "%s acquired a token from %s", self.__class__.__name__, self._successful_credential.__class__.__name__ ) return token - return super(AzureApplicationCredential, self).get_token(*scopes, **kwargs) + return super(AzureApplicationCredential, self).get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py b/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py index ba0220353b37..422857acb732 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py @@ -61,7 +61,9 @@ def close(self) -> None: """Close the credential's transport session.""" self.__exit__() - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -74,6 +76,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -82,7 +85,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: ``response`` attribute. """ # pylint:disable=useless-super-delegation - return super(AuthorizationCodeCredential, self).get_token(*scopes, **kwargs) + return super(AuthorizationCodeCredential, self).get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) def _acquire_token_silently(self, *scopes: str, **kwargs) -> Optional[AccessToken]: return self._client.get_cached_access_token(scopes, **kwargs) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py index 9cf4f244fe2a..7808ce48bdf0 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py @@ -91,7 +91,9 @@ def close(self) -> None: """Calling this method is unnecessary.""" @log_get_token("AzureDeveloperCliCredential") - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. Applications calling this method directly must @@ -101,6 +103,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -117,7 +120,11 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: commandString = " --scope ".join(scopes) command = COMMAND_LINE.format(commandString) tenant = resolve_tenant( - default_tenant=self.tenant_id, additionally_allowed_tenants=self._additionally_allowed_tenants, **kwargs + default_tenant=self.tenant_id, + tenant_id=tenant_id, + additionally_allowed_tenants=self._additionally_allowed_tenants, + claims=claims, + **kwargs, ) if tenant: command += " --tenant-id " + tenant diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py index 530f5c1cd0c1..7027a4784553 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py @@ -69,7 +69,9 @@ def close(self) -> None: """Calling this method is unnecessary.""" @log_get_token("AzureCliCredential") - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. Applications calling this method directly must @@ -79,6 +81,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -91,7 +94,11 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: resource = _scopes_to_resource(*scopes) command = COMMAND_LINE.format(resource) tenant = resolve_tenant( - default_tenant=self.tenant_id, additionally_allowed_tenants=self._additionally_allowed_tenants, **kwargs + default_tenant=self.tenant_id, + tenant_id=tenant_id, + additionally_allowed_tenants=self._additionally_allowed_tenants, + claims=claims, + **kwargs, ) if tenant: command += " --tenant " + tenant diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py index d671a0ff3cc5..73073a8eaf10 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py @@ -83,7 +83,9 @@ def close(self) -> None: """Calling this method is unnecessary.""" @log_get_token("AzurePowerShellCredential") - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. Applications calling this method directly must @@ -93,6 +95,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -103,7 +106,11 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: receive an access token """ tenant_id = resolve_tenant( - default_tenant=self.tenant_id, additionally_allowed_tenants=self._additionally_allowed_tenants, **kwargs + default_tenant=self.tenant_id, + tenant_id=tenant_id, + additionally_allowed_tenants=self._additionally_allowed_tenants, + claims=claims, + **kwargs, ) command_line = get_command_line(scopes, tenant_id) output = run_command_line(command_line, self._process_timeout) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py index 01dc1020b8d1..ecf7d1fcb1ac 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py @@ -101,7 +101,9 @@ def __exit__(self, *args): if self._client: self._client.__exit__(*args) - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: if not scopes: raise ValueError("'get_token' requires at least one scope") @@ -127,7 +129,9 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: # try each refresh token, returning the first access token acquired for refresh_token in self._get_refresh_tokens(account, is_cae=is_cae): - token = self._client.obtain_token_by_refresh_token(scopes, refresh_token, **kwargs) + token = self._client.obtain_token_by_refresh_token( + scopes, refresh_token, claims=claims, tenant_id=tenant_id, **kwargs + ) return token raise CredentialUnavailableError(message=NO_TOKEN.format(account.get("username"))) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/silent.py b/sdk/identity/azure-identity/azure/identity/_credentials/silent.py index 04dc6a42b940..ec15d0435cfa 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/silent.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/silent.py @@ -54,7 +54,9 @@ def __enter__(self): def __exit__(self, *args): self._client.__exit__(*args) - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: if not scopes: raise ValueError('"get_token" requires at least one scope') @@ -70,7 +72,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: raise CredentialUnavailableError(message="Shared token cache unavailable") raise ClientAuthenticationError(message="Shared token cache unavailable") - return self._acquire_token_silent(*scopes, **kwargs) + return self._acquire_token_silent(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) def _initialize_cache(self, is_cae: bool = False) -> Optional[TokenCache]: diff --git a/sdk/identity/azure-identity/azure/identity/_internal/interactive.py b/sdk/identity/azure-identity/azure/identity/_internal/interactive.py index 868e86a4a22a..f01a85f397de 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/interactive.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/interactive.py @@ -111,7 +111,9 @@ def __init__( else: super(InteractiveCredential, self).__init__(**kwargs) - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -120,7 +122,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str claims: additional claims required in the token, such as those returned in a resource provider's - claims challenge following an authorization failure + claims challenge following an authorization failure :keyword str tenant_id: optional tenant to include in the token request. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. @@ -140,7 +142,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: allow_prompt = kwargs.pop("_allow_prompt", not self._disable_automatic_authentication) try: - token = self._acquire_token_silent(*scopes, **kwargs) + token = self._acquire_token_silent(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) _LOGGER.info("%s.get_token succeeded", self.__class__.__name__) return token except Exception as ex: # pylint:disable=broad-except @@ -157,7 +159,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: now = int(time.time()) try: - result = self._request_token(*scopes, **kwargs) + result = self._request_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) if "access_token" not in result: message = "Authentication failed: {}".format(result.get("error_description") or result.get("error")) response = self._client.get_error_response(result) diff --git a/sdk/identity/azure-identity/azure/identity/_internal/managed_identity_base.py b/sdk/identity/azure-identity/azure/identity/_internal/managed_identity_base.py index 33b8b2fd36f6..554122530f83 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/managed_identity_base.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/managed_identity_base.py @@ -39,10 +39,12 @@ def __exit__(self, *args): def close(self) -> None: self.__exit__() - def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + ) -> AccessToken: if not self._client: raise CredentialUnavailableError(message=self.get_unavailable_message()) - return super(ManagedIdentityBase, self).get_token(*scopes, **kwargs) + return super(ManagedIdentityBase, self).get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) def _acquire_token_silently(self, *scopes: str, **kwargs: Any) -> Optional[AccessToken]: # casting because mypy can't determine that these methods are called diff --git a/sdk/identity/azure-identity/tests/test_interactive_credential.py b/sdk/identity/azure-identity/tests/test_interactive_credential.py index 22c65e68eb05..de1c3f550b91 100644 --- a/sdk/identity/azure-identity/tests/test_interactive_credential.py +++ b/sdk/identity/azure-identity/tests/test_interactive_credential.py @@ -157,7 +157,7 @@ def validate_scopes(*scopes, **_): def test_authenticate_default_scopes(authority, expected_scope): """when given no scopes, authenticate should default to the ARM scope appropriate for the configured authority""" - def validate_scopes(*scopes): + def validate_scopes(*scopes, **_): assert scopes == (expected_scope,) return REQUEST_TOKEN_RESULT From b7da648d1bfe461c99e0b705ce5e3b5db7d1b414 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Fri, 21 Jul 2023 17:57:34 -0700 Subject: [PATCH 06/21] Update async credentials, docstrings --- .../azure/identity/_credentials/application.py | 2 +- .../identity/_credentials/authorization_code.py | 2 +- .../azure/identity/_credentials/azd_cli.py | 2 +- .../azure/identity/_credentials/azure_cli.py | 2 +- .../azure/identity/_credentials/azure_powershell.py | 2 +- .../azure/identity/_credentials/chained.py | 2 +- .../azure/identity/_credentials/default.py | 2 +- .../azure/identity/_credentials/environment.py | 2 +- .../azure/identity/_credentials/managed_identity.py | 2 +- .../azure/identity/_credentials/shared_cache.py | 4 ++-- .../azure/identity/_credentials/silent.py | 2 +- .../azure/identity/_credentials/vscode.py | 4 +++- .../azure/identity/_internal/get_token_mixin.py | 2 +- .../azure/identity/_internal/interactive.py | 2 +- .../identity/_internal/managed_identity_base.py | 2 +- .../azure/identity/aio/_credentials/application.py | 10 +++++++--- .../identity/aio/_credentials/authorization_code.py | 7 +++++-- .../azure/identity/aio/_credentials/azd_cli.py | 13 ++++++++++--- .../azure/identity/aio/_credentials/azure_cli.py | 13 ++++++++++--- .../identity/aio/_credentials/azure_powershell.py | 13 ++++++++++--- .../azure/identity/aio/_credentials/chained.py | 8 ++++++-- .../azure/identity/aio/_credentials/default.py | 11 +++++++---- .../azure/identity/aio/_credentials/environment.py | 7 +++++-- .../identity/aio/_credentials/managed_identity.py | 8 ++++++-- .../azure/identity/aio/_credentials/shared_cache.py | 12 +++++++++--- .../azure/identity/aio/_credentials/vscode.py | 9 ++++++--- .../azure/identity/aio/_internal/get_token_mixin.py | 6 +++++- .../identity/aio/_internal/managed_identity_base.py | 6 ++++-- 28 files changed, 108 insertions(+), 49 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/application.py b/sdk/identity/azure-identity/azure/identity/_credentials/application.py index aab1f60a2566..5783a5ff41d9 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/application.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/application.py @@ -64,7 +64,7 @@ def __init__(self, **kwargs: Any) -> None: ) def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py b/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py index 422857acb732..d6980b670d20 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py @@ -62,7 +62,7 @@ def close(self) -> None: self.__exit__() def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py index 7808ce48bdf0..c1185e4ae203 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py @@ -92,7 +92,7 @@ def close(self) -> None: @log_get_token("AzureDeveloperCliCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py index 7027a4784553..d743524273ca 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py @@ -70,7 +70,7 @@ def close(self) -> None: @log_get_token("AzureCliCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py index 73073a8eaf10..9b68aa9210b0 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py @@ -84,7 +84,7 @@ def close(self) -> None: @log_get_token("AzurePowerShellCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py index 5ff3fcdd37b2..5170134970a2 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py @@ -70,7 +70,7 @@ def close(self) -> None: self.__exit__() def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request a token from each chained credential, in order, returning the first token received. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/default.py b/sdk/identity/azure-identity/azure/identity/_credentials/default.py index f9740e52c98e..f22d34655c7d 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/default.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/default.py @@ -196,7 +196,7 @@ def __init__(self, **kwargs: Any) -> None: # pylint: disable=too-many-statement super(DefaultAzureCredential, self).__init__(*credentials) def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py index c07a58d92146..ddd60199573c 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py @@ -121,7 +121,7 @@ def close(self) -> None: @log_get_token("EnvironmentCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py index 400a7f7a4487..1ef4b259d7c9 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py @@ -109,7 +109,7 @@ def close(self) -> None: @log_get_token("ManagedIdentityCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py index ecf7d1fcb1ac..76666713effd 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py @@ -53,7 +53,7 @@ def close(self) -> None: @log_get_token("SharedTokenCacheCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Get an access token for `scopes` from the shared cache. @@ -102,7 +102,7 @@ def __exit__(self, *args): self._client.__exit__(*args) def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: if not scopes: raise ValueError("'get_token' requires at least one scope") diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/silent.py b/sdk/identity/azure-identity/azure/identity/_credentials/silent.py index ec15d0435cfa..32180a63e2b2 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/silent.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/silent.py @@ -55,7 +55,7 @@ def __exit__(self, *args): self._client.__exit__(*args) def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: if not scopes: raise ValueError('"get_token" requires at least one scope') diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py index c25b515afe37..3fa7fbf65560 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py @@ -141,7 +141,7 @@ def close(self) -> None: @log_get_token("VSCodeCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request an access token for `scopes` as the user currently signed in to Visual Studio Code. @@ -150,6 +150,8 @@ def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py index e5960687c517..87871ded28a2 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py @@ -54,7 +54,7 @@ def _should_refresh(self, token: AccessToken) -> bool: return True def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_internal/interactive.py b/sdk/identity/azure-identity/azure/identity/_internal/interactive.py index f01a85f397de..ead73b0f97ce 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/interactive.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/interactive.py @@ -112,7 +112,7 @@ def __init__( super(InteractiveCredential, self).__init__(**kwargs) def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_internal/managed_identity_base.py b/sdk/identity/azure-identity/azure/identity/_internal/managed_identity_base.py index 554122530f83..ff2a111f1f4f 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/managed_identity_base.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/managed_identity_base.py @@ -40,7 +40,7 @@ def close(self) -> None: self.__exit__() def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: if not self._client: raise CredentialUnavailableError(message=self.get_unavailable_message()) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py index e902364586b4..2b5638258ad7 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py @@ -62,7 +62,9 @@ def __init__( ManagedIdentityCredential(client_id=managed_identity_client_id, **kwargs), ) - async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """Asynchronously request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -70,6 +72,8 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -77,10 +81,10 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: `message` attribute listing each authentication attempt and its error message. """ if self._successful_credential: - token = await self._successful_credential.get_token(*scopes, **kwargs) + token = await self._successful_credential.get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) _LOGGER.info( "%s acquired a token from %s", self.__class__.__name__, self._successful_credential.__class__.__name__ ) return token - return await super().get_token(*scopes, **kwargs) + return await super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py index 4f7b30601f9e..dde09e36202c 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py @@ -68,7 +68,9 @@ def __init__( self._redirect_uri = redirect_uri super().__init__() - async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -81,6 +83,7 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -88,7 +91,7 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: attribute gives a reason. Any error response from Azure Active Directory is available as the error's ``response`` attribute. """ - return await super().get_token(*scopes, **kwargs) + return await super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) async def _acquire_token_silently(self, *scopes: str, **kwargs: Any) -> Optional[AccessToken]: return self._client.get_cached_access_token(scopes, **kwargs) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py index b03ea546660e..ef2d33717e86 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py @@ -79,7 +79,9 @@ def __init__( self._process_timeout = process_timeout @log_get_token_async - async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. Applications calling this method directly must @@ -89,6 +91,7 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -98,7 +101,7 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: """ # only ProactorEventLoop supports subprocesses on Windows (and it isn't the default loop on Python < 3.8) if sys.platform.startswith("win") and not isinstance(asyncio.get_event_loop(), asyncio.ProactorEventLoop): - return _SyncAzureDeveloperCliCredential().get_token(*scopes, **kwargs) + return _SyncAzureDeveloperCliCredential().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) if not scopes: raise ValueError("Missing scope in request. \n") @@ -106,7 +109,11 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: commandString = " --scope ".join(scopes) command = COMMAND_LINE.format(commandString) tenant = resolve_tenant( - default_tenant=self.tenant_id, additionally_allowed_tenants=self._additionally_allowed_tenants, **kwargs + default_tenant=self.tenant_id, + tenant_id=tenant_id, + additionally_allowed_tenants=self._additionally_allowed_tenants, + claims=claims, + **kwargs, ) if tenant: diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py index 649ada95a965..8cf9342bd649 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py @@ -60,7 +60,9 @@ def __init__( self._process_timeout = process_timeout @log_get_token_async - async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. Applications calling this method directly must @@ -70,6 +72,7 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -79,12 +82,16 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: """ # only ProactorEventLoop supports subprocesses on Windows (and it isn't the default loop on Python < 3.8) if sys.platform.startswith("win") and not isinstance(asyncio.get_event_loop(), asyncio.ProactorEventLoop): - return _SyncAzureCliCredential().get_token(*scopes, **kwargs) + return _SyncAzureCliCredential().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) resource = _scopes_to_resource(*scopes) command = COMMAND_LINE.format(resource) tenant = resolve_tenant( - default_tenant=self.tenant_id, additionally_allowed_tenants=self._additionally_allowed_tenants, **kwargs + default_tenant=self.tenant_id, + tenant_id=tenant_id, + additionally_allowed_tenants=self._additionally_allowed_tenants, + claims=claims, + **kwargs, ) if tenant: diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py index c704c9614de6..922b4e0173b3 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py @@ -54,7 +54,9 @@ def __init__( self._process_timeout = process_timeout @log_get_token_async - async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. Applications calling this method directly must @@ -64,6 +66,7 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -74,10 +77,14 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: """ # only ProactorEventLoop supports subprocesses on Windows (and it isn't the default loop on Python < 3.8) if sys.platform.startswith("win") and not isinstance(asyncio.get_event_loop(), asyncio.ProactorEventLoop): - return _SyncCredential().get_token(*scopes, **kwargs) + return _SyncCredential().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) tenant_id = resolve_tenant( - default_tenant=self.tenant_id, additionally_allowed_tenants=self._additionally_allowed_tenants, **kwargs + default_tenant=self.tenant_id, + tenant_id=tenant_id, + additionally_allowed_tenants=self._additionally_allowed_tenants, + claims=claims, + **kwargs, ) command_line = get_command_line(scopes, tenant_id) output = await run_command_line(command_line, self._process_timeout) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py index 8547d5e134f2..81cf813712e1 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py @@ -50,7 +50,9 @@ async def close(self) -> None: await asyncio.gather(*(credential.close() for credential in self.credentials)) - async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """Asynchronously request a token from each credential, in order, returning the first token received. If no credential provides a token, raises :class:`azure.core.exceptions.ClientAuthenticationError` @@ -61,6 +63,8 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -70,7 +74,7 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: history = [] for credential in self.credentials: try: - token = await credential.get_token(*scopes, **kwargs) + token = await credential.get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) _LOGGER.info("%s acquired a token from %s", self.__class__.__name__, credential.__class__.__name__) self._successful_credential = credential return token diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py index bb539650d7db..430f42183b44 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py @@ -4,7 +4,7 @@ # ------------------------------------ import logging import os -from typing import List, TYPE_CHECKING, Any, cast +from typing import List, Optional, TYPE_CHECKING, Any, cast from azure.core.credentials import AccessToken from ..._constants import EnvironmentVariables @@ -176,7 +176,9 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(*credentials) - async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """Asynchronously request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -185,6 +187,7 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -192,8 +195,8 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: `message` attribute listing each authentication attempt and its error message. """ if self._successful_credential: - return await self._successful_credential.get_token(*scopes, **kwargs) + return await self._successful_credential.get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) within_dac.set(True) - token = await super().get_token(*scopes, **kwargs) + token = await super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) within_dac.set(False) return token diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py index 750af4040325..c78c90871f69 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py @@ -93,7 +93,9 @@ async def close(self) -> None: await self._credential.__aexit__() @log_get_token_async - async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """Asynchronously request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -102,6 +104,7 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -114,4 +117,4 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: "this issue." ) raise CredentialUnavailableError(message=message) - return await self._credential.get_token(*scopes, **kwargs) + return await self._credential.get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py index 1e4d7a507e5c..458d1db7082d 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py @@ -114,7 +114,9 @@ async def close(self) -> None: await self._credential.close() @log_get_token_async - async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """Asynchronously request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -122,6 +124,8 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: :param str scopes: desired scope for the access token. This credential allows only one scope per request. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -134,4 +138,4 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: "Visit https://aka.ms/azsdk/python/identity/managedidentitycredential/troubleshoot to " "troubleshoot this issue." ) - return await self._credential.get_token(*scopes, **kwargs) + return await self._credential.get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py index 04c3cd3ffaad..d14b909eeb32 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py @@ -2,7 +2,7 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. # ------------------------------------ -from typing import Any +from typing import Any, Optional from azure.core.credentials import AccessToken from ..._internal.aad_client import AadClientBase from ... import CredentialUnavailableError @@ -42,7 +42,9 @@ async def close(self) -> None: await self._client.__aexit__() # type: ignore @log_get_token_async - async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: # pylint:disable=unused-argument + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """Get an access token for `scopes` from the shared cache. If no access token is cached, attempt to acquire one using a cached refresh token. @@ -53,8 +55,10 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: # pylint For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. + :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken :raises ~azure.identity.CredentialUnavailableError: the cache is unavailable or contains insufficient user @@ -88,7 +92,9 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: # pylint # try each refresh token, returning the first access token acquired for refresh_token in self._get_refresh_tokens(account, is_cae=is_cae): - token = await self._client.obtain_token_by_refresh_token(scopes, refresh_token, **kwargs) + token = await self._client.obtain_token_by_refresh_token( + scopes, refresh_token, claims=claims, tenant_id=tenant_id, **kwargs + ) return token raise CredentialUnavailableError(message=NO_TOKEN.format(account.get("username"))) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py index ddd1d0e012ec..153e3d7ed614 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py @@ -47,7 +47,9 @@ async def close(self) -> None: await self._client.__aexit__() @log_get_token_async - async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """Request an access token for `scopes` as the user currently signed in to Visual Studio Code. This method is called automatically by Azure SDK clients. @@ -56,6 +58,7 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -73,11 +76,11 @@ async def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: raise CredentialUnavailableError("Initialization failed") if within_dac.get(): try: - token = await super().get_token(*scopes, **kwargs) + token = await super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) return token except ClientAuthenticationError as ex: raise CredentialUnavailableError(message=ex.message) from ex - return await super().get_token(*scopes, **kwargs) + return await super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) async def _acquire_token_silently(self, *scopes: str, **kwargs: Any) -> Optional[AccessToken]: self._client = cast(AadClient, self._client) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py b/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py index 6128113454ab..9a54b8901d94 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py @@ -53,7 +53,9 @@ def _should_refresh(self, token: AccessToken) -> bool: return False return True - async def get_token(self, *scopes: str, **kwargs) -> AccessToken: + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """Request an access token for `scopes`. This method is called automatically by Azure SDK clients. @@ -62,8 +64,10 @@ async def get_token(self, *scopes: str, **kwargs) -> AccessToken: For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. + :keyword str claims: not used by this credential; any value provided will be ignored. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. + :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken :raises CredentialUnavailableError: the credential is unable to attempt authentication because it lacks diff --git a/sdk/identity/azure-identity/azure/identity/aio/_internal/managed_identity_base.py b/sdk/identity/azure-identity/azure/identity/aio/_internal/managed_identity_base.py index d0a81349d898..caa27bdfec00 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_internal/managed_identity_base.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_internal/managed_identity_base.py @@ -39,10 +39,12 @@ async def __aexit__(self, *args): async def close(self) -> None: await self.__aexit__() - async def get_token(self, *scopes: str, **kwargs) -> AccessToken: + async def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: if not self._client: raise CredentialUnavailableError(message=self.get_unavailable_message()) - return await super().get_token(*scopes, **kwargs) + return await super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) async def _acquire_token_silently(self, *scopes: str, **kwargs) -> Optional[AccessToken]: # casting because mypy can't determine that these methods are called From f49f74f66dc4dd8849b76ecddd2ea152b150bed0 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Thu, 27 Jul 2023 15:05:33 -0700 Subject: [PATCH 07/21] Fix async mixin; black --- .../azure-identity/azure/identity/_credentials/chained.py | 2 +- .../azure/identity/aio/_internal/get_token_mixin.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py index 5170134970a2..f08fc2cfc363 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py @@ -70,7 +70,7 @@ def close(self) -> None: self.__exit__() def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs ) -> AccessToken: """Request a token from each chained credential, in order, returning the first token received. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py b/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py index 9a54b8901d94..3223850f5674 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py @@ -79,14 +79,14 @@ async def get_token( raise ValueError('"get_token" requires at least one scope') try: - token = await self._acquire_token_silently(*scopes, **kwargs) + token = await self._acquire_token_silently(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) if not token: self._last_request_time = int(time.time()) - token = await self._request_token(*scopes, **kwargs) + token = await self._request_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) elif self._should_refresh(token): try: self._last_request_time = int(time.time()) - token = await self._request_token(*scopes, **kwargs) + token = await self._request_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) except Exception: # pylint:disable=broad-except pass _LOGGER.log( From 475f782838c7d42b1c0fe36b0d037eefdf602cc9 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Thu, 27 Jul 2023 17:32:43 -0700 Subject: [PATCH 08/21] Update async tests --- .../test_chained_token_credential_async.py | 10 +++++----- .../tests/test_get_token_mixin_async.py | 20 +++++++++---------- .../tests/test_vscode_credential_async.py | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sdk/identity/azure-identity/tests/test_chained_token_credential_async.py b/sdk/identity/azure-identity/tests/test_chained_token_credential_async.py index 1b751be946e1..df04deebb1b5 100644 --- a/sdk/identity/azure-identity/tests/test_chained_token_credential_async.py +++ b/sdk/identity/azure-identity/tests/test_chained_token_credential_async.py @@ -56,14 +56,14 @@ async def test_credential_chain_error_message(): @pytest.mark.asyncio async def test_chain_attempts_all_credentials(): - async def credential_unavailable(message="it didn't work"): + async def credential_unavailable(message="it didn't work", **_): raise CredentialUnavailableError(message) expected_token = AccessToken("expected_token", 0) credentials = [ Mock(get_token=Mock(wraps=credential_unavailable)), Mock(get_token=Mock(wraps=credential_unavailable)), - Mock(get_token=wrap_in_future(lambda _: expected_token)), + Mock(get_token=wrap_in_future(lambda _, **__: expected_token)), ] token = await ChainedTokenCredential(*credentials).get_token("scope") @@ -77,7 +77,7 @@ async def credential_unavailable(message="it didn't work"): async def test_chain_raises_for_unexpected_error(): """the chain should not continue after an unexpected error (i.e. anything but CredentialUnavailableError)""" - async def credential_unavailable(message="it didn't work"): + async def credential_unavailable(message="it didn't work", **_): raise CredentialUnavailableError(message) expected_message = "it can't be done" @@ -85,7 +85,7 @@ async def credential_unavailable(message="it didn't work"): credentials = [ Mock(get_token=Mock(wraps=credential_unavailable)), Mock(get_token=Mock(side_effect=ValueError(expected_message))), - Mock(get_token=Mock(wraps=wrap_in_future(lambda _: AccessToken("**", 42)))), + Mock(get_token=Mock(wraps=wrap_in_future(lambda _, **__: AccessToken("**", 42)))), ] with pytest.raises(ClientAuthenticationError) as ex: @@ -98,7 +98,7 @@ async def credential_unavailable(message="it didn't work"): @pytest.mark.asyncio async def test_returns_first_token(): expected_token = Mock() - first_credential = Mock(get_token=wrap_in_future(lambda _: expected_token)) + first_credential = Mock(get_token=wrap_in_future(lambda _, **__: expected_token)) second_credential = Mock(get_token=Mock()) aggregate = ChainedTokenCredential(first_credential, second_credential) diff --git a/sdk/identity/azure-identity/tests/test_get_token_mixin_async.py b/sdk/identity/azure-identity/tests/test_get_token_mixin_async.py index 4fcc3098d1e1..1b84608dfb30 100644 --- a/sdk/identity/azure-identity/tests/test_get_token_mixin_async.py +++ b/sdk/identity/azure-identity/tests/test_get_token_mixin_async.py @@ -43,8 +43,8 @@ async def test_no_cached_token(): credential = MockCredential() token = await credential.get_token(SCOPE) - credential.acquire_token_silently.assert_called_once_with(SCOPE) - credential.request_token.assert_called_once_with(SCOPE) + credential.acquire_token_silently.assert_called_once_with(SCOPE, claims=None, tenant_id=None) + credential.request_token.assert_called_once_with(SCOPE, claims=None, tenant_id=None) assert token.token == MockCredential.NEW_TOKEN.token @@ -64,7 +64,7 @@ async def test_token_acquisition_failure(): with pytest.raises(Exception): await credential.get_token(SCOPE) assert credential.request_token.call_count == i + 1 - credential.request_token.assert_called_with(SCOPE) + credential.request_token.assert_called_with(SCOPE, claims=None, tenant_id=None) async def test_expired_token(): @@ -74,8 +74,8 @@ async def test_expired_token(): credential = MockCredential(cached_token=AccessToken(CACHED_TOKEN, now - 1)) token = await credential.get_token(SCOPE) - credential.acquire_token_silently.assert_called_once_with(SCOPE) - credential.request_token.assert_called_once_with(SCOPE) + credential.acquire_token_silently.assert_called_once_with(SCOPE, claims=None, tenant_id=None) + credential.request_token.assert_called_once_with(SCOPE, claims=None, tenant_id=None) assert token.token == MockCredential.NEW_TOKEN.token @@ -85,7 +85,7 @@ async def test_cached_token_outside_refresh_window(): credential = MockCredential(cached_token=AccessToken(CACHED_TOKEN, time.time() + DEFAULT_REFRESH_OFFSET + 1)) token = await credential.get_token(SCOPE) - credential.acquire_token_silently.assert_called_once_with(SCOPE) + credential.acquire_token_silently.assert_called_once_with(SCOPE, claims=None, tenant_id=None) assert credential.request_token.call_count == 0 assert token.token == CACHED_TOKEN @@ -96,8 +96,8 @@ async def test_cached_token_within_refresh_window(): credential = MockCredential(cached_token=AccessToken(CACHED_TOKEN, time.time() + DEFAULT_REFRESH_OFFSET - 1)) token = await credential.get_token(SCOPE) - credential.acquire_token_silently.assert_called_once_with(SCOPE) - credential.request_token.assert_called_once_with(SCOPE) + credential.acquire_token_silently.assert_called_once_with(SCOPE, claims=None, tenant_id=None) + credential.request_token.assert_called_once_with(SCOPE, claims=None, tenant_id=None) assert token.token == MockCredential.NEW_TOKEN.token @@ -112,5 +112,5 @@ async def test_retry_delay(): for i in range(4): token = await credential.get_token(SCOPE) assert token.token == CACHED_TOKEN - credential.acquire_token_silently.assert_called_with(SCOPE) - credential.request_token.assert_called_once_with(SCOPE) + credential.acquire_token_silently.assert_called_with(SCOPE, claims=None, tenant_id=None) + credential.request_token.assert_called_once_with(SCOPE, claims=None, tenant_id=None) diff --git a/sdk/identity/azure-identity/tests/test_vscode_credential_async.py b/sdk/identity/azure-identity/tests/test_vscode_credential_async.py index ec4bbcdacfc7..1879b20a85ed 100644 --- a/sdk/identity/azure-identity/tests/test_vscode_credential_async.py +++ b/sdk/identity/azure-identity/tests/test_vscode_credential_async.py @@ -160,7 +160,7 @@ async def test_redeem_token(): credential = get_credential(_client=mock_client) token = await credential.get_token("scope") assert token is expected_token - token_by_refresh_token.assert_called_with(("scope",), expected_value) + token_by_refresh_token.assert_called_with(("scope",), expected_value, claims=None, tenant_id=None) @pytest.mark.asyncio From be836ab6d3268d15d44be7931cc5897100242683 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Thu, 27 Jul 2023 18:30:07 -0700 Subject: [PATCH 09/21] Remove unused imports --- .../azure/identity/_credentials/azure_powershell.py | 2 +- .../azure-identity/azure/identity/aio/_credentials/azd_cli.py | 2 +- .../azure-identity/azure/identity/aio/_credentials/azure_cli.py | 2 +- .../azure/identity/aio/_credentials/azure_powershell.py | 2 +- .../azure-identity/azure/identity/aio/_credentials/chained.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py index 9b68aa9210b0..b7a0b68abaf6 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py @@ -6,7 +6,7 @@ import logging import subprocess import sys -from typing import List, Tuple, Optional, Any +from typing import List, Tuple, Optional from azure.core.credentials import AccessToken from azure.core.exceptions import ClientAuthenticationError diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py index ef2d33717e86..90bc1b545df6 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py @@ -6,7 +6,7 @@ import os import shutil import sys -from typing import Any, List, Optional +from typing import List, Optional from azure.core.exceptions import ClientAuthenticationError from azure.core.credentials import AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py index 8cf9342bd649..454012a68f72 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py @@ -6,7 +6,7 @@ import os import shutil import sys -from typing import List, Any, Optional +from typing import List, Optional from azure.core.exceptions import ClientAuthenticationError from azure.core.credentials import AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py index 922b4e0173b3..fb1c72b28e13 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py @@ -4,7 +4,7 @@ # ------------------------------------ import asyncio import sys -from typing import cast, List, Any, Optional +from typing import cast, List, Optional from azure.core.credentials import AccessToken from .._internal import AsyncContextManager diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py index 81cf813712e1..ad1afbf84e85 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py @@ -4,7 +4,7 @@ # ------------------------------------ import asyncio import logging -from typing import Optional, TYPE_CHECKING, Any +from typing import Optional, TYPE_CHECKING from azure.core.exceptions import ClientAuthenticationError from azure.core.credentials import AccessToken From becd6b52197a666ce5af156558ef1faa4d2a939a Mon Sep 17 00:00:00 2001 From: mccoyp Date: Fri, 28 Jul 2023 12:17:58 -0700 Subject: [PATCH 10/21] Update sample and changelog --- sdk/identity/azure-identity/CHANGELOG.md | 3 +++ .../samples/custom_credentials.py | 25 ++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/sdk/identity/azure-identity/CHANGELOG.md b/sdk/identity/azure-identity/CHANGELOG.md index 6d5ea8f50ac1..f70a19de4d9a 100644 --- a/sdk/identity/azure-identity/CHANGELOG.md +++ b/sdk/identity/azure-identity/CHANGELOG.md @@ -14,6 +14,9 @@ ### Bugs Fixed +- Credential types correctly implement `azure-core`'s `TokenCredential` protocol. + ([#25175](https://github.com/Azure/azure-sdk-for-python/issues/25175)) + ### Other Changes ## 1.14.0b2 (2023-07-11) diff --git a/sdk/identity/azure-identity/samples/custom_credentials.py b/sdk/identity/azure-identity/samples/custom_credentials.py index 2787c2454214..6177a4dbf0a7 100644 --- a/sdk/identity/azure-identity/samples/custom_credentials.py +++ b/sdk/identity/azure-identity/samples/custom_credentials.py @@ -5,34 +5,31 @@ """Demonstrates custom credential implementations using existing access tokens and an MSAL client""" import time -from typing import TYPE_CHECKING +from typing import Optional, Union from azure.core.credentials import AccessToken from azure.identity import AuthenticationRequiredError, AzureAuthorityHosts import msal -if TYPE_CHECKING: - from typing import Any, Union - class StaticTokenCredential(object): - """Authenticates with a previously acquired access token + """Authenticates with a previously-acquired access token Note that an access token is valid only for certain resources and eventually expires. This credential is therefore quite limited. An application using it must ensure the token is valid and contains all claims required by any service client given an instance of this credential. """ - def __init__(self, access_token): - # type: (Union[str, AccessToken]) -> None + def __init__(self, access_token: Union[str, AccessToken]) -> None: if isinstance(access_token, AccessToken): self._token = access_token else: # setting expires_on in the past causes Azure SDK clients to call get_token every time they need a token self._token = AccessToken(token=access_token, expires_on=0) - def get_token(self, *scopes, **kwargs): - # type: (*str, **Any) -> AccessToken + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """get_token is the only method a credential must implement""" return self._token @@ -41,18 +38,18 @@ def get_token(self, *scopes, **kwargs): class MsalTokenCredential(object): """Uses an MSAL client directly to obtain access tokens with an interactive flow.""" - def __init__(self, tenant_id, client_id): - # type: (str, str) -> None + def __init__(self, tenant_id: str, client_id: str) -> None: self._app = msal.PublicClientApplication( client_id=client_id, authority="https://{}/{}".format(AzureAuthorityHosts.AZURE_PUBLIC_CLOUD, tenant_id) ) - def get_token(self, *scopes, **kwargs): - # type: (*str, **Any) -> AccessToken + def get_token( + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + ) -> AccessToken: """get_token is the only method a credential must implement""" now = int(time.time()) - result = self._app.acquire_token_interactive(list(scopes), **kwargs) + result = self._app.acquire_token_interactive(list(scopes), claims=claims, tenant_id=tenant_id, **kwargs) try: return AccessToken(result["access_token"], now + int(result["expires_in"])) From 65d7552acabc44aac13e92179b32858334f77f29 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Fri, 28 Jul 2023 12:20:05 -0700 Subject: [PATCH 11/21] Refine language on unused args --- .../azure-identity/azure/identity/_credentials/application.py | 4 ++-- .../azure/identity/_credentials/authorization_code.py | 2 +- .../azure-identity/azure/identity/_credentials/azd_cli.py | 2 +- .../azure-identity/azure/identity/_credentials/azure_cli.py | 2 +- .../azure/identity/_credentials/azure_powershell.py | 2 +- .../azure-identity/azure/identity/_credentials/chained.py | 4 ++-- .../azure-identity/azure/identity/_credentials/default.py | 2 +- .../azure-identity/azure/identity/_credentials/environment.py | 2 +- .../azure/identity/_credentials/managed_identity.py | 4 ++-- .../azure/identity/_credentials/shared_cache.py | 2 +- .../azure-identity/azure/identity/_credentials/vscode.py | 4 ++-- .../azure/identity/_internal/get_token_mixin.py | 2 +- .../azure/identity/aio/_credentials/application.py | 4 ++-- .../azure/identity/aio/_credentials/authorization_code.py | 2 +- .../azure-identity/azure/identity/aio/_credentials/azd_cli.py | 2 +- .../azure/identity/aio/_credentials/azure_cli.py | 2 +- .../azure/identity/aio/_credentials/azure_powershell.py | 2 +- .../azure-identity/azure/identity/aio/_credentials/chained.py | 4 ++-- .../azure-identity/azure/identity/aio/_credentials/default.py | 2 +- .../azure/identity/aio/_credentials/environment.py | 2 +- .../azure/identity/aio/_credentials/managed_identity.py | 4 ++-- .../azure/identity/aio/_credentials/shared_cache.py | 2 +- .../azure-identity/azure/identity/aio/_credentials/vscode.py | 2 +- .../azure/identity/aio/_internal/get_token_mixin.py | 2 +- 24 files changed, 31 insertions(+), 31 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/application.py b/sdk/identity/azure-identity/azure/identity/_credentials/application.py index 5783a5ff41d9..3a0cf89271d0 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/application.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/application.py @@ -73,8 +73,8 @@ def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not used by this credential; any value provided will be ignored. - :keyword str tenant_id: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. + :keyword str tenant_id: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py b/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py index d6980b670d20..33bbd19e06db 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py @@ -76,7 +76,7 @@ def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py index c1185e4ae203..651cc1f84f4d 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py @@ -103,7 +103,7 @@ def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py index d743524273ca..021b74db4ec2 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py @@ -81,7 +81,7 @@ def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py index b7a0b68abaf6..45c1b1843cec 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py @@ -95,7 +95,7 @@ def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py index f08fc2cfc363..861c55797e22 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py @@ -79,8 +79,8 @@ def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not used by this credential; any value provided will be ignored. - :keyword str tenant_id: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. + :keyword str tenant_id: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/default.py b/sdk/identity/azure-identity/azure/identity/_credentials/default.py index f22d34655c7d..7fe61979c3d0 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/default.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/default.py @@ -206,7 +206,7 @@ def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py index ddd60199573c..f45f65df0262 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py @@ -131,7 +131,7 @@ def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py index 1ef4b259d7c9..2c56e23a36ba 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py @@ -119,8 +119,8 @@ def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not used by this credential; any value provided will be ignored. - :keyword str tenant_id: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. + :keyword str tenant_id: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py index 76666713effd..1de2c3497cca 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py @@ -66,7 +66,7 @@ def get_token( https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str claims: additional claims required in the token, such as those returned in a resource provider's claims challenge following an authorization failure - :keyword str tenant_id: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: not supported by this credential. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py index 3fa7fbf65560..d62206020fe2 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py @@ -150,8 +150,8 @@ def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not used by this credential; any value provided will be ignored. - :keyword str tenant_id: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. + :keyword str tenant_id: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py index 87871ded28a2..156cbb95497c 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py @@ -64,7 +64,7 @@ def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py index 2b5638258ad7..7b4ea8efd1e7 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py @@ -72,8 +72,8 @@ async def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not used by this credential; any value provided will be ignored. - :keyword str tenant_id: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. + :keyword str tenant_id: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py index dde09e36202c..70b1c6c3d2d0 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py @@ -83,7 +83,7 @@ async def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py index 90bc1b545df6..64f0cad4e6fe 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py @@ -91,7 +91,7 @@ async def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py index 454012a68f72..e056dfa2a32a 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py @@ -72,7 +72,7 @@ async def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py index fb1c72b28e13..0a907db486d6 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py @@ -66,7 +66,7 @@ async def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py index ad1afbf84e85..fc467d52d6b9 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py @@ -63,8 +63,8 @@ async def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not used by this credential; any value provided will be ignored. - :keyword str tenant_id: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. + :keyword str tenant_id: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py index 430f42183b44..5af51876ab94 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py @@ -187,7 +187,7 @@ async def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py index c78c90871f69..d68af184e509 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py @@ -104,7 +104,7 @@ async def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py index 458d1db7082d..0fe66bae5b3e 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py @@ -124,8 +124,8 @@ async def get_token( :param str scopes: desired scope for the access token. This credential allows only one scope per request. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not used by this credential; any value provided will be ignored. - :keyword str tenant_id: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. + :keyword str tenant_id: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py index d14b909eeb32..aec0e03efd89 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py @@ -55,7 +55,7 @@ async def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py index 153e3d7ed614..d02d3e8ce828 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py @@ -58,7 +58,7 @@ async def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py b/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py index 3223850f5674..0f29f5302199 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py @@ -64,7 +64,7 @@ async def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str claims: not supported by this credential. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. From fc5410b5c10f854d3be6cde0741844734ce74223 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Tue, 1 Aug 2023 16:50:06 -0700 Subject: [PATCH 12/21] Test for kwargs in transport --- .../tests/test_application_credential.py | 5 ++- .../test_application_credential_async.py | 5 ++- .../azure-identity/tests/test_auth_code.py | 15 +++++-- .../tests/test_auth_code_async.py | 15 +++++-- .../tests/test_certificate_credential.py | 20 ++++++++-- .../test_certificate_credential_async.py | 15 +++++-- .../tests/test_client_secret_credential.py | 19 +++++++-- .../test_client_secret_credential_async.py | 14 +++++-- .../tests/test_imds_credential.py | 5 ++- .../tests/test_imds_credential_async.py | 5 ++- .../tests/test_interactive_credential.py | 10 ++++- .../tests/test_managed_identity.py | 25 +++++++++--- .../tests/test_managed_identity_async.py | 25 +++++++++--- sdk/identity/azure-identity/tests/test_obo.py | 10 ++++- .../azure-identity/tests/test_obo_async.py | 20 ++++++++-- .../tests/test_shared_cache_credential.py | 40 +++++++++++++++---- .../test_shared_cache_credential_async.py | 25 +++++++++--- .../tests/test_vscode_credential.py | 15 +++++-- .../tests/test_vscode_credential_async.py | 15 +++++-- 19 files changed, 242 insertions(+), 61 deletions(-) diff --git a/sdk/identity/azure-identity/tests/test_application_credential.py b/sdk/identity/azure-identity/tests/test_application_credential.py index 49235c7fd576..689bc044e095 100644 --- a/sdk/identity/azure-identity/tests/test_application_credential.py +++ b/sdk/identity/azure-identity/tests/test_application_credential.py @@ -22,7 +22,10 @@ def test_get_token(): expected_token = "***" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant_id = parsed.path.split("/")[1] if "/oauth2/v2.0/token" in request.url: diff --git a/sdk/identity/azure-identity/tests/test_application_credential_async.py b/sdk/identity/azure-identity/tests/test_application_credential_async.py index ce4b3c8e192c..f3cfab729897 100644 --- a/sdk/identity/azure-identity/tests/test_application_credential_async.py +++ b/sdk/identity/azure-identity/tests/test_application_credential_async.py @@ -79,7 +79,10 @@ def test_initialization(mock_credential, expect_argument): async def test_get_token(): expected_token = "***" - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs return mock_response(json_payload=build_aad_response(access_token=expected_token)) with patch.dict("os.environ", {var: "..." for var in EnvironmentVariables.CLIENT_SECRET_VARS}, clear=True): diff --git a/sdk/identity/azure-identity/tests/test_auth_code.py b/sdk/identity/azure-identity/tests/test_auth_code.py index 6ffcbec0b0a0..e3ba13bf2971 100644 --- a/sdk/identity/azure-identity/tests/test_auth_code.py +++ b/sdk/identity/azure-identity/tests/test_auth_code.py @@ -30,7 +30,10 @@ def test_no_scopes(): def test_policies_configurable(): policy = Mock(spec_set=SansIOHTTPPolicy, on_request=Mock()) - def send(*_, **__): + def send(*_, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs return mock_response(json_payload=build_aad_response(access_token="**")) credential = AuthorizationCodeCredential( @@ -142,7 +145,10 @@ def test_multitenant_authentication(): second_tenant = "second-tenant" second_token = first_token * 2 - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] assert tenant in (first_tenant, second_tenant), 'unexpected tenant "{}"'.format(tenant) @@ -175,7 +181,10 @@ def test_multitenant_authentication_not_allowed(): expected_tenant = "expected-tenant" expected_token = "***" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] token = expected_token if tenant == expected_tenant else expected_token * 2 diff --git a/sdk/identity/azure-identity/tests/test_auth_code_async.py b/sdk/identity/azure-identity/tests/test_auth_code_async.py index baf786b9a9b5..8bd8946d4205 100644 --- a/sdk/identity/azure-identity/tests/test_auth_code_async.py +++ b/sdk/identity/azure-identity/tests/test_auth_code_async.py @@ -30,7 +30,10 @@ async def test_no_scopes(): async def test_policies_configurable(): policy = Mock(spec_set=SansIOHTTPPolicy, on_request=Mock()) - async def send(*_, **__): + async def send(*_, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs return mock_response(json_payload=build_aad_response(access_token="**")) credential = AuthorizationCodeCredential( @@ -166,7 +169,10 @@ async def test_multitenant_authentication(): second_tenant = "second-tenant" second_token = first_token * 2 - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] assert tenant in (first_tenant, second_tenant), 'unexpected tenant "{}"'.format(tenant) @@ -199,7 +205,10 @@ async def test_multitenant_authentication_not_allowed(): expected_tenant = "expected-tenant" expected_token = "***" - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] token = expected_token if tenant == expected_tenant else expected_token * 2 diff --git a/sdk/identity/azure-identity/tests/test_certificate_credential.py b/sdk/identity/azure-identity/tests/test_certificate_credential.py index 9f9674196234..d75fe489d06d 100644 --- a/sdk/identity/azure-identity/tests/test_certificate_credential.py +++ b/sdk/identity/azure-identity/tests/test_certificate_credential.py @@ -299,7 +299,10 @@ def test_token_cache_persistent(cert_path, cert_password): access_token = "foo token" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] if "/oauth2/v2.0/token" not in parsed.path: @@ -337,7 +340,10 @@ def test_token_cache_memory(cert_path, cert_password): """The credential should default to in-memory cache if no persistence options are provided.""" access_token = "foo token" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] if "/oauth2/v2.0/token" not in parsed.path: @@ -427,7 +433,10 @@ def test_multitenant_authentication(cert_path, cert_password): second_tenant = "second-tenant" second_token = first_token * 2 - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] assert tenant in (first_tenant, second_tenant, "common"), 'unexpected tenant "{}"'.format(tenant) @@ -464,7 +473,10 @@ def test_multitenant_authentication_backcompat(cert_path, cert_password): expected_tenant = "expected-tenant" expected_token = "***" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) if "/oauth2/v2.0/token" not in parsed.path: return get_discovery_response("https://{}/{}".format(parsed.netloc, expected_tenant)) diff --git a/sdk/identity/azure-identity/tests/test_certificate_credential_async.py b/sdk/identity/azure-identity/tests/test_certificate_credential_async.py index c0a5d6dd5863..e93990d92cfe 100644 --- a/sdk/identity/azure-identity/tests/test_certificate_credential_async.py +++ b/sdk/identity/azure-identity/tests/test_certificate_credential_async.py @@ -76,7 +76,10 @@ async def test_context_manager(): async def test_policies_configurable(): policy = Mock(spec_set=SansIOHTTPPolicy, on_request=Mock()) - async def send(*_, **__): + async def send(*_, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs return mock_response(json_payload=build_aad_response(access_token="**")) credential = CertificateCredential( @@ -351,7 +354,10 @@ async def test_multitenant_authentication(cert_path, cert_password): second_tenant = "second-tenant" second_token = first_token * 2 - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] assert tenant in (first_tenant, second_tenant), 'unexpected tenant "{}"'.format(tenant) @@ -386,7 +392,10 @@ async def test_multitenant_authentication_backcompat(cert_path, cert_password): expected_tenant = "expected-tenant" expected_token = "***" - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] token = expected_token if tenant == expected_tenant else expected_token * 2 diff --git a/sdk/identity/azure-identity/tests/test_client_secret_credential.py b/sdk/identity/azure-identity/tests/test_client_secret_credential.py index 75074f5f1cab..5a2c3023767b 100644 --- a/sdk/identity/azure-identity/tests/test_client_secret_credential.py +++ b/sdk/identity/azure-identity/tests/test_client_secret_credential.py @@ -153,7 +153,10 @@ def test_token_cache_persistent(): access_token = "foo token" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] if "/oauth2/v2.0/token" not in parsed.path: @@ -188,7 +191,10 @@ def test_token_cache_memory(): """The credential should default to in-memory cache if no persistence options are provided.""" access_token = "foo token" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] if "/oauth2/v2.0/token" not in parsed.path: @@ -264,7 +270,9 @@ def test_multitenant_authentication(): second_token = first_token * 2 def send(request, **kwargs): - assert "tenant_id" not in kwargs, "tenant_id kwarg shouldn't get passed to send method" + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] @@ -310,7 +318,10 @@ def test_multitenant_authentication_not_allowed(): expected_tenant = "expected-tenant" expected_token = "***" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) if "/oauth2/v2.0/token" not in parsed.path: return get_discovery_response("https://{}/{}".format(parsed.netloc, expected_tenant)) diff --git a/sdk/identity/azure-identity/tests/test_client_secret_credential_async.py b/sdk/identity/azure-identity/tests/test_client_secret_credential_async.py index 68c6ba161a46..d84105807014 100644 --- a/sdk/identity/azure-identity/tests/test_client_secret_credential_async.py +++ b/sdk/identity/azure-identity/tests/test_client_secret_credential_async.py @@ -67,7 +67,10 @@ async def test_context_manager(): async def test_policies_configurable(): policy = Mock(spec_set=SansIOHTTPPolicy, on_request=Mock()) - async def send(*_, **__): + async def send(*_, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs return mock_response(json_payload=build_aad_response(access_token="**")) credential = ClientSecretCredential( @@ -312,7 +315,9 @@ async def test_multitenant_authentication(): second_token = first_token * 2 async def send(request, **kwargs): - assert "tenant_id" not in kwargs, "tenant_id kwarg shouldn't get passed to send method" + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] @@ -360,7 +365,10 @@ async def test_multitenant_authentication_not_allowed(): expected_tenant = "expected-tenant" expected_token = "***" - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] token = expected_token if tenant == expected_tenant else expected_token * 2 diff --git a/sdk/identity/azure-identity/tests/test_imds_credential.py b/sdk/identity/azure-identity/tests/test_imds_credential.py index 7eec40eb9bae..2ecf0cc0bf8b 100644 --- a/sdk/identity/azure-identity/tests/test_imds_credential.py +++ b/sdk/identity/azure-identity/tests/test_imds_credential.py @@ -62,7 +62,10 @@ def test_unexpected_error(): for code in range(401, 600): - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` kwargs from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs if "resource" not in request.query: # availability probe return mock_response(status_code=400, json_payload={}) diff --git a/sdk/identity/azure-identity/tests/test_imds_credential_async.py b/sdk/identity/azure-identity/tests/test_imds_credential_async.py index d8f13e62cfb9..fb631121da18 100644 --- a/sdk/identity/azure-identity/tests/test_imds_credential_async.py +++ b/sdk/identity/azure-identity/tests/test_imds_credential_async.py @@ -92,7 +92,10 @@ async def test_unexpected_error(): for code in range(401, 600): - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` kwargs from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs if "resource" not in request.query: # availability probe return mock_response(status_code=400, json_payload={}) diff --git a/sdk/identity/azure-identity/tests/test_interactive_credential.py b/sdk/identity/azure-identity/tests/test_interactive_credential.py index de1c3f550b91..30c6cd012505 100644 --- a/sdk/identity/azure-identity/tests/test_interactive_credential.py +++ b/sdk/identity/azure-identity/tests/test_interactive_credential.py @@ -328,7 +328,10 @@ def request_token(*args, **kwargs): ), ) - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert "/oauth2/v2.0/token" not in request.url, 'mock "request_token" should prevent sending a token request' parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] @@ -371,7 +374,10 @@ def request_token(*_, **__): ), ) - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert "/oauth2/v2.0/token" not in request.url, 'mock "request_token" should prevent sending a token request' parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] diff --git a/sdk/identity/azure-identity/tests/test_managed_identity.py b/sdk/identity/azure-identity/tests/test_managed_identity.py index 3c1a373a81e9..8f8aec2da44e 100644 --- a/sdk/identity/azure-identity/tests/test_managed_identity.py +++ b/sdk/identity/azure-identity/tests/test_managed_identity.py @@ -487,7 +487,10 @@ def test_app_service_2019_08_01(): new_secret = "new-expected-secret" scope = "scope" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert request.url.startswith(new_endpoint) assert request.method == "GET" assert request.headers["X-IDENTITY-HEADER"] == new_secret @@ -531,7 +534,10 @@ def test_app_service_2019_08_01_tenant_id(): new_secret = "new-expected-secret" scope = "scope" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert request.url.startswith(new_endpoint) assert request.method == "GET" assert request.headers["X-IDENTITY-HEADER"] == new_secret @@ -707,7 +713,10 @@ def test_client_id_none(): expected_access_token = "****" scope = "scope" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert "client_id" not in request.query if request.data: assert "client_id" not in request.body # Cloud Shell @@ -779,7 +788,10 @@ def test_service_fabric(): thumbprint = "SHA1HEX" scope = "scope" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert request.url.startswith(endpoint) assert request.method == "GET" assert request.headers["Secret"] == secret @@ -816,7 +828,10 @@ def test_service_fabric_tenant_id(): thumbprint = "SHA1HEX" scope = "scope" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert request.url.startswith(endpoint) assert request.method == "GET" assert request.headers["Secret"] == secret diff --git a/sdk/identity/azure-identity/tests/test_managed_identity_async.py b/sdk/identity/azure-identity/tests/test_managed_identity_async.py index c36050fe71c3..ff91e3816edb 100644 --- a/sdk/identity/azure-identity/tests/test_managed_identity_async.py +++ b/sdk/identity/azure-identity/tests/test_managed_identity_async.py @@ -451,7 +451,10 @@ async def test_app_service_2019_08_01(): new_secret = "new-expected-secret" scope = "scope" - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert request.url.startswith(new_endpoint) assert request.method == "GET" assert request.headers["X-IDENTITY-HEADER"] == new_secret @@ -494,7 +497,10 @@ async def test_app_service_2019_08_01_tenant_id(): new_secret = "new-expected-secret" scope = "scope" - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert request.url.startswith(new_endpoint) assert request.method == "GET" assert request.headers["X-IDENTITY-HEADER"] == new_secret @@ -592,7 +598,10 @@ async def test_client_id_none(): expected_access_token = "****" scope = "scope" - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert "client_id" not in request.query # IMDS if request.data: assert "client_id" not in request.body # Cloud Shell @@ -742,7 +751,10 @@ async def test_service_fabric(): thumbprint = "SHA1HEX" scope = "scope" - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert request.url.startswith(endpoint) assert request.method == "GET" assert request.headers["Secret"] == secret @@ -780,7 +792,10 @@ async def test_service_fabric_tenant_id(): thumbprint = "SHA1HEX" scope = "scope" - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert request.url.startswith(endpoint) assert request.method == "GET" assert request.headers["Secret"] == secret diff --git a/sdk/identity/azure-identity/tests/test_obo.py b/sdk/identity/azure-identity/tests/test_obo.py index 8256f103914e..4761dc40a50a 100644 --- a/sdk/identity/azure-identity/tests/test_obo.py +++ b/sdk/identity/azure-identity/tests/test_obo.py @@ -100,7 +100,10 @@ def test_multitenant_authentication(): second_tenant = "second-tenant" second_token = first_token * 2 - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert request.headers["User-Agent"].startswith(USER_AGENT) parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] @@ -193,7 +196,10 @@ def test_no_scopes(): def test_policies_configurable(): policy = Mock(spec_set=SansIOHTTPPolicy, on_request=Mock(), on_exception=lambda _: False) - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] if "/oauth2/v2.0/token" not in parsed.path: diff --git a/sdk/identity/azure-identity/tests/test_obo_async.py b/sdk/identity/azure-identity/tests/test_obo_async.py index adf4a3846d61..8c143d4b72e2 100644 --- a/sdk/identity/azure-identity/tests/test_obo_async.py +++ b/sdk/identity/azure-identity/tests/test_obo_async.py @@ -128,7 +128,10 @@ async def test_multitenant_authentication(): second_tenant = "second-tenant" second_token = first_token * 2 - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert request.headers["User-Agent"].startswith(USER_AGENT) parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] @@ -174,7 +177,10 @@ async def test_authority(authority): expected_authority = "https://{}/{}".format(expected_netloc, tenant_id) expected_token = "***" - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs assert request.url.startswith(expected_authority) return mock_response(json_payload=build_aad_response(access_token=expected_token)) @@ -203,7 +209,10 @@ async def send(request, **_): async def test_policies_configurable(): policy = Mock(spec_set=SansIOHTTPPolicy, on_request=Mock(), on_exception=lambda _: False) - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] if "/oauth2/v2.0/token" not in parsed.path: @@ -235,7 +244,10 @@ async def test_refresh_token(): refresh_token = "refresh-token" requests = 0 - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs nonlocal requests assert requests < 3, "unexpected request" requests += 1 diff --git a/sdk/identity/azure-identity/tests/test_shared_cache_credential.py b/sdk/identity/azure-identity/tests/test_shared_cache_credential.py index 281aecf48757..78b02142724c 100644 --- a/sdk/identity/azure-identity/tests/test_shared_cache_credential.py +++ b/sdk/identity/azure-identity/tests/test_shared_cache_credential.py @@ -103,7 +103,10 @@ def test_no_scopes(): def test_policies_configurable(): policy = Mock(spec_set=SansIOHTTPPolicy, on_request=Mock()) - def send(*_, **__): + def send(*_, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs return mock_response(json_payload=build_aad_response(access_token="**")) credential = SharedTokenCacheCredential( @@ -585,7 +588,10 @@ def test_authority_environment_variable(): def test_authentication_record_empty_cache(): record = AuthenticationRecord("tenant-id", "client_id", "authority", "home_account_id", "username") - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs # expecting only MSAL discovery requests assert request.method == "GET" return get_discovery_response() @@ -607,7 +613,10 @@ def test_authentication_record_no_match(): username = "me" record = AuthenticationRecord(tenant_id, client_id, authority, home_account_id, username) - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs # expecting only MSAL discovery requests assert request.method == "GET" return get_discovery_response() @@ -811,7 +820,10 @@ def mock_send(request, **_): def test_client_capabilities(): """the credential should configure MSAL for capability CP1 only if enable_cae is passed.""" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs # expecting only the discovery requests triggered by creating an msal.PublicClientApplication # because the cache is empty--the credential shouldn't send a token request return get_discovery_response("https://localhost/tenant") @@ -836,7 +848,10 @@ def send(request, **_): def test_within_dac_error(): - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs # expecting only the discovery requests triggered by creating an msal.PublicClientApplication # because the cache is empty--the credential shouldn't send a token request return get_discovery_response("https://localhost/tenant") @@ -880,7 +895,10 @@ def test_multitenant_authentication(): second_tenant = "second-tenant" second_token = first_token * 2 - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant_id = parsed.path.split("/")[1] assert tenant_id in (default_tenant, second_tenant), 'unexpected tenant "{}"'.format(tenant_id) @@ -925,7 +943,10 @@ def test_multitenant_authentication_auth_record(): home_account_id = object_id + "." + default_tenant record = AuthenticationRecord(default_tenant, "client-id", authority, home_account_id, "user") - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant_id = parsed.path.split("/")[1] if "/oauth2/v2.0/token" not in request.url: @@ -1000,7 +1021,10 @@ def test_multitenant_authentication_not_allowed(): default_tenant = "organizations" expected_token = "***" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant_id = parsed.path.split("/")[1] assert tenant_id == default_tenant diff --git a/sdk/identity/azure-identity/tests/test_shared_cache_credential_async.py b/sdk/identity/azure-identity/tests/test_shared_cache_credential_async.py index df013eac426c..1982b98ccf7e 100644 --- a/sdk/identity/azure-identity/tests/test_shared_cache_credential_async.py +++ b/sdk/identity/azure-identity/tests/test_shared_cache_credential_async.py @@ -42,7 +42,10 @@ async def test_no_scopes(): @pytest.mark.asyncio async def test_close(): - async def send(*_, **__): + async def send(*_, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs return mock_response(json_payload=build_aad_response(access_token="**")) transport = AsyncMockTransport(send=send) @@ -60,7 +63,10 @@ async def send(*_, **__): @pytest.mark.asyncio async def test_context_manager(): - async def send(*_, **__): + async def send(*_, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs return mock_response(json_payload=build_aad_response(access_token="**")) transport = AsyncMockTransport(send=send) @@ -102,7 +108,10 @@ async def test_context_manager_no_cache(): async def test_policies_configurable(): policy = Mock(spec_set=SansIOHTTPPolicy, on_request=Mock()) - async def send(*_, **__): + async def send(*_, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs return mock_response(json_payload=build_aad_response(access_token="**")) credential = SharedTokenCacheCredential( @@ -643,7 +652,10 @@ async def test_multitenant_authentication(): second_tenant = "second-tenant" second_token = first_token * 2 - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant_id = parsed.path.split("/")[1] return mock_response( @@ -681,7 +693,10 @@ async def test_multitenant_authentication_not_allowed(): default_tenant = "organizations" expected_token = "***" - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant_id = parsed.path.split("/")[1] assert tenant_id == default_tenant diff --git a/sdk/identity/azure-identity/tests/test_vscode_credential.py b/sdk/identity/azure-identity/tests/test_vscode_credential.py index 0c2715bab939..3cc495122afd 100644 --- a/sdk/identity/azure-identity/tests/test_vscode_credential.py +++ b/sdk/identity/azure-identity/tests/test_vscode_credential.py @@ -87,7 +87,10 @@ def test_no_scopes(): def test_policies_configurable(): policy = mock.Mock(spec_set=SansIOHTTPPolicy, on_request=mock.Mock()) - def send(*_, **__): + def send(*_, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs return mock_response(json_payload=build_aad_response(access_token="**")) credential = get_credential(policies=[policy], transport=mock.Mock(send=send)) @@ -285,7 +288,10 @@ def test_multitenant_authentication(): second_tenant = "second-tenant" second_token = first_token * 2 - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] assert tenant in (first_tenant, second_tenant), 'unexpected tenant "{}"'.format(tenant) @@ -315,7 +321,10 @@ def test_multitenant_authentication_not_allowed(): expected_tenant = "expected-tenant" expected_token = "***" - def send(request, **_): + def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] token = expected_token if tenant == expected_tenant else expected_token * 2 diff --git a/sdk/identity/azure-identity/tests/test_vscode_credential_async.py b/sdk/identity/azure-identity/tests/test_vscode_credential_async.py index 1879b20a85ed..c6bb7c8eef20 100644 --- a/sdk/identity/azure-identity/tests/test_vscode_credential_async.py +++ b/sdk/identity/azure-identity/tests/test_vscode_credential_async.py @@ -85,7 +85,10 @@ async def test_no_scopes(): async def test_policies_configurable(): policy = mock.Mock(spec_set=SansIOHTTPPolicy, on_request=mock.Mock()) - async def send(*_, **__): + async def send(*_, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs return mock_response(json_payload=build_aad_response(access_token="**")) credential = get_credential(policies=[policy], transport=mock.Mock(send=send)) @@ -274,7 +277,10 @@ async def test_multitenant_authentication(): second_tenant = "second-tenant" second_token = first_token * 2 - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] assert tenant in (first_tenant, second_tenant), 'unexpected tenant "{}"'.format(tenant) @@ -305,7 +311,10 @@ async def test_multitenant_authentication_not_allowed(): expected_tenant = "expected-tenant" expected_token = "***" - async def send(request, **_): + async def send(request, **kwargs): + # ensure the `claims` and `tenant_id` keywords from credential's `get_token` method don't make it to transport + assert "claims" not in kwargs + assert "tenant_id" not in kwargs parsed = urlparse(request.url) tenant = parsed.path.split("/")[1] token = expected_token if tenant == expected_tenant else expected_token * 2 From f052ada48d12b113d18d8d83c3732dfdfde79076 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Tue, 1 Aug 2023 17:08:42 -0700 Subject: [PATCH 13/21] Update chained/default docstrings --- .../azure-identity/azure/identity/_credentials/chained.py | 5 +++-- .../azure-identity/azure/identity/_credentials/default.py | 3 ++- .../azure/identity/aio/_credentials/chained.py | 5 +++-- .../azure/identity/aio/_credentials/default.py | 3 ++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py index 861c55797e22..b932f94ebd76 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py @@ -79,8 +79,9 @@ def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not supported by this credential. - :keyword str tenant_id: not supported by this credential. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. + :keyword str tenant_id: optional tenant to include in the token request. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/default.py b/sdk/identity/azure-identity/azure/identity/_credentials/default.py index 7fe61979c3d0..9e03dcc99166 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/default.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/default.py @@ -205,8 +205,9 @@ def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py index fc467d52d6b9..4db2a968af4a 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py @@ -63,8 +63,9 @@ async def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not supported by this credential. - :keyword str tenant_id: not supported by this credential. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. + :keyword str tenant_id: optional tenant to include in the token request. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py index 5af51876ab94..70d928f2ff51 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py @@ -186,8 +186,9 @@ async def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken From 7fac8ac232db86db8be19ba86340acc26754bb75 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Tue, 1 Aug 2023 17:14:11 -0700 Subject: [PATCH 14/21] Remove claims from resolve_tenant calls --- .../azure-identity/azure/identity/_credentials/azd_cli.py | 1 - .../azure-identity/azure/identity/_credentials/azure_cli.py | 1 - .../azure/identity/_credentials/azure_powershell.py | 1 - .../azure-identity/azure/identity/aio/_credentials/azd_cli.py | 1 - .../azure-identity/azure/identity/aio/_credentials/azure_cli.py | 1 - .../azure/identity/aio/_credentials/azure_powershell.py | 1 - 6 files changed, 6 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py index 651cc1f84f4d..5f1d75cd2216 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py @@ -123,7 +123,6 @@ def get_token( default_tenant=self.tenant_id, tenant_id=tenant_id, additionally_allowed_tenants=self._additionally_allowed_tenants, - claims=claims, **kwargs, ) if tenant: diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py index 021b74db4ec2..0d39cc7f237d 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py @@ -97,7 +97,6 @@ def get_token( default_tenant=self.tenant_id, tenant_id=tenant_id, additionally_allowed_tenants=self._additionally_allowed_tenants, - claims=claims, **kwargs, ) if tenant: diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py index 45c1b1843cec..7f75c8b59040 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py @@ -109,7 +109,6 @@ def get_token( default_tenant=self.tenant_id, tenant_id=tenant_id, additionally_allowed_tenants=self._additionally_allowed_tenants, - claims=claims, **kwargs, ) command_line = get_command_line(scopes, tenant_id) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py index 64f0cad4e6fe..9204652f2089 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py @@ -112,7 +112,6 @@ async def get_token( default_tenant=self.tenant_id, tenant_id=tenant_id, additionally_allowed_tenants=self._additionally_allowed_tenants, - claims=claims, **kwargs, ) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py index e056dfa2a32a..6e1716879b60 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py @@ -90,7 +90,6 @@ async def get_token( default_tenant=self.tenant_id, tenant_id=tenant_id, additionally_allowed_tenants=self._additionally_allowed_tenants, - claims=claims, **kwargs, ) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py index 0a907db486d6..50e2a3b8570d 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py @@ -83,7 +83,6 @@ async def get_token( default_tenant=self.tenant_id, tenant_id=tenant_id, additionally_allowed_tenants=self._additionally_allowed_tenants, - claims=claims, **kwargs, ) command_line = get_command_line(scopes, tenant_id) From 890268ecb55cf4426ca9cc3db450f6ffaf9ec907 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Tue, 1 Aug 2023 17:40:04 -0700 Subject: [PATCH 15/21] Pylint --- .../azure-identity/azure/identity/_credentials/azd_cli.py | 4 ++-- .../azure-identity/azure/identity/_credentials/azure_cli.py | 4 ++-- .../azure/identity/_credentials/azure_powershell.py | 4 ++-- .../azure/identity/aio/_credentials/azd_cli.py | 6 +++--- .../azure/identity/aio/_credentials/azure_cli.py | 6 +++--- .../azure/identity/aio/_credentials/azure_powershell.py | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py index 5f1d75cd2216..24578862baa6 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py @@ -92,7 +92,7 @@ def close(self) -> None: @log_get_token("AzureDeveloperCliCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. @@ -103,7 +103,7 @@ def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py index 0d39cc7f237d..cdc5edcefb72 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py @@ -70,7 +70,7 @@ def close(self) -> None: @log_get_token("AzureCliCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. @@ -81,7 +81,7 @@ def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py index 7f75c8b59040..e674506bb232 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py @@ -84,7 +84,7 @@ def close(self) -> None: @log_get_token("AzurePowerShellCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. @@ -95,7 +95,7 @@ def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py index 9204652f2089..68691e87e441 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py @@ -80,7 +80,7 @@ def __init__( @log_get_token_async async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. @@ -91,7 +91,7 @@ async def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -101,7 +101,7 @@ async def get_token( """ # only ProactorEventLoop supports subprocesses on Windows (and it isn't the default loop on Python < 3.8) if sys.platform.startswith("win") and not isinstance(asyncio.get_event_loop(), asyncio.ProactorEventLoop): - return _SyncAzureDeveloperCliCredential().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) + return _SyncAzureDeveloperCliCredential().get_token(*scopes, tenant_id=tenant_id, **kwargs) if not scopes: raise ValueError("Missing scope in request. \n") diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py index 6e1716879b60..f3ded7c7790c 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py @@ -61,7 +61,7 @@ def __init__( @log_get_token_async async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. @@ -72,7 +72,7 @@ async def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -82,7 +82,7 @@ async def get_token( """ # only ProactorEventLoop supports subprocesses on Windows (and it isn't the default loop on Python < 3.8) if sys.platform.startswith("win") and not isinstance(asyncio.get_event_loop(), asyncio.ProactorEventLoop): - return _SyncAzureCliCredential().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) + return _SyncAzureCliCredential().get_token(*scopes, tenant_id=tenant_id, **kwargs) resource = _scopes_to_resource(*scopes) command = COMMAND_LINE.format(resource) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py index 50e2a3b8570d..353f98796db9 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py @@ -55,7 +55,7 @@ def __init__( @log_get_token_async async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. @@ -66,7 +66,7 @@ async def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. + :keyword str claims: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken @@ -77,7 +77,7 @@ async def get_token( """ # only ProactorEventLoop supports subprocesses on Windows (and it isn't the default loop on Python < 3.8) if sys.platform.startswith("win") and not isinstance(asyncio.get_event_loop(), asyncio.ProactorEventLoop): - return _SyncCredential().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) + return _SyncCredential().get_token(*scopes, tenant_id=tenant_id, **kwargs) tenant_id = resolve_tenant( default_tenant=self.tenant_id, From 86627d3836dbb336bf2615d6b09c7a46aac4467a Mon Sep 17 00:00:00 2001 From: mccoyp Date: Wed, 2 Aug 2023 10:51:03 -0700 Subject: [PATCH 16/21] Update creds that support claims --- .../azure/identity/_credentials/authorization_code.py | 3 ++- .../azure-identity/azure/identity/_credentials/environment.py | 3 ++- .../azure-identity/azure/identity/_internal/get_token_mixin.py | 3 ++- .../azure/identity/aio/_credentials/authorization_code.py | 3 ++- .../azure/identity/aio/_credentials/environment.py | 3 ++- .../azure/identity/aio/_credentials/shared_cache.py | 3 ++- .../azure/identity/aio/_internal/get_token_mixin.py | 3 ++- 7 files changed, 14 insertions(+), 7 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py b/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py index 33bbd19e06db..d765aeb43687 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py @@ -75,8 +75,9 @@ def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py index f45f65df0262..532df29cf52d 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py @@ -130,8 +130,9 @@ def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py index 156cbb95497c..23a765b80f43 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py @@ -63,8 +63,9 @@ def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py index 70b1c6c3d2d0..e157302b5288 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py @@ -82,8 +82,9 @@ async def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py index d68af184e509..7afc3be1308a 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py @@ -103,8 +103,9 @@ async def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py index aec0e03efd89..70b601723365 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py @@ -54,8 +54,9 @@ async def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py b/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py index 0f29f5302199..9953b0111a8f 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py @@ -63,8 +63,9 @@ async def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. From f8fc4ec06e3a64e94c23f5beef6125a070f788fc Mon Sep 17 00:00:00 2001 From: mccoyp Date: Wed, 2 Aug 2023 11:57:56 -0700 Subject: [PATCH 17/21] black; clarify all kwargs behavior --- .../azure/identity/_credentials/application.py | 5 +++-- .../azure-identity/azure/identity/_credentials/azd_cli.py | 6 +++++- .../azure-identity/azure/identity/_credentials/azure_cli.py | 6 +++++- .../azure/identity/_credentials/azure_powershell.py | 6 +++++- .../azure/identity/_credentials/managed_identity.py | 4 ++-- .../azure/identity/_credentials/shared_cache.py | 2 +- .../azure-identity/azure/identity/_credentials/vscode.py | 5 +++-- .../azure/identity/aio/_credentials/application.py | 5 +++-- .../azure/identity/aio/_credentials/azd_cli.py | 6 +++++- .../azure/identity/aio/_credentials/azure_cli.py | 6 +++++- .../azure/identity/aio/_credentials/azure_powershell.py | 6 +++++- .../azure/identity/aio/_credentials/managed_identity.py | 4 ++-- .../azure/identity/aio/_credentials/vscode.py | 3 ++- 13 files changed, 46 insertions(+), 18 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/application.py b/sdk/identity/azure-identity/azure/identity/_credentials/application.py index 3a0cf89271d0..8dacee3ebd79 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/application.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/application.py @@ -73,8 +73,9 @@ def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not supported by this credential. - :keyword str tenant_id: not supported by this credential. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. + :keyword str tenant_id: optional tenant to include in the token request. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py index 24578862baa6..508d3ade0de6 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py @@ -92,7 +92,11 @@ def close(self) -> None: @log_get_token("AzureDeveloperCliCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs # pylint:disable=unused-argument + self, + *scopes: str, + claims: Optional[str] = None, + tenant_id: Optional[str] = None, + **kwargs, # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py index cdc5edcefb72..b42e03be8d2c 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py @@ -70,7 +70,11 @@ def close(self) -> None: @log_get_token("AzureCliCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs # pylint:disable=unused-argument + self, + *scopes: str, + claims: Optional[str] = None, + tenant_id: Optional[str] = None, + **kwargs, # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py index e674506bb232..d54db2dfd19b 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py @@ -84,7 +84,11 @@ def close(self) -> None: @log_get_token("AzurePowerShellCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs # pylint:disable=unused-argument + self, + *scopes: str, + claims: Optional[str] = None, + tenant_id: Optional[str] = None, + **kwargs, # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py index 2c56e23a36ba..1ef4b259d7c9 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py @@ -119,8 +119,8 @@ def get_token( For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not supported by this credential. - :keyword str tenant_id: not supported by this credential. + :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py index 1de2c3497cca..76666713effd 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py @@ -66,7 +66,7 @@ def get_token( https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. :keyword str claims: additional claims required in the token, such as those returned in a resource provider's claims challenge following an authorization failure - :keyword str tenant_id: not supported by this credential. + :keyword str tenant_id: not used by this credential; any value provided will be ignored. :keyword bool enable_cae: indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. Defaults to False. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py index d62206020fe2..ab5b317dc3d5 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py @@ -150,8 +150,9 @@ def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not supported by this credential. - :keyword str tenant_id: not supported by this credential. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. + :keyword str tenant_id: optional tenant to include in the token request. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py index 7b4ea8efd1e7..9cd9ce07998c 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py @@ -72,8 +72,9 @@ async def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not supported by this credential. - :keyword str tenant_id: not supported by this credential. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. + :keyword str tenant_id: optional tenant to include in the token request. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py index 68691e87e441..9a7df184fff0 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py @@ -80,7 +80,11 @@ def __init__( @log_get_token_async async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs # pylint:disable=unused-argument + self, + *scopes: str, + claims: Optional[str] = None, + tenant_id: Optional[str] = None, + **kwargs, # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py index f3ded7c7790c..3dc2d58f17bb 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py @@ -61,7 +61,11 @@ def __init__( @log_get_token_async async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs # pylint:disable=unused-argument + self, + *scopes: str, + claims: Optional[str] = None, + tenant_id: Optional[str] = None, + **kwargs, # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py index 353f98796db9..f84cf23a641d 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py @@ -55,7 +55,11 @@ def __init__( @log_get_token_async async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs # pylint:disable=unused-argument + self, + *scopes: str, + claims: Optional[str] = None, + tenant_id: Optional[str] = None, + **kwargs, # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py index 0fe66bae5b3e..458d1db7082d 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py @@ -124,8 +124,8 @@ async def get_token( :param str scopes: desired scope for the access token. This credential allows only one scope per request. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str claims: not supported by this credential. - :keyword str tenant_id: not supported by this credential. + :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: not used by this credential; any value provided will be ignored. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py index d02d3e8ce828..2ac9a6522a39 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py @@ -57,8 +57,9 @@ async def get_token( :param str scopes: desired scopes for the access token. This method requires at least one scope. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. + :keyword str claims: additional claims required in the token, such as those returned in a resource provider's + claims challenge following an authorization failure. :keyword str tenant_id: optional tenant to include in the token request. - :keyword str claims: not supported by this credential. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken From 4122aed1012fd35c965c9821cc869fed50e86e68 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Thu, 3 Aug 2023 17:12:40 -0700 Subject: [PATCH 18/21] Align docstring/signature ordering --- .../azure-identity/azure/identity/_credentials/azd_cli.py | 2 +- .../azure-identity/azure/identity/_credentials/azure_cli.py | 2 +- .../azure/identity/_credentials/azure_powershell.py | 2 +- .../azure-identity/azure/identity/aio/_credentials/azd_cli.py | 2 +- .../azure-identity/azure/identity/aio/_credentials/azure_cli.py | 2 +- .../azure/identity/aio/_credentials/azure_powershell.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py index 508d3ade0de6..d7b286210fcb 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py @@ -106,8 +106,8 @@ def get_token( :param str scopes: desired scope for the access token. This credential allows only one scope per request. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str tenant_id: optional tenant to include in the token request. :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: optional tenant to include in the token request. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py index b42e03be8d2c..d6098ece3f70 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py @@ -84,8 +84,8 @@ def get_token( :param str scopes: desired scope for the access token. This credential allows only one scope per request. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str tenant_id: optional tenant to include in the token request. :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: optional tenant to include in the token request. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py index d54db2dfd19b..97ec54fdac93 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py @@ -98,8 +98,8 @@ def get_token( :param str scopes: desired scope for the access token. This credential allows only one scope per request. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str tenant_id: optional tenant to include in the token request. :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: optional tenant to include in the token request. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py index 9a7df184fff0..b60695c6e77e 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py @@ -94,8 +94,8 @@ async def get_token( :param str scopes: desired scope for the access token. This credential allows only one scope per request. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str tenant_id: optional tenant to include in the token request. :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: optional tenant to include in the token request. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py index 3dc2d58f17bb..f8b636473431 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py @@ -75,8 +75,8 @@ async def get_token( :param str scopes: desired scope for the access token. This credential allows only one scope per request. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str tenant_id: optional tenant to include in the token request. :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: optional tenant to include in the token request. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py index f84cf23a641d..d135daf21ae8 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py @@ -69,8 +69,8 @@ async def get_token( :param str scopes: desired scope for the access token. This credential allows only one scope per request. For more information about scopes, see https://learn.microsoft.com/azure/active-directory/develop/scopes-oidc. - :keyword str tenant_id: optional tenant to include in the token request. :keyword str claims: not used by this credential; any value provided will be ignored. + :keyword str tenant_id: optional tenant to include in the token request. :return: An access token with the desired scopes. :rtype: ~azure.core.credentials.AccessToken From d2485248d7ca9780c5f8889bd857e2463884ee08 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Fri, 4 Aug 2023 13:37:11 -0700 Subject: [PATCH 19/21] Add back Any type for kwargs --- .../azure-identity/azure/identity/_credentials/application.py | 2 +- .../azure/identity/_credentials/authorization_code.py | 2 +- .../azure-identity/azure/identity/_credentials/chained.py | 2 +- .../azure-identity/azure/identity/_credentials/default.py | 2 +- .../azure-identity/azure/identity/_credentials/environment.py | 2 +- .../azure/identity/_credentials/managed_identity.py | 2 +- .../azure/identity/_credentials/shared_cache.py | 4 ++-- .../azure-identity/azure/identity/_credentials/silent.py | 2 +- .../azure-identity/azure/identity/_credentials/vscode.py | 2 +- .../azure/identity/_internal/get_token_mixin.py | 2 +- .../azure-identity/azure/identity/_internal/interactive.py | 2 +- .../azure/identity/_internal/managed_identity_base.py | 2 +- .../azure/identity/aio/_credentials/application.py | 2 +- .../azure/identity/aio/_credentials/authorization_code.py | 2 +- .../azure-identity/azure/identity/aio/_credentials/chained.py | 4 ++-- .../azure-identity/azure/identity/aio/_credentials/default.py | 2 +- .../azure/identity/aio/_credentials/environment.py | 2 +- .../azure/identity/aio/_credentials/managed_identity.py | 2 +- .../azure/identity/aio/_credentials/shared_cache.py | 2 +- .../azure-identity/azure/identity/aio/_credentials/vscode.py | 2 +- .../azure/identity/aio/_internal/get_token_mixin.py | 4 ++-- .../azure/identity/aio/_internal/managed_identity_base.py | 4 ++-- 22 files changed, 26 insertions(+), 26 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/application.py b/sdk/identity/azure-identity/azure/identity/_credentials/application.py index 8dacee3ebd79..28f64c376329 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/application.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/application.py @@ -64,7 +64,7 @@ def __init__(self, **kwargs: Any) -> None: ) def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py b/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py index d765aeb43687..1895fcf2a628 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/authorization_code.py @@ -62,7 +62,7 @@ def close(self) -> None: self.__exit__() def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py index b932f94ebd76..8c2e41844c68 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/chained.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/chained.py @@ -70,7 +70,7 @@ def close(self) -> None: self.__exit__() def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Request a token from each chained credential, in order, returning the first token received. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/default.py b/sdk/identity/azure-identity/azure/identity/_credentials/default.py index 9e03dcc99166..b58ee999ef59 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/default.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/default.py @@ -196,7 +196,7 @@ def __init__(self, **kwargs: Any) -> None: # pylint: disable=too-many-statement super(DefaultAzureCredential, self).__init__(*credentials) def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py index 532df29cf52d..fb7e6b88083a 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py @@ -121,7 +121,7 @@ def close(self) -> None: @log_get_token("EnvironmentCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py index 1ef4b259d7c9..400a7f7a4487 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/managed_identity.py @@ -109,7 +109,7 @@ def close(self) -> None: @log_get_token("ManagedIdentityCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py index 76666713effd..ecf7d1fcb1ac 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/shared_cache.py @@ -53,7 +53,7 @@ def close(self) -> None: @log_get_token("SharedTokenCacheCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Get an access token for `scopes` from the shared cache. @@ -102,7 +102,7 @@ def __exit__(self, *args): self._client.__exit__(*args) def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: if not scopes: raise ValueError("'get_token' requires at least one scope") diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/silent.py b/sdk/identity/azure-identity/azure/identity/_credentials/silent.py index 32180a63e2b2..ec15d0435cfa 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/silent.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/silent.py @@ -55,7 +55,7 @@ def __exit__(self, *args): self._client.__exit__(*args) def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: if not scopes: raise ValueError('"get_token" requires at least one scope') diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py index ab5b317dc3d5..92c9e6a70905 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/vscode.py @@ -141,7 +141,7 @@ def close(self) -> None: @log_get_token("VSCodeCredential") def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Request an access token for `scopes` as the user currently signed in to Visual Studio Code. diff --git a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py index 23a765b80f43..a3dc76ce507b 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/get_token_mixin.py @@ -54,7 +54,7 @@ def _should_refresh(self, token: AccessToken) -> bool: return True def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_internal/interactive.py b/sdk/identity/azure-identity/azure/identity/_internal/interactive.py index ead73b0f97ce..f01a85f397de 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/interactive.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/interactive.py @@ -112,7 +112,7 @@ def __init__( super(InteractiveCredential, self).__init__(**kwargs) def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_internal/managed_identity_base.py b/sdk/identity/azure-identity/azure/identity/_internal/managed_identity_base.py index ff2a111f1f4f..554122530f83 100644 --- a/sdk/identity/azure-identity/azure/identity/_internal/managed_identity_base.py +++ b/sdk/identity/azure-identity/azure/identity/_internal/managed_identity_base.py @@ -40,7 +40,7 @@ def close(self) -> None: self.__exit__() def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: if not self._client: raise CredentialUnavailableError(message=self.get_unavailable_message()) diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py index 9cd9ce07998c..3d38ec1c5482 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/application.py @@ -63,7 +63,7 @@ def __init__( ) async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Asynchronously request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py index e157302b5288..ee9e394ae470 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/authorization_code.py @@ -69,7 +69,7 @@ def __init__( super().__init__() async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py index 4db2a968af4a..9c11f66e2538 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/chained.py @@ -4,7 +4,7 @@ # ------------------------------------ import asyncio import logging -from typing import Optional, TYPE_CHECKING +from typing import Any, Optional, TYPE_CHECKING from azure.core.exceptions import ClientAuthenticationError from azure.core.credentials import AccessToken @@ -51,7 +51,7 @@ async def close(self) -> None: await asyncio.gather(*(credential.close() for credential in self.credentials)) async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Asynchronously request a token from each credential, in order, returning the first token received. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py index 70d928f2ff51..a78887c2db2c 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/default.py @@ -177,7 +177,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(*credentials) async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Asynchronously request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py index 7afc3be1308a..1451e858f199 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py @@ -94,7 +94,7 @@ async def close(self) -> None: @log_get_token_async async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Asynchronously request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py index 458d1db7082d..9bf257e4bc11 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/managed_identity.py @@ -115,7 +115,7 @@ async def close(self) -> None: @log_get_token_async async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Asynchronously request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py index 70b601723365..4284d3267c06 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/shared_cache.py @@ -43,7 +43,7 @@ async def close(self) -> None: @log_get_token_async async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Get an access token for `scopes` from the shared cache. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py index 2ac9a6522a39..2a3d45f1b574 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/vscode.py @@ -48,7 +48,7 @@ async def close(self) -> None: @log_get_token_async async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Request an access token for `scopes` as the user currently signed in to Visual Studio Code. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py b/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py index 9953b0111a8f..162e6a51da57 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_internal/get_token_mixin.py @@ -5,7 +5,7 @@ import abc import logging import time -from typing import Optional +from typing import Any, Optional from azure.core.credentials import AccessToken from ..._constants import DEFAULT_REFRESH_OFFSET, DEFAULT_TOKEN_REFRESH_RETRY_DELAY @@ -54,7 +54,7 @@ def _should_refresh(self, token: AccessToken) -> bool: return True async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_internal/managed_identity_base.py b/sdk/identity/azure-identity/azure/identity/aio/_internal/managed_identity_base.py index caa27bdfec00..22d5119e19bd 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_internal/managed_identity_base.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_internal/managed_identity_base.py @@ -3,7 +3,7 @@ # Licensed under the MIT License. # ------------------------------------ import abc -from typing import cast, Optional +from typing import Any, cast, Optional from azure.core.credentials import AccessToken from . import AsyncContextManager @@ -40,7 +40,7 @@ async def close(self) -> None: await self.__aexit__() async def get_token( - self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs + self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any ) -> AccessToken: if not self._client: raise CredentialUnavailableError(message=self.get_unavailable_message()) From ed4e1233ff0d7564f31f4c6f42dc44bf2e18d7d7 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Fri, 4 Aug 2023 13:41:41 -0700 Subject: [PATCH 20/21] Update final stragglers --- .../azure-identity/azure/identity/_credentials/azd_cli.py | 2 +- .../azure-identity/azure/identity/_credentials/azure_cli.py | 2 +- .../azure/identity/_credentials/azure_powershell.py | 4 ++-- .../azure-identity/azure/identity/aio/_credentials/azd_cli.py | 4 ++-- .../azure/identity/aio/_credentials/azure_cli.py | 4 ++-- .../azure/identity/aio/_credentials/azure_powershell.py | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py index d7b286210fcb..f60d59e559c3 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py @@ -96,7 +96,7 @@ def get_token( *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, - **kwargs, # pylint:disable=unused-argument + **kwargs: Any, # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py index d6098ece3f70..f69542000ce3 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py @@ -74,7 +74,7 @@ def get_token( *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, - **kwargs, # pylint:disable=unused-argument + **kwargs: Any, # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py index 97ec54fdac93..e7379fae5ffd 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py @@ -6,7 +6,7 @@ import logging import subprocess import sys -from typing import List, Tuple, Optional +from typing import Any, List, Tuple, Optional from azure.core.credentials import AccessToken from azure.core.exceptions import ClientAuthenticationError @@ -88,7 +88,7 @@ def get_token( *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, - **kwargs, # pylint:disable=unused-argument + **kwargs: Any, # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py index b60695c6e77e..0fbbe72de620 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py @@ -6,7 +6,7 @@ import os import shutil import sys -from typing import List, Optional +from typing import Any, List, Optional from azure.core.exceptions import ClientAuthenticationError from azure.core.credentials import AccessToken @@ -84,7 +84,7 @@ async def get_token( *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, - **kwargs, # pylint:disable=unused-argument + **kwargs: Any, # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py index f8b636473431..ea76c38a86d2 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py @@ -6,7 +6,7 @@ import os import shutil import sys -from typing import List, Optional +from typing import Any, List, Optional from azure.core.exceptions import ClientAuthenticationError from azure.core.credentials import AccessToken @@ -65,7 +65,7 @@ async def get_token( *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, - **kwargs, # pylint:disable=unused-argument + **kwargs: Any, # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py index d135daf21ae8..85aba87503d3 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py @@ -4,7 +4,7 @@ # ------------------------------------ import asyncio import sys -from typing import cast, List, Optional +from typing import Any, cast, List, Optional from azure.core.credentials import AccessToken from .._internal import AsyncContextManager @@ -59,7 +59,7 @@ async def get_token( *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, - **kwargs, # pylint:disable=unused-argument + **kwargs: Any, # pylint:disable=unused-argument ) -> AccessToken: """Request an access token for `scopes`. From 91490baaa37ab2699f98e51a8a466844f7c17ad7 Mon Sep 17 00:00:00 2001 From: mccoyp Date: Fri, 4 Aug 2023 13:57:08 -0700 Subject: [PATCH 21/21] Fix pylint warning disable --- .../azure-identity/azure/identity/_credentials/azd_cli.py | 4 ++-- .../azure-identity/azure/identity/_credentials/azure_cli.py | 4 ++-- .../azure/identity/_credentials/azure_powershell.py | 4 ++-- .../azure-identity/azure/identity/aio/_credentials/azd_cli.py | 4 ++-- .../azure/identity/aio/_credentials/azure_cli.py | 4 ++-- .../azure/identity/aio/_credentials/azure_powershell.py | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py index f60d59e559c3..4d1d5ff9e740 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py @@ -94,9 +94,9 @@ def close(self) -> None: def get_token( self, *scopes: str, - claims: Optional[str] = None, + claims: Optional[str] = None, # pylint:disable=unused-argument tenant_id: Optional[str] = None, - **kwargs: Any, # pylint:disable=unused-argument + **kwargs: Any, ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py index f69542000ce3..2cdd7f1a3a32 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py @@ -72,9 +72,9 @@ def close(self) -> None: def get_token( self, *scopes: str, - claims: Optional[str] = None, + claims: Optional[str] = None, # pylint:disable=unused-argument tenant_id: Optional[str] = None, - **kwargs: Any, # pylint:disable=unused-argument + **kwargs: Any, ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py index e7379fae5ffd..4007ef006c3f 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py @@ -86,9 +86,9 @@ def close(self) -> None: def get_token( self, *scopes: str, - claims: Optional[str] = None, + claims: Optional[str] = None, # pylint:disable=unused-argument tenant_id: Optional[str] = None, - **kwargs: Any, # pylint:disable=unused-argument + **kwargs: Any, ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py index 0fbbe72de620..b1c229edf617 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azd_cli.py @@ -82,9 +82,9 @@ def __init__( async def get_token( self, *scopes: str, - claims: Optional[str] = None, + claims: Optional[str] = None, # pylint:disable=unused-argument tenant_id: Optional[str] = None, - **kwargs: Any, # pylint:disable=unused-argument + **kwargs: Any, ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py index ea76c38a86d2..c767e8840009 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_cli.py @@ -63,9 +63,9 @@ def __init__( async def get_token( self, *scopes: str, - claims: Optional[str] = None, + claims: Optional[str] = None, # pylint:disable=unused-argument tenant_id: Optional[str] = None, - **kwargs: Any, # pylint:disable=unused-argument + **kwargs: Any, ) -> AccessToken: """Request an access token for `scopes`. diff --git a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py index 85aba87503d3..59560f26b3fb 100644 --- a/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py +++ b/sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_powershell.py @@ -57,9 +57,9 @@ def __init__( async def get_token( self, *scopes: str, - claims: Optional[str] = None, + claims: Optional[str] = None, # pylint:disable=unused-argument tenant_id: Optional[str] = None, - **kwargs: Any, # pylint:disable=unused-argument + **kwargs: Any, ) -> AccessToken: """Request an access token for `scopes`.