-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add AzureNamedKeyCredential #17548
Add AzureNamedKeyCredential #17548
Changes from 10 commits
7f70520
3db2ef2
be51628
87530e9
8be7ce5
8b21514
75ecf46
05c4205
d8ba6de
1555f1d
6ab090c
6a98f0b
5f94691
53fab2e
0865f90
4a6736f
4c2143d
71f0b35
6bc4c0a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,38 @@ 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 credential(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It feels odd to have a credential property on a credential object. Is this the right name? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changed to |
||
# type () -> str | ||
"""The value of the configured name. | ||
|
||
:rtype: str | ||
""" | ||
return self._credential | ||
|
||
def update(self, name, key): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have scenarios where you want to update/change the name of the key? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think one scenario could be that users want to use a new share access policy which has new name and key. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can user update key only? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. technically - they are allowed to provide the same name - but they must provide a name There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the most common scenario is the name is fixed after creation, but user may modify the key value? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @yunhaoling any thoughts on this? If we know that users may normally not modify the name, I'll incline towards making name kwarg only There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually on second thought, i think we should let this be - as much as i like kwargs, it doesn't seem like they'll grow later in this case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also, if the user thinks they wont need to change name for their use case, AzureKeyCredential serves their purpose There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...unless they need to initially specify the name? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm, right - still doesn't change tht kwargs would not grow in this case - so will stick to it |
||
# 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. | ||
""" | ||
if not isinstance(name, six.string_types) or not isinstance(key, six.string_types): | ||
raise TypeError("Both name and key must be Strings.") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why Strings (with capital S)? |
||
self._credential = AzureNamedKey(name, key) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,13 @@ | |
if TYPE_CHECKING: | ||
# pylint:disable=unused-import | ||
from typing import Any, Dict, Optional | ||
from azure.core.credentials import AccessToken, TokenCredential, AzureKeyCredential, AzureSasCredential | ||
from azure.core.credentials import ( | ||
AccessToken, | ||
TokenCredential, | ||
AzureKeyCredential, | ||
AzureSasCredential, | ||
AzureNamedKeyCredential | ||
) | ||
from azure.core.pipeline import PipelineRequest | ||
|
||
|
||
|
@@ -145,3 +151,20 @@ def on_request(self, request): | |
else: | ||
url = url + "?" + signature | ||
request.http_request.url = url | ||
|
||
|
||
class AzureNamedKeyCredentialPolicy(SansIOHTTPPolicy): | ||
"""Adds a key header for the provided credential. | ||
|
||
:param credential: The credential used to authenticate requests. | ||
:type credential: ~azure.core.credentials.AzureNamedKeyCredential | ||
:raises: ValueError or TypeError | ||
""" | ||
def __init__(self, credential, name, **kwargs): # pylint: disable=unused-argument | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Who is consuming the name of the |
||
# type: (AzureNamedKeyCredential, str, **Any) -> None | ||
super(AzureNamedKeyCredentialPolicy, self).__init__() | ||
self._credential = credential | ||
self._name = name | ||
|
||
def on_request(self, request): | ||
request.http_request.headers[self._name] = self._credential.credential.key |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the policy in your PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updted the change log