diff --git a/sdk/core/azure-core/CHANGELOG.md b/sdk/core/azure-core/CHANGELOG.md index abf182418057..4f5feaa9a18a 100644 --- a/sdk/core/azure-core/CHANGELOG.md +++ b/sdk/core/azure-core/CHANGELOG.md @@ -1,7 +1,10 @@ # Release History -## 1.13.1 (Unreleased) +## 1.14.0 (Unreleased) +### New Features + +- Added `azure.core.credentials.AzureNamedKeyCredential` credential #17548. ## 1.13.0 (2021-04-02) diff --git a/sdk/core/azure-core/azure/core/_version.py b/sdk/core/azure-core/azure/core/_version.py index 36514ce9837d..656148f88d2b 100644 --- a/sdk/core/azure-core/azure/core/_version.py +++ b/sdk/core/azure-core/azure/core/_version.py @@ -9,4 +9,4 @@ # regenerated. # -------------------------------------------------------------------------- -VERSION = "1.13.1" +VERSION = "1.14.0" diff --git a/sdk/core/azure-core/azure/core/credentials.py b/sdk/core/azure-core/azure/core/credentials.py index 21aeb433ac81..e5146d7f947a 100644 --- a/sdk/core/azure-core/azure/core/credentials.py +++ b/sdk/core/azure-core/azure/core/credentials.py @@ -3,10 +3,10 @@ # Licensed under the MIT License. See LICENSE.txt in the project root for # license information. # ------------------------------------------------------------------------- +from collections import namedtuple from typing import TYPE_CHECKING import six - if TYPE_CHECKING: from typing import Any, NamedTuple from typing_extensions import Protocol @@ -26,11 +26,12 @@ def get_token(self, *scopes, **kwargs): else: - from collections import namedtuple - AccessToken = namedtuple("AccessToken", ["token", "expires_on"]) -__all__ = ["AzureKeyCredential", "AzureSasCredential", "AccessToken"] +AzureNamedKey = namedtuple("AzureNamedKey", ["name", "key"]) + + +__all__ = ["AzureKeyCredential", "AzureSasCredential", "AccessToken", "AzureNamedKeyCredential"] class AzureKeyCredential(object): @@ -111,3 +112,41 @@ def update(self, signature): if not isinstance(signature, six.string_types): raise TypeError("The signature used for updating must be a string.") self._signature = signature + + +class AzureNamedKeyCredential(object): + """Credential type used for working with any service needing a named key that follows patterns + established by the other credential types. + + :param str name: The name of the credential used to authenticate to an Azure service. + :param str key: The key used to authenticate to an Azure service. + :raises: TypeError + """ + def __init__(self, name, key): + # type: (str, str) -> None + if not isinstance(name, six.string_types) or not isinstance(key, six.string_types): + raise TypeError("Both name and key must be strings.") + self._credential = AzureNamedKey(name, key) + + @property + def named_key(self): + # type () -> AzureNamedKey + """The value of the configured name. + + :rtype: AzureNamedKey + """ + return self._credential + + def update(self, name, key): + # type: (str, str) -> None + """Update the named key credential. + + Both name and key must be provided in order to update the named key credential. + Individual attributes cannot be updated. + + :param str name: The name of the credential used to authenticate to an Azure service. + :param str key: The key used to authenticate to an Azure service. + """ + if not isinstance(name, six.string_types) or not isinstance(key, six.string_types): + raise TypeError("Both name and key must be strings.") + self._credential = AzureNamedKey(name, key) diff --git a/sdk/core/azure-core/tests/test_authentication.py b/sdk/core/azure-core/tests/test_authentication.py index ddfcc314fcd9..6c112aa5926e 100644 --- a/sdk/core/azure-core/tests/test_authentication.py +++ b/sdk/core/azure-core/tests/test_authentication.py @@ -6,10 +6,13 @@ import time import azure.core -from azure.core.credentials import AccessToken, AzureKeyCredential, AzureSasCredential +from azure.core.credentials import AccessToken, AzureKeyCredential, AzureSasCredential, AzureNamedKeyCredential from azure.core.exceptions import ServiceRequestError from azure.core.pipeline import Pipeline -from azure.core.pipeline.policies import BearerTokenCredentialPolicy, SansIOHTTPPolicy, AzureKeyCredentialPolicy, AzureSasCredentialPolicy +from azure.core.pipeline.policies import ( + BearerTokenCredentialPolicy, SansIOHTTPPolicy, AzureKeyCredentialPolicy, + AzureSasCredentialPolicy +) from azure.core.pipeline.transport import HttpRequest import pytest @@ -230,3 +233,26 @@ def test_azure_sas_credential_policy_raises(): sas = 1234 with pytest.raises(TypeError): credential = AzureSasCredential(sas) + +def test_azure_named_key_credential(): + cred = AzureNamedKeyCredential("sample_name", "samplekey") + + assert cred.named_key.name == "sample_name" + assert cred.named_key.key == "samplekey" + assert isinstance(cred.named_key, tuple) + + cred.update("newname", "newkey") + assert cred.named_key.name == "newname" + assert cred.named_key.key == "newkey" + assert isinstance(cred.named_key, tuple) + +def test_azure_named_key_credential_raises(): + with pytest.raises(TypeError, match="Both name and key must be strings."): + cred = AzureNamedKeyCredential("sample_name", 123345) + + cred = AzureNamedKeyCredential("sample_name", "samplekey") + assert cred.named_key.name == "sample_name" + assert cred.named_key.key == "samplekey" + + with pytest.raises(TypeError, match="Both name and key must be strings."): + cred.update(1234, "newkey")