Skip to content

Commit 28785f7

Browse files
authored
[Key Vault] Allow case-insensitive KeyType declaration (Azure#23328)
1 parent 8ba6f29 commit 28785f7

File tree

9 files changed

+64
-13
lines changed

9 files changed

+64
-13
lines changed

sdk/keyvault/azure-keyvault-certificates/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
### Breaking Changes
88

99
### Bugs Fixed
10+
- `KeyType` now ignores casing during declaration, which resolves a scenario where Key Vault
11+
keys created with non-standard casing could not be fetched with the SDK
12+
([#22797](https://github.com/Azure/azure-sdk-for-python/issues/22797))
1013

1114
### Other Changes
1215
- (From 4.4.0b3) Python 2.7 is no longer supported. Please use Python version 3.6 or later.

sdk/keyvault/azure-keyvault-certificates/azure/keyvault/certificates/_enums.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,28 @@
22
# Copyright (c) Microsoft Corporation.
33
# Licensed under the MIT License.
44
# ------------------------------------
5+
# pylint:skip-file (avoids crash due to six.with_metaclass https://github.com/PyCQA/astroid/issues/713)
56
from enum import Enum
7+
from six import with_metaclass
68

9+
from azure.core import CaseInsensitiveEnumMeta
710

8-
class CertificatePolicyAction(str, Enum):
11+
12+
class CertificatePolicyAction(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)):
913
"""The supported action types for the lifetime of a certificate"""
1014

1115
email_contacts = "EmailContacts"
1216
auto_renew = "AutoRenew"
1317

1418

15-
class CertificateContentType(str, Enum):
19+
class CertificateContentType(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)):
1620
"""Content type of the secrets as specified in Certificate Policy"""
1721

1822
pkcs12 = "application/x-pkcs12"
1923
pem = "application/x-pem-file"
2024

2125

22-
class KeyUsageType(str, Enum):
26+
class KeyUsageType(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)):
2327
"""The supported types of key usages"""
2428

2529
digital_signature = "digitalSignature"
@@ -33,16 +37,25 @@ class KeyUsageType(str, Enum):
3337
decipher_only = "decipherOnly"
3438

3539

36-
class KeyType(str, Enum):
40+
class KeyType(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)):
3741
"""Supported key types"""
3842

3943
ec = "EC" #: Elliptic Curve
4044
ec_hsm = "EC-HSM" #: Elliptic Curve with a private key which is not exportable from the HSM
4145
rsa = "RSA" #: RSA (https://tools.ietf.org/html/rfc3447)
4246
rsa_hsm = "RSA-HSM" #: RSA with a private key which is not exportable from the HSM
47+
oct = "oct" #: Octet sequence (used to represent symmetric keys)
48+
oct_hsm = "oct-HSM" #: Octet sequence with a private key which is not exportable from the HSM
49+
50+
@classmethod
51+
def _missing_(cls, value):
52+
for member in cls:
53+
if member.value.lower() == value.lower():
54+
return member
55+
raise ValueError(f"{value} is not a valid KeyType")
4356

4457

45-
class KeyCurveName(str, Enum):
58+
class KeyCurveName(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)):
4659
"""Supported elliptic curves"""
4760

4861
p_256 = "P-256" #: The NIST P-256 elliptic curve, AKA SECG curve SECP256R1.
@@ -51,7 +64,7 @@ class KeyCurveName(str, Enum):
5164
p_256_k = "P-256K" #: The SECG SECP256K1 elliptic curve.
5265

5366

54-
class WellKnownIssuerNames(str, Enum):
67+
class WellKnownIssuerNames(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)):
5568
"""Collection of well-known issuer names"""
5669

5770
self = "Self" #: Use this issuer for a self-signed certificate

sdk/keyvault/azure-keyvault-certificates/azure/keyvault/certificates/_shared/_polling.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ def result(self): # type: ignore
4848

4949
@distributed_trace
5050
def wait(self, timeout=None):
51-
# type: (Optional[int]) -> None
51+
# type: (Optional[float]) -> None
5252
"""Wait on the long running operation for a number of seconds.
5353
5454
You can check if this call has ended with timeout with the "done()" method.
5555
56-
:param int timeout: Period of time to wait for the long running
56+
:param float timeout: Period of time to wait for the long running
5757
operation to complete (in seconds).
5858
:raises ~azure.core.exceptions.HttpResponseError: Server problem with the query.
5959
"""

sdk/keyvault/azure-keyvault-certificates/tests/test_certificates_client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,3 +731,15 @@ class CustomHookPolicy(SansIOHTTPPolicy):
731731

732732
client = CertificateClient("...", object(), custom_hook_policy=CustomHookPolicy())
733733
assert isinstance(client._client._config.custom_hook_policy, CustomHookPolicy)
734+
735+
736+
def test_case_insensitive_key_type():
737+
"""Ensure a KeyType can be created regardless of casing since the service can create keys with non-standard casing.
738+
See https://github.com/Azure/azure-sdk-for-python/issues/22797
739+
"""
740+
# KeyType with all upper-case value
741+
assert KeyType("rsa") == KeyType.rsa
742+
# KeyType with all lower-case value
743+
assert KeyType("OCT") == KeyType.oct
744+
# KeyType with mixed-case value
745+
assert KeyType("oct-hsm") == KeyType.oct_hsm

sdk/keyvault/azure-keyvault-keys/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
### Breaking Changes
88

99
### Bugs Fixed
10+
- `KeyType` now ignores casing during declaration, which resolves a scenario where Key Vault
11+
keys created with non-standard casing could not be fetched with the SDK
12+
([#22797](https://github.com/Azure/azure-sdk-for-python/issues/22797))
1013

1114
### Other Changes
1215
- (From 4.5.0b6) Python 2.7 is no longer supported. Please use Python version 3.6 or later.

sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_enums.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,14 @@ class KeyType(with_metaclass(CaseInsensitiveEnumMeta, str, Enum)):
5151

5252
ec = "EC" #: Elliptic Curve
5353
ec_hsm = "EC-HSM" #: Elliptic Curve with a private key which is not exportable from the HSM
54-
rsa = "RSA"
54+
rsa = "RSA" #: RSA (https://tools.ietf.org/html/rfc3447)
5555
rsa_hsm = "RSA-HSM" #: RSA with a private key which is not exportable from the HSM
5656
oct = "oct" #: Octet sequence (used to represent symmetric keys)
5757
oct_hsm = "oct-HSM" #: Octet sequence with a private key which is not exportable from the HSM
58+
59+
@classmethod
60+
def _missing_(cls, value):
61+
for member in cls:
62+
if member.value.lower() == value.lower():
63+
return member
64+
raise ValueError(f"{value} is not a valid KeyType")

sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/_polling.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ def result(self): # type: ignore
4848

4949
@distributed_trace
5050
def wait(self, timeout=None):
51-
# type: (Optional[int]) -> None
51+
# type: (Optional[float]) -> None
5252
"""Wait on the long running operation for a number of seconds.
5353
5454
You can check if this call has ended with timeout with the "done()" method.
5555
56-
:param int timeout: Period of time to wait for the long running
56+
:param float timeout: Period of time to wait for the long running
5757
operation to complete (in seconds).
5858
:raises ~azure.core.exceptions.HttpResponseError: Server problem with the query.
5959
"""

sdk/keyvault/azure-keyvault-keys/tests/test_key_client.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
KeyReleasePolicy,
1919
KeyRotationLifetimeAction,
2020
KeyRotationPolicyAction,
21+
KeyType,
2122
)
2223
import pytest
2324
from six import byte2int
@@ -709,3 +710,15 @@ class CustomHookPolicy(SansIOHTTPPolicy):
709710

710711
client = KeyClient("...", object(), custom_hook_policy=CustomHookPolicy())
711712
assert isinstance(client._client._config.custom_hook_policy, CustomHookPolicy)
713+
714+
715+
def test_case_insensitive_key_type():
716+
"""Ensure a KeyType can be created regardless of casing since the service can create keys with non-standard casing.
717+
See https://github.com/Azure/azure-sdk-for-python/issues/22797
718+
"""
719+
# KeyType with all upper-case value
720+
assert KeyType("rsa") == KeyType.rsa
721+
# KeyType with all lower-case value
722+
assert KeyType("OCT") == KeyType.oct
723+
# KeyType with mixed-case value
724+
assert KeyType("oct-hsm") == KeyType.oct_hsm

sdk/keyvault/azure-keyvault-secrets/azure/keyvault/secrets/_shared/_polling.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ def result(self): # type: ignore
4848

4949
@distributed_trace
5050
def wait(self, timeout=None):
51-
# type: (Optional[int]) -> None
51+
# type: (Optional[float]) -> None
5252
"""Wait on the long running operation for a number of seconds.
5353
5454
You can check if this call has ended with timeout with the "done()" method.
5555
56-
:param int timeout: Period of time to wait for the long running
56+
:param float timeout: Period of time to wait for the long running
5757
operation to complete (in seconds).
5858
:raises ~azure.core.exceptions.HttpResponseError: Server problem with the query.
5959
"""

0 commit comments

Comments
 (0)