From fcbb64dd8b0b9cbd50d24900f904bcfc3cdb0870 Mon Sep 17 00:00:00 2001 From: SDKAuto Date: Wed, 23 Apr 2025 22:33:36 +0000 Subject: [PATCH] CodeGen from PR 34032 in Azure/azure-rest-api-specs Merge c05749c07658b43406ee1632c47ff96074aa5137 into 4689e75cdeaa04dbeead0237b72cae8dc8dbba4d --- sdk/keyvault/azure-keyvault-keys/MANIFEST.in | 6 +- sdk/keyvault/azure-keyvault-keys/_meta.json | 6 + .../apiview-properties.json | 67 + .../azure-keyvault-keys/azure/__init__.py | 4 - .../azure/keyvault/__init__.py | 4 - .../azure/keyvault/keys/__init__.py | 65 +- .../azure/keyvault/keys/_client.py | 1065 ++-------------- .../keys/{_generated => }/_configuration.py | 0 .../azure/keyvault/keys/_enums.py | 72 -- .../keyvault/keys/_generated/__init__.py | 32 - .../azure/keyvault/keys/_generated/_client.py | 100 -- .../keyvault/keys/_generated/_version.py | 9 - .../keyvault/keys/_generated/aio/__init__.py | 29 - .../keyvault/keys/_generated/aio/_client.py | 102 -- .../keyvault/keys/_generated/models/_patch.py | 20 - .../azure/keyvault/keys/_generated/py.typed | 1 - .../keys/_generated/tsp-location.yaml | 5 - .../keys/{_generated => }/_model_base.py | 27 +- .../azure/keyvault/keys/_models.py | 655 ---------- .../{_generated => }/_operations/__init__.py | 0 .../_operations/_operations.py | 224 ++-- .../{_generated => }/_operations/_patch.py | 9 +- .../aio/_operations => }/_patch.py | 9 +- .../azure/keyvault/keys/_sdk_moniker.py | 7 - .../keys/{_generated => }/_serialization.py | 32 +- .../azure/keyvault/keys/_shared/__init__.py | 77 -- .../azure/keyvault/keys/_shared/_polling.py | 142 --- .../keyvault/keys/_shared/_polling_async.py | 87 -- .../_shared/async_challenge_auth_policy.py | 262 ---- .../keys/_shared/async_client_base.py | 117 -- .../keys/_shared/challenge_auth_policy.py | 270 ----- .../keyvault/keys/_shared/client_base.py | 161 --- .../keyvault/keys/_shared/http_challenge.py | 182 --- .../keys/_shared/http_challenge_cache.py | 93 -- .../keys/{_generated => }/_validation.py | 0 .../keyvault/keys/{_generated => }/_vendor.py | 0 .../azure/keyvault/keys/_version.py | 13 +- .../azure/keyvault/keys/aio/__init__.py | 34 +- .../azure/keyvault/keys/aio/_client.py | 1077 ++--------------- .../{_generated => }/aio/_configuration.py | 0 .../aio/_operations/__init__.py | 0 .../aio/_operations/_operations.py | 206 ++-- .../{_generated => aio/_operations}/_patch.py | 9 +- .../keys/{_generated => }/aio/_patch.py | 9 +- .../keys/{_generated => }/aio/_vendor.py | 0 .../azure/keyvault/keys/crypto/__init__.py | 32 - .../azure/keyvault/keys/crypto/_client.py | 581 --------- .../azure/keyvault/keys/crypto/_enums.py | 66 - .../keys/crypto/_internal/__init__.py | 32 - .../keys/crypto/_internal/_internal.py | 131 -- .../keys/crypto/_internal/algorithm.py | 78 -- .../crypto/_internal/algorithms/__init__.py | 38 - .../crypto/_internal/algorithms/aes_cbc.py | 145 --- .../_internal/algorithms/aes_cbc_hmac.py | 149 --- .../crypto/_internal/algorithms/aes_kw.py | 68 -- .../keys/crypto/_internal/algorithms/ecdsa.py | 60 - .../_internal/algorithms/rsa_encryption.py | 79 -- .../_internal/algorithms/rsa_signing.py | 75 -- .../keys/crypto/_internal/algorithms/sha_2.py | 53 - .../keyvault/keys/crypto/_internal/ec_key.py | 106 -- .../keyvault/keys/crypto/_internal/key.py | 94 -- .../keyvault/keys/crypto/_internal/rsa_key.py | 221 ---- .../keys/crypto/_internal/symmetric_key.py | 125 -- .../keys/crypto/_internal/transform.py | 61 - .../keyvault/keys/crypto/_key_validity.py | 16 - .../azure/keyvault/keys/crypto/_models.py | 582 --------- .../keys/crypto/_providers/__init__.py | 36 - .../keyvault/keys/crypto/_providers/ec.py | 34 - .../keys/crypto/_providers/local_provider.py | 104 -- .../keyvault/keys/crypto/_providers/rsa.py | 34 - .../keys/crypto/_providers/symmetric.py | 28 - .../keyvault/keys/crypto/aio/__init__.py | 50 - .../azure/keyvault/keys/crypto/aio/_client.py | 503 -------- .../keys/{_generated => }/models/__init__.py | 4 +- .../keys/{_generated => }/models/_enums.py | 60 +- .../keys/{_generated => }/models/_models.py | 415 ++++--- .../azure/keyvault/keys/models/_patch.py | 21 + .../azure/keyvault/keys/py.typed | 1 + .../samples/backup_restore_operations.py | 3 +- .../backup_restore_operations_async.py | 4 +- .../samples/hello_world.py | 7 +- .../samples/hello_world_async.py | 2 + .../samples/key_rotation.py | 3 +- .../samples/key_rotation_async.py | 4 +- .../samples/list_operations.py | 3 +- .../samples/list_operations_async.py | 2 + .../samples/recover_purge_operations.py | 3 +- .../samples/recover_purge_operations_async.py | 2 + .../samples/send_request.py | 5 +- sdk/keyvault/azure-keyvault-keys/setup.py | 58 +- .../tests/_keys_test_case.py | 6 +- .../tests/_shared/test_case.py | 2 - .../tests/_shared/test_case_async.py | 2 +- .../azure-keyvault-keys/tests/conftest.py | 31 +- .../azure-keyvault-keys/tests/keys.py | 1 + .../tests/perfstress_tests/sign.py | 1 + .../tests/test_challenge_auth.py | 18 +- .../tests/test_challenge_auth_async.py | 24 +- .../tests/test_crypto_client.py | 87 +- .../tests/test_crypto_client_async.py | 76 +- .../tests/test_examples_crypto.py | 5 +- .../tests/test_examples_crypto_async.py | 10 +- .../tests/test_key_client.py | 106 +- .../tests/test_keys_async.py | 132 +- .../tests/test_local_crypto.py | 16 +- .../tests/test_parse_id.py | 2 +- .../tests/test_samples_keys.py | 12 +- .../tests/test_samples_keys_async.py | 12 +- .../azure-keyvault-keys/tsp-location.yaml | 5 + 109 files changed, 1177 insertions(+), 8838 deletions(-) create mode 100644 sdk/keyvault/azure-keyvault-keys/_meta.json create mode 100644 sdk/keyvault/azure-keyvault-keys/apiview-properties.json rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/_configuration.py (100%) delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_enums.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/__init__.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_client.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_version.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/__init__.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_client.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/_patch.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/py.typed delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/tsp-location.yaml rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/_model_base.py (98%) delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_models.py rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/_operations/__init__.py (100%) rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/_operations/_operations.py (95%) rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/_operations/_patch.py (61%) rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated/aio/_operations => }/_patch.py (61%) delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_sdk_moniker.py rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/_serialization.py (98%) delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/__init__.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/_polling.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/_polling_async.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/async_challenge_auth_policy.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/async_client_base.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/challenge_auth_policy.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/client_base.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/http_challenge.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/http_challenge_cache.py rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/_validation.py (100%) rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/_vendor.py (100%) rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/aio/_configuration.py (100%) rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/aio/_operations/__init__.py (100%) rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/aio/_operations/_operations.py (94%) rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => aio/_operations}/_patch.py (61%) rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/aio/_patch.py (61%) rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/aio/_vendor.py (100%) delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/__init__.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_client.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_enums.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/__init__.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/_internal.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithm.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/__init__.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/aes_cbc.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/aes_cbc_hmac.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/aes_kw.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/ecdsa.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/rsa_encryption.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/rsa_signing.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/sha_2.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/ec_key.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/key.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/rsa_key.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/symmetric_key.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/transform.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_key_validity.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_models.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/__init__.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/ec.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/local_provider.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/rsa.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/symmetric.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/aio/__init__.py delete mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/aio/_client.py rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/models/__init__.py (98%) rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/models/_enums.py (76%) rename sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/{_generated => }/models/_models.py (76%) create mode 100644 sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/_patch.py create mode 100644 sdk/keyvault/azure-keyvault-keys/tsp-location.yaml diff --git a/sdk/keyvault/azure-keyvault-keys/MANIFEST.in b/sdk/keyvault/azure-keyvault-keys/MANIFEST.in index da63874bd18d..d4688a08c24e 100644 --- a/sdk/keyvault/azure-keyvault-keys/MANIFEST.in +++ b/sdk/keyvault/azure-keyvault-keys/MANIFEST.in @@ -1,7 +1,7 @@ include *.md include LICENSE +include azure/keyvault/keys/py.typed +recursive-include tests *.py +recursive-include samples *.py *.md include azure/__init__.py include azure/keyvault/__init__.py -recursive-include samples *.py -recursive-include tests *.py -include azure/keyvault/keys/py.typed diff --git a/sdk/keyvault/azure-keyvault-keys/_meta.json b/sdk/keyvault/azure-keyvault-keys/_meta.json new file mode 100644 index 000000000000..df2bb14484c0 --- /dev/null +++ b/sdk/keyvault/azure-keyvault-keys/_meta.json @@ -0,0 +1,6 @@ +{ + "commit": "4465f2aaefeb75e8a088c7e0950979e03430a234", + "repository_url": "https://github.com/Azure/azure-rest-api-specs", + "typespec_src": "specification/keyvault/Security.KeyVault.Keys", + "@azure-tools/typespec-python": "0.43.0" +} \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-keys/apiview-properties.json b/sdk/keyvault/azure-keyvault-keys/apiview-properties.json new file mode 100644 index 000000000000..3340b480ed1c --- /dev/null +++ b/sdk/keyvault/azure-keyvault-keys/apiview-properties.json @@ -0,0 +1,67 @@ +{ + "CrossLanguagePackageId": "KeyVault", + "CrossLanguageDefinitionId": { + "azure.keyvault.keys.models.BackupKeyResult": "KeyVault.BackupKeyResult", + "azure.keyvault.keys.models.DeletedKeyBundle": "KeyVault.DeletedKeyBundle", + "azure.keyvault.keys.models.DeletedKeyItem": "KeyVault.DeletedKeyItem", + "azure.keyvault.keys.models.Error": "Error", + "azure.keyvault.keys.models.GetRandomBytesRequest": "KeyVault.GetRandomBytesRequest", + "azure.keyvault.keys.models.JsonWebKey": "KeyVault.JsonWebKey", + "azure.keyvault.keys.models.KeyAttestation": "KeyVault.KeyAttestation", + "azure.keyvault.keys.models.KeyAttributes": "KeyVault.KeyAttributes", + "azure.keyvault.keys.models.KeyBundle": "KeyVault.KeyBundle", + "azure.keyvault.keys.models.KeyCreateParameters": "KeyVault.KeyCreateParameters", + "azure.keyvault.keys.models.KeyImportParameters": "KeyVault.KeyImportParameters", + "azure.keyvault.keys.models.KeyItem": "KeyVault.KeyItem", + "azure.keyvault.keys.models.KeyOperationResult": "KeyVault.KeyOperationResult", + "azure.keyvault.keys.models.KeyOperationsParameters": "KeyVault.KeyOperationsParameters", + "azure.keyvault.keys.models.KeyReleaseParameters": "KeyVault.KeyReleaseParameters", + "azure.keyvault.keys.models.KeyReleasePolicy": "KeyVault.KeyReleasePolicy", + "azure.keyvault.keys.models.KeyReleaseResult": "KeyVault.KeyReleaseResult", + "azure.keyvault.keys.models.KeyRestoreParameters": "KeyVault.KeyRestoreParameters", + "azure.keyvault.keys.models.KeyRotationPolicy": "KeyVault.KeyRotationPolicy", + "azure.keyvault.keys.models.KeyRotationPolicyAttributes": "KeyVault.KeyRotationPolicyAttributes", + "azure.keyvault.keys.models.KeySignParameters": "KeyVault.KeySignParameters", + "azure.keyvault.keys.models.KeyUpdateParameters": "KeyVault.KeyUpdateParameters", + "azure.keyvault.keys.models.KeyVaultError": "KeyVaultError", + "azure.keyvault.keys.models.KeyVerifyParameters": "KeyVault.KeyVerifyParameters", + "azure.keyvault.keys.models.KeyVerifyResult": "KeyVault.KeyVerifyResult", + "azure.keyvault.keys.models.LifetimeActions": "KeyVault.LifetimeActions", + "azure.keyvault.keys.models.LifetimeActionsTrigger": "KeyVault.LifetimeActionsTrigger", + "azure.keyvault.keys.models.LifetimeActionsType": "KeyVault.LifetimeActionsType", + "azure.keyvault.keys.models.RandomBytes": "KeyVault.RandomBytes", + "azure.keyvault.keys.models.JsonWebKeyType": "KeyVault.JsonWebKeyType", + "azure.keyvault.keys.models.JsonWebKeyCurveName": "KeyVault.JsonWebKeyCurveName", + "azure.keyvault.keys.models.DeletionRecoveryLevel": "KeyVault.DeletionRecoveryLevel", + "azure.keyvault.keys.models.JsonWebKeyOperation": "KeyVault.JsonWebKeyOperation", + "azure.keyvault.keys.models.JsonWebKeyEncryptionAlgorithm": "KeyVault.JsonWebKeyEncryptionAlgorithm", + "azure.keyvault.keys.models.JsonWebKeySignatureAlgorithm": "KeyVault.JsonWebKeySignatureAlgorithm", + "azure.keyvault.keys.models.KeyEncryptionAlgorithm": "KeyVault.KeyEncryptionAlgorithm", + "azure.keyvault.keys.models.KeyRotationPolicyAction": "KeyVault.KeyRotationPolicyAction", + "azure.keyvault.keys.KeyVaultClient.create_key": "KeyVault.createKey", + "azure.keyvault.keys.KeyVaultClient.rotate_key": "KeyVault.rotateKey", + "azure.keyvault.keys.KeyVaultClient.import_key": "KeyVault.importKey", + "azure.keyvault.keys.KeyVaultClient.delete_key": "KeyVault.deleteKey", + "azure.keyvault.keys.KeyVaultClient.update_key": "KeyVault.updateKey", + "azure.keyvault.keys.KeyVaultClient.get_key": "KeyVault.getKey", + "azure.keyvault.keys.KeyVaultClient.get_key_versions": "KeyVault.getKeyVersions", + "azure.keyvault.keys.KeyVaultClient.get_keys": "KeyVault.getKeys", + "azure.keyvault.keys.KeyVaultClient.backup_key": "KeyVault.backupKey", + "azure.keyvault.keys.KeyVaultClient.restore_key": "KeyVault.restoreKey", + "azure.keyvault.keys.KeyVaultClient.encrypt": "KeyVault.encrypt", + "azure.keyvault.keys.KeyVaultClient.decrypt": "KeyVault.decrypt", + "azure.keyvault.keys.KeyVaultClient.sign": "KeyVault.sign", + "azure.keyvault.keys.KeyVaultClient.verify": "KeyVault.verify", + "azure.keyvault.keys.KeyVaultClient.wrap_key": "KeyVault.wrapKey", + "azure.keyvault.keys.KeyVaultClient.unwrap_key": "KeyVault.unwrapKey", + "azure.keyvault.keys.KeyVaultClient.release": "KeyVault.release", + "azure.keyvault.keys.KeyVaultClient.get_deleted_keys": "KeyVault.getDeletedKeys", + "azure.keyvault.keys.KeyVaultClient.get_deleted_key": "KeyVault.getDeletedKey", + "azure.keyvault.keys.KeyVaultClient.purge_deleted_key": "KeyVault.purgeDeletedKey", + "azure.keyvault.keys.KeyVaultClient.recover_deleted_key": "KeyVault.recoverDeletedKey", + "azure.keyvault.keys.KeyVaultClient.get_key_rotation_policy": "KeyVault.getKeyRotationPolicy", + "azure.keyvault.keys.KeyVaultClient.update_key_rotation_policy": "KeyVault.updateKeyRotationPolicy", + "azure.keyvault.keys.KeyVaultClient.get_random_bytes": "KeyVault.getRandomBytes", + "azure.keyvault.keys.KeyVaultClient.get_key_attestation": "KeyVault.getKeyAttestation" + } +} \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-keys/azure/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/__init__.py index 679ab6995134..d55ccad1f573 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/__init__.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/__init__.py @@ -1,5 +1 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ __path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/__init__.py index 679ab6995134..d55ccad1f573 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/__init__.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/__init__.py @@ -1,5 +1 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ __path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/__init__.py index 3a06bca6b656..4f7962408227 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/__init__.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/__init__.py @@ -1,43 +1,32 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------- -from ._enums import KeyCurveName, KeyExportEncryptionAlgorithm, KeyOperation, KeyRotationPolicyAction, KeyType -from ._shared.client_base import ApiVersion -from ._models import ( - DeletedKey, - JsonWebKey, - KeyAttestation, - KeyProperties, - KeyReleasePolicy, - KeyRotationLifetimeAction, - KeyRotationPolicy, - KeyVaultKey, - KeyVaultKeyIdentifier, - ReleaseKeyResult, -) -from ._client import KeyClient +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +# pylint: disable=wrong-import-position -__all__ = [ - "ApiVersion", - "KeyClient", - "JsonWebKey", - "KeyAttestation", - "KeyVaultKey", - "KeyVaultKeyIdentifier", - "KeyCurveName", - "KeyExportEncryptionAlgorithm", - "KeyOperation", - "KeyRotationPolicyAction", - "KeyType", - "DeletedKey", - "KeyProperties", - "KeyReleasePolicy", - "KeyRotationLifetimeAction", - "KeyRotationPolicy", - "ReleaseKeyResult", -] +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from ._patch import * # pylint: disable=unused-wildcard-import + +from ._client import KeyVaultClient # type: ignore from ._version import VERSION __version__ = VERSION + +try: + from ._patch import __all__ as _patch_all + from ._patch import * +except ImportError: + _patch_all = [] +from ._patch import patch_sdk as _patch_sdk + +__all__ = [ + "KeyVaultClient", +] +__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore + +_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_client.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_client.py index 6ab95a316bd7..ad79f0c7348a 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_client.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_client.py @@ -1,1010 +1,101 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from datetime import datetime -from functools import partial -from typing import Any, Dict, List, Optional, Union +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- -from azure.core.paging import ItemPaged -from azure.core.polling import LROPoller -from azure.core.tracing.decorator import distributed_trace +from copy import deepcopy +from typing import Any, TYPE_CHECKING +from typing_extensions import Self -from .crypto import CryptographyClient -from ._enums import KeyCurveName, KeyExportEncryptionAlgorithm, KeyOperation, KeyType -from ._generated.models import KeyAttributes -from ._models import JsonWebKey, KeyRotationLifetimeAction -from ._shared import KeyVaultClientBase -from ._shared._polling import DeleteRecoverPollingMethod, KeyVaultOperationPoller -from ._models import DeletedKey, KeyVaultKey, KeyProperties, KeyReleasePolicy, KeyRotationPolicy, ReleaseKeyResult +from azure.core import PipelineClient +from azure.core.pipeline import policies +from azure.core.rest import HttpRequest, HttpResponse +from ._configuration import KeyVaultClientConfiguration +from ._operations import KeyVaultClientOperationsMixin +from ._serialization import Deserializer, Serializer -def _get_key_id(vault_url, key_name, version=None): - without_version = f"{vault_url}/keys/{key_name}" - return without_version + "/" + version if version else without_version +if TYPE_CHECKING: + from azure.core.credentials import TokenCredential -class KeyClient(KeyVaultClientBase): - """A high-level interface for managing a vault's keys. +class KeyVaultClient(KeyVaultClientOperationsMixin): + """The key vault client performs cryptographic key operations and vault operations against the Key + Vault service. - :param str vault_url: URL of the vault the client will access. This is also called the vault's "DNS Name". - You should validate that this URL references a valid Key Vault or Managed HSM resource. - See https://aka.ms/azsdk/blog/vault-uri for details. - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity` + :param vault_base_url: Required. + :type vault_base_url: str + :param credential: Credential used to authenticate requests to the service. Required. :type credential: ~azure.core.credentials.TokenCredential - - :keyword api_version: Version of the service API to use. Defaults to the most recent. - :paramtype api_version: ~azure.keyvault.keys.ApiVersion or str - :keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key - Vault or Managed HSM domain. Defaults to True. - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START create_key_client] - :end-before: [END create_key_client] - :language: python - :caption: Create a new ``KeyClient`` - :dedent: 4 + :keyword api_version: The API version to use for this operation. Default value is + "7.6-preview.2". Note that overriding this default value may result in unsupported behavior. + :paramtype api_version: str """ - # pylint:disable=protected-access, too-many-public-methods - - def _get_attributes( - self, - enabled: Optional[bool], - not_before: Optional[datetime], - expires_on: Optional[datetime], - exportable: Optional[bool] = None, - ) -> Optional[KeyAttributes]: - """Return a KeyAttributes object if non-None attributes are provided, or None otherwise. - - :param enabled: Whether the key is enabled. - :type enabled: bool or None - :param not_before: Not before date of the key in UTC. - :type not_before: ~datetime.datetime or None - :param expires_on: Expiry date of the key in UTC. - :type expires_on: ~datetime.datetime or None - :param exportable: Whether the private key can be exported. - :type exportable: bool or None - - :returns: An autorest-generated model of the key's attributes. - :rtype: KeyAttributes - """ - if enabled is not None or not_before is not None or expires_on is not None or exportable is not None: - return self._models.KeyAttributes( - enabled=enabled, not_before=not_before, expires=expires_on, exportable=exportable - ) - return None - - def get_cryptography_client( - self, - key_name: str, - *, - key_version: Optional[str] = None, - **kwargs, # pylint: disable=unused-argument - ) -> CryptographyClient: - """Gets a :class:`~azure.keyvault.keys.crypto.CryptographyClient` for the given key. - - :param str key_name: The name of the key used to perform cryptographic operations. - - :keyword key_version: Optional version of the key used to perform cryptographic operations. - :paramtype key_version: str or None - - :returns: A :class:`~azure.keyvault.keys.crypto.CryptographyClient` using the same options, credentials, and - HTTP client as this :class:`~azure.keyvault.keys.KeyClient`. - :rtype: ~azure.keyvault.keys.crypto.CryptographyClient - """ - key_id = _get_key_id(self._vault_url, key_name, key_version) - - # We provide a fake credential because the generated client already has the KeyClient's real credential - return CryptographyClient( - key_id, object(), generated_client=self._client, generated_models=self._models # type: ignore - ) - - @distributed_trace - def create_key( - self, - name: str, - key_type: Union[str, KeyType], - *, - size: Optional[int] = None, - curve: Optional[Union[str, KeyCurveName]] = None, - public_exponent: Optional[int] = None, - key_operations: Optional[List[Union[str, KeyOperation]]] = None, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - exportable: Optional[bool] = None, - release_policy: Optional[KeyReleasePolicy] = None, - **kwargs: Any, - ) -> KeyVaultKey: - """Create a key or, if ``name`` is already in use, create a new version of the key. - - Requires keys/create permission. - - :param str name: The name of the new key. - :param key_type: The type of key to create - :type key_type: ~azure.keyvault.keys.KeyType or str - - :keyword size: Key size in bits. Applies only to RSA and symmetric keys. Consider using - :func:`create_rsa_key` or :func:`create_oct_key` instead. - :paramtype size: int or None - :keyword curve: Elliptic curve name. Applies only to elliptic curve keys. Defaults to the NIST P-256 - elliptic curve. To create an elliptic curve key, consider using :func:`create_ec_key` instead. - :paramtype curve: ~azure.keyvault.keys.KeyCurveName or str or None - :keyword public_exponent: The RSA public exponent to use. Applies only to RSA keys created in a Managed HSM. - :paramtype public_exponent: int or None - :keyword key_operations: Allowed key operations - :paramtype key_operations: List[~azure.keyvault.keys.KeyOperation or str] or None - :keyword enabled: Whether the key is enabled for use. - :paramtype enabled: bool or None - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword not_before: Not before date of the key in UTC - :paramtype not_before: ~datetime.datetime or None - :keyword expires_on: Expiry date of the key in UTC - :paramtype expires_on: ~datetime.datetime or None - :keyword exportable: Whether the private key can be exported. - :paramtype exportable: bool or None - :keyword release_policy: The policy rules under which the key can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None - - :returns: The created key - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START create_key] - :end-before: [END create_key] - :language: python - :caption: Create a key - :dedent: 8 - """ - attributes = self._get_attributes( - enabled=enabled, not_before=not_before, expires_on=expires_on, exportable=exportable - ) - - policy = release_policy - if policy is not None: - policy = self._models.KeyReleasePolicy( - encoded_policy=policy.encoded_policy, content_type=policy.content_type, immutable=policy.immutable - ) - parameters = self._models.KeyCreateParameters( - kty=key_type, - key_size=size, - key_attributes=attributes, - key_ops=key_operations, - tags=tags, - curve=curve, - public_exponent=public_exponent, - release_policy=policy, - ) - - bundle = self._client.create_key(key_name=name, parameters=parameters, **kwargs) - return KeyVaultKey._from_key_bundle(bundle) - - @distributed_trace - def create_rsa_key( - self, - name: str, - *, - size: Optional[int] = None, - public_exponent: Optional[int] = None, - hardware_protected: Optional[bool] = False, - key_operations: Optional[List[Union[str, KeyOperation]]] = None, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - exportable: Optional[bool] = None, - release_policy: Optional[KeyReleasePolicy] = None, - **kwargs: Any, - ) -> KeyVaultKey: - """Create a new RSA key or, if ``name`` is already in use, create a new version of the key - - Requires the keys/create permission. - - :param str name: The name for the new key. - - :keyword size: Key size in bits, for example 2048, 3072, or 4096. - :paramtype size: int or None - :keyword public_exponent: The RSA public exponent to use. Applies only to RSA keys created in a Managed HSM. - :paramtype public_exponent: int or None - :keyword hardware_protected: Whether the key should be created in a hardware security module. - Defaults to ``False``. - :paramtype hardware_protected: bool or None - :keyword key_operations: Allowed key operations - :paramtype key_operations: List[~azure.keyvault.keys.KeyOperation or str] or None - :keyword enabled: Whether the key is enabled for use. - :paramtype enabled: bool or None - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword not_before: Not before date of the key in UTC - :paramtype not_before: ~datetime.datetime or None - :keyword expires_on: Expiry date of the key in UTC - :paramtype expires_on: ~datetime.datetime or None - :keyword exportable: Whether the private key can be exported. - :paramtype exportable: bool or None - :keyword release_policy: The policy rules under which the key can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None - - :returns: The created key - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START create_rsa_key] - :end-before: [END create_rsa_key] - :language: python - :caption: Create RSA key - :dedent: 8 - """ - return self.create_key( - name, - key_type="RSA-HSM" if hardware_protected else "RSA", - size=size, - public_exponent=public_exponent, - key_operations=key_operations, - enabled=enabled, - tags=tags, - not_before=not_before, - expires_on=expires_on, - exportable=exportable, - release_policy=release_policy, - **kwargs, - ) - - @distributed_trace - def create_ec_key( - self, - name: str, - *, - curve: Optional[Union[str, KeyCurveName]] = None, - key_operations: Optional[List[Union[str, KeyOperation]]] = None, - hardware_protected: Optional[bool] = False, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - exportable: Optional[bool] = None, - release_policy: Optional[KeyReleasePolicy] = None, - **kwargs: Any, - ) -> KeyVaultKey: - """Create a new elliptic curve key or, if ``name`` is already in use, create a new version of the key. - - Requires the keys/create permission. - - :param str name: The name for the new key. - - :keyword curve: Elliptic curve name. Defaults to the NIST P-256 elliptic curve. - :paramtype curve: ~azure.keyvault.keys.KeyCurveName or str or None - :keyword key_operations: Allowed key operations - :paramtype key_operations: List[~azure.keyvault.keys.KeyOperation or str] or None - :keyword hardware_protected: Whether the key should be created in a hardware security module. - Defaults to ``False``. - :paramtype hardware_protected: bool or None - :keyword enabled: Whether the key is enabled for use. - :paramtype enabled: bool or None - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword not_before: Not before date of the key in UTC - :paramtype not_before: ~datetime.datetime or None - :keyword expires_on: Expiry date of the key in UTC - :paramtype expires_on: ~datetime.datetime or None - :keyword exportable: Whether the private key can be exported. - :paramtype exportable: bool or None - :keyword release_policy: The policy rules under which the key can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None - - :returns: The created key - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START create_ec_key] - :end-before: [END create_ec_key] - :language: python - :caption: Create an elliptic curve key - :dedent: 8 - """ - return self.create_key( - name, - key_type="EC-HSM" if hardware_protected else "EC", - curve=curve, - key_operations=key_operations, - enabled=enabled, - tags=tags, - not_before=not_before, - expires_on=expires_on, - exportable=exportable, - release_policy=release_policy, - **kwargs, - ) - - @distributed_trace - def create_oct_key( - self, - name: str, - *, - size: Optional[int] = None, - key_operations: Optional[List[Union[str, KeyOperation]]] = None, - hardware_protected: Optional[bool] = False, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - exportable: Optional[bool] = None, - release_policy: Optional[KeyReleasePolicy] = None, - **kwargs: Any, - ) -> KeyVaultKey: - """Create a new octet sequence (symmetric) key or, if ``name`` is in use, create a new version of the key. - - Requires the keys/create permission. - - :param str name: The name for the new key. - - :keyword size: Key size in bits, for example 128, 192, or 256. - :paramtype size: int or None - :keyword key_operations: Allowed key operations. - :paramtype key_operations: List[~azure.keyvault.keys.KeyOperation or str] or None - :keyword hardware_protected: Whether the key should be created in a hardware security module. - Defaults to ``False``. - :paramtype hardware_protected: bool or None - :keyword enabled: Whether the key is enabled for use. - :paramtype enabled: bool or None - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword not_before: Not before date of the key in UTC - :paramtype not_before: ~datetime.datetime or None - :keyword expires_on: Expiry date of the key in UTC - :paramtype expires_on: ~datetime.datetime or None - :keyword exportable: Whether the key can be exported. - :paramtype exportable: bool or None - :keyword release_policy: The policy rules under which the key can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None - - :returns: The created key - :rtype: ~azure.keyvault.keys.KeyVaultKey - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START create_oct_key] - :end-before: [END create_oct_key] - :language: python - :caption: Create an octet sequence (symmetric) key - :dedent: 8 - """ - return self.create_key( - name, - key_type="oct-HSM" if hardware_protected else "oct", - size=size, - key_operations=key_operations, - enabled=enabled, - tags=tags, - not_before=not_before, - expires_on=expires_on, - exportable=exportable, - release_policy=release_policy, - **kwargs, - ) - - @distributed_trace - def begin_delete_key(self, name: str, **kwargs: Any) -> LROPoller[DeletedKey]: # pylint:disable=bad-option-value,delete-operation-wrong-return-type - """Delete all versions of a key and its cryptographic material. - - Requires keys/delete permission. When this method returns Key Vault has begun deleting the key. Deletion may - take several seconds in a vault with soft-delete enabled. This method therefore returns a poller enabling you to - wait for deletion to complete. - - :param str name: The name of the key to delete. - - :returns: A poller for the delete key operation. The poller's `result` method returns the - :class:`~azure.keyvault.keys.DeletedKey` without waiting for deletion to complete. If the vault has - soft-delete enabled and you want to permanently delete the key with :func:`purge_deleted_key`, call the - poller's `wait` method first. It will block until the deletion is complete. The `wait` method requires - keys/get permission. - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.keys.DeletedKey] - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the key doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START delete_key] - :end-before: [END delete_key] - :language: python - :caption: Delete a key - :dedent: 8 - """ - polling_interval = kwargs.pop("_polling_interval", None) - if polling_interval is None: - polling_interval = 2 - pipeline_response, deleted_key_bundle = self._client.delete_key( - key_name=name, - cls=lambda pipeline_response, deserialized, _: (pipeline_response, deserialized), - **kwargs, - ) - deleted_key = DeletedKey._from_deleted_key_bundle(deleted_key_bundle) - - command = partial(self.get_deleted_key, name=name, **kwargs) - polling_method = DeleteRecoverPollingMethod( - # no recovery ID means soft-delete is disabled, in which case we initialize the poller as finished - finished=deleted_key.recovery_id is None, - pipeline_response=pipeline_response, - command=command, - final_resource=deleted_key, - interval=polling_interval, - ) - return KeyVaultOperationPoller(polling_method) - - @distributed_trace - def get_key(self, name: str, version: Optional[str] = None, **kwargs: Any) -> KeyVaultKey: - """Get a key's attributes and, if it's an asymmetric key, its public material. - - Requires keys/get permission. - - :param str name: The name of the key to get. - :param version: (optional) A specific version of the key to get. If not specified, gets the latest version - of the key. - :type version: str or None - - :returns: The fetched key. - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the key doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START get_key] - :end-before: [END get_key] - :language: python - :caption: Get a key - :dedent: 8 - """ - bundle = self._client.get_key(name, key_version=version or "", **kwargs) - return KeyVaultKey._from_key_bundle(bundle) - - @distributed_trace - def get_deleted_key(self, name: str, **kwargs: Any) -> DeletedKey: - """Get a deleted key. Possible only in a vault with soft-delete enabled. - - Requires keys/get permission. - - :param str name: The name of the key - - :returns: The deleted key - :rtype: ~azure.keyvault.keys.DeletedKey - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the key doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START get_deleted_key] - :end-before: [END get_deleted_key] - :language: python - :caption: Get a deleted key - :dedent: 8 - """ - bundle = self._client.get_deleted_key(name, **kwargs) - return DeletedKey._from_deleted_key_bundle(bundle) - - @distributed_trace - def list_deleted_keys(self, **kwargs: Any) -> ItemPaged[DeletedKey]: - """List all deleted keys, including the public part of each. Possible only in a vault with soft-delete enabled. - - Requires keys/list permission. - - :returns: An iterator of deleted keys - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.keys.DeletedKey] - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START list_deleted_keys] - :end-before: [END list_deleted_keys] - :language: python - :caption: List all the deleted keys - :dedent: 8 - """ - return self._client.get_deleted_keys( - maxresults=kwargs.pop("max_page_size", None), - cls=lambda objs: [DeletedKey._from_deleted_key_item(x) for x in objs], - **kwargs - ) - - @distributed_trace - def list_properties_of_keys(self, **kwargs: Any) -> ItemPaged[KeyProperties]: - """List identifiers and properties of all keys in the vault. - - Requires keys/list permission. - - :returns: An iterator of keys without their cryptographic material or version information - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.keys.KeyProperties] - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START list_keys] - :end-before: [END list_keys] - :language: python - :caption: List all keys - :dedent: 8 - """ - return self._client.get_keys( - maxresults=kwargs.pop("max_page_size", None), - cls=lambda objs: [KeyProperties._from_key_item(x) for x in objs], - **kwargs - ) - - @distributed_trace - def list_properties_of_key_versions(self, name: str, **kwargs: Any) -> ItemPaged[KeyProperties]: - """List the identifiers and properties of a key's versions. - - Requires keys/list permission. - - :param str name: The name of the key - - :returns: An iterator of keys without their cryptographic material - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.keys.KeyProperties] - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START list_properties_of_key_versions] - :end-before: [END list_properties_of_key_versions] - :language: python - :caption: List all versions of a key - :dedent: 8 - """ - return self._client.get_key_versions( - name, - maxresults=kwargs.pop("max_page_size", None), - cls=lambda objs: [KeyProperties._from_key_item(x) for x in objs], - **kwargs - ) - - @distributed_trace - def purge_deleted_key(self, name: str, **kwargs: Any) -> None: - """Permanently deletes a deleted key. Only possible in a vault with soft-delete enabled. - - Performs an irreversible deletion of the specified key, without possibility for recovery. The operation is not - available if the :py:attr:`~azure.keyvault.keys.KeyProperties.recovery_level` does not specify 'Purgeable'. - This method is only necessary for purging a key before its - :py:attr:`~azure.keyvault.keys.DeletedKey.scheduled_purge_date`. - - Requires keys/purge permission. - - :param str name: The name of the deleted key to purge - - :returns: None - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # if the vault has soft-delete enabled, purge permanently deletes a deleted key - # (with soft-delete disabled, begin_delete_key is permanent) - key_client.purge_deleted_key("key-name") - - """ - self._client.purge_deleted_key(key_name=name, **kwargs) - - @distributed_trace - def begin_recover_deleted_key(self, name: str, **kwargs: Any) -> LROPoller[KeyVaultKey]: - """Recover a deleted key to its latest version. Possible only in a vault with soft-delete enabled. - - Requires keys/recover permission. - - When this method returns Key Vault has begun recovering the key. Recovery may take several seconds. This - method therefore returns a poller enabling you to wait for recovery to complete. Waiting is only necessary when - you want to use the recovered key in another operation immediately. - - :param str name: The name of the deleted key to recover - - :returns: A poller for the recovery operation. The poller's `result` method returns the recovered - :class:`~azure.keyvault.keys.KeyVaultKey` without waiting for recovery to complete. If you want to use the - recovered key immediately, call the poller's `wait` method, which blocks until the key is ready to use. The - `wait` method requires keys/get permission. - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.keys.KeyVaultKey] - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START recover_deleted_key] - :end-before: [END recover_deleted_key] - :language: python - :caption: Recover a deleted key - :dedent: 8 - """ - polling_interval = kwargs.pop("_polling_interval", None) - if polling_interval is None: - polling_interval = 2 - pipeline_response, recovered_key_bundle = self._client.recover_deleted_key( - key_name=name, - cls=lambda pipeline_response, deserialized, _: (pipeline_response, deserialized), - **kwargs, - ) - recovered_key = KeyVaultKey._from_key_bundle(recovered_key_bundle) - command = partial(self.get_key, name=name, **kwargs) - polling_method = DeleteRecoverPollingMethod( - finished=False, - pipeline_response=pipeline_response, - command=command, - final_resource=recovered_key, - interval=polling_interval, - ) - - return KeyVaultOperationPoller(polling_method) - - @distributed_trace - def update_key_properties( - self, - name: str, - version: Optional[str] = None, - *, - key_operations: Optional[List[Union[str, KeyOperation]]] = None, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - release_policy: Optional[KeyReleasePolicy] = None, - **kwargs: Any, - ) -> KeyVaultKey: - """Change a key's properties (not its cryptographic material). - - Requires keys/update permission. - - :param str name: The name of key to update - :param version: (optional) The version of the key to update. If unspecified, the latest version is updated. - :type version: str or None - - :keyword key_operations: Allowed key operations - :paramtype key_operations: List[~azure.keyvault.keys.KeyOperation or str] or None - :keyword enabled: Whether the key is enabled for use. - :paramtype enabled: bool or None - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword not_before: Not before date of the key in UTC - :paramtype not_before: ~datetime.datetime or None - :keyword expires_on: Expiry date of the key in UTC - :paramtype expires_on: ~datetime.datetime or None - :keyword release_policy: The policy rules under which the key can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None - - :returns: The updated key - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the key doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START update_key] - :end-before: [END update_key] - :language: python - :caption: Update a key's attributes - :dedent: 8 - """ - attributes = self._get_attributes(enabled=enabled, not_before=not_before, expires_on=expires_on) - - policy = release_policy - if policy is not None: - policy = self._models.KeyReleasePolicy( - content_type=policy.content_type, encoded_policy=policy.encoded_policy, immutable=policy.immutable - ) - parameters = self._models.KeyUpdateParameters( - key_ops=key_operations, - key_attributes=attributes, - tags=tags, - release_policy=policy, - ) - - bundle = self._client.update_key( - name, key_version=version or "", parameters=parameters, **kwargs - ) - return KeyVaultKey._from_key_bundle(bundle) - - @distributed_trace - def backup_key(self, name: str, **kwargs: Any) -> bytes: - """Back up a key in a protected form useable only by Azure Key Vault. - - Requires keys/backup permission. - - This is intended to allow copying a key from one vault to another. Both vaults must be owned by the same Azure - subscription. Also, backup / restore cannot be performed across geopolitical boundaries. For example, a backup - from a vault in a USA region cannot be restored to a vault in an EU region. - - :param str name: The name of the key to back up - - :returns: The key backup result, in a protected bytes format that can only be used by Azure Key Vault. - :rtype: bytes - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the key doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START backup_key] - :end-before: [END backup_key] - :language: python - :caption: Get a key backup - :dedent: 8 - """ - backup_result = self._client.backup_key(name, **kwargs) - return backup_result.value - - @distributed_trace - def restore_key_backup(self, backup: bytes, **kwargs: Any) -> KeyVaultKey: - """Restore a key backup to the vault. - - Requires keys/restore permission. - - This imports all versions of the key, with its name, attributes, and access control policies. If the key's name - is already in use, restoring it will fail. Also, the target vault must be owned by the same Microsoft Azure - subscription as the source vault. - - :param bytes backup: A key backup as returned by :func:`backup_key` - - :returns: The restored key - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.ResourceExistsError or ~azure.core.exceptions.HttpResponseError: - the former if the backed up key's name is already in use; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_keys.py - :start-after: [START restore_key_backup] - :end-before: [END restore_key_backup] - :language: python - :caption: Restore a key backup - :dedent: 8 - """ - bundle = self._client.restore_key( - parameters=self._models.KeyRestoreParameters(key_bundle_backup=backup), - **kwargs - ) - return KeyVaultKey._from_key_bundle(bundle) - - @distributed_trace - def import_key( - self, - name: str, - key: JsonWebKey, - *, - hardware_protected: Optional[bool] = None, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - exportable: Optional[bool] = None, - release_policy: Optional[KeyReleasePolicy] = None, - **kwargs: Any, - ) -> KeyVaultKey: - """Import a key created externally. + def __init__(self, vault_base_url: str, credential: "TokenCredential", **kwargs: Any) -> None: + _endpoint = "{vaultBaseUrl}" + self._config = KeyVaultClientConfiguration(vault_base_url=vault_base_url, credential=credential, **kwargs) + + _policies = kwargs.pop("policies", None) + if _policies is None: + _policies = [ + policies.RequestIdPolicy(**kwargs), + self._config.headers_policy, + self._config.user_agent_policy, + self._config.proxy_policy, + policies.ContentDecodePolicy(**kwargs), + self._config.redirect_policy, + self._config.retry_policy, + self._config.authentication_policy, + self._config.custom_hook_policy, + self._config.logging_policy, + policies.DistributedTracingPolicy(**kwargs), + policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None, + self._config.http_logging_policy, + ] + self._client: PipelineClient = PipelineClient(base_url=_endpoint, policies=_policies, **kwargs) - Requires keys/import permission. If ``name`` is already in use, the key will be imported as a new version. + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False - :param str name: Name for the imported key - :param key: The JSON web key to import - :type key: ~azure.keyvault.keys.JsonWebKey + def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse: + """Runs the network request through the client's chained policies. - :keyword hardware_protected: Whether the key should be backed by a hardware security module - :paramtype hardware_protected: bool or None - :keyword enabled: Whether the key is enabled for use. - :paramtype enabled: bool or None - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword not_before: Not before date of the key in UTC - :paramtype not_before: ~datetime.datetime or None - :keyword expires_on: Expiry date of the key in UTC - :paramtype expires_on: ~datetime.datetime or None - :keyword exportable: Whether the private key can be exported. - :paramtype exportable: bool or None - :keyword release_policy: The policy rules under which the key can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None + >>> from azure.core.rest import HttpRequest + >>> request = HttpRequest("GET", "https://www.example.org/") + + >>> response = client.send_request(request) + - :returns: The imported key - :rtype: ~azure.keyvault.keys.KeyVaultKey + For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request - :raises ~azure.core.exceptions.HttpResponseError: + :param request: The network request you want to make. Required. + :type request: ~azure.core.rest.HttpRequest + :keyword bool stream: Whether the response payload will be streamed. Defaults to False. + :return: The response of your network call. Does not do error handling on your response. + :rtype: ~azure.core.rest.HttpResponse """ - attributes = self._get_attributes( - enabled=enabled, not_before=not_before, expires_on=expires_on, exportable=exportable - ) - - policy = release_policy - if policy is not None: - policy = self._models.KeyReleasePolicy( - content_type=policy.content_type, encoded_policy=policy.encoded_policy, immutable=policy.immutable - ) - parameters = self._models.KeyImportParameters( - key=key._to_generated_model(), - key_attributes=attributes, - hsm=hardware_protected, - tags=tags, - release_policy=policy, - ) - - bundle = self._client.import_key(name, parameters=parameters, **kwargs) - return KeyVaultKey._from_key_bundle(bundle) - - @distributed_trace - def release_key( - self, - name: str, - target_attestation_token: str, - *, - version: Optional[str] = None, - algorithm: Optional[Union[str, KeyExportEncryptionAlgorithm]] = None, - nonce: Optional[str] = None, - **kwargs: Any, - ) -> ReleaseKeyResult: - """Releases a key. - - The release key operation is applicable to all key types. The target key must be marked - exportable. This operation requires the keys/release permission. - - :param str name: The name of the key to get. - :param str target_attestation_token: The attestation assertion for the target of the key release. - - :keyword version: A specific version of the key to release. If unspecified, the latest version is released. - :paramtype version: str or None - :keyword algorithm: The encryption algorithm to use to protect the released key material. - :paramtype algorithm: str or ~azure.keyvault.keys.KeyExportEncryptionAlgorithm or None - :keyword nonce: A client-provided nonce for freshness. - :paramtype nonce: str or None - - :return: The result of the key release. - :rtype: ~azure.keyvault.keys.ReleaseKeyResult - :raises ~azure.core.exceptions.HttpResponseError: - """ - result = self._client.release( - key_name=name, - key_version=version or "", - parameters=self._models.KeyReleaseParameters( - target_attestation_token=target_attestation_token, - nonce=nonce, - enc=algorithm, + request_copy = deepcopy(request) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True ), - **kwargs - ) - return ReleaseKeyResult(result.value) - - @distributed_trace - def get_random_bytes(self, count: int, **kwargs: Any) -> bytes: - """Get the requested number of random bytes from a managed HSM. - - :param int count: The requested number of random bytes. - - :return: The random bytes. - :rtype: bytes - - :raises ValueError or ~azure.core.exceptions.HttpResponseError: - the former if less than one random byte is requested; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_key_client.py - :start-after: [START get_random_bytes] - :end-before: [END get_random_bytes] - :language: python - :caption: Get random bytes - :dedent: 12 - """ - if count < 1: - raise ValueError("At least one random byte must be requested") - parameters = self._models.GetRandomBytesRequest(count=count) - result = self._client.get_random_bytes(parameters=parameters, **kwargs) - return result.value - - @distributed_trace - def get_key_rotation_policy(self, key_name: str, **kwargs: Any) -> KeyRotationPolicy: - """Get the rotation policy of a Key Vault key. - - :param str key_name: The name of the key. - - :return: The key rotation policy. - :rtype: ~azure.keyvault.keys.KeyRotationPolicy + } - :raises ~azure.core.exceptions.HttpResponseError: - """ - policy = self._client.get_key_rotation_policy(key_name=key_name, **kwargs) - return KeyRotationPolicy._from_generated(policy) - - @distributed_trace - def rotate_key(self, name: str, **kwargs: Any) -> KeyVaultKey: - """Rotate the key based on the key policy by generating a new version of the key. - - This operation requires the keys/rotate permission. - - :param str name: The name of the key to rotate. - - :return: The new version of the rotated key. - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.HttpResponseError: - """ - bundle = self._client.rotate_key(key_name=name, **kwargs) - return KeyVaultKey._from_key_bundle(bundle) - - @distributed_trace - def update_key_rotation_policy( # pylint: disable=unused-argument - self, - key_name: str, - policy: KeyRotationPolicy, - *, - lifetime_actions: Optional[List[KeyRotationLifetimeAction]] = None, - expires_in: Optional[str] = None, - **kwargs: Any, - ) -> KeyRotationPolicy: - """Updates the rotation policy of a Key Vault key. - - This operation requires the keys/update permission. - - :param str key_name: The name of the key in the given vault. - :param policy: The new rotation policy for the key. - :type policy: ~azure.keyvault.keys.KeyRotationPolicy - - :keyword lifetime_actions: Actions that will be performed by Key Vault over the lifetime of a key. This will - override the lifetime actions of the provided ``policy``. - :paramtype lifetime_actions: List[~azure.keyvault.keys.KeyRotationLifetimeAction] - :keyword str expires_in: The expiry time of the policy that will be applied on new key versions, defined as an - ISO 8601 duration. For example: 90 days is "P90D", 3 months is "P3M", and 48 hours is "PT48H". See - `Wikipedia `_ for more information on ISO 8601 durations. - This will override the expiry time of the provided ``policy``. + request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) + return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore - :return: The updated rotation policy. - :rtype: ~azure.keyvault.keys.KeyRotationPolicy + def close(self) -> None: + self._client.close() - :raises ~azure.core.exceptions.HttpResponseError: - """ - actions = lifetime_actions or policy.lifetime_actions - if actions: - actions = [ - self._models.LifetimeActions( - action=self._models.LifetimeActionsType(type=action.action), - trigger=self._models.LifetimeActionsTrigger( - time_after_create=action.time_after_create, time_before_expiry=action.time_before_expiry - ), - ) - for action in actions - ] - - attributes = self._models.KeyRotationPolicyAttributes(expiry_time=expires_in or policy.expires_in) - new_policy = self._models.KeyRotationPolicy(lifetime_actions=actions or [], attributes=attributes) - result = self._client.update_key_rotation_policy(key_name=key_name, key_rotation_policy=new_policy) - return KeyRotationPolicy._from_generated(result) - - @distributed_trace - def get_key_attestation(self, name: str, version: Optional[str] = None, **kwargs: Any) -> KeyVaultKey: - """Get a key and its attestation blob. - - This method is applicable to any key stored in Azure Key Vault Managed HSM. This operation requires the keys/get - permission. - - :param str name: The name of the key. - :param version: (optional) A specific version of the key to get. If not specified, gets the latest version - of the key. - :type version: str or None - - :return: The key attestation. - :rtype: ~azure.keyvault.keys.KeyAttestation - - :raises ~azure.core.exceptions.HttpResponseError: - """ - bundle = self._client.get_key_attestation(key_name=name, key_version=version or "", **kwargs) - return KeyVaultKey._from_key_bundle(bundle) - - def __enter__(self) -> "KeyClient": + def __enter__(self) -> Self: self._client.__enter__() return self + + def __exit__(self, *exc_details: Any) -> None: + self._client.__exit__(*exc_details) diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_configuration.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_configuration.py similarity index 100% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_configuration.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_configuration.py diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_enums.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_enums.py deleted file mode 100644 index 24dab8ff5ad7..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_enums.py +++ /dev/null @@ -1,72 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ - -# pylint: disable=enum-must-be-uppercase - -from enum import Enum - -from azure.core import CaseInsensitiveEnumMeta - - -class KeyCurveName(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Supported elliptic curves""" - - p_256 = "P-256" #: The NIST P-256 elliptic curve, AKA SECG curve SECP256R1. - p_384 = "P-384" #: The NIST P-384 elliptic curve, AKA SECG curve SECP384R1. - p_521 = "P-521" #: The NIST P-521 elliptic curve, AKA SECG curve SECP521R1. - p_256_k = "P-256K" #: The SECG SECP256K1 elliptic curve. - - -class KeyExportEncryptionAlgorithm(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Supported algorithms for protecting exported key material""" - - ckm_rsa_aes_key_wrap = "CKM_RSA_AES_KEY_WRAP" - rsa_aes_key_wrap_256 = "RSA_AES_KEY_WRAP_256" - rsa_aes_key_wrap_384 = "RSA_AES_KEY_WRAP_384" - - -class KeyOperation(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Supported key operations""" - - encrypt = "encrypt" - decrypt = "decrypt" - import_key = "import" - sign = "sign" - verify = "verify" - wrap_key = "wrapKey" - unwrap_key = "unwrapKey" - export = "export" - - -class KeyRotationPolicyAction(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """The action that will be executed in a key rotation policy""" - - rotate = "Rotate" #: Rotate the key based on the key policy. - notify = "Notify" #: Trigger Event Grid events. - - @classmethod - def _missing_(cls, value): - for member in cls: - if member.value.lower() == value.lower(): - return member - raise ValueError(f"{value} is not a valid KeyRotationPolicyAction") - - -class KeyType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Supported key types""" - - ec = "EC" #: Elliptic Curve - ec_hsm = "EC-HSM" #: Elliptic Curve with a private key which is not exportable from the HSM - rsa = "RSA" #: RSA (https://tools.ietf.org/html/rfc3447) - rsa_hsm = "RSA-HSM" #: RSA with a private key which is not exportable from the HSM - oct = "oct" #: Octet sequence (used to represent symmetric keys) - oct_hsm = "oct-HSM" #: Octet sequence with a private key which is not exportable from the HSM - - @classmethod - def _missing_(cls, value): - for member in cls: - if member.value.lower() == value.lower(): - return member - raise ValueError(f"{value} is not a valid KeyType") diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/__init__.py deleted file mode 100644 index 4f7962408227..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) Python Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- -# pylint: disable=wrong-import-position - -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from ._patch import * # pylint: disable=unused-wildcard-import - -from ._client import KeyVaultClient # type: ignore -from ._version import VERSION - -__version__ = VERSION - -try: - from ._patch import __all__ as _patch_all - from ._patch import * -except ImportError: - _patch_all = [] -from ._patch import patch_sdk as _patch_sdk - -__all__ = [ - "KeyVaultClient", -] -__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore - -_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_client.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_client.py deleted file mode 100644 index a4f2ae420fbe..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_client.py +++ /dev/null @@ -1,100 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) Python Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- - -from copy import deepcopy -from typing import Any, TYPE_CHECKING -from typing_extensions import Self - -from azure.core import PipelineClient -from azure.core.pipeline import policies -from azure.core.rest import HttpRequest, HttpResponse - -from ._configuration import KeyVaultClientConfiguration -from ._operations import KeyVaultClientOperationsMixin -from ._serialization import Deserializer, Serializer - -if TYPE_CHECKING: - from azure.core.credentials import TokenCredential - - -class KeyVaultClient(KeyVaultClientOperationsMixin): - """The key vault client performs cryptographic key operations and vault operations against the Key - Vault service. - - :param vault_base_url: Required. - :type vault_base_url: str - :param credential: Credential used to authenticate requests to the service. Required. - :type credential: ~azure.core.credentials.TokenCredential - :keyword api_version: The API version to use for this operation. Default value is - "7.6-preview.2". Note that overriding this default value may result in unsupported behavior. - :paramtype api_version: str - """ - - def __init__(self, vault_base_url: str, credential: "TokenCredential", **kwargs: Any) -> None: - _endpoint = "{vaultBaseUrl}" - self._config = KeyVaultClientConfiguration(vault_base_url=vault_base_url, credential=credential, **kwargs) - _policies = kwargs.pop("policies", None) - if _policies is None: - _policies = [ - policies.RequestIdPolicy(**kwargs), - self._config.headers_policy, - self._config.user_agent_policy, - self._config.proxy_policy, - policies.ContentDecodePolicy(**kwargs), - self._config.redirect_policy, - self._config.retry_policy, - self._config.authentication_policy, - self._config.custom_hook_policy, - self._config.logging_policy, - policies.DistributedTracingPolicy(**kwargs), - policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None, - self._config.http_logging_policy, - ] - self._client: PipelineClient = PipelineClient(base_url=_endpoint, policies=_policies, **kwargs) - - self._serialize = Serializer() - self._deserialize = Deserializer() - self._serialize.client_side_validation = False - - def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse: - """Runs the network request through the client's chained policies. - - >>> from azure.core.rest import HttpRequest - >>> request = HttpRequest("GET", "https://www.example.org/") - - >>> response = client.send_request(request) - - - For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request - - :param request: The network request you want to make. Required. - :type request: ~azure.core.rest.HttpRequest - :keyword bool stream: Whether the response payload will be streamed. Defaults to False. - :return: The response of your network call. Does not do error handling on your response. - :rtype: ~azure.core.rest.HttpResponse - """ - - request_copy = deepcopy(request) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url( - "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True - ), - } - - request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) - return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore - - def close(self) -> None: - self._client.close() - - def __enter__(self) -> Self: - self._client.__enter__() - return self - - def __exit__(self, *exc_details: Any) -> None: - self._client.__exit__(*exc_details) diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_version.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_version.py deleted file mode 100644 index bd412784f4e1..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_version.py +++ /dev/null @@ -1,9 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) Python Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- - -VERSION = "4.10.0b1" diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/__init__.py deleted file mode 100644 index 8c996b993b8a..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/__init__.py +++ /dev/null @@ -1,29 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) Python Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- -# pylint: disable=wrong-import-position - -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from ._patch import * # pylint: disable=unused-wildcard-import - -from ._client import KeyVaultClient # type: ignore - -try: - from ._patch import __all__ as _patch_all - from ._patch import * -except ImportError: - _patch_all = [] -from ._patch import patch_sdk as _patch_sdk - -__all__ = [ - "KeyVaultClient", -] -__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore - -_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_client.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_client.py deleted file mode 100644 index 2d775e8b1ece..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_client.py +++ /dev/null @@ -1,102 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) Python Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- - -from copy import deepcopy -from typing import Any, Awaitable, TYPE_CHECKING -from typing_extensions import Self - -from azure.core import AsyncPipelineClient -from azure.core.pipeline import policies -from azure.core.rest import AsyncHttpResponse, HttpRequest - -from .._serialization import Deserializer, Serializer -from ._configuration import KeyVaultClientConfiguration -from ._operations import KeyVaultClientOperationsMixin - -if TYPE_CHECKING: - from azure.core.credentials_async import AsyncTokenCredential - - -class KeyVaultClient(KeyVaultClientOperationsMixin): - """The key vault client performs cryptographic key operations and vault operations against the Key - Vault service. - - :param vault_base_url: Required. - :type vault_base_url: str - :param credential: Credential used to authenticate requests to the service. Required. - :type credential: ~azure.core.credentials_async.AsyncTokenCredential - :keyword api_version: The API version to use for this operation. Default value is - "7.6-preview.2". Note that overriding this default value may result in unsupported behavior. - :paramtype api_version: str - """ - - def __init__(self, vault_base_url: str, credential: "AsyncTokenCredential", **kwargs: Any) -> None: - _endpoint = "{vaultBaseUrl}" - self._config = KeyVaultClientConfiguration(vault_base_url=vault_base_url, credential=credential, **kwargs) - _policies = kwargs.pop("policies", None) - if _policies is None: - _policies = [ - policies.RequestIdPolicy(**kwargs), - self._config.headers_policy, - self._config.user_agent_policy, - self._config.proxy_policy, - policies.ContentDecodePolicy(**kwargs), - self._config.redirect_policy, - self._config.retry_policy, - self._config.authentication_policy, - self._config.custom_hook_policy, - self._config.logging_policy, - policies.DistributedTracingPolicy(**kwargs), - policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None, - self._config.http_logging_policy, - ] - self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, policies=_policies, **kwargs) - - self._serialize = Serializer() - self._deserialize = Deserializer() - self._serialize.client_side_validation = False - - def send_request( - self, request: HttpRequest, *, stream: bool = False, **kwargs: Any - ) -> Awaitable[AsyncHttpResponse]: - """Runs the network request through the client's chained policies. - - >>> from azure.core.rest import HttpRequest - >>> request = HttpRequest("GET", "https://www.example.org/") - - >>> response = await client.send_request(request) - - - For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request - - :param request: The network request you want to make. Required. - :type request: ~azure.core.rest.HttpRequest - :keyword bool stream: Whether the response payload will be streamed. Defaults to False. - :return: The response of your network call. Does not do error handling on your response. - :rtype: ~azure.core.rest.AsyncHttpResponse - """ - - request_copy = deepcopy(request) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url( - "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True - ), - } - - request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) - return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore - - async def close(self) -> None: - await self._client.close() - - async def __aenter__(self) -> Self: - await self._client.__aenter__() - return self - - async def __aexit__(self, *exc_details: Any) -> None: - await self._client.__aexit__(*exc_details) diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/_patch.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/_patch.py deleted file mode 100644 index f7dd32510333..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/_patch.py +++ /dev/null @@ -1,20 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -"""Customize generated code here. - -Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize -""" -from typing import List - -__all__: List[str] = [] # Add all objects you want publicly available to users at this package level - - -def patch_sdk(): - """Do not remove from this file. - - `patch_sdk` is a last resort escape hatch that allows you to do customizations - you can't accomplish using the techniques described in - https://aka.ms/azsdk/python/dpcodegen/python/customize - """ diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/py.typed b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/py.typed deleted file mode 100644 index e5aff4f83af8..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/py.typed +++ /dev/null @@ -1 +0,0 @@ -# Marker file for PEP 561. \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/tsp-location.yaml b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/tsp-location.yaml deleted file mode 100644 index 4db5dc3f94eb..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/tsp-location.yaml +++ /dev/null @@ -1,5 +0,0 @@ -directory: specification/keyvault/Security.KeyVault.Keys -commit: b8d26b0e4c1886458fa56c22aac09c3e3e9a5c9e -repo: Azure/azure-rest-api-specs -additionalDirectories: -- specification/keyvault/Security.KeyVault.Common/ diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_model_base.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_model_base.py similarity index 98% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_model_base.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_model_base.py index 3072ee252ed9..49d5c7259389 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_model_base.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_model_base.py @@ -2,8 +2,9 @@ # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- # pylint: disable=protected-access, broad-except @@ -21,6 +22,7 @@ from datetime import datetime, date, time, timedelta, timezone from json import JSONEncoder import xml.etree.ElementTree as ET +from collections.abc import MutableMapping from typing_extensions import Self import isodate from azure.core.exceptions import DeserializationError @@ -28,11 +30,6 @@ from azure.core.pipeline import PipelineResponse from azure.core.serialization import _Null -if sys.version_info >= (3, 9): - from collections.abc import MutableMapping -else: - from typing import MutableMapping - _LOGGER = logging.getLogger(__name__) __all__ = ["SdkJSONEncoder", "Model", "rest_field", "rest_discriminator"] @@ -347,7 +344,7 @@ def _get_model(module_name: str, model_name: str): _UNSET = object() -class _MyMutableMapping(MutableMapping[str, typing.Any]): # pylint: disable=unsubscriptable-object +class _MyMutableMapping(MutableMapping[str, typing.Any]): def __init__(self, data: typing.Dict[str, typing.Any]) -> None: self._data = data @@ -407,13 +404,13 @@ def get(self, key: str, default: typing.Any = None) -> typing.Any: return default @typing.overload - def pop(self, key: str) -> typing.Any: ... + def pop(self, key: str) -> typing.Any: ... # pylint: disable=arguments-differ @typing.overload - def pop(self, key: str, default: _T) -> _T: ... + def pop(self, key: str, default: _T) -> _T: ... # pylint: disable=signature-differs @typing.overload - def pop(self, key: str, default: typing.Any) -> typing.Any: ... + def pop(self, key: str, default: typing.Any) -> typing.Any: ... # pylint: disable=signature-differs def pop(self, key: str, default: typing.Any = _UNSET) -> typing.Any: """ @@ -443,7 +440,7 @@ def clear(self) -> None: """ self._data.clear() - def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: + def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: # pylint: disable=arguments-differ """ Updates D from mapping/iterable E and F. :param any args: Either a mapping object or an iterable of key-value pairs. @@ -454,7 +451,7 @@ def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: def setdefault(self, key: str, default: None = None) -> None: ... @typing.overload - def setdefault(self, key: str, default: typing.Any) -> typing.Any: ... + def setdefault(self, key: str, default: typing.Any) -> typing.Any: ... # pylint: disable=signature-differs def setdefault(self, key: str, default: typing.Any = _UNSET) -> typing.Any: """ @@ -644,7 +641,7 @@ def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> Self: cls._attr_to_rest_field: typing.Dict[str, _RestField] = dict(attr_to_rest_field.items()) cls._calculated.add(f"{cls.__module__}.{cls.__qualname__}") - return super().__new__(cls) # pylint: disable=no-value-for-parameter + return super().__new__(cls) def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: for base in cls.__bases__: @@ -680,7 +677,7 @@ def _deserialize(cls, data, exist_discriminators): discriminator_value = data.find(xml_name).text # pyright: ignore else: discriminator_value = data.get(discriminator._rest_name) - mapped_cls = cls.__mapping__.get(discriminator_value, cls) # pyright: ignore + mapped_cls = cls.__mapping__.get(discriminator_value, cls) # pyright: ignore # pylint: disable=no-member return mapped_cls._deserialize(data, exist_discriminators) def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_models.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_models.py deleted file mode 100644 index b5c6e7af61d0..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_models.py +++ /dev/null @@ -1,655 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------- -from collections import namedtuple -from datetime import datetime -from typing import Any, Dict, List, Optional, Union, TYPE_CHECKING - -from ._enums import KeyOperation, KeyRotationPolicyAction, KeyType -from ._shared import parse_key_vault_id -from ._generated.models import JsonWebKey as _JsonWebKey - -if TYPE_CHECKING: - from ._generated import models as _models - -KeyOperationResult = namedtuple("KeyOperationResult", ["id", "value"]) - - -class JsonWebKey(object): - """As defined in http://tools.ietf.org/html/draft-ietf-jose-json-web-key-18. All parameters are optional. - - :keyword str kid: Key identifier. - :keyword kty: Key Type (kty), as defined in https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40 - :paramtype kty: ~azure.keyvault.keys.KeyType or str - :keyword key_ops: Allowed operations for the key - :paramtype key_ops: list[str or ~azure.keyvault.keys.KeyOperation] - :keyword bytes n: RSA modulus. - :keyword bytes e: RSA public exponent. - :keyword bytes d: RSA private exponent, or the D component of an EC private key. - :keyword bytes dp: RSA private key parameter. - :keyword bytes dq: RSA private key parameter. - :keyword bytes qi: RSA private key parameter. - :keyword bytes p: RSA secret prime. - :keyword bytes q: RSA secret prime, with p < q. - :keyword bytes k: Symmetric key. - :keyword bytes t: HSM Token, used with 'Bring Your Own Key'. - :keyword crv: Elliptic curve name. - :paramtype crv: ~azure.keyvault.keys.KeyCurveName or str - :keyword bytes x: X component of an EC public key. - :keyword bytes y: Y component of an EC public key. - """ - - _FIELDS = ("kid", "kty", "key_ops", "n", "e", "d", "dp", "dq", "qi", "p", "q", "k", "t", "crv", "x", "y") - - def __init__(self, **kwargs: Any) -> None: - for field in self._FIELDS: - setattr(self, field, kwargs.get(field)) - - def _to_generated_model(self) -> _JsonWebKey: - jwk = _JsonWebKey() - for field in self._FIELDS: - setattr(jwk, field, getattr(self, field)) - return jwk - - -class KeyAttestation: - """The key attestation information. - - :ivar certificate_pem_file: The certificate used for attestation validation, in PEM format. - :vartype certificate_pem_file: bytes or None - :ivar private_key_attestation: The key attestation corresponding to the private key material of the key. - :vartype private_key_attestation: bytes or None - :ivar public_key_attestation: The key attestation corresponding to the public key material of the key. - :vartype public_key_attestation: bytes or None - :ivar version: The version of the attestation. - :vartype version: str or None - """ - - def __init__( - self, - certificate_pem_file: Optional[bytes] = None, - private_key_attestation: Optional[bytes] = None, - public_key_attestation: Optional[bytes] = None, - version: Optional[str] = None, - ) -> None: - self.certificate_pem_file = certificate_pem_file - self.private_key_attestation = private_key_attestation - self.public_key_attestation = public_key_attestation - self.version = version - - def __repr__(self) -> str: - return f""[:1024] - - @classmethod - def _from_generated(cls, attestation: "_models.KeyAttestation") -> "KeyAttestation": - return cls( - certificate_pem_file=attestation.certificate_pem_file, - private_key_attestation=attestation.private_key_attestation, - public_key_attestation=attestation.public_key_attestation, - version=attestation.version, - ) - - -class KeyProperties(object): - """A key's ID and attributes. - - :param str key_id: The key ID. - :param attributes: The key attributes. - :type attributes: ~azure.keyvault.keys._generated.models.KeyAttributes - - :keyword bool managed: Whether the key's lifetime is managed by Key Vault. - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword release_policy: The azure.keyvault.keys.KeyReleasePolicy specifying the rules under which the key - can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None - """ - - def __init__(self, key_id: str, attributes: "Optional[_models.KeyAttributes]" = None, **kwargs: Any) -> None: - self._attributes = attributes - self._id = key_id - self._vault_id = KeyVaultKeyIdentifier(key_id) - self._managed = kwargs.get("managed", None) - self._tags = kwargs.get("tags", None) - self._release_policy = kwargs.pop("release_policy", None) - - def __repr__(self) -> str: - return f""[:1024] - - @classmethod - def _from_key_bundle(cls, key_bundle: Union["_models.KeyBundle", "_models.DeletedKeyBundle"]) -> "KeyProperties": - # pylint:disable=line-too-long - # release_policy was added in 7.3-preview - release_policy = None - if ( - hasattr(key_bundle, "release_policy") and key_bundle.release_policy is not None # type: ignore[attr-defined] - ): - release_policy = KeyReleasePolicy( - encoded_policy=key_bundle.release_policy.encoded_policy, # type: ignore - content_type=key_bundle.release_policy.content_type, # type: ignore[attr-defined] - immutable=key_bundle.release_policy.immutable, # type: ignore[attr-defined] - ) - - return cls( - key_bundle.key.kid, # type: ignore - attributes=key_bundle.attributes, - managed=key_bundle.managed, - tags=key_bundle.tags, - release_policy=release_policy, - ) - - @classmethod - def _from_key_item(cls, key_item: Union["_models.KeyItem", "_models.DeletedKeyItem"]) -> "KeyProperties": - return cls( - key_id=key_item.kid, # type: ignore - attributes=key_item.attributes, - managed=key_item.managed, - tags=key_item.tags, - ) - - @property - def id(self) -> str: - """The key ID. - - :returns: The key ID. - :rtype: str - """ - return self._id - - @property - def name(self) -> str: - """The key name. - - :returns: The key name. - :rtype: str - """ - return self._vault_id.name - - @property - def version(self) -> Optional[str]: - """The key version. - - :returns: The key version. - :rtype: str or None - """ - return self._vault_id.version - - @property - def enabled(self) -> Optional[bool]: - """Whether the key is enabled for use. - - :returns: True if the key is enabled for use; False otherwise. - :rtype: bool or None - """ - return self._attributes.enabled if self._attributes else None - - @property - def not_before(self) -> Optional[datetime]: - """The time before which the key can not be used, in UTC. - - :returns: The time before which the key can not be used, in UTC. - :rtype: ~datetime.datetime or None - """ - return self._attributes.not_before if self._attributes else None - - @property - def expires_on(self) -> Optional[datetime]: - """When the key will expire, in UTC. - - :returns: When the key will expire, in UTC. - :rtype: ~datetime.datetime or None - """ - return self._attributes.expires if self._attributes else None - - @property - def created_on(self) -> Optional[datetime]: - """When the key was created, in UTC. - - :returns: When the key was created, in UTC. - :rtype: ~datetime.datetime or None - """ - return self._attributes.created if self._attributes else None - - @property - def updated_on(self) -> Optional[datetime]: - """When the key was last updated, in UTC. - - :returns: When the key was last updated, in UTC. - :rtype: ~datetime.datetime or None - """ - return self._attributes.updated if self._attributes else None - - @property - def vault_url(self) -> str: - """URL of the vault containing the key. - - :returns: URL of the vault containing the key. - :rtype: str - """ - return self._vault_id.vault_url - - @property - def recoverable_days(self) -> Optional[int]: - """The number of days the key is retained before being deleted from a soft-delete enabled Key Vault. - - :returns: The number of days the key is retained before being deleted from a soft-delete enabled Key Vault. - :rtype: int or None - """ - # recoverable_days was added in 7.1-preview - if self._attributes: - return getattr(self._attributes, "recoverable_days", None) - return None - - @property - def recovery_level(self) -> Optional[str]: - """The vault's deletion recovery level for keys. - - :returns: The vault's deletion recovery level for keys. - :rtype: str or None - """ - return self._attributes.recovery_level if self._attributes else None - - @property - def tags(self) -> Dict[str, str]: - """Application specific metadata in the form of key-value pairs. - - :returns: A dictionary of tags attached to the key. - :rtype: dict[str, str] - """ - return self._tags - - @property - def managed(self) -> Optional[bool]: - """Whether the key's lifetime is managed by Key Vault. If the key backs a certificate, this will be true. - - :returns: True if the key's lifetime is managed by Key Vault; False otherwise. - :rtype: bool or None - """ - return self._managed - - @property - def exportable(self) -> Optional[bool]: - """Whether the private key can be exported. - - :returns: True if the private key can be exported; False otherwise. - :rtype: bool or None - """ - # exportable was added in 7.3-preview - if self._attributes: - return getattr(self._attributes, "exportable", None) - return None - - @property - def release_policy(self) -> "Optional[KeyReleasePolicy]": - """The :class:`~azure.keyvault.keys.KeyReleasePolicy` specifying the rules under which the key can be exported. - - :returns: The key's release policy specifying the rules for exporting. - :rtype: ~azure.keyvault.keys.KeyReleasePolicy or None - """ - return self._release_policy - - @property - def hsm_platform(self) -> Optional[str]: - """The underlying HSM platform. - - :returns: The underlying HSM platform. - :rtype: str or None - """ - # hsm_platform was added in 7.5-preview.1 - if self._attributes: - return getattr(self._attributes, "hsm_platform", None) - return None - - @property - def attestation(self) -> Optional[KeyAttestation]: - """The key attestation, if available and requested. - - :returns: The key or key version attestation information. - :rtype: ~azure.keyvault.keys.KeyAttestation or None - """ - # attestation was added in 7.6-preview.2 - if self._attributes: - attestation = getattr(self._attributes, "attestation", None) - return KeyAttestation._from_generated(attestation=attestation) if attestation else None # pylint:disable=protected-access - return None - - -class KeyReleasePolicy(object): - """The policy rules under which a key can be exported. - - :param bytes encoded_policy: The policy rules under which the key can be released. Encoded based on the - ``content_type``. For more information regarding release policy grammar, please refer to: - https://aka.ms/policygrammarkeys for Azure Key Vault; https://aka.ms/policygrammarmhsm for Azure Managed HSM. - - :keyword str content_type: Content type and version of the release policy. Defaults to "application/json; - charset=utf-8" if omitted. - :keyword bool immutable: Marks a release policy as immutable. An immutable release policy cannot be changed or - updated after being marked immutable. Release policies are mutable by default. - """ - - def __init__(self, encoded_policy: bytes, **kwargs: Any) -> None: - self.encoded_policy = encoded_policy - self.content_type = kwargs.get("content_type", None) - self.immutable = kwargs.get("immutable", None) - - -class ReleaseKeyResult(object): - """The result of a key release operation. - - :ivar str value: A signed token containing the released key. - - :param str value: A signed token containing the released key. - """ - - def __init__(self, value: str) -> None: - self.value = value - - -class KeyRotationLifetimeAction(object): - """An action and its corresponding trigger that will be performed by Key Vault over the lifetime of a key. - - :param action: The action that will be executed. - :type action: ~azure.keyvault.keys.KeyRotationPolicyAction or str - - :keyword time_after_create: Time after creation to attempt the specified action, as an ISO 8601 duration. - For example, 90 days is "P90D". See `Wikipedia `_ for more - information on ISO 8601 durations. - :paramtype time_after_create: str or None - :keyword time_before_expiry: Time before expiry to attempt the specified action, as an ISO 8601 duration. - For example, 90 days is "P90D". See `Wikipedia `_ for more - information on ISO 8601 durations. - :paramtype time_before_expiry: str or None - """ - - def __init__(self, action: Union[KeyRotationPolicyAction, str], **kwargs: Any) -> None: - self.action = action - self.time_after_create: Optional[str] = kwargs.get("time_after_create", None) - self.time_before_expiry: Optional[str] = kwargs.get("time_before_expiry", None) - - @classmethod - def _from_generated(cls, lifetime_action: "_models.LifetimeActions") -> "KeyRotationLifetimeAction": - if lifetime_action.action: - if lifetime_action.trigger: - return cls( - action=lifetime_action.action.type, # type: ignore - time_after_create=lifetime_action.trigger.time_after_create, - time_before_expiry=lifetime_action.trigger.time_before_expiry, - ) - return cls(action=lifetime_action.action) # type: ignore - raise ValueError("Provided LifetimeActions model is missing a required lifetime action property.") - - -class KeyRotationPolicy(object): - """The key rotation policy that belongs to a key. - - :ivar id: The identifier of the key rotation policy. - :vartype id: str or None - :ivar lifetime_actions: Actions that will be performed by Key Vault over the lifetime of a key. - :vartype lifetime_actions: list[~azure.keyvault.keys.KeyRotationLifetimeAction] - :ivar expires_in: The expiry time of the policy that will be applied on new key versions, defined as an ISO 8601 - duration. For example, 90 days is "P90D". See `Wikipedia `_ for - more information on ISO 8601 durations. - :vartype expires_in: str or None - :ivar created_on: When the policy was created, in UTC - :vartype created_on: ~datetime.datetime or None - :ivar updated_on: When the policy was last updated, in UTC - :vartype updated_on: ~datetime.datetime or None - """ - - def __init__(self, **kwargs: Any) -> None: - self.id = kwargs.get("policy_id", None) - self.lifetime_actions: List[KeyRotationLifetimeAction] = kwargs.get("lifetime_actions", []) - self.expires_in = kwargs.get("expires_in", None) - self.created_on = kwargs.get("created_on", None) - self.updated_on = kwargs.get("updated_on", None) - - @classmethod - def _from_generated(cls, policy: "_models.KeyRotationPolicy") -> "KeyRotationPolicy": - lifetime_actions = ( - [] - if policy.lifetime_actions is None - else [ - KeyRotationLifetimeAction._from_generated(action) for action in policy.lifetime_actions # pylint:disable=protected-access - ] - ) - if policy.attributes: - return cls( - policy_id=policy.id, - lifetime_actions=lifetime_actions, - expires_in=policy.attributes.expiry_time, - created_on=policy.attributes.created, - updated_on=policy.attributes.updated, - ) - return cls(policy_id=policy.id, lifetime_actions=lifetime_actions) - - -class KeyVaultKey(object): - """A key's attributes and cryptographic material. - - :param str key_id: Key Vault's identifier for the key. Typically a URI, e.g. - https://myvault.vault.azure.net/keys/my-key/version - :param jwk: The key's cryptographic material as a JSON Web Key (https://tools.ietf.org/html/rfc7517). This may be - provided as a dictionary or keyword arguments. See :class:`~azure.keyvault.keys.models.JsonWebKey` for field - names. - :type jwk: Dict[str, Any] - - Providing cryptographic material as keyword arguments: - - .. code-block:: python - - from azure.keyvault.keys.models import KeyVaultKey - - key_id = 'https://myvault.vault.azure.net/keys/my-key/my-key-version' - key_bytes = os.urandom(32) - key = KeyVaultKey(key_id, k=key_bytes, kty='oct', key_ops=['unwrapKey', 'wrapKey']) - - Providing cryptographic material as a dictionary: - - .. code-block:: python - - from azure.keyvault.keys.models import KeyVaultKey - - key_id = 'https://myvault.vault.azure.net/keys/my-key/my-key-version' - key_bytes = os.urandom(32) - jwk = {'k': key_bytes, 'kty': 'oct', 'key_ops': ['unwrapKey', 'wrapKey']} - key = KeyVaultKey(key_id, jwk=jwk) - - """ - - def __init__(self, key_id: str, jwk: Optional[Dict[str, Any]] = None, **kwargs) -> None: - self._properties: KeyProperties = kwargs.pop("properties", None) or KeyProperties(key_id, **kwargs) - if isinstance(jwk, dict): - if any(field in kwargs for field in JsonWebKey._FIELDS): - raise ValueError( - "Individual keyword arguments for key material and the 'jwk' argument are mutually exclusive." - ) - self._key_material = JsonWebKey(**jwk) - else: - self._key_material = JsonWebKey(**kwargs) - - def __repr__(self) -> str: - return f""[:1024] - - @classmethod - def _from_key_bundle(cls, key_bundle: "_models.KeyBundle") -> "KeyVaultKey": - # pylint:disable=protected-access - return cls( - key_id=key_bundle.key.kid, # type: ignore - jwk={field: getattr(key_bundle.key, field, None) for field in JsonWebKey._FIELDS}, - properties=KeyProperties._from_key_bundle(key_bundle), - ) - - @property - def id(self) -> str: - """The key ID. - - :returns: The key ID. - :rtype: str - """ - return self._properties.id - - @property - def name(self) -> str: - """The key name. - - :returns: The key name. - :rtype: str - """ - return self._properties.name - - @property - def properties(self) -> KeyProperties: - """The key properties. - - :returns: The key properties. - :rtype: ~azure.keyvault.keys.KeyProperties - """ - return self._properties - - @property - def key(self) -> JsonWebKey: - """The JSON Web Key (JWK) for the key. - - :returns: The JSON Web Key (JWK) for the key. - :rtype: ~azure.keyvault.keys.JsonWebKey - """ - return self._key_material - - @property - def key_type(self) -> Union[str, KeyType]: - """The key's type. See :class:`~azure.keyvault.keys.KeyType` for possible values. - - :returns: The key's type. See :class:`~azure.keyvault.keys.KeyType` for possible values. - :rtype: ~azure.keyvault.keys.KeyType or str - """ - # pylint:disable=no-member - return self._key_material.kty # type: ignore[attr-defined] - - @property - def key_operations(self) -> List[Union[str, KeyOperation]]: - """Permitted operations. See :class:`~azure.keyvault.keys.KeyOperation` for possible values. - - :returns: Permitted operations. See :class:`~azure.keyvault.keys.KeyOperation` for possible values. - :rtype: List[~azure.keyvault.keys.KeyOperation or str] - """ - # pylint:disable=no-member - return self._key_material.key_ops # type: ignore[attr-defined] - - -class KeyVaultKeyIdentifier(object): - """Information about a KeyVaultKey parsed from a key ID. - - :param str source_id: The full original identifier of a key - - :raises ValueError: if the key ID is improperly formatted - - Example: - .. literalinclude:: ../tests/test_parse_id.py - :start-after: [START parse_key_vault_key_id] - :end-before: [END parse_key_vault_key_id] - :language: python - :caption: Parse a key's ID - :dedent: 8 - """ - - def __init__(self, source_id: str) -> None: - self._resource_id = parse_key_vault_id(source_id) - - @property - def source_id(self) -> str: - return self._resource_id.source_id - - @property - def vault_url(self) -> str: - return self._resource_id.vault_url - - @property - def name(self) -> str: - return self._resource_id.name - - @property - def version(self) -> Optional[str]: - return self._resource_id.version - - -class DeletedKey(KeyVaultKey): - """A deleted key's properties, cryptographic material and its deletion information. - - If soft-delete is enabled, returns information about its recovery as well. - - :param properties: Properties of the deleted key. - :type properties: ~azure.keyvault.keys.KeyProperties - :param deleted_date: When the key was deleted, in UTC. - :type deleted_date: ~datetime.datetime or None - :param recovery_id: An identifier used to recover the deleted key. Returns ``None`` if soft-delete is disabled. - :type recovery_id: str or None - :param scheduled_purge_date: When the key is scheduled to be purged, in UTC. Returns ``None`` if soft-delete is - disabled. - :type scheduled_purge_date: ~datetime.datetime or None - """ - - def __init__( - self, - properties: KeyProperties, - deleted_date: Optional[datetime] = None, - recovery_id: Optional[str] = None, - scheduled_purge_date: Optional[datetime] = None, - **kwargs: Any, - ) -> None: - super(DeletedKey, self).__init__(properties=properties, **kwargs) - self._deleted_date = deleted_date - self._recovery_id = recovery_id - self._scheduled_purge_date = scheduled_purge_date - - def __repr__(self) -> str: - return f""[:1024] - - @classmethod - def _from_deleted_key_bundle(cls, deleted_key_bundle: "_models.DeletedKeyBundle") -> "DeletedKey": - # pylint:disable=protected-access - return cls( - properties=KeyProperties._from_key_bundle(deleted_key_bundle), - key_id=deleted_key_bundle.key.kid, # type: ignore - jwk={field: getattr(deleted_key_bundle.key, field, None) for field in JsonWebKey._FIELDS}, - deleted_date=deleted_key_bundle.deleted_date, - recovery_id=deleted_key_bundle.recovery_id, - scheduled_purge_date=deleted_key_bundle.scheduled_purge_date, - ) - - @classmethod - def _from_deleted_key_item(cls, deleted_key_item: "_models.DeletedKeyItem") -> "DeletedKey": - return cls( - properties=KeyProperties._from_key_item(deleted_key_item), # pylint: disable=protected-access - key_id=deleted_key_item.kid, - deleted_date=deleted_key_item.deleted_date, - recovery_id=deleted_key_item.recovery_id, - scheduled_purge_date=deleted_key_item.scheduled_purge_date, - ) - - @property - def deleted_date(self) -> Optional[datetime]: - """When the key was deleted, in UTC. - - :returns: When the key was deleted, in UTC. - :rtype: ~datetime.datetime or None - """ - return self._deleted_date - - @property - def recovery_id(self) -> Optional[str]: - """An identifier used to recover the deleted key. Returns ``None`` if soft-delete is disabled. - - :returns: An identifier used to recover the deleted key. Returns ``None`` if soft-delete is disabled. - :rtype: str or None - """ - return self._recovery_id - - @property - def scheduled_purge_date(self) -> Optional[datetime]: - """When the key is scheduled to be purged, in UTC. Returns ``None`` if soft-delete is disabled. - - :returns: When the key is scheduled to be purged, in UTC. Returns ``None`` if soft-delete is disabled. - :rtype: ~datetime.datetime or None - """ - return self._scheduled_purge_date diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_operations/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_operations/__init__.py similarity index 100% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_operations/__init__.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_operations/__init__.py diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_operations/_operations.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_operations/_operations.py similarity index 95% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_operations/_operations.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_operations/_operations.py index a5abe6e0d54c..12e3390839f7 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_operations/_operations.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_operations/_operations.py @@ -6,9 +6,9 @@ # Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- +from collections.abc import MutableMapping from io import IOBase import json -import sys from typing import Any, Callable, Dict, IO, Iterable, List, Optional, TypeVar, Union, overload import urllib.parse @@ -34,11 +34,7 @@ from .._validation import api_version_validation from .._vendor import KeyVaultClientMixinABC -if sys.version_info >= (3, 9): - from collections.abc import MutableMapping -else: - from typing import MutableMapping # type: ignore -JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object +JSON = MutableMapping[str, Any] T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] @@ -157,7 +153,7 @@ def build_key_vault_update_key_request(key_name: str, key_version: str, **kwargs accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/keys/{key-name}/{key-version}" + _url = "/keys/{key-name}{key-version}" path_format_arguments = { "key-name": _SERIALIZER.url("key_name", key_name, "str"), "key-version": _SERIALIZER.url("key_version", key_version, "str"), @@ -184,7 +180,7 @@ def build_key_vault_get_key_request(key_name: str, key_version: str, **kwargs: A accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/keys/{key-name}/{key-version}" + _url = "/keys/{key-name}{key-version}" path_format_arguments = { "key-name": _SERIALIZER.url("key_name", key_name, "str"), "key-version": _SERIALIZER.url("key_version", key_version, "str"), @@ -305,7 +301,7 @@ def build_key_vault_encrypt_request(key_name: str, key_version: str, **kwargs: A accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/keys/{key-name}/{key-version}/encrypt" + _url = "/keys/{key-name}{key-version}/encrypt" path_format_arguments = { "key-name": _SERIALIZER.url("key_name", key_name, "str"), "key-version": _SERIALIZER.url("key_version", key_version, "str"), @@ -333,7 +329,7 @@ def build_key_vault_decrypt_request(key_name: str, key_version: str, **kwargs: A accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/keys/{key-name}/{key-version}/decrypt" + _url = "/keys/{key-name}{key-version}/decrypt" path_format_arguments = { "key-name": _SERIALIZER.url("key_name", key_name, "str"), "key-version": _SERIALIZER.url("key_version", key_version, "str"), @@ -361,7 +357,7 @@ def build_key_vault_sign_request(key_name: str, key_version: str, **kwargs: Any) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/keys/{key-name}/{key-version}/sign" + _url = "/keys/{key-name}{key-version}/sign" path_format_arguments = { "key-name": _SERIALIZER.url("key_name", key_name, "str"), "key-version": _SERIALIZER.url("key_version", key_version, "str"), @@ -389,7 +385,7 @@ def build_key_vault_verify_request(key_name: str, key_version: str, **kwargs: An accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/keys/{key-name}/{key-version}/verify" + _url = "/keys/{key-name}{key-version}/verify" path_format_arguments = { "key-name": _SERIALIZER.url("key_name", key_name, "str"), "key-version": _SERIALIZER.url("key_version", key_version, "str"), @@ -417,7 +413,7 @@ def build_key_vault_wrap_key_request(key_name: str, key_version: str, **kwargs: accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/keys/{key-name}/{key-version}/wrapkey" + _url = "/keys/{key-name}{key-version}/wrapkey" path_format_arguments = { "key-name": _SERIALIZER.url("key_name", key_name, "str"), "key-version": _SERIALIZER.url("key_version", key_version, "str"), @@ -445,7 +441,7 @@ def build_key_vault_unwrap_key_request(key_name: str, key_version: str, **kwargs accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/keys/{key-name}/{key-version}/unwrapkey" + _url = "/keys/{key-name}{key-version}/unwrapkey" path_format_arguments = { "key-name": _SERIALIZER.url("key_name", key_name, "str"), "key-version": _SERIALIZER.url("key_version", key_version, "str"), @@ -473,7 +469,7 @@ def build_key_vault_release_request(key_name: str, key_version: str, **kwargs: A accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/keys/{key-name}/{key-version}/release" + _url = "/keys/{key-name}{key-version}/release" path_format_arguments = { "key-name": _SERIALIZER.url("key_name", key_name, "str"), "key-version": _SERIALIZER.url("key_version", key_version, "str"), @@ -676,7 +672,7 @@ def build_key_vault_get_key_attestation_request( # pylint: disable=name-too-lon accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/keys/{key-name}/{key-version}/attestation" + _url = "/keys/{key-name}{key-version}/attestation" path_format_arguments = { "key-name": _SERIALIZER.url("key_name", key_name, "str"), "key-version": _SERIALIZER.url("key_version", key_version, "str"), @@ -716,12 +712,12 @@ def create_key( Required. :type key_name: str :param parameters: The parameters to create a key. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyCreateParameters + :type parameters: ~azure.keyvault.keys.models.KeyCreateParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -746,7 +742,7 @@ def create_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -771,7 +767,7 @@ def create_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -792,9 +788,9 @@ def create_key( :type key_name: str :param parameters: The parameters to create a key. Is one of the following types: KeyCreateParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyCreateParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyCreateParameters or JSON or IO[bytes] :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -872,7 +868,7 @@ def rotate_key(self, key_name: str, **kwargs: Any) -> _models.KeyBundle: specified key. Required. :type key_name: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -949,12 +945,12 @@ def import_key( identifiable or sensitive information. Required. :type key_name: str :param parameters: The parameters to import a key. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyImportParameters + :type parameters: ~azure.keyvault.keys.models.KeyImportParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -979,7 +975,7 @@ def import_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1004,7 +1000,7 @@ def import_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1025,9 +1021,9 @@ def import_key( :type key_name: str :param parameters: The parameters to import a key. Is one of the following types: KeyImportParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyImportParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyImportParameters or JSON or IO[bytes] :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1105,7 +1101,7 @@ def delete_key(self, key_name: str, **kwargs: Any) -> _models.DeletedKeyBundle: :param key_name: The name of the key to delete. Required. :type key_name: str :return: DeletedKeyBundle. The DeletedKeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.DeletedKeyBundle + :rtype: ~azure.keyvault.keys.models.DeletedKeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1183,12 +1179,12 @@ def update_key( :param key_version: The version of the key to update. Required. :type key_version: str :param parameters: The parameters of the key to update. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyUpdateParameters + :type parameters: ~azure.keyvault.keys.models.KeyUpdateParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1219,7 +1215,7 @@ def update_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1250,7 +1246,7 @@ def update_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1275,9 +1271,9 @@ def update_key( :type key_version: str :param parameters: The parameters of the key to update. Is one of the following types: KeyUpdateParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyUpdateParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyUpdateParameters or JSON or IO[bytes] :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1358,7 +1354,7 @@ def get_key(self, key_name: str, key_version: str, **kwargs: Any) -> _models.Key Required. :type key_version: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1430,7 +1426,7 @@ def get_key_versions( service will return up to 25 results. Default value is None. :paramtype maxresults: int :return: An iterator like instance of KeyItem - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.keys._generated.models.KeyItem] + :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.keys.models.KeyItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} @@ -1487,7 +1483,7 @@ def prepare_request(next_link=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize(List[_models.KeyItem], deserialized["value"]) + list_of_elem = _deserialize(List[_models.KeyItem], deserialized.get("value", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore return deserialized.get("nextLink") or None, iter(list_of_elem) @@ -1523,7 +1519,7 @@ def get_keys(self, *, maxresults: Optional[int] = None, **kwargs: Any) -> Iterab service will return up to 25 results. Default value is None. :paramtype maxresults: int :return: An iterator like instance of KeyItem - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.keys._generated.models.KeyItem] + :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.keys.models.KeyItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} @@ -1579,7 +1575,7 @@ def prepare_request(next_link=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize(List[_models.KeyItem], deserialized["value"]) + list_of_elem = _deserialize(List[_models.KeyItem], deserialized.get("value", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore return deserialized.get("nextLink") or None, iter(list_of_elem) @@ -1621,7 +1617,7 @@ def backup_key(self, key_name: str, **kwargs: Any) -> _models.BackupKeyResult: :param key_name: The name of the key. Required. :type key_name: str :return: BackupKeyResult. The BackupKeyResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.BackupKeyResult + :rtype: ~azure.keyvault.keys.models.BackupKeyResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1695,12 +1691,12 @@ def restore_key( in the target Key Vault. This operation requires the keys/restore permission. :param parameters: The parameters to restore the key. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyRestoreParameters + :type parameters: ~azure.keyvault.keys.models.KeyRestoreParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1727,7 +1723,7 @@ def restore_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1754,7 +1750,7 @@ def restore_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1777,9 +1773,9 @@ def restore_key( :param parameters: The parameters to restore the key. Is one of the following types: KeyRestoreParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyRestoreParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyRestoreParameters or JSON or IO[bytes] :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1870,12 +1866,12 @@ def encrypt( :param key_version: The version of the key. Required. :type key_version: str :param parameters: The parameters for the encryption operation. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1910,7 +1906,7 @@ def encrypt( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1945,7 +1941,7 @@ def encrypt( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1974,9 +1970,9 @@ def encrypt( :type key_version: str :param parameters: The parameters for the encryption operation. Is one of the following types: KeyOperationsParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters or JSON or IO[bytes] :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -2062,7 +2058,8 @@ def decrypt( stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/decrypt permission. Microsoft recommends not to use CBC algorithms for decryption without first ensuring the integrity of the ciphertext using an HMAC, for example. See - https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode for more + `https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode + `_ for more information. :param key_name: The name of the key. Required. @@ -2070,12 +2067,12 @@ def decrypt( :param key_version: The version of the key. Required. :type key_version: str :param parameters: The parameters for the decryption operation. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2098,7 +2095,8 @@ def decrypt( stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/decrypt permission. Microsoft recommends not to use CBC algorithms for decryption without first ensuring the integrity of the ciphertext using an HMAC, for example. See - https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode for more + `https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode + `_ for more information. :param key_name: The name of the key. Required. @@ -2111,7 +2109,7 @@ def decrypt( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2134,7 +2132,8 @@ def decrypt( stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/decrypt permission. Microsoft recommends not to use CBC algorithms for decryption without first ensuring the integrity of the ciphertext using an HMAC, for example. See - https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode for more + `https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode + `_ for more information. :param key_name: The name of the key. Required. @@ -2147,7 +2146,7 @@ def decrypt( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2168,7 +2167,8 @@ def decrypt( stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/decrypt permission. Microsoft recommends not to use CBC algorithms for decryption without first ensuring the integrity of the ciphertext using an HMAC, for example. See - https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode for more + `https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode + `_ for more information. :param key_name: The name of the key. Required. @@ -2177,9 +2177,9 @@ def decrypt( :type key_version: str :param parameters: The parameters for the decryption operation. Is one of the following types: KeyOperationsParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters or JSON or IO[bytes] :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -2267,12 +2267,12 @@ def sign( :param key_version: The version of the key. Required. :type key_version: str :param parameters: The parameters for the signing operation. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeySignParameters + :type parameters: ~azure.keyvault.keys.models.KeySignParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2302,7 +2302,7 @@ def sign( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2332,7 +2332,7 @@ def sign( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2356,9 +2356,9 @@ def sign( :type key_version: str :param parameters: The parameters for the signing operation. Is one of the following types: KeySignParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeySignParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeySignParameters or JSON or IO[bytes] :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -2448,12 +2448,12 @@ def verify( :param key_version: The version of the key. Required. :type key_version: str :param parameters: The parameters for verify operations. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyVerifyParameters + :type parameters: ~azure.keyvault.keys.models.KeyVerifyParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyVerifyResult. The KeyVerifyResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyVerifyResult + :rtype: ~azure.keyvault.keys.models.KeyVerifyResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2485,7 +2485,7 @@ def verify( Default value is "application/json". :paramtype content_type: str :return: KeyVerifyResult. The KeyVerifyResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyVerifyResult + :rtype: ~azure.keyvault.keys.models.KeyVerifyResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2517,7 +2517,7 @@ def verify( Default value is "application/json". :paramtype content_type: str :return: KeyVerifyResult. The KeyVerifyResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyVerifyResult + :rtype: ~azure.keyvault.keys.models.KeyVerifyResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2543,9 +2543,9 @@ def verify( :type key_version: str :param parameters: The parameters for verify operations. Is one of the following types: KeyVerifyParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyVerifyParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyVerifyParameters or JSON or IO[bytes] :return: KeyVerifyResult. The KeyVerifyResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyVerifyResult + :rtype: ~azure.keyvault.keys.models.KeyVerifyResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -2636,12 +2636,12 @@ def wrap_key( :param key_version: The version of the key. Required. :type key_version: str :param parameters: The parameters for wrap operation. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2674,7 +2674,7 @@ def wrap_key( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2707,7 +2707,7 @@ def wrap_key( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2734,9 +2734,9 @@ def wrap_key( :type key_version: str :param parameters: The parameters for wrap operation. Is one of the following types: KeyOperationsParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters or JSON or IO[bytes] :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -2825,12 +2825,12 @@ def unwrap_key( :param key_version: The version of the key. Required. :type key_version: str :param parameters: The parameters for the key operation. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2861,7 +2861,7 @@ def unwrap_key( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2892,7 +2892,7 @@ def unwrap_key( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2917,9 +2917,9 @@ def unwrap_key( :type key_version: str :param parameters: The parameters for the key operation. Is one of the following types: KeyOperationsParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters or JSON or IO[bytes] :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3007,12 +3007,12 @@ def release( Required. :type key_version: str :param parameters: The parameters for the key release operation. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyReleaseParameters + :type parameters: ~azure.keyvault.keys.models.KeyReleaseParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyReleaseResult. The KeyReleaseResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyReleaseResult + :rtype: ~azure.keyvault.keys.models.KeyReleaseResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -3042,7 +3042,7 @@ def release( Default value is "application/json". :paramtype content_type: str :return: KeyReleaseResult. The KeyReleaseResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyReleaseResult + :rtype: ~azure.keyvault.keys.models.KeyReleaseResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -3072,7 +3072,7 @@ def release( Default value is "application/json". :paramtype content_type: str :return: KeyReleaseResult. The KeyReleaseResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyReleaseResult + :rtype: ~azure.keyvault.keys.models.KeyReleaseResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -3096,9 +3096,9 @@ def release( :type key_version: str :param parameters: The parameters for the key release operation. Is one of the following types: KeyReleaseParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyReleaseParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyReleaseParameters or JSON or IO[bytes] :return: KeyReleaseResult. The KeyReleaseResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyReleaseResult + :rtype: ~azure.keyvault.keys.models.KeyReleaseResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3181,7 +3181,7 @@ def get_deleted_keys( service will return up to 25 results. Default value is None. :paramtype maxresults: int :return: An iterator like instance of DeletedKeyItem - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.keys._generated.models.DeletedKeyItem] + :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.keys.models.DeletedKeyItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} @@ -3237,7 +3237,7 @@ def prepare_request(next_link=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize(List[_models.DeletedKeyItem], deserialized["value"]) + list_of_elem = _deserialize(List[_models.DeletedKeyItem], deserialized.get("value", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore return deserialized.get("nextLink") or None, iter(list_of_elem) @@ -3271,7 +3271,7 @@ def get_deleted_key(self, key_name: str, **kwargs: Any) -> _models.DeletedKeyBun :param key_name: The name of the key. Required. :type key_name: str :return: DeletedKeyBundle. The DeletedKeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.DeletedKeyBundle + :rtype: ~azure.keyvault.keys.models.DeletedKeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3394,7 +3394,7 @@ def recover_deleted_key(self, key_name: str, **kwargs: Any) -> _models.KeyBundle :param key_name: The name of the deleted key. Required. :type key_name: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3460,7 +3460,7 @@ def get_key_rotation_policy(self, key_name: str, **kwargs: Any) -> _models.KeyRo :param key_name: The name of the key in a given key vault. Required. :type key_name: str :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy + :rtype: ~azure.keyvault.keys.models.KeyRotationPolicy :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3533,12 +3533,12 @@ def update_key_rotation_policy( :param key_name: The name of the key in the given vault. Required. :type key_name: str :param key_rotation_policy: The policy for the key. Required. - :type key_rotation_policy: ~azure.keyvault.keys._generated.models.KeyRotationPolicy + :type key_rotation_policy: ~azure.keyvault.keys.models.KeyRotationPolicy :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy + :rtype: ~azure.keyvault.keys.models.KeyRotationPolicy :raises ~azure.core.exceptions.HttpResponseError: """ @@ -3559,7 +3559,7 @@ def update_key_rotation_policy( Default value is "application/json". :paramtype content_type: str :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy + :rtype: ~azure.keyvault.keys.models.KeyRotationPolicy :raises ~azure.core.exceptions.HttpResponseError: """ @@ -3580,7 +3580,7 @@ def update_key_rotation_policy( Default value is "application/json". :paramtype content_type: str :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy + :rtype: ~azure.keyvault.keys.models.KeyRotationPolicy :raises ~azure.core.exceptions.HttpResponseError: """ @@ -3597,9 +3597,9 @@ def update_key_rotation_policy( :type key_name: str :param key_rotation_policy: The policy for the key. Is one of the following types: KeyRotationPolicy, JSON, IO[bytes] Required. - :type key_rotation_policy: ~azure.keyvault.keys._generated.models.KeyRotationPolicy or JSON or IO[bytes] + :type key_rotation_policy: ~azure.keyvault.keys.models.KeyRotationPolicy or JSON or IO[bytes] :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy + :rtype: ~azure.keyvault.keys.models.KeyRotationPolicy :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3674,12 +3674,12 @@ def get_random_bytes( Get the requested number of bytes containing random values from a managed HSM. :param parameters: The request object to get random bytes. Required. - :type parameters: ~azure.keyvault.keys._generated.models.GetRandomBytesRequest + :type parameters: ~azure.keyvault.keys.models.GetRandomBytesRequest :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: RandomBytes. The RandomBytes is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.RandomBytes + :rtype: ~azure.keyvault.keys.models.RandomBytes :raises ~azure.core.exceptions.HttpResponseError: """ @@ -3697,7 +3697,7 @@ def get_random_bytes( Default value is "application/json". :paramtype content_type: str :return: RandomBytes. The RandomBytes is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.RandomBytes + :rtype: ~azure.keyvault.keys.models.RandomBytes :raises ~azure.core.exceptions.HttpResponseError: """ @@ -3715,7 +3715,7 @@ def get_random_bytes( Default value is "application/json". :paramtype content_type: str :return: RandomBytes. The RandomBytes is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.RandomBytes + :rtype: ~azure.keyvault.keys.models.RandomBytes :raises ~azure.core.exceptions.HttpResponseError: """ @@ -3729,9 +3729,9 @@ def get_random_bytes( :param parameters: The request object to get random bytes. Is one of the following types: GetRandomBytesRequest, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.GetRandomBytesRequest or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.GetRandomBytesRequest or JSON or IO[bytes] :return: RandomBytes. The RandomBytes is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.RandomBytes + :rtype: ~azure.keyvault.keys.models.RandomBytes :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3814,7 +3814,7 @@ def get_key_attestation(self, key_name: str, key_version: str, **kwargs: Any) -> key attestation blob is returned. Required. :type key_version: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_operations/_patch.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_operations/_patch.py similarity index 61% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_operations/_patch.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_operations/_patch.py index f7dd32510333..8bcb627aa475 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_operations/_patch.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_operations/_patch.py @@ -1,7 +1,8 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------- """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_operations/_patch.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_patch.py similarity index 61% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_operations/_patch.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_patch.py index f7dd32510333..8bcb627aa475 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_operations/_patch.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_patch.py @@ -1,7 +1,8 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------- """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_sdk_moniker.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_sdk_moniker.py deleted file mode 100644 index 6677724a8b67..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_sdk_moniker.py +++ /dev/null @@ -1,7 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from ._version import VERSION - -SDK_MONIKER = f"keyvault-keys/{VERSION}" diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_serialization.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_serialization.py similarity index 98% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_serialization.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_serialization.py index a066e16a64dd..eb86ea23c965 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_serialization.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_serialization.py @@ -1,28 +1,10 @@ -# pylint: disable=too-many-lines +# pylint: disable=line-too-long,useless-suppression,too-many-lines +# coding=utf-8 # -------------------------------------------------------------------------- -# # Copyright (c) Microsoft Corporation. All rights reserved. -# -# The MIT License (MIT) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the ""Software""), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -# +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- # pyright: reportUnnecessaryTypeIgnoreComment=false @@ -411,7 +393,7 @@ def from_dict( :param function key_extractors: A key extractor function. :param str content_type: JSON by default, set application/xml if XML. :returns: An instance of this model - :raises: DeserializationError if something went wrong + :raises DeserializationError: if something went wrong :rtype: Self """ deserializer = Deserializer(cls._infer_class_models()) @@ -1361,7 +1343,7 @@ def xml_key_extractor(attr, attr_desc, data): # pylint: disable=unused-argument # Iter and wrapped, should have found one node only (the wrap one) if len(children) != 1: raise DeserializationError( - "Tried to deserialize an array not wrapped, and found several nodes '{}'. Maybe you should declare this array as wrapped?".format( # pylint: disable=line-too-long + "Tried to deserialize an array not wrapped, and found several nodes '{}'. Maybe you should declare this array as wrapped?".format( xml_name ) ) diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/__init__.py deleted file mode 100644 index 4bcf3faed073..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/__init__.py +++ /dev/null @@ -1,77 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import Optional -from urllib import parse - -from .challenge_auth_policy import ChallengeAuthPolicy -from .client_base import KeyVaultClientBase -from .http_challenge import HttpChallenge -from . import http_challenge_cache - -HttpChallengeCache = http_challenge_cache # to avoid aliasing pylint error (C4745) - - -__all__ = [ - "ChallengeAuthPolicy", - "HttpChallenge", - "HttpChallengeCache", - "KeyVaultClientBase", -] - -class KeyVaultResourceId(): - """Represents a Key Vault identifier and its parsed contents. - - :param str source_id: The complete identifier received from Key Vault - :param str vault_url: The vault URL - :param str name: The name extracted from the ID - :param str version: The version extracted from the ID - """ - - def __init__( - self, - source_id: str, - vault_url: str, - name: str, - version: "Optional[str]" = None, - ) -> None: - self.source_id = source_id - self.vault_url = vault_url - self.name = name - self.version = version - - -def parse_key_vault_id(source_id: str) -> KeyVaultResourceId: - try: - parsed_uri = parse.urlparse(source_id) - except Exception as exc: - raise ValueError(f"'{source_id}' is not a valid ID") from exc - if not (parsed_uri.scheme and parsed_uri.hostname): - raise ValueError(f"'{source_id}' is not a valid ID") - - path = list(filter(None, parsed_uri.path.split("/"))) - - if len(path) < 2 or len(path) > 3: - raise ValueError(f"'{source_id}' is not a valid ID") - - vault_url = f"{parsed_uri.scheme}://{parsed_uri.hostname}" - if parsed_uri.port: - vault_url += f":{parsed_uri.port}" - - return KeyVaultResourceId( - source_id=source_id, - vault_url=vault_url, - name=path[1], - version=path[2] if len(path) == 3 else None, - ) - - -try: - # pylint:disable=unused-import - from .async_challenge_auth_policy import AsyncChallengeAuthPolicy - from .async_client_base import AsyncKeyVaultClientBase - - __all__.extend(["AsyncChallengeAuthPolicy", "AsyncKeyVaultClientBase"]) -except (SyntaxError, ImportError): - pass diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/_polling.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/_polling.py deleted file mode 100644 index d4b83a0eca57..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/_polling.py +++ /dev/null @@ -1,142 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import logging -import threading -import uuid -from typing import Any, Callable, cast, Optional - -from azure.core.exceptions import ResourceNotFoundError, HttpResponseError -from azure.core.pipeline import PipelineResponse -from azure.core.pipeline.transport import HttpTransport -from azure.core.polling import PollingMethod, LROPoller, NoPolling - -from azure.core.tracing.decorator import distributed_trace -from azure.core.tracing.common import with_current_context - -logger = logging.getLogger(__name__) - - -class KeyVaultOperationPoller(LROPoller): - """Poller for long running operations where calling result() doesn't wait for operation to complete. - - :param polling_method: The poller's polling method. - :type polling_method: ~azure.core.polling.PollingMethod - """ - - def __init__(self, polling_method: PollingMethod) -> None: - super(KeyVaultOperationPoller, self).__init__(None, None, lambda *_: None, NoPolling()) - self._polling_method = polling_method - - # pylint: disable=arguments-differ - def result(self) -> "Any": # type: ignore - """Returns a representation of the final resource without waiting for the operation to complete. - - :returns: The deserialized resource of the long running operation - :rtype: Any - - :raises ~azure.core.exceptions.HttpResponseError: Server problem with the query. - """ - return self._polling_method.resource() - - @distributed_trace - def wait(self, timeout: Optional[float] = None) -> None: - """Wait on the long running operation for a number of seconds. - - You can check if this call has ended with timeout with the "done()" method. - - :param float timeout: Period of time to wait for the long running operation to complete (in seconds). - - :raises ~azure.core.exceptions.HttpResponseError: Server problem with the query. - """ - - if not self._polling_method.finished(): - self._done = threading.Event() - self._thread = threading.Thread( - target=with_current_context(self._start), name=f"KeyVaultOperationPoller({uuid.uuid4()})" - ) - self._thread.daemon = True - self._thread.start() - - if self._thread is None: - return - self._thread.join(timeout=timeout) - try: - # Let's handle possible None in forgiveness here - raise self._exception # type: ignore - except TypeError: # Was None - pass - - -class DeleteRecoverPollingMethod(PollingMethod): - """Poller for deleting resources, and recovering deleted resources, in vaults with soft-delete enabled. - - This works by polling for the existence of the deleted or recovered resource. When a resource is deleted, Key Vault - immediately removes it from its collection. However, the resource will not immediately appear in the deleted - collection. Key Vault will therefore respond 404 to GET requests for the deleted resource; when it responds 2xx, - the resource exists in the deleted collection i.e. its deletion is complete. - - Similarly, while recovering a deleted resource, Key Vault will respond 404 to GET requests for the non-deleted - resource; when it responds 2xx, the resource exists in the non-deleted collection, i.e. its recovery is complete. - - :param pipeline_response: The operation's original pipeline response. - :type pipeline_response: PipelineResponse - :param command: A callable to invoke when polling. - :type command: Callable - :param final_resource: The final resource returned by the polling operation. - :type final_resource: Any - :param bool finished: Whether or not the polling operation is completed. - :param int interval: The polling interval, in seconds. - """ - def __init__( - self, - pipeline_response: PipelineResponse, - command: Callable, - final_resource: Any, - finished: bool, - interval: int = 2 - ) -> None: - self._pipeline_response = pipeline_response - self._command = command - self._resource = final_resource - self._polling_interval = interval - self._finished = finished - - def _update_status(self) -> None: - try: - self._command() - self._finished = True - except ResourceNotFoundError: - pass - except HttpResponseError as e: - # If we are polling on get_deleted_* and we don't have get permissions, we will get - # ResourceNotFoundError until the resource is recovered, at which point we'll get a 403. - if e.status_code == 403: - self._finished = True - else: - raise - - def initialize(self, client: Any, initial_response: Any, deserialization_callback: Callable) -> None: - pass - - def run(self) -> None: - try: - while not self.finished(): - self._update_status() - if not self.finished(): - # We should always ask the client's transport to sleep, instead of sleeping directly - transport: HttpTransport = cast(HttpTransport, self._pipeline_response.context.transport) - transport.sleep(self._polling_interval) - except Exception as e: - logger.warning(str(e)) - raise - - def finished(self) -> bool: - return self._finished - - def resource(self) -> Any: - return self._resource - - def status(self) -> str: - return "finished" if self._finished else "polling" diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/_polling_async.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/_polling_async.py deleted file mode 100644 index a089567b7c1f..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/_polling_async.py +++ /dev/null @@ -1,87 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import logging -from typing import Any, Callable, cast - -from azure.core.exceptions import ResourceNotFoundError, HttpResponseError -from azure.core.pipeline import PipelineResponse -from azure.core.pipeline.transport import AsyncHttpTransport -from azure.core.polling import AsyncPollingMethod - -logger = logging.getLogger(__name__) - - -class AsyncDeleteRecoverPollingMethod(AsyncPollingMethod): - """Poller for deleting resources, and recovering deleted resources, in vaults with soft-delete enabled. - - This works by polling for the existence of the deleted or recovered resource. When a resource is deleted, Key Vault - immediately removes it from its collection. However, the resource will not immediately appear in the deleted - collection. Key Vault will therefore respond 404 to GET requests for the deleted resource; when it responds 2xx, - the resource exists in the deleted collection i.e. its deletion is complete. - - Similarly, while recovering a deleted resource, Key Vault will respond 404 to GET requests for the non-deleted - resource; when it responds 2xx, the resource exists in the non-deleted collection, i.e. its recovery is complete. - - :param pipeline_response: The operation's original pipeline response. - :type pipeline_response: PipelineResponse - :param command: An awaitable to invoke when polling. - :type command: Callable - :param final_resource: The final resource returned by the polling operation. - :type final_resource: Any - :param bool finished: Whether or not the polling operation is completed. - :param int interval: The polling interval, in seconds. - """ - - def __init__( - self, - pipeline_response: PipelineResponse, - command: Callable, - final_resource: Any, - finished: bool, - interval: int = 2 - ) -> None: - self._pipeline_response = pipeline_response - self._command = command - self._resource = final_resource - self._polling_interval = interval - self._finished = finished - - def initialize(self, client, initial_response, deserialization_callback): - pass - - async def _update_status(self) -> None: - try: - await self._command() - self._finished = True - except ResourceNotFoundError: - pass - except HttpResponseError as e: - # If we are polling on get_deleted_* and we don't have get permissions, we will get - # ResourceNotFoundError until the resource is recovered, at which point we'll get a 403. - if e.status_code == 403: - self._finished = True - else: - raise - - async def run(self) -> None: - try: - while not self.finished(): - await self._update_status() - if not self.finished(): - # We should always ask the client's transport to sleep, instead of sleeping directly - transport: AsyncHttpTransport = cast(AsyncHttpTransport, self._pipeline_response.context.transport) - await transport.sleep(self._polling_interval) - except Exception as e: - logger.warning(str(e)) - raise - - def finished(self) -> bool: - return self._finished - - def resource(self) -> Any: - return self._resource - - def status(self) -> str: - return "finished" if self._finished else "polling" diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/async_challenge_auth_policy.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/async_challenge_auth_policy.py deleted file mode 100644 index dad851f8f58c..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/async_challenge_auth_policy.py +++ /dev/null @@ -1,262 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -"""Policy implementing Key Vault's challenge authentication protocol. - -Normally the protocol is only used for the client's first service request, upon which: -1. The challenge authentication policy sends a copy of the request, without authorization or content. -2. Key Vault responds 401 with a header (the 'challenge') detailing how the client should authenticate such a request. -3. The policy authenticates according to the challenge and sends the original request with authorization. - -The policy caches the challenge and thus knows how to authenticate future requests. However, authentication -requirements can change. For example, a vault may move to a new tenant. In such a case the policy will attempt the -protocol again. -""" - -from copy import deepcopy -import sys -import time -from typing import Any, Callable, cast, Optional, overload, TypeVar, Union -from urllib.parse import urlparse - -from typing_extensions import ParamSpec - -from azure.core.credentials import AccessToken, AccessTokenInfo, TokenRequestOptions -from azure.core.credentials_async import AsyncSupportsTokenInfo, AsyncTokenCredential, AsyncTokenProvider -from azure.core.pipeline import PipelineRequest, PipelineResponse -from azure.core.pipeline.policies import AsyncBearerTokenCredentialPolicy -from azure.core.rest import AsyncHttpResponse, HttpRequest - -from .http_challenge import HttpChallenge -from . import http_challenge_cache as ChallengeCache -from .challenge_auth_policy import _enforce_tls, _has_claims, _update_challenge - -if sys.version_info < (3, 9): - from typing import Awaitable -else: - from collections.abc import Awaitable - - -P = ParamSpec("P") -T = TypeVar("T") - - -@overload -async def await_result(func: Callable[P, Awaitable[T]], *args: P.args, **kwargs: P.kwargs) -> T: ... - - -@overload -async def await_result(func: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T: ... - - -async def await_result(func: Callable[P, Union[T, Awaitable[T]]], *args: P.args, **kwargs: P.kwargs) -> T: - """If func returns an awaitable, await it. - - :param func: The function to run. - :type func: callable - :param args: The positional arguments to pass to the function. - :type args: list - :rtype: any - :return: The result of the function - """ - result = func(*args, **kwargs) - if isinstance(result, Awaitable): - return await result - return result - - -class AsyncChallengeAuthPolicy(AsyncBearerTokenCredentialPolicy): - """Policy for handling HTTP authentication challenges. - - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity.aio` - :type credential: ~azure.core.credentials_async.AsyncTokenProvider - """ - - def __init__(self, credential: AsyncTokenProvider, *scopes: str, **kwargs: Any) -> None: - # Pass `enable_cae` so `enable_cae=True` is always passed through self.authorize_request - super().__init__(credential, *scopes, enable_cae=True, **kwargs) - self._credential: AsyncTokenProvider = credential - self._token: Optional[Union["AccessToken", "AccessTokenInfo"]] = None - self._verify_challenge_resource = kwargs.pop("verify_challenge_resource", True) - self._request_copy: Optional[HttpRequest] = None - - async def send( - self, request: PipelineRequest[HttpRequest] - ) -> PipelineResponse[HttpRequest, AsyncHttpResponse]: - """Authorize request with a bearer token and send it to the next policy. - - We implement this method to account for the valid scenario where a Key Vault authentication challenge is - immediately followed by a CAE claims challenge. The base class's implementation would return the second 401 to - the caller, but we should handle that second challenge as well (and only return any third 401 response). - - :param request: The pipeline request object - :type request: ~azure.core.pipeline.PipelineRequest - :return: The pipeline response object - :rtype: ~azure.core.pipeline.PipelineResponse - """ - await await_result(self.on_request, request) - response: PipelineResponse[HttpRequest, AsyncHttpResponse] - try: - response = await self.next.send(request) - except Exception: # pylint:disable=broad-except - await await_result(self.on_exception, request) - raise - await await_result(self.on_response, request, response) - - if response.http_response.status_code == 401: - return await self.handle_challenge_flow(request, response) - return response - - async def handle_challenge_flow( - self, - request: PipelineRequest[HttpRequest], - response: PipelineResponse[HttpRequest, AsyncHttpResponse], - consecutive_challenge: bool = False, - ) -> PipelineResponse[HttpRequest, AsyncHttpResponse]: - """Handle the challenge flow of Key Vault and CAE authentication. - - :param request: The pipeline request object - :type request: ~azure.core.pipeline.PipelineRequest - :param response: The pipeline response object - :type response: ~azure.core.pipeline.PipelineResponse - :param bool consecutive_challenge: Whether the challenge is arriving immediately after another challenge. - Consecutive challenges can only be valid if a Key Vault challenge is followed by a CAE claims challenge. - True if the preceding challenge was a Key Vault challenge; False otherwise. - - :return: The pipeline response object - :rtype: ~azure.core.pipeline.PipelineResponse - """ - self._token = None # any cached token is invalid - if "WWW-Authenticate" in response.http_response.headers: - # If the previous challenge was a KV challenge and this one is too, return the 401 - claims_challenge = _has_claims(response.http_response.headers["WWW-Authenticate"]) - if consecutive_challenge and not claims_challenge: - return response - - request_authorized = await self.on_challenge(request, response) - if request_authorized: - # if we receive a challenge response, we retrieve a new token - # which matches the new target. In this case, we don't want to remove - # token from the request so clear the 'insecure_domain_change' tag - request.context.options.pop("insecure_domain_change", False) - try: - response = await self.next.send(request) - except Exception: # pylint:disable=broad-except - await await_result(self.on_exception, request) - raise - - # If consecutive_challenge == True, this could be a third consecutive 401 - if response.http_response.status_code == 401 and not consecutive_challenge: - # If the previous challenge wasn't from CAE, we can try this function one more time - if not claims_challenge: - return await self.handle_challenge_flow(request, response, consecutive_challenge=True) - await await_result(self.on_response, request, response) - return response - - - async def on_request(self, request: PipelineRequest) -> None: - _enforce_tls(request) - challenge = ChallengeCache.get_challenge_for_url(request.http_request.url) - if challenge: - # Note that if the vault has moved to a new tenant since our last request for it, this request will fail. - if self._need_new_token(): - # azure-identity credentials require an AADv2 scope but the challenge may specify an AADv1 resource - scope = challenge.get_scope() or challenge.get_resource() + "/.default" - await self._request_kv_token(scope, challenge) - - bearer_token = cast(Union[AccessToken, AccessTokenInfo], self._token).token - request.http_request.headers["Authorization"] = f"Bearer {bearer_token}" - return - - # else: discover authentication information by eliciting a challenge from Key Vault. Remove any request data, - # saving it for later. Key Vault will reject the request as unauthorized and respond with a challenge. - # on_challenge will parse that challenge, use the original request including the body, authorize the - # request, and tell super to send it again. - if request.http_request.content: - self._request_copy = request.http_request - bodiless_request = HttpRequest( - method=request.http_request.method, - url=request.http_request.url, - headers=deepcopy(request.http_request.headers), - ) - bodiless_request.headers["Content-Length"] = "0" - request.http_request = bodiless_request - - - async def on_challenge(self, request: PipelineRequest, response: PipelineResponse) -> bool: - try: - # CAE challenges may not include a scope or tenant; cache from the previous challenge to use if necessary - old_scope: Optional[str] = None - old_tenant: Optional[str] = None - cached_challenge = ChallengeCache.get_challenge_for_url(request.http_request.url) - if cached_challenge: - old_scope = cached_challenge.get_scope() or cached_challenge.get_resource() + "/.default" - old_tenant = cached_challenge.tenant_id - - challenge = _update_challenge(request, response) - # CAE challenges may not include a scope or tenant; use the previous challenge's values if necessary - if challenge.claims and old_scope: - challenge._parameters["scope"] = old_scope # pylint:disable=protected-access - challenge.tenant_id = old_tenant - # azure-identity credentials require an AADv2 scope but the challenge may specify an AADv1 resource - scope = challenge.get_scope() or challenge.get_resource() + "/.default" - except ValueError: - return False - - if self._verify_challenge_resource: - resource_domain = urlparse(scope).netloc - if not resource_domain: - raise ValueError(f"The challenge contains invalid scope '{scope}'.") - - request_domain = urlparse(request.http_request.url).netloc - if not request_domain.lower().endswith(f".{resource_domain.lower()}"): - raise ValueError( - f"The challenge resource '{resource_domain}' does not match the requested domain. Pass " - "`verify_challenge_resource=False` to your client's constructor to disable this verification. " - "See https://aka.ms/azsdk/blog/vault-uri for more information." - ) - - # If we had created a request copy in on_request, use it now to send along the original body content - if self._request_copy: - request.http_request = self._request_copy - - # The tenant parsed from AD FS challenges is "adfs"; we don't actually need a tenant for AD FS authentication - # For AD FS we skip cross-tenant authentication per https://github.com/Azure/azure-sdk-for-python/issues/28648 - if challenge.tenant_id and challenge.tenant_id.lower().endswith("adfs"): - await self.authorize_request(request, scope, claims=challenge.claims) - else: - await self.authorize_request( - request, scope, claims=challenge.claims, tenant_id=challenge.tenant_id - ) - - return True - - def _need_new_token(self) -> bool: - now = time.time() - refresh_on = getattr(self._token, "refresh_on", None) - return not self._token or (refresh_on and refresh_on <= now) or self._token.expires_on - now < 300 - - async def _request_kv_token(self, scope: str, challenge: HttpChallenge) -> None: - """Implementation of BearerTokenCredentialPolicy's _request_token method, but specific to Key Vault. - - :param str scope: The scope for which to request a token. - :param challenge: The challenge for the request being made. - :type challenge: HttpChallenge - """ - # Exclude tenant for AD FS authentication - exclude_tenant = challenge.tenant_id and challenge.tenant_id.lower().endswith("adfs") - # The AsyncSupportsTokenInfo protocol needs TokenRequestOptions for token requests instead of kwargs - if hasattr(self._credential, "get_token_info"): - options: TokenRequestOptions = {"enable_cae": True} - if challenge.tenant_id and not exclude_tenant: - options["tenant_id"] = challenge.tenant_id - self._token = await cast(AsyncSupportsTokenInfo, self._credential).get_token_info(scope, options=options) - else: - if exclude_tenant: - self._token = await self._credential.get_token(scope, enable_cae=True) - else: - self._token = await cast(AsyncTokenCredential, self._credential).get_token( - scope, tenant_id=challenge.tenant_id, enable_cae=True - ) diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/async_client_base.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/async_client_base.py deleted file mode 100644 index ebef8d98ca41..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/async_client_base.py +++ /dev/null @@ -1,117 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import sys -from typing import Any - -from azure.core.credentials_async import AsyncTokenCredential -from azure.core.pipeline.policies import HttpLoggingPolicy -from azure.core.rest import AsyncHttpResponse, HttpRequest -from azure.core.tracing.decorator_async import distributed_trace_async - -from . import AsyncChallengeAuthPolicy -from .client_base import ApiVersion, DEFAULT_VERSION, _format_api_version, _SERIALIZER -from .._sdk_moniker import SDK_MONIKER -from .._generated.aio import KeyVaultClient as _KeyVaultClient -from .._generated import models as _models - -if sys.version_info < (3, 9): - from typing import Awaitable -else: - from collections.abc import Awaitable - - -class AsyncKeyVaultClientBase(object): - # pylint:disable=protected-access - def __init__(self, vault_url: str, credential: AsyncTokenCredential, **kwargs: Any) -> None: - if not credential: - raise ValueError( - "credential should be an object supporting the AsyncTokenCredential protocol, " - "such as a credential from azure-identity" - ) - if not vault_url: - raise ValueError("vault_url must be the URL of an Azure Key Vault") - - try: - self.api_version = kwargs.pop("api_version", DEFAULT_VERSION) - # If API version was provided as an enum value, need to make a plain string for 3.11 compatibility - if hasattr(self.api_version, "value"): - self.api_version = self.api_version.value - self._vault_url = vault_url.strip(" /") - - client = kwargs.get("generated_client") - if client: - # caller provided a configured client -> only models left to initialize - self._client = client - models = kwargs.get("generated_models") - self._models = models or _models - return - - http_logging_policy = HttpLoggingPolicy(**kwargs) - http_logging_policy.allowed_header_names.update( - {"x-ms-keyvault-network-info", "x-ms-keyvault-region", "x-ms-keyvault-service-version"} - ) - - verify_challenge = kwargs.pop("verify_challenge_resource", True) - self._client = _KeyVaultClient( - credential=credential, - vault_base_url=self._vault_url, - api_version=self.api_version, - authentication_policy=AsyncChallengeAuthPolicy(credential, verify_challenge_resource=verify_challenge), - sdk_moniker=SDK_MONIKER, - http_logging_policy=http_logging_policy, - **kwargs - ) - self._models = _models - except ValueError as exc: - # Ignore pyright error that comes from not identifying ApiVersion as an iterable enum - raise NotImplementedError( - f"This package doesn't support API version '{self.api_version}'. " - + "Supported versions: " - + f"{', '.join(v.value for v in ApiVersion)}" # pyright: ignore[reportGeneralTypeIssues] - ) from exc - - @property - def vault_url(self) -> str: - return self._vault_url - - async def __aenter__(self) -> "AsyncKeyVaultClientBase": - await self._client.__aenter__() - return self - - async def __aexit__(self, *args: Any) -> None: - await self._client.__aexit__(*args) - - async def close(self) -> None: - """Close sockets opened by the client. - - Calling this method is unnecessary when using the client as a context manager. - """ - await self._client.close() - - @distributed_trace_async - def send_request( - self, request: HttpRequest, *, stream: bool = False, **kwargs: Any - ) -> Awaitable[AsyncHttpResponse]: - """Runs a network request using the client's existing pipeline. - - The request URL can be relative to the vault URL. The service API version used for the request is the same as - the client's unless otherwise specified. This method does not raise if the response is an error; to raise an - exception, call `raise_for_status()` on the returned response object. For more information about how to send - custom requests with this method, see https://aka.ms/azsdk/dpcodegen/python/send_request. - - :param request: The network request you want to make. - :type request: ~azure.core.rest.HttpRequest - - :keyword bool stream: Whether the response payload will be streamed. Defaults to False. - - :return: The response of your network call. Does not do error handling on your response. - :rtype: ~azure.core.rest.AsyncHttpResponse - """ - request_copy = _format_api_version(request, self.api_version) - path_format_arguments = { - "vaultBaseUrl": _SERIALIZER.url("vault_base_url", self._vault_url, "str", skip_quote=True), - } - request_copy.url = self._client._client.format_url(request_copy.url, **path_format_arguments) - return self._client._client.send_request(request_copy, stream=stream, **kwargs) diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/challenge_auth_policy.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/challenge_auth_policy.py deleted file mode 100644 index eb4073d0e699..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/challenge_auth_policy.py +++ /dev/null @@ -1,270 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -"""Policy implementing Key Vault's challenge authentication protocol. - -Normally the protocol is only used for the client's first service request, upon which: -1. The challenge authentication policy sends a copy of the request, without authorization or content. -2. Key Vault responds 401 with a header (the 'challenge') detailing how the client should authenticate such a request. -3. The policy authenticates according to the challenge and sends the original request with authorization. - -The policy caches the challenge and thus knows how to authenticate future requests. However, authentication -requirements can change. For example, a vault may move to a new tenant. In such a case the policy will attempt the -protocol again. -""" - -from copy import deepcopy -import time -from typing import Any, cast, Optional, Union -from urllib.parse import urlparse - -from azure.core.credentials import ( - AccessToken, - AccessTokenInfo, - TokenCredential, - TokenProvider, - TokenRequestOptions, - SupportsTokenInfo, -) -from azure.core.exceptions import ServiceRequestError -from azure.core.pipeline import PipelineRequest, PipelineResponse -from azure.core.pipeline.policies import BearerTokenCredentialPolicy -from azure.core.rest import HttpRequest, HttpResponse - -from .http_challenge import HttpChallenge -from . import http_challenge_cache as ChallengeCache - - -def _enforce_tls(request: PipelineRequest) -> None: - if not request.http_request.url.lower().startswith("https"): - raise ServiceRequestError( - "Bearer token authentication is not permitted for non-TLS protected (non-https) URLs." - ) - - -def _has_claims(challenge: str) -> bool: - """Check if a challenge header contains claims. - - :param challenge: The challenge header to check. - :type challenge: str - - :returns: True if the challenge contains claims; False otherwise. - :rtype: bool - """ - # Split the challenge into its scheme and parameters, then check if any parameter contains claims - split_challenge = challenge.strip().split(" ", 1) - return any("claims=" in item for item in split_challenge[1].split(",")) - - -def _update_challenge(request: PipelineRequest, challenger: PipelineResponse) -> HttpChallenge: - """Parse challenge from a challenge response, cache it, and return it. - - :param request: The pipeline request that prompted the challenge response. - :type request: ~azure.core.pipeline.PipelineRequest - :param challenger: The pipeline response containing the authentication challenge. - :type challenger: ~azure.core.pipeline.PipelineResponse - - :returns: An HttpChallenge object representing the authentication challenge. - :rtype: HttpChallenge - """ - - challenge = HttpChallenge( - request.http_request.url, - challenger.http_response.headers.get("WWW-Authenticate"), - response_headers=challenger.http_response.headers, - ) - ChallengeCache.set_challenge_for_url(request.http_request.url, challenge) - return challenge - - -class ChallengeAuthPolicy(BearerTokenCredentialPolicy): - """Policy for handling HTTP authentication challenges. - - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity` - :type credential: ~azure.core.credentials.TokenProvider - :param str scopes: Lets you specify the type of access needed. - """ - - def __init__(self, credential: TokenProvider, *scopes: str, **kwargs: Any) -> None: - # Pass `enable_cae` so `enable_cae=True` is always passed through self.authorize_request - super(ChallengeAuthPolicy, self).__init__(credential, *scopes, enable_cae=True, **kwargs) - self._credential: TokenProvider = credential - self._token: Optional[Union["AccessToken", "AccessTokenInfo"]] = None - self._verify_challenge_resource = kwargs.pop("verify_challenge_resource", True) - self._request_copy: Optional[HttpRequest] = None - - def send(self, request: PipelineRequest[HttpRequest]) -> PipelineResponse[HttpRequest, HttpResponse]: - """Authorize request with a bearer token and send it to the next policy. - - We implement this method to account for the valid scenario where a Key Vault authentication challenge is - immediately followed by a CAE claims challenge. The base class's implementation would return the second 401 to - the caller, but we should handle that second challenge as well (and only return any third 401 response). - - :param request: The pipeline request object - :type request: ~azure.core.pipeline.PipelineRequest - - :return: The pipeline response object - :rtype: ~azure.core.pipeline.PipelineResponse - """ - self.on_request(request) - try: - response = self.next.send(request) - except Exception: # pylint:disable=broad-except - self.on_exception(request) - raise - - self.on_response(request, response) - if response.http_response.status_code == 401: - return self.handle_challenge_flow(request, response) - return response - - def handle_challenge_flow( - self, - request: PipelineRequest[HttpRequest], - response: PipelineResponse[HttpRequest, HttpResponse], - consecutive_challenge: bool = False, - ) -> PipelineResponse[HttpRequest, HttpResponse]: - """Handle the challenge flow of Key Vault and CAE authentication. - - :param request: The pipeline request object - :type request: ~azure.core.pipeline.PipelineRequest - :param response: The pipeline response object - :type response: ~azure.core.pipeline.PipelineResponse - :param bool consecutive_challenge: Whether the challenge is arriving immediately after another challenge. - Consecutive challenges can only be valid if a Key Vault challenge is followed by a CAE claims challenge. - True if the preceding challenge was a Key Vault challenge; False otherwise. - - :return: The pipeline response object - :rtype: ~azure.core.pipeline.PipelineResponse - """ - self._token = None # any cached token is invalid - if "WWW-Authenticate" in response.http_response.headers: - # If the previous challenge was a KV challenge and this one is too, return the 401 - claims_challenge = _has_claims(response.http_response.headers["WWW-Authenticate"]) - if consecutive_challenge and not claims_challenge: - return response - - request_authorized = self.on_challenge(request, response) - if request_authorized: - # if we receive a challenge response, we retrieve a new token - # which matches the new target. In this case, we don't want to remove - # token from the request so clear the 'insecure_domain_change' tag - request.context.options.pop("insecure_domain_change", False) - try: - response = self.next.send(request) - except Exception: # pylint:disable=broad-except - self.on_exception(request) - raise - - # If consecutive_challenge == True, this could be a third consecutive 401 - if response.http_response.status_code == 401 and not consecutive_challenge: - # If the previous challenge wasn't from CAE, we can try this function one more time - if not claims_challenge: - return self.handle_challenge_flow(request, response, consecutive_challenge=True) - self.on_response(request, response) - return response - - def on_request(self, request: PipelineRequest) -> None: - _enforce_tls(request) - challenge = ChallengeCache.get_challenge_for_url(request.http_request.url) - if challenge: - # Note that if the vault has moved to a new tenant since our last request for it, this request will fail. - if self._need_new_token: - # azure-identity credentials require an AADv2 scope but the challenge may specify an AADv1 resource - scope = challenge.get_scope() or challenge.get_resource() + "/.default" - self._request_kv_token(scope, challenge) - - bearer_token = cast(Union["AccessToken", "AccessTokenInfo"], self._token).token - request.http_request.headers["Authorization"] = f"Bearer {bearer_token}" - return - - # else: discover authentication information by eliciting a challenge from Key Vault. Remove any request data, - # saving it for later. Key Vault will reject the request as unauthorized and respond with a challenge. - # on_challenge will parse that challenge, use the original request including the body, authorize the - # request, and tell super to send it again. - if request.http_request.content: - self._request_copy = request.http_request - bodiless_request = HttpRequest( - method=request.http_request.method, - url=request.http_request.url, - headers=deepcopy(request.http_request.headers), - ) - bodiless_request.headers["Content-Length"] = "0" - request.http_request = bodiless_request - - def on_challenge(self, request: PipelineRequest, response: PipelineResponse) -> bool: - try: - # CAE challenges may not include a scope or tenant; cache from the previous challenge to use if necessary - old_scope: Optional[str] = None - old_tenant: Optional[str] = None - cached_challenge = ChallengeCache.get_challenge_for_url(request.http_request.url) - if cached_challenge: - old_scope = cached_challenge.get_scope() or cached_challenge.get_resource() + "/.default" - old_tenant = cached_challenge.tenant_id - - challenge = _update_challenge(request, response) - # CAE challenges may not include a scope or tenant; use the previous challenge's values if necessary - if challenge.claims and old_scope: - challenge._parameters["scope"] = old_scope # pylint:disable=protected-access - challenge.tenant_id = old_tenant - # azure-identity credentials require an AADv2 scope but the challenge may specify an AADv1 resource - scope = challenge.get_scope() or challenge.get_resource() + "/.default" - except ValueError: - return False - - if self._verify_challenge_resource: - resource_domain = urlparse(scope).netloc - if not resource_domain: - raise ValueError(f"The challenge contains invalid scope '{scope}'.") - - request_domain = urlparse(request.http_request.url).netloc - if not request_domain.lower().endswith(f".{resource_domain.lower()}"): - raise ValueError( - f"The challenge resource '{resource_domain}' does not match the requested domain. Pass " - "`verify_challenge_resource=False` to your client's constructor to disable this verification. " - "See https://aka.ms/azsdk/blog/vault-uri for more information." - ) - - # If we had created a request copy in on_request, use it now to send along the original body content - if self._request_copy: - request.http_request = self._request_copy - - # The tenant parsed from AD FS challenges is "adfs"; we don't actually need a tenant for AD FS authentication - # For AD FS we skip cross-tenant authentication per https://github.com/Azure/azure-sdk-for-python/issues/28648 - if challenge.tenant_id and challenge.tenant_id.lower().endswith("adfs"): - self.authorize_request(request, scope, claims=challenge.claims) - else: - self.authorize_request(request, scope, claims=challenge.claims, tenant_id=challenge.tenant_id) - - return True - - @property - def _need_new_token(self) -> bool: - now = time.time() - refresh_on = getattr(self._token, "refresh_on", None) - return not self._token or (refresh_on and refresh_on <= now) or self._token.expires_on - now < 300 - - def _request_kv_token(self, scope: str, challenge: HttpChallenge) -> None: - """Implementation of BearerTokenCredentialPolicy's _request_token method, but specific to Key Vault. - - :param str scope: The scope for which to request a token. - :param challenge: The challenge for the request being made. - :type challenge: HttpChallenge - """ - # Exclude tenant for AD FS authentication - exclude_tenant = challenge.tenant_id and challenge.tenant_id.lower().endswith("adfs") - # The SupportsTokenInfo protocol needs TokenRequestOptions for token requests instead of kwargs - if hasattr(self._credential, "get_token_info"): - options: TokenRequestOptions = {"enable_cae": True} - if challenge.tenant_id and not exclude_tenant: - options["tenant_id"] = challenge.tenant_id - self._token = cast(SupportsTokenInfo, self._credential).get_token_info(scope, options=options) - else: - if exclude_tenant: - self._token = self._credential.get_token(scope, enable_cae=True) - else: - self._token = cast(TokenCredential, self._credential).get_token( - scope, tenant_id=challenge.tenant_id, enable_cae=True - ) diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/client_base.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/client_base.py deleted file mode 100644 index 43057eb1dd0f..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/client_base.py +++ /dev/null @@ -1,161 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from copy import deepcopy -from enum import Enum -from typing import Any -from urllib.parse import urlparse - -from azure.core import CaseInsensitiveEnumMeta -from azure.core.credentials import TokenCredential -from azure.core.pipeline.policies import HttpLoggingPolicy -from azure.core.rest import HttpRequest, HttpResponse -from azure.core.tracing.decorator import distributed_trace - -from . import ChallengeAuthPolicy -from .._generated import KeyVaultClient as _KeyVaultClient -from .._generated import models as _models -from .._generated._serialization import Serializer -from .._sdk_moniker import SDK_MONIKER - - -class ApiVersion(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Key Vault API versions supported by this package""" - - #: this is the default version - V7_6_PREVIEW_2 = "7.6-preview.2" - V7_5 = "7.5" - V7_4 = "7.4" - V7_3 = "7.3" - V7_2 = "7.2" - V7_1 = "7.1" - V7_0 = "7.0" - V2016_10_01 = "2016-10-01" - - -DEFAULT_VERSION = ApiVersion.V7_6_PREVIEW_2 - -_SERIALIZER = Serializer() -_SERIALIZER.client_side_validation = False - - -def _format_api_version(request: HttpRequest, api_version: str) -> HttpRequest: - """Returns a request copy that includes an api-version query parameter if one wasn't originally present. - - :param request: The HTTP request being sent. - :type request: ~azure.core.rest.HttpRequest - :param str api_version: The service API version that the request should include. - - :returns: A copy of the request that includes an api-version query parameter. - :rtype: azure.core.rest.HttpRequest - """ - request_copy = deepcopy(request) - params = {"api-version": api_version} # By default, we want to use the client's API version - query = urlparse(request_copy.url).query - - if query: - request_copy.url = request_copy.url.partition("?")[0] - existing_params = {p[0]: p[-1] for p in [p.partition("=") for p in query.split("&")]} - params.update(existing_params) # If an api-version was provided, this will overwrite our default - - # Reconstruct the query parameters onto the URL - query_params = [] - for k, v in params.items(): - query_params.append("{}={}".format(k, v)) - query = "?" + "&".join(query_params) - request_copy.url = request_copy.url + query - return request_copy - - -class KeyVaultClientBase(object): - # pylint:disable=protected-access - def __init__(self, vault_url: str, credential: TokenCredential, **kwargs: Any) -> None: - if not credential: - raise ValueError( - "credential should be an object supporting the TokenCredential protocol, " - "such as a credential from azure-identity" - ) - if not vault_url: - raise ValueError("vault_url must be the URL of an Azure Key Vault") - - try: - self.api_version = kwargs.pop("api_version", DEFAULT_VERSION) - # If API version was provided as an enum value, need to make a plain string for 3.11 compatibility - if hasattr(self.api_version, "value"): - self.api_version = self.api_version.value - self._vault_url = vault_url.strip(" /") - - client = kwargs.get("generated_client") - if client: - # caller provided a configured client -> only models left to initialize - self._client = client - models = kwargs.get("generated_models") - self._models = models or _models - return - - http_logging_policy = HttpLoggingPolicy(**kwargs) - http_logging_policy.allowed_header_names.update( - {"x-ms-keyvault-network-info", "x-ms-keyvault-region", "x-ms-keyvault-service-version"} - ) - - verify_challenge = kwargs.pop("verify_challenge_resource", True) - self._client = _KeyVaultClient( - credential=credential, - vault_base_url=self._vault_url, - api_version=self.api_version, - authentication_policy=ChallengeAuthPolicy(credential, verify_challenge_resource=verify_challenge), - sdk_moniker=SDK_MONIKER, - http_logging_policy=http_logging_policy, - **kwargs - ) - self._models = _models - except ValueError as exc: - # Ignore pyright error that comes from not identifying ApiVersion as an iterable enum - raise NotImplementedError( - f"This package doesn't support API version '{self.api_version}'. " - + "Supported versions: " - + f"{', '.join(v.value for v in ApiVersion)}" # pyright: ignore[reportGeneralTypeIssues] - ) from exc - - @property - def vault_url(self) -> str: - return self._vault_url - - def __enter__(self) -> "KeyVaultClientBase": - self._client.__enter__() - return self - - def __exit__(self, *args: Any) -> None: - self._client.__exit__(*args) - - def close(self) -> None: - """Close sockets opened by the client. - - Calling this method is unnecessary when using the client as a context manager. - """ - self._client.close() - - @distributed_trace - def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse: - """Runs a network request using the client's existing pipeline. - - The request URL can be relative to the vault URL. The service API version used for the request is the same as - the client's unless otherwise specified. This method does not raise if the response is an error; to raise an - exception, call `raise_for_status()` on the returned response object. For more information about how to send - custom requests with this method, see https://aka.ms/azsdk/dpcodegen/python/send_request. - - :param request: The network request you want to make. - :type request: ~azure.core.rest.HttpRequest - - :keyword bool stream: Whether the response payload will be streamed. Defaults to False. - - :return: The response of your network call. Does not do error handling on your response. - :rtype: ~azure.core.rest.HttpResponse - """ - request_copy = _format_api_version(request, self.api_version) - path_format_arguments = { - "vaultBaseUrl": _SERIALIZER.url("vault_base_url", self._vault_url, "str", skip_quote=True), - } - request_copy.url = self._client._client.format_url(request_copy.url, **path_format_arguments) - return self._client._client.send_request(request_copy, stream=stream, **kwargs) diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/http_challenge.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/http_challenge.py deleted file mode 100644 index 0320df5a868b..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/http_challenge.py +++ /dev/null @@ -1,182 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import base64 -from typing import Dict, MutableMapping, Optional -from urllib import parse - - -class HttpChallenge(object): - """An object representing the content of a Key Vault authentication challenge. - - :param str request_uri: The URI of the HTTP request that prompted this challenge. - :param str challenge: The WWW-Authenticate header of the challenge response. - :param response_headers: Optional. The headers attached to the challenge response. - :type response_headers: MutableMapping[str, str] or None - """ - - def __init__( - self, request_uri: str, challenge: str, response_headers: "Optional[MutableMapping[str, str]]" = None - ) -> None: - """Parses an HTTP WWW-Authentication Bearer challenge from a server. - - Example challenge with claims: - Bearer authorization="https://login.windows-ppe.net/", error="invalid_token", - error_description="User session has been revoked", - claims="eyJhY2Nlc3NfdG9rZW4iOnsibmJmIjp7ImVzc2VudGlhbCI6dHJ1ZSwgInZhbHVlIjoiMTYwMzc0MjgwMCJ9fX0=" - """ - self.source_authority = self._validate_request_uri(request_uri) - self.source_uri = request_uri - self._parameters: "Dict[str, str]" = {} - - # get the scheme of the challenge and remove from the challenge string - trimmed_challenge = self._validate_challenge(challenge) - split_challenge = trimmed_challenge.split(" ", 1) - self.scheme = split_challenge[0] - trimmed_challenge = split_challenge[1] - - self.claims = None - # split trimmed challenge into comma-separated name=value pairs. Values are expected - # to be surrounded by quotes which are stripped here. - for item in trimmed_challenge.split(","): - # Special case for claims, which can contain = symbols as padding. Assume at most one claim per challenge - if "claims=" in item: - encoded_claims = item[item.index("=") + 1 :].strip(" \"'") - padding_needed = -len(encoded_claims) % 4 - try: - decoded_claims = base64.urlsafe_b64decode(encoded_claims + "=" * padding_needed).decode() - self.claims = decoded_claims - except Exception: # pylint:disable=broad-except - continue - # process name=value pairs - else: - comps = item.split("=") - if len(comps) == 2: - key = comps[0].strip(' "') - value = comps[1].strip(' "') - if key: - self._parameters[key] = value - - # minimum set of parameters - if not self._parameters: - raise ValueError("Invalid challenge parameters") - - # must specify authorization or authorization_uri - if "authorization" not in self._parameters and "authorization_uri" not in self._parameters: - raise ValueError("Invalid challenge parameters") - - authorization_uri = self.get_authorization_server() - # the authorization server URI should look something like https://login.windows.net/tenant-id - raw_uri_path = str(parse.urlparse(authorization_uri).path) - uri_path = raw_uri_path.lstrip("/") - self.tenant_id = uri_path.split("/", maxsplit=1)[0] or None - - # if the response headers were supplied - if response_headers: - # get the message signing key and message key encryption key from the headers - self.server_signature_key = response_headers.get("x-ms-message-signing-key", None) - self.server_encryption_key = response_headers.get("x-ms-message-encryption-key", None) - - def is_bearer_challenge(self) -> bool: - """Tests whether the HttpChallenge is a Bearer challenge. - - :returns: True if the challenge is a Bearer challenge; False otherwise. - :rtype: bool - """ - if not self.scheme: - return False - - return self.scheme.lower() == "bearer" - - def is_pop_challenge(self) -> bool: - """Tests whether the HttpChallenge is a proof of possession challenge. - - :returns: True if the challenge is a proof of possession challenge; False otherwise. - :rtype: bool - """ - if not self.scheme: - return False - - return self.scheme.lower() == "pop" - - def get_value(self, key: str) -> "Optional[str]": - return self._parameters.get(key) - - def get_authorization_server(self) -> str: - """Returns the URI for the authorization server if present, otherwise an empty string. - - :returns: The URI for the authorization server if present, otherwise an empty string. - :rtype: str - """ - value = "" - for key in ["authorization_uri", "authorization"]: - value = self.get_value(key) or "" - if value: - break - return value - - def get_resource(self) -> str: - """Returns the resource if present, otherwise an empty string. - - :returns: The challenge resource if present, otherwise an empty string. - :rtype: str - """ - return self.get_value("resource") or "" - - def get_scope(self) -> str: - """Returns the scope if present, otherwise an empty string. - - :returns: The challenge scope if present, otherwise an empty string. - :rtype: str - """ - return self.get_value("scope") or "" - - def supports_pop(self) -> bool: - """Returns True if the challenge supports proof of possession token auth; False otherwise. - - :returns: True if the challenge supports proof of possession token auth; False otherwise. - :rtype: bool - """ - return self._parameters.get("supportspop", "").lower() == "true" - - def supports_message_protection(self) -> bool: - """Returns True if the challenge vault supports message protection; False otherwise. - - :returns: True if the challenge vault supports message protection; False otherwise. - :rtype: bool - """ - return self.supports_pop() and self.server_encryption_key and self.server_signature_key # type: ignore - - def _validate_challenge(self, challenge: str) -> str: # pylint:disable=bad-option-value,useless-option-value,no-self-use - """Verifies that the challenge is a valid auth challenge and returns the key=value pairs. - - :param str challenge: The WWW-Authenticate header of the challenge response. - - :returns: The challenge key/value pairs, with whitespace removed, as a string. - :rtype: str - """ - if not challenge: - raise ValueError("Challenge cannot be empty") - - return challenge.strip() - - def _validate_request_uri(self, uri: str) -> str: # pylint:disable=bad-option-value,useless-option-value,no-self-use - """Extracts the host authority from the given URI. - - :param str uri: The URI of the HTTP request that prompted the challenge. - - :returns: The challenge host authority. - :rtype: str - """ - if not uri: - raise ValueError("request_uri cannot be empty") - - parsed = parse.urlparse(uri) - if not parsed.netloc: - raise ValueError("request_uri must be an absolute URI") - - if parsed.scheme.lower() not in ["http", "https"]: - raise ValueError("request_uri must be HTTP or HTTPS") - - return parsed.netloc diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/http_challenge_cache.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/http_challenge_cache.py deleted file mode 100644 index f1448cc53391..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_shared/http_challenge_cache.py +++ /dev/null @@ -1,93 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import threading -from typing import Dict, Optional -from urllib import parse - -from .http_challenge import HttpChallenge - - -_cache: "Dict[str, HttpChallenge]" = {} -_lock = threading.Lock() - - -def get_challenge_for_url(url: str) -> "Optional[HttpChallenge]": - """Gets the challenge for the cached URL. - - :param str url: the URL the challenge is cached for. - - :returns: The challenge for the cached request URL, or None if the request URL isn't cached. - :rtype: HttpChallenge or None - """ - - if not url: - raise ValueError("URL cannot be None") - - key = _get_cache_key(url) - - with _lock: - return _cache.get(key) - - -def _get_cache_key(url: str) -> str: - """Use the URL's netloc as cache key except when the URL specifies the default port for its scheme. In that case - use the netloc without the port. That is to say, https://foo.bar and https://foo.bar:443 are considered equivalent. - - This equivalency prevents an unnecessary challenge when using Key Vault's paging API. The Key Vault client doesn't - specify ports, but Key Vault's next page links do, so a redundant challenge would otherwise be executed when the - client requests the next page. - - :param str url: The HTTP request URL. - - :returns: The URL's `netloc`, minus any port attached to the URL. - :rtype: str - """ - - parsed = parse.urlparse(url) - if parsed.scheme == "https" and parsed.port == 443: - return parsed.netloc[:-4] - return parsed.netloc - - -def remove_challenge_for_url(url: str) -> None: - """Removes the cached challenge for the specified URL. - - :param str url: the URL for which to remove the cached challenge - """ - if not url: - raise ValueError("URL cannot be empty") - - parsed = parse.urlparse(url) - - with _lock: - del _cache[parsed.netloc] - - -def set_challenge_for_url(url: str, challenge: "HttpChallenge") -> None: - """Caches the challenge for the specified URL. - - :param str url: the URL for which to cache the challenge - :param challenge: the challenge to cache - :type challenge: HttpChallenge - """ - if not url: - raise ValueError("URL cannot be empty") - - if not challenge: - raise ValueError("Challenge cannot be empty") - - src_url = parse.urlparse(url) - if src_url.netloc != challenge.source_authority: - raise ValueError("Source URL and Challenge URL do not match") - - with _lock: - _cache[src_url.netloc] = challenge - - -def clear() -> None: - """Clears the cache.""" - - with _lock: - _cache.clear() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_validation.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_validation.py similarity index 100% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_validation.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_validation.py diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_vendor.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_vendor.py similarity index 100% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_vendor.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_vendor.py diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_version.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_version.py index f31c2a457904..bd412784f4e1 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_version.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_version.py @@ -1,6 +1,9 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- -VERSION = "4.11.0b2" +VERSION = "4.10.0b1" diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/__init__.py index 71cad7e66b18..8c996b993b8a 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/__init__.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/__init__.py @@ -1,7 +1,29 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from ._client import KeyClient +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +# pylint: disable=wrong-import-position -__all__ = ["KeyClient"] +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ._patch import * # pylint: disable=unused-wildcard-import + +from ._client import KeyVaultClient # type: ignore + +try: + from ._patch import __all__ as _patch_all + from ._patch import * +except ImportError: + _patch_all = [] +from ._patch import patch_sdk as _patch_sdk + +__all__ = [ + "KeyVaultClient", +] +__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore + +_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_client.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_client.py index 2f1c30a96b01..86d6fc4a3056 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_client.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_client.py @@ -1,1018 +1,103 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -# pylint:disable=too-many-lines -from datetime import datetime -from functools import partial -from typing import Any, Dict, List, Optional, Union +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- -from azure.core.async_paging import AsyncItemPaged -from azure.core.tracing.decorator import distributed_trace -from azure.core.tracing.decorator_async import distributed_trace_async +from copy import deepcopy +from typing import Any, Awaitable, TYPE_CHECKING +from typing_extensions import Self -from ..crypto.aio import CryptographyClient -from .._client import _get_key_id -from .._enums import KeyCurveName, KeyExportEncryptionAlgorithm, KeyOperation -from .._generated.models import KeyAttributes -from .._shared._polling_async import AsyncDeleteRecoverPollingMethod -from .._shared import AsyncKeyVaultClientBase -from .. import ( - DeletedKey, - JsonWebKey, - KeyProperties, - KeyReleasePolicy, - KeyRotationLifetimeAction, - KeyRotationPolicy, - KeyType, - KeyVaultKey, - ReleaseKeyResult, -) +from azure.core import AsyncPipelineClient +from azure.core.pipeline import policies +from azure.core.rest import AsyncHttpResponse, HttpRequest +from .._serialization import Deserializer, Serializer +from ._configuration import KeyVaultClientConfiguration +from ._operations import KeyVaultClientOperationsMixin -class KeyClient(AsyncKeyVaultClientBase): - """A high-level asynchronous interface for managing a vault's keys. +if TYPE_CHECKING: + from azure.core.credentials_async import AsyncTokenCredential - :param str vault_url: URL of the vault the client will access. This is also called the vault's "DNS Name". - You should validate that this URL references a valid Key Vault or Managed HSM resource. - See https://aka.ms/azsdk/blog/vault-uri for details. - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity.aio` - :type credential: ~azure.core.credentials_async.AsyncTokenCredential - :keyword api_version: Version of the service API to use. Defaults to the most recent. - :paramtype api_version: ~azure.keyvault.keys.ApiVersion or str - :keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key - Vault or Managed HSM domain. Defaults to True. +class KeyVaultClient(KeyVaultClientOperationsMixin): + """The key vault client performs cryptographic key operations and vault operations against the Key + Vault service. - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START create_key_client] - :end-before: [END create_key_client] - :language: python - :caption: Create a new ``KeyClient`` - :dedent: 4 + :param vault_base_url: Required. + :type vault_base_url: str + :param credential: Credential used to authenticate requests to the service. Required. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :keyword api_version: The API version to use for this operation. Default value is + "7.6-preview.2". Note that overriding this default value may result in unsupported behavior. + :paramtype api_version: str """ - # pylint:disable=protected-access, too-many-public-methods - - def _get_attributes( - self, - enabled: Optional[bool], - not_before: Optional[datetime], - expires_on: Optional[datetime], - exportable: Optional[bool] = None, - ) -> Optional[KeyAttributes]: - """Return a KeyAttributes object if non-None attributes are provided, or None otherwise. - - :param enabled: Whether the key is enabled. - :type enabled: bool or None - :param not_before: Not before date of the key in UTC. - :type not_before: ~datetime.datetime or None - :param expires_on: Expiry date of the key in UTC. - :type expires_on: ~datetime.datetime or None - :param exportable: Whether the private key can be exported. - :type exportable: bool or None - - :returns: An autorest-generated model of the key's attributes. - :rtype: KeyAttributes - """ - if enabled is not None or not_before is not None or expires_on is not None or exportable is not None: - return self._models.KeyAttributes( - enabled=enabled, not_before=not_before, expires=expires_on, exportable=exportable - ) - return None - - def get_cryptography_client( - self, - key_name: str, - *, - key_version: Optional[str] = None, - **kwargs, # pylint: disable=unused-argument - ) -> CryptographyClient: - """Gets a :class:`~azure.keyvault.keys.crypto.aio.CryptographyClient` for the given key. - - :param str key_name: The name of the key used to perform cryptographic operations. - - :keyword key_version: Optional version of the key used to perform cryptographic operations. - :paramtype key_version: str or None - - :returns: A :class:`~azure.keyvault.keys.crypto.aio.CryptographyClient` using the same options, credentials, and - HTTP client as this :class:`~azure.keyvault.keys.aio.KeyClient`. - :rtype: ~azure.keyvault.keys.crypto.aio.CryptographyClient - """ - key_id = _get_key_id(self._vault_url, key_name, key_version) - - # We provide a fake credential because the generated client already has the KeyClient's real credential - return CryptographyClient( - key_id, object(), generated_client=self._client, generated_models=self._models # type: ignore - ) - - @distributed_trace_async - async def create_key( - self, - name: str, - key_type: Union[str, KeyType], - *, - size: Optional[int] = None, - curve: Optional[Union[str, KeyCurveName]] = None, - public_exponent: Optional[int] = None, - key_operations: Optional[List[Union[str, KeyOperation]]] = None, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - exportable: Optional[bool] = None, - release_policy: Optional[KeyReleasePolicy] = None, - **kwargs: Any, - ) -> KeyVaultKey: - """Create a key or, if ``name`` is already in use, create a new version of the key. - - Requires keys/create permission. - - :param str name: The name of the new key. - :param key_type: The type of key to create - :type key_type: ~azure.keyvault.keys.KeyType or str - - :keyword size: Key size in bits. Applies only to RSA and symmetric keys. Consider using - :func:`create_rsa_key` or :func:`create_oct_key` instead. - :paramtype size: int or None - :keyword curve: Elliptic curve name. Applies only to elliptic curve keys. Defaults to the NIST P-256 - elliptic curve. To create an elliptic curve key, consider using :func:`create_ec_key` instead. - :paramtype curve: ~azure.keyvault.keys.KeyCurveName or str or None - :keyword public_exponent: The RSA public exponent to use. Applies only to RSA keys created in a Managed HSM. - :paramtype public_exponent: int or None - :keyword key_operations: Allowed key operations - :paramtype key_operations: List[~azure.keyvault.keys.KeyOperation or str] or None - :keyword enabled: Whether the key is enabled for use. - :paramtype enabled: bool or None - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword not_before: Not before date of the key in UTC - :paramtype not_before: ~datetime.datetime or None - :keyword expires_on: Expiry date of the key in UTC - :paramtype expires_on: ~datetime.datetime or None - :keyword exportable: Whether the private key can be exported. - :paramtype exportable: bool or None - :keyword release_policy: The policy rules under which the key can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None - - :returns: The created key - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START create_key] - :end-before: [END create_key] - :language: python - :caption: Create a key - :dedent: 8 - """ - attributes = self._get_attributes( - enabled=enabled, not_before=not_before, expires_on=expires_on, exportable=exportable - ) - - policy = release_policy - if policy is not None: - policy = self._models.KeyReleasePolicy( - encoded_policy=policy.encoded_policy, content_type=policy.content_type, immutable=policy.immutable - ) - parameters = self._models.KeyCreateParameters( - kty=key_type, - key_size=size, - key_attributes=attributes, - key_ops=key_operations, - tags=tags, - curve=curve, - public_exponent=public_exponent, - release_policy=policy, - ) - - bundle = await self._client.create_key( - key_name=name, - parameters=parameters, - **kwargs, - ) - return KeyVaultKey._from_key_bundle(bundle) - - @distributed_trace_async - async def create_rsa_key( - self, - name: str, - *, - size: Optional[int] = None, - public_exponent: Optional[int] = None, - hardware_protected: Optional[bool] = False, - key_operations: Optional[List[Union[str, KeyOperation]]] = None, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - exportable: Optional[bool] = None, - release_policy: Optional[KeyReleasePolicy] = None, - **kwargs: Any, - ) -> KeyVaultKey: - """Create a new RSA key or, if ``name`` is already in use, create a new version of the key - - Requires the keys/create permission. - - :param str name: The name for the new key. - - :keyword size: Key size in bits, for example 2048, 3072, or 4096. - :paramtype size: int or None - :keyword public_exponent: The RSA public exponent to use. Applies only to RSA keys created in a Managed HSM. - :paramtype public_exponent: int or None - :keyword hardware_protected: Whether the key should be created in a hardware security module. - Defaults to ``False``. - :paramtype hardware_protected: bool or None - :keyword key_operations: Allowed key operations - :paramtype key_operations: List[~azure.keyvault.keys.KeyOperation or str] or None - :keyword enabled: Whether the key is enabled for use. - :paramtype enabled: bool or None - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword not_before: Not before date of the key in UTC - :paramtype not_before: ~datetime.datetime or None - :keyword expires_on: Expiry date of the key in UTC - :paramtype expires_on: ~datetime.datetime or None - :keyword exportable: Whether the private key can be exported. - :paramtype exportable: bool or None - :keyword release_policy: The policy rules under which the key can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None - - :returns: The created key - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START create_rsa_key] - :end-before: [END create_rsa_key] - :language: python - :caption: Create RSA key - :dedent: 8 - """ - return await self.create_key( - name, - key_type="RSA-HSM" if hardware_protected else "RSA", - size=size, - public_exponent=public_exponent, - key_operations=key_operations, - enabled=enabled, - tags=tags, - not_before=not_before, - expires_on=expires_on, - exportable=exportable, - release_policy=release_policy, - **kwargs, - ) - - @distributed_trace_async - async def create_ec_key( - self, - name: str, - *, - curve: Optional[Union[str, KeyCurveName]] = None, - key_operations: Optional[List[Union[str, KeyOperation]]] = None, - hardware_protected: Optional[bool] = False, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - exportable: Optional[bool] = None, - release_policy: Optional[KeyReleasePolicy] = None, - **kwargs: Any, - ) -> KeyVaultKey: - """Create a new elliptic curve key or, if ``name`` is already in use, create a new version of the key. - - Requires the keys/create permission. - - :param str name: The name for the new key. - - :keyword curve: Elliptic curve name. Defaults to the NIST P-256 elliptic curve. - :paramtype curve: ~azure.keyvault.keys.KeyCurveName or str or None - :keyword key_operations: Allowed key operations - :paramtype key_operations: List[~azure.keyvault.keys.KeyOperation or str] or None - :keyword hardware_protected: Whether the key should be created in a hardware security module. - Defaults to ``False``. - :paramtype hardware_protected: bool or None - :keyword enabled: Whether the key is enabled for use. - :paramtype enabled: bool or None - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword not_before: Not before date of the key in UTC - :paramtype not_before: ~datetime.datetime or None - :keyword expires_on: Expiry date of the key in UTC - :paramtype expires_on: ~datetime.datetime or None - :keyword exportable: Whether the private key can be exported. - :paramtype exportable: bool or None - :keyword release_policy: The policy rules under which the key can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None - - :returns: The created key - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START create_ec_key] - :end-before: [END create_ec_key] - :language: python - :caption: Create an elliptic curve key - :dedent: 8 - """ - return await self.create_key( - name, - key_type="EC-HSM" if hardware_protected else "EC", - curve=curve, - key_operations=key_operations, - enabled=enabled, - tags=tags, - not_before=not_before, - expires_on=expires_on, - exportable=exportable, - release_policy=release_policy, - **kwargs, - ) - - @distributed_trace_async - async def create_oct_key( - self, - name: str, - *, - size: Optional[int] = None, - key_operations: Optional[List[Union[str, KeyOperation]]] = None, - hardware_protected: Optional[bool] = False, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - exportable: Optional[bool] = None, - release_policy: Optional[KeyReleasePolicy] = None, - **kwargs: Any, - ) -> KeyVaultKey: - """Create a new octet sequence (symmetric) key or, if ``name`` is in use, create a new version of the key. - - Requires the keys/create permission. - - :param str name: The name for the new key. - - :keyword size: Key size in bits, for example 128, 192, or 256. - :paramtype size: int or None - :keyword key_operations: Allowed key operations. - :paramtype key_operations: List[~azure.keyvault.keys.KeyOperation or str] or None - :keyword hardware_protected: Whether the key should be created in a hardware security module. - Defaults to ``False``. - :paramtype hardware_protected: bool or None - :keyword enabled: Whether the key is enabled for use. - :paramtype enabled: bool or None - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword not_before: Not before date of the key in UTC - :paramtype not_before: ~datetime.datetime or None - :keyword expires_on: Expiry date of the key in UTC - :paramtype expires_on: ~datetime.datetime or None - :keyword exportable: Whether the key can be exported. - :paramtype exportable: bool or None - :keyword release_policy: The policy rules under which the key can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None - - :returns: The created key - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START create_oct_key] - :end-before: [END create_oct_key] - :language: python - :caption: Create an octet sequence (symmetric) key - :dedent: 8 - """ - return await self.create_key( - name, - key_type="oct-HSM" if hardware_protected else "oct", - size=size, - key_operations=key_operations, - enabled=enabled, - tags=tags, - not_before=not_before, - expires_on=expires_on, - exportable=exportable, - release_policy=release_policy, - **kwargs, - ) - - @distributed_trace_async - async def delete_key(self, name: str, **kwargs: Any) -> DeletedKey: - """Delete all versions of a key and its cryptographic material. - - Requires keys/delete permission. If the vault has soft-delete enabled, deletion may take several seconds to - complete. - - :param str name: The name of the key to delete - - :returns: The deleted key - :rtype: ~azure.keyvault.keys.DeletedKey - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the key doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START delete_key] - :end-before: [END delete_key] - :language: python - :caption: Delete a key - :dedent: 8 - """ - polling_interval = kwargs.pop("_polling_interval", None) - if polling_interval is None: - polling_interval = 2 - pipeline_response, deleted_key_bundle = await self._client.delete_key( - key_name=name, - cls=lambda pipeline_response, deserialized, _: (pipeline_response, deserialized), - **kwargs, - ) - deleted_key = DeletedKey._from_deleted_key_bundle(deleted_key_bundle) - - polling_method = AsyncDeleteRecoverPollingMethod( - # no recovery ID means soft-delete is disabled, in which case we initialize the poller as finished - finished=deleted_key.recovery_id is None, - pipeline_response=pipeline_response, - command=partial(self.get_deleted_key, name=name, **kwargs), - final_resource=deleted_key, - interval=polling_interval, - ) - await polling_method.run() - - return polling_method.resource() - - @distributed_trace_async - async def get_key(self, name: str, version: Optional[str] = None, **kwargs: Any) -> KeyVaultKey: - """Get a key's attributes and, if it's an asymmetric key, its public material. - - Requires keys/get permission. - - :param str name: The name of the key to get. - :param version: (optional) A specific version of the key to get. If not specified, gets the latest version - of the key. - :type version: str or None - - :returns: The fetched key. - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the key doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START get_key] - :end-before: [END get_key] - :language: python - :caption: Get a key - :dedent: 8 - """ - if version is None: - version = "" - - bundle = await self._client.get_key(name, version, **kwargs) - return KeyVaultKey._from_key_bundle(bundle) - - @distributed_trace_async - async def get_deleted_key(self, name: str, **kwargs: Any) -> DeletedKey: - """Get a deleted key. Possible only in a vault with soft-delete enabled. - - Requires keys/get permission. - - :param str name: The name of the key - - :returns: The deleted key - :rtype: ~azure.keyvault.keys.DeletedKey - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the key doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START get_deleted_key] - :end-before: [END get_deleted_key] - :language: python - :caption: Get a deleted key - :dedent: 8 - """ - bundle = await self._client.get_deleted_key(name, **kwargs) - return DeletedKey._from_deleted_key_bundle(bundle) - - @distributed_trace - def list_deleted_keys(self, **kwargs: Any) -> AsyncItemPaged[DeletedKey]: - """List all deleted keys, including the public part of each. Possible only in a vault with soft-delete enabled. - - Requires keys/list permission. - - :returns: An iterator of deleted keys - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.keys.DeletedKey] - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START list_deleted_keys] - :end-before: [END list_deleted_keys] - :language: python - :caption: List all the deleted keys - :dedent: 8 - """ - return self._client.get_deleted_keys( - maxresults=kwargs.pop("max_page_size", None), - cls=lambda objs: [DeletedKey._from_deleted_key_item(x) for x in objs], - **kwargs, - ) - - @distributed_trace - def list_properties_of_keys(self, **kwargs: Any) -> AsyncItemPaged[KeyProperties]: - """List identifiers and properties of all keys in the vault. - - Requires keys/list permission. - - :returns: An iterator of keys without their cryptographic material or version information - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.keys.KeyProperties] - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START list_keys] - :end-before: [END list_keys] - :language: python - :caption: List all keys - :dedent: 8 - """ - return self._client.get_keys( - maxresults=kwargs.pop("max_page_size", None), - cls=lambda objs: [KeyProperties._from_key_item(x) for x in objs], - **kwargs, - ) - - @distributed_trace - def list_properties_of_key_versions(self, name: str, **kwargs: Any) -> AsyncItemPaged[KeyProperties]: - """List the identifiers and properties of a key's versions. - - Requires keys/list permission. - - :param str name: The name of the key - - :returns: An iterator of keys without their cryptographic material - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.keys.KeyProperties] - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START list_properties_of_key_versions] - :end-before: [END list_properties_of_key_versions] - :language: python - :caption: List all versions of a key - :dedent: 8 - """ - return self._client.get_key_versions( - name, - maxresults=kwargs.pop("max_page_size", None), - cls=lambda objs: [KeyProperties._from_key_item(x) for x in objs], - **kwargs, - ) - - @distributed_trace_async - async def purge_deleted_key(self, name: str, **kwargs: Any) -> None: - """Permanently deletes a deleted key. Only possible in a vault with soft-delete enabled. - - Performs an irreversible deletion of the specified key, without possibility for recovery. The operation is not - available if the :py:attr:`~azure.keyvault.keys.KeyProperties.recovery_level` does not specify 'Purgeable'. - This method is only necessary for purging a key before its - :py:attr:`~azure.keyvault.keys.DeletedKey.scheduled_purge_date`. - - Requires keys/purge permission. - - :param str name: The name of the deleted key to purge - - :returns: None - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. code-block:: python - - # if the vault has soft-delete enabled, purge permanently deletes a deleted key - # (with soft-delete disabled, delete_key is permanent) - await key_client.purge_deleted_key("key-name") - - """ - await self._client.purge_deleted_key(name, **kwargs) - - @distributed_trace_async - async def recover_deleted_key(self, name: str, **kwargs: Any) -> KeyVaultKey: - """Recover a deleted key to its latest version. Possible only in a vault with soft-delete enabled. - - Requires keys/recover permission. If the vault does not have soft-delete enabled, :func:`delete_key` is - permanent, and this method will raise an error. Attempting to recover a non-deleted key will also raise an - error. - - :param str name: The name of the deleted key - - :returns: The recovered key - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.HttpResponseError: - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START recover_deleted_key] - :end-before: [END recover_deleted_key] - :language: python - :caption: Recover a deleted key - :dedent: 8 - """ - polling_interval = kwargs.pop("_polling_interval", None) - if polling_interval is None: - polling_interval = 2 - pipeline_response, recovered_key_bundle = await self._client.recover_deleted_key( - key_name=name, - cls=lambda pipeline_response, deserialized, _: (pipeline_response, deserialized), - **kwargs, - ) - recovered_key = KeyVaultKey._from_key_bundle(recovered_key_bundle) - - command = partial(self.get_key, name=name, **kwargs) - polling_method = AsyncDeleteRecoverPollingMethod( - pipeline_response=pipeline_response, - command=command, - final_resource=recovered_key, - finished=False, - interval=polling_interval - ) - await polling_method.run() - - return polling_method.resource() - - @distributed_trace_async - async def update_key_properties( - self, - name: str, - version: Optional[str] = None, - *, - key_operations: Optional[List[Union[str, KeyOperation]]] = None, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - release_policy: Optional[KeyReleasePolicy] = None, - **kwargs: Any, - ) -> KeyVaultKey: - """Change a key's properties (not its cryptographic material). - - Requires keys/update permission. - - :param str name: The name of key to update - :param version: (optional) The version of the key to update. If unspecified, the latest version is updated. - :type version: str or None - - :keyword key_operations: Allowed key operations - :paramtype key_operations: List[~azure.keyvault.keys.KeyOperation or str] or None - :keyword enabled: Whether the key is enabled for use. - :paramtype enabled: bool or None - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword not_before: Not before date of the key in UTC - :paramtype not_before: ~datetime.datetime or None - :keyword expires_on: Expiry date of the key in UTC - :paramtype expires_on: ~datetime.datetime or None - :keyword release_policy: The policy rules under which the key can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None - - :returns: The updated key - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the key doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START update_key] - :end-before: [END update_key] - :language: python - :caption: Update a key's attributes - :dedent: 8 - """ - attributes = self._get_attributes(enabled=enabled, not_before=not_before, expires_on=expires_on) - - policy = release_policy - if policy is not None: - policy = self._models.KeyReleasePolicy( - content_type=policy.content_type, encoded_policy=policy.encoded_policy, immutable=policy.immutable - ) - parameters = self._models.KeyUpdateParameters( - key_ops=key_operations, - key_attributes=attributes, - tags=tags, - release_policy=policy, - ) - - bundle = await self._client.update_key( - name, - key_version=version or "", - parameters=parameters, - **kwargs, - ) - return KeyVaultKey._from_key_bundle(bundle) - - @distributed_trace_async - async def backup_key(self, name: str, **kwargs: Any) -> bytes: - """Back up a key in a protected form useable only by Azure Key Vault. - - Requires key/backup permission. This is intended to allow copying a key from one vault to another. Both vaults - must be owned by the same Azure subscription. Also, backup / restore cannot be performed across geopolitical - boundaries. For example, a backup from a vault in a USA region cannot be restored to a vault in an EU region. - - :param str name: The name of the key to back up - - :returns: The key backup result, in a protected bytes format that can only be used by Azure Key Vault. - :rtype: bytes - - :raises ~azure.core.exceptions.ResourceNotFoundError or ~azure.core.exceptions.HttpResponseError: - the former if the key doesn't exist; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START backup_key] - :end-before: [END backup_key] - :language: python - :caption: Get a key backup - :dedent: 8 - """ - backup_result = await self._client.backup_key(name, **kwargs) - return backup_result.value - - @distributed_trace_async - async def restore_key_backup(self, backup: bytes, **kwargs: Any) -> KeyVaultKey: - """Restore a key backup to the vault. - - Requires keys/restore permission. This imports all versions of the key, with its name, attributes, and access - control policies. If the key's name is already in use, restoring it will fail. Also, the target vault must be - owned by the same Microsoft Azure subscription as the source vault. - - :param bytes backup: A key backup as returned by :func:`backup_key` - - :returns: The restored key - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.ResourceExistsError or ~azure.core.exceptions.HttpResponseError: - the former if the backed up key's name is already in use; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_samples_keys_async.py - :start-after: [START restore_key_backup] - :end-before: [END restore_key_backup] - :language: python - :caption: Restore a key backup - :dedent: 8 - """ - bundle = await self._client.restore_key( - parameters=self._models.KeyRestoreParameters(key_bundle_backup=backup), - **kwargs, - ) - return KeyVaultKey._from_key_bundle(bundle) - - @distributed_trace_async - async def import_key( - self, - name: str, - key: JsonWebKey, - *, - hardware_protected: Optional[bool] = None, - enabled: Optional[bool] = None, - tags: Optional[Dict[str, str]] = None, - not_before: Optional[datetime] = None, - expires_on: Optional[datetime] = None, - exportable: Optional[bool] = None, - release_policy: Optional[KeyReleasePolicy] = None, - **kwargs: Any, - ) -> KeyVaultKey: - """Import a key created externally. + def __init__(self, vault_base_url: str, credential: "AsyncTokenCredential", **kwargs: Any) -> None: + _endpoint = "{vaultBaseUrl}" + self._config = KeyVaultClientConfiguration(vault_base_url=vault_base_url, credential=credential, **kwargs) + + _policies = kwargs.pop("policies", None) + if _policies is None: + _policies = [ + policies.RequestIdPolicy(**kwargs), + self._config.headers_policy, + self._config.user_agent_policy, + self._config.proxy_policy, + policies.ContentDecodePolicy(**kwargs), + self._config.redirect_policy, + self._config.retry_policy, + self._config.authentication_policy, + self._config.custom_hook_policy, + self._config.logging_policy, + policies.DistributedTracingPolicy(**kwargs), + policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None, + self._config.http_logging_policy, + ] + self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, policies=_policies, **kwargs) - Requires keys/import permission. If ``name`` is already in use, the key will be imported as a new version. + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False - :param str name: Name for the imported key - :param key: The JSON web key to import - :type key: ~azure.keyvault.keys.JsonWebKey + def send_request( + self, request: HttpRequest, *, stream: bool = False, **kwargs: Any + ) -> Awaitable[AsyncHttpResponse]: + """Runs the network request through the client's chained policies. - :keyword hardware_protected: Whether the key should be backed by a hardware security module - :paramtype hardware_protected: bool or None - :keyword enabled: Whether the key is enabled for use. - :paramtype enabled: bool or None - :keyword tags: Application specific metadata in the form of key-value pairs. - :paramtype tags: dict[str, str] or None - :keyword not_before: Not before date of the key in UTC - :paramtype not_before: ~datetime.datetime or None - :keyword expires_on: Expiry date of the key in UTC - :paramtype expires_on: ~datetime.datetime or None - :keyword exportable: Whether the private key can be exported. - :paramtype exportable: bool or None - :keyword release_policy: The policy rules under which the key can be exported. - :paramtype release_policy: ~azure.keyvault.keys.KeyReleasePolicy or None + >>> from azure.core.rest import HttpRequest + >>> request = HttpRequest("GET", "https://www.example.org/") + + >>> response = await client.send_request(request) + - :returns: The imported key - :rtype: ~azure.keyvault.keys.KeyVaultKey + For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request - :raises ~azure.core.exceptions.HttpResponseError: + :param request: The network request you want to make. Required. + :type request: ~azure.core.rest.HttpRequest + :keyword bool stream: Whether the response payload will be streamed. Defaults to False. + :return: The response of your network call. Does not do error handling on your response. + :rtype: ~azure.core.rest.AsyncHttpResponse """ - attributes = self._get_attributes( - enabled=enabled, not_before=not_before, expires_on=expires_on, exportable=exportable - ) - - policy = release_policy - if policy is not None: - policy = self._models.KeyReleasePolicy( - content_type=policy.content_type, encoded_policy=policy.encoded_policy, immutable=policy.immutable - ) - parameters = self._models.KeyImportParameters( - key=key._to_generated_model(), - key_attributes=attributes, - hsm=hardware_protected, - tags=tags, - release_policy=policy, - ) - - bundle = await self._client.import_key( - name, parameters=parameters, **kwargs - ) - return KeyVaultKey._from_key_bundle(bundle) - - @distributed_trace_async - async def release_key( - self, - name: str, - target_attestation_token: str, - *, - version: Optional[str] = None, - algorithm: Optional[Union[str, KeyExportEncryptionAlgorithm]] = None, - nonce: Optional[str] = None, - **kwargs: Any, - ) -> ReleaseKeyResult: - """Releases a key. - - The release key operation is applicable to all key types. The target key must be marked - exportable. This operation requires the keys/release permission. - - :param str name: The name of the key to get. - :param str target_attestation_token: The attestation assertion for the target of the key release. - - :keyword version: A specific version of the key to release. If unspecified, the latest version is released. - :paramtype version: str or None - :keyword algorithm: The encryption algorithm to use to protect the released key material. - :paramtype algorithm: str or ~azure.keyvault.keys.KeyExportEncryptionAlgorithm or None - :keyword nonce: A client-provided nonce for freshness. - :paramtype nonce: str or None - - :return: The result of the key release. - :rtype: ~azure.keyvault.keys.ReleaseKeyResult - :raises ~azure.core.exceptions.HttpResponseError: - """ - result = await self._client.release( - key_name=name, - key_version=version or "", - parameters=self._models.KeyReleaseParameters( - target_attestation_token=target_attestation_token, - nonce=nonce, - enc=algorithm, + request_copy = deepcopy(request) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True ), - **kwargs, - ) - return ReleaseKeyResult(result.value) - - @distributed_trace_async - async def get_random_bytes(self, count: int, **kwargs: Any) -> bytes: - """Get the requested number of random bytes from a managed HSM. - - :param int count: The requested number of random bytes. - - :return: The random bytes. - :rtype: bytes - - :raises ValueError or ~azure.core.exceptions.HttpResponseError: - the former if less than one random byte is requested; the latter for other errors - - Example: - .. literalinclude:: ../tests/test_keys_async.py - :start-after: [START get_random_bytes] - :end-before: [END get_random_bytes] - :language: python - :caption: Get random bytes - :dedent: 12 - """ - if count < 1: - raise ValueError("At least one random byte must be requested") - parameters = self._models.GetRandomBytesRequest(count=count) - result = await self._client.get_random_bytes(parameters=parameters, **kwargs) - return result.value - - @distributed_trace_async - async def get_key_rotation_policy(self, key_name: str, **kwargs: Any) -> KeyRotationPolicy: - """Get the rotation policy of a Key Vault key. - - :param str key_name: The name of the key. - - :return: The key rotation policy. - :rtype: ~azure.keyvault.keys.KeyRotationPolicy + } - :raises ~azure.core.exceptions.HttpResponseError: - """ - policy = await self._client.get_key_rotation_policy(key_name=key_name, **kwargs) - return KeyRotationPolicy._from_generated(policy) - - @distributed_trace_async - async def rotate_key(self, name: str, **kwargs: Any) -> KeyVaultKey: - """Rotate the key based on the key policy by generating a new version of the key. - - This operation requires the keys/rotate permission. - - :param str name: The name of the key to rotate. - - :return: The new version of the rotated key. - :rtype: ~azure.keyvault.keys.KeyVaultKey - - :raises ~azure.core.exceptions.HttpResponseError: - """ - bundle = await self._client.rotate_key(key_name=name, **kwargs) - return KeyVaultKey._from_key_bundle(bundle) - - @distributed_trace_async - async def update_key_rotation_policy( # pylint: disable=unused-argument - self, - key_name: str, - policy: KeyRotationPolicy, - *, - lifetime_actions: Optional[List[KeyRotationLifetimeAction]] = None, - expires_in: Optional[str] = None, - **kwargs: Any, - ) -> KeyRotationPolicy: - """Updates the rotation policy of a Key Vault key. - - This operation requires the keys/update permission. - - :param str key_name: The name of the key in the given vault. - :param policy: The new rotation policy for the key. - :type policy: ~azure.keyvault.keys.KeyRotationPolicy - - :keyword lifetime_actions: Actions that will be performed by Key Vault over the lifetime of a key. This will - override the lifetime actions of the provided ``policy``. - :paramtype lifetime_actions: List[~azure.keyvault.keys.KeyRotationLifetimeAction] - :keyword str expires_in: The expiry time of the policy that will be applied on new key versions, defined as an - ISO 8601 duration. For example: 90 days is "P90D", 3 months is "P3M", and 48 hours is "PT48H". See - `Wikipedia `_ for more information on ISO 8601 durations. - This will override the expiry time of the provided ``policy``. + request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) + return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore - :return: The updated rotation policy. - :rtype: ~azure.keyvault.keys.KeyRotationPolicy + async def close(self) -> None: + await self._client.close() - :raises ~azure.core.exceptions.HttpResponseError: - """ - actions = lifetime_actions or policy.lifetime_actions - if actions: - actions = [ - self._models.LifetimeActions( - action=self._models.LifetimeActionsType(type=action.action), - trigger=self._models.LifetimeActionsTrigger( - time_after_create=action.time_after_create, time_before_expiry=action.time_before_expiry - ), - ) - for action in actions - ] - - attributes = self._models.KeyRotationPolicyAttributes(expiry_time=expires_in or policy.expires_in) - new_policy = self._models.KeyRotationPolicy(lifetime_actions=actions or [], attributes=attributes) - result = await self._client.update_key_rotation_policy(key_name=key_name, key_rotation_policy=new_policy) - return KeyRotationPolicy._from_generated(result) - - @distributed_trace_async - async def get_key_attestation(self, name: str, version: Optional[str] = None, **kwargs: Any) -> KeyVaultKey: - """Get a key and its attestation blob. - - This method is applicable to any key stored in Azure Key Vault Managed HSM. This operation requires the keys/get - permission. - - :param str name: The name of the key. - :param version: (optional) A specific version of the key to get. If not specified, gets the latest version - of the key. - :type version: str or None - - :return: The key attestation. - :rtype: ~azure.keyvault.keys.KeyAttestation - - :raises ~azure.core.exceptions.HttpResponseError: - """ - bundle = await self._client.get_key_attestation(key_name=name, key_version=version or "", **kwargs) - return KeyVaultKey._from_key_bundle(bundle) - - async def __aenter__(self) -> "KeyClient": + async def __aenter__(self) -> Self: await self._client.__aenter__() return self + + async def __aexit__(self, *exc_details: Any) -> None: + await self._client.__aexit__(*exc_details) diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_configuration.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_configuration.py similarity index 100% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_configuration.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_configuration.py diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_operations/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_operations/__init__.py similarity index 100% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_operations/__init__.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_operations/__init__.py diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_operations/_operations.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_operations/_operations.py similarity index 94% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_operations/_operations.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_operations/_operations.py index 4cd9329fad0e..2f3a8134431f 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_operations/_operations.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_operations/_operations.py @@ -1,4 +1,4 @@ -# pylint: disable=too-many-lines +# pylint: disable=line-too-long,useless-suppression,too-many-lines # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -6,9 +6,9 @@ # Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- +from collections.abc import MutableMapping from io import IOBase import json -import sys from typing import Any, AsyncIterable, Callable, Dict, IO, List, Optional, TypeVar, Union, overload import urllib.parse @@ -61,11 +61,7 @@ from ..._validation import api_version_validation from .._vendor import KeyVaultClientMixinABC -if sys.version_info >= (3, 9): - from collections.abc import MutableMapping -else: - from typing import MutableMapping # type: ignore -JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object +JSON = MutableMapping[str, Any] T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] @@ -93,12 +89,12 @@ async def create_key( Required. :type key_name: str :param parameters: The parameters to create a key. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyCreateParameters + :type parameters: ~azure.keyvault.keys.models.KeyCreateParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -123,7 +119,7 @@ async def create_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -148,7 +144,7 @@ async def create_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -169,9 +165,9 @@ async def create_key( :type key_name: str :param parameters: The parameters to create a key. Is one of the following types: KeyCreateParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyCreateParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyCreateParameters or JSON or IO[bytes] :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -249,7 +245,7 @@ async def rotate_key(self, key_name: str, **kwargs: Any) -> _models.KeyBundle: specified key. Required. :type key_name: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -326,12 +322,12 @@ async def import_key( identifiable or sensitive information. Required. :type key_name: str :param parameters: The parameters to import a key. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyImportParameters + :type parameters: ~azure.keyvault.keys.models.KeyImportParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -356,7 +352,7 @@ async def import_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -381,7 +377,7 @@ async def import_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -402,9 +398,9 @@ async def import_key( :type key_name: str :param parameters: The parameters to import a key. Is one of the following types: KeyImportParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyImportParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyImportParameters or JSON or IO[bytes] :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -482,7 +478,7 @@ async def delete_key(self, key_name: str, **kwargs: Any) -> _models.DeletedKeyBu :param key_name: The name of the key to delete. Required. :type key_name: str :return: DeletedKeyBundle. The DeletedKeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.DeletedKeyBundle + :rtype: ~azure.keyvault.keys.models.DeletedKeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -560,12 +556,12 @@ async def update_key( :param key_version: The version of the key to update. Required. :type key_version: str :param parameters: The parameters of the key to update. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyUpdateParameters + :type parameters: ~azure.keyvault.keys.models.KeyUpdateParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -596,7 +592,7 @@ async def update_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -627,7 +623,7 @@ async def update_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -652,9 +648,9 @@ async def update_key( :type key_version: str :param parameters: The parameters of the key to update. Is one of the following types: KeyUpdateParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyUpdateParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyUpdateParameters or JSON or IO[bytes] :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -735,7 +731,7 @@ async def get_key(self, key_name: str, key_version: str, **kwargs: Any) -> _mode Required. :type key_version: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -807,7 +803,7 @@ def get_key_versions( service will return up to 25 results. Default value is None. :paramtype maxresults: int :return: An iterator like instance of KeyItem - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.keys._generated.models.KeyItem] + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.keys.models.KeyItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} @@ -864,7 +860,7 @@ def prepare_request(next_link=None): async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize(List[_models.KeyItem], deserialized["value"]) + list_of_elem = _deserialize(List[_models.KeyItem], deserialized.get("value", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore return deserialized.get("nextLink") or None, AsyncList(list_of_elem) @@ -900,7 +896,7 @@ def get_keys(self, *, maxresults: Optional[int] = None, **kwargs: Any) -> AsyncI service will return up to 25 results. Default value is None. :paramtype maxresults: int :return: An iterator like instance of KeyItem - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.keys._generated.models.KeyItem] + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.keys.models.KeyItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} @@ -956,7 +952,7 @@ def prepare_request(next_link=None): async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize(List[_models.KeyItem], deserialized["value"]) + list_of_elem = _deserialize(List[_models.KeyItem], deserialized.get("value", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore return deserialized.get("nextLink") or None, AsyncList(list_of_elem) @@ -998,7 +994,7 @@ async def backup_key(self, key_name: str, **kwargs: Any) -> _models.BackupKeyRes :param key_name: The name of the key. Required. :type key_name: str :return: BackupKeyResult. The BackupKeyResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.BackupKeyResult + :rtype: ~azure.keyvault.keys.models.BackupKeyResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1072,12 +1068,12 @@ async def restore_key( in the target Key Vault. This operation requires the keys/restore permission. :param parameters: The parameters to restore the key. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyRestoreParameters + :type parameters: ~azure.keyvault.keys.models.KeyRestoreParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1104,7 +1100,7 @@ async def restore_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1131,7 +1127,7 @@ async def restore_key( Default value is "application/json". :paramtype content_type: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1154,9 +1150,9 @@ async def restore_key( :param parameters: The parameters to restore the key. Is one of the following types: KeyRestoreParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyRestoreParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyRestoreParameters or JSON or IO[bytes] :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1247,12 +1243,12 @@ async def encrypt( :param key_version: The version of the key. Required. :type key_version: str :param parameters: The parameters for the encryption operation. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1287,7 +1283,7 @@ async def encrypt( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1322,7 +1318,7 @@ async def encrypt( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1351,9 +1347,9 @@ async def encrypt( :type key_version: str :param parameters: The parameters for the encryption operation. Is one of the following types: KeyOperationsParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters or JSON or IO[bytes] :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1439,7 +1435,8 @@ async def decrypt( stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/decrypt permission. Microsoft recommends not to use CBC algorithms for decryption without first ensuring the integrity of the ciphertext using an HMAC, for example. See - https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode for more + `https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode + `_ for more information. :param key_name: The name of the key. Required. @@ -1447,12 +1444,12 @@ async def decrypt( :param key_version: The version of the key. Required. :type key_version: str :param parameters: The parameters for the decryption operation. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1475,7 +1472,8 @@ async def decrypt( stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/decrypt permission. Microsoft recommends not to use CBC algorithms for decryption without first ensuring the integrity of the ciphertext using an HMAC, for example. See - https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode for more + `https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode + `_ for more information. :param key_name: The name of the key. Required. @@ -1488,7 +1486,7 @@ async def decrypt( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1511,7 +1509,8 @@ async def decrypt( stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/decrypt permission. Microsoft recommends not to use CBC algorithms for decryption without first ensuring the integrity of the ciphertext using an HMAC, for example. See - https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode for more + `https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode + `_ for more information. :param key_name: The name of the key. Required. @@ -1524,7 +1523,7 @@ async def decrypt( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1545,7 +1544,8 @@ async def decrypt( stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/decrypt permission. Microsoft recommends not to use CBC algorithms for decryption without first ensuring the integrity of the ciphertext using an HMAC, for example. See - https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode for more + `https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode + `_ for more information. :param key_name: The name of the key. Required. @@ -1554,9 +1554,9 @@ async def decrypt( :type key_version: str :param parameters: The parameters for the decryption operation. Is one of the following types: KeyOperationsParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters or JSON or IO[bytes] :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1644,12 +1644,12 @@ async def sign( :param key_version: The version of the key. Required. :type key_version: str :param parameters: The parameters for the signing operation. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeySignParameters + :type parameters: ~azure.keyvault.keys.models.KeySignParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1679,7 +1679,7 @@ async def sign( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1709,7 +1709,7 @@ async def sign( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1733,9 +1733,9 @@ async def sign( :type key_version: str :param parameters: The parameters for the signing operation. Is one of the following types: KeySignParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeySignParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeySignParameters or JSON or IO[bytes] :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -1825,12 +1825,12 @@ async def verify( :param key_version: The version of the key. Required. :type key_version: str :param parameters: The parameters for verify operations. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyVerifyParameters + :type parameters: ~azure.keyvault.keys.models.KeyVerifyParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyVerifyResult. The KeyVerifyResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyVerifyResult + :rtype: ~azure.keyvault.keys.models.KeyVerifyResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1862,7 +1862,7 @@ async def verify( Default value is "application/json". :paramtype content_type: str :return: KeyVerifyResult. The KeyVerifyResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyVerifyResult + :rtype: ~azure.keyvault.keys.models.KeyVerifyResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1894,7 +1894,7 @@ async def verify( Default value is "application/json". :paramtype content_type: str :return: KeyVerifyResult. The KeyVerifyResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyVerifyResult + :rtype: ~azure.keyvault.keys.models.KeyVerifyResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -1920,9 +1920,9 @@ async def verify( :type key_version: str :param parameters: The parameters for verify operations. Is one of the following types: KeyVerifyParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyVerifyParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyVerifyParameters or JSON or IO[bytes] :return: KeyVerifyResult. The KeyVerifyResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyVerifyResult + :rtype: ~azure.keyvault.keys.models.KeyVerifyResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -2013,12 +2013,12 @@ async def wrap_key( :param key_version: The version of the key. Required. :type key_version: str :param parameters: The parameters for wrap operation. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2051,7 +2051,7 @@ async def wrap_key( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2084,7 +2084,7 @@ async def wrap_key( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2111,9 +2111,9 @@ async def wrap_key( :type key_version: str :param parameters: The parameters for wrap operation. Is one of the following types: KeyOperationsParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters or JSON or IO[bytes] :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -2202,12 +2202,12 @@ async def unwrap_key( :param key_version: The version of the key. Required. :type key_version: str :param parameters: The parameters for the key operation. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2238,7 +2238,7 @@ async def unwrap_key( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2269,7 +2269,7 @@ async def unwrap_key( Default value is "application/json". :paramtype content_type: str :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2294,9 +2294,9 @@ async def unwrap_key( :type key_version: str :param parameters: The parameters for the key operation. Is one of the following types: KeyOperationsParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyOperationsParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyOperationsParameters or JSON or IO[bytes] :return: KeyOperationResult. The KeyOperationResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyOperationResult + :rtype: ~azure.keyvault.keys.models.KeyOperationResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -2384,12 +2384,12 @@ async def release( Required. :type key_version: str :param parameters: The parameters for the key release operation. Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyReleaseParameters + :type parameters: ~azure.keyvault.keys.models.KeyReleaseParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyReleaseResult. The KeyReleaseResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyReleaseResult + :rtype: ~azure.keyvault.keys.models.KeyReleaseResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2419,7 +2419,7 @@ async def release( Default value is "application/json". :paramtype content_type: str :return: KeyReleaseResult. The KeyReleaseResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyReleaseResult + :rtype: ~azure.keyvault.keys.models.KeyReleaseResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2449,7 +2449,7 @@ async def release( Default value is "application/json". :paramtype content_type: str :return: KeyReleaseResult. The KeyReleaseResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyReleaseResult + :rtype: ~azure.keyvault.keys.models.KeyReleaseResult :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2473,9 +2473,9 @@ async def release( :type key_version: str :param parameters: The parameters for the key release operation. Is one of the following types: KeyReleaseParameters, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.KeyReleaseParameters or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.KeyReleaseParameters or JSON or IO[bytes] :return: KeyReleaseResult. The KeyReleaseResult is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyReleaseResult + :rtype: ~azure.keyvault.keys.models.KeyReleaseResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -2558,7 +2558,7 @@ def get_deleted_keys( service will return up to 25 results. Default value is None. :paramtype maxresults: int :return: An iterator like instance of DeletedKeyItem - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.keys._generated.models.DeletedKeyItem] + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.keys.models.DeletedKeyItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} @@ -2614,7 +2614,7 @@ def prepare_request(next_link=None): async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize(List[_models.DeletedKeyItem], deserialized["value"]) + list_of_elem = _deserialize(List[_models.DeletedKeyItem], deserialized.get("value", [])) if cls: list_of_elem = cls(list_of_elem) # type: ignore return deserialized.get("nextLink") or None, AsyncList(list_of_elem) @@ -2648,7 +2648,7 @@ async def get_deleted_key(self, key_name: str, **kwargs: Any) -> _models.Deleted :param key_name: The name of the key. Required. :type key_name: str :return: DeletedKeyBundle. The DeletedKeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.DeletedKeyBundle + :rtype: ~azure.keyvault.keys.models.DeletedKeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -2771,7 +2771,7 @@ async def recover_deleted_key(self, key_name: str, **kwargs: Any) -> _models.Key :param key_name: The name of the deleted key. Required. :type key_name: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -2837,7 +2837,7 @@ async def get_key_rotation_policy(self, key_name: str, **kwargs: Any) -> _models :param key_name: The name of the key in a given key vault. Required. :type key_name: str :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy + :rtype: ~azure.keyvault.keys.models.KeyRotationPolicy :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -2910,12 +2910,12 @@ async def update_key_rotation_policy( :param key_name: The name of the key in the given vault. Required. :type key_name: str :param key_rotation_policy: The policy for the key. Required. - :type key_rotation_policy: ~azure.keyvault.keys._generated.models.KeyRotationPolicy + :type key_rotation_policy: ~azure.keyvault.keys.models.KeyRotationPolicy :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy + :rtype: ~azure.keyvault.keys.models.KeyRotationPolicy :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2936,7 +2936,7 @@ async def update_key_rotation_policy( Default value is "application/json". :paramtype content_type: str :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy + :rtype: ~azure.keyvault.keys.models.KeyRotationPolicy :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2957,7 +2957,7 @@ async def update_key_rotation_policy( Default value is "application/json". :paramtype content_type: str :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy + :rtype: ~azure.keyvault.keys.models.KeyRotationPolicy :raises ~azure.core.exceptions.HttpResponseError: """ @@ -2974,9 +2974,9 @@ async def update_key_rotation_policy( :type key_name: str :param key_rotation_policy: The policy for the key. Is one of the following types: KeyRotationPolicy, JSON, IO[bytes] Required. - :type key_rotation_policy: ~azure.keyvault.keys._generated.models.KeyRotationPolicy or JSON or IO[bytes] + :type key_rotation_policy: ~azure.keyvault.keys.models.KeyRotationPolicy or JSON or IO[bytes] :return: KeyRotationPolicy. The KeyRotationPolicy is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyRotationPolicy + :rtype: ~azure.keyvault.keys.models.KeyRotationPolicy :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3051,12 +3051,12 @@ async def get_random_bytes( Get the requested number of bytes containing random values from a managed HSM. :param parameters: The request object to get random bytes. Required. - :type parameters: ~azure.keyvault.keys._generated.models.GetRandomBytesRequest + :type parameters: ~azure.keyvault.keys.models.GetRandomBytesRequest :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str :return: RandomBytes. The RandomBytes is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.RandomBytes + :rtype: ~azure.keyvault.keys.models.RandomBytes :raises ~azure.core.exceptions.HttpResponseError: """ @@ -3074,7 +3074,7 @@ async def get_random_bytes( Default value is "application/json". :paramtype content_type: str :return: RandomBytes. The RandomBytes is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.RandomBytes + :rtype: ~azure.keyvault.keys.models.RandomBytes :raises ~azure.core.exceptions.HttpResponseError: """ @@ -3092,7 +3092,7 @@ async def get_random_bytes( Default value is "application/json". :paramtype content_type: str :return: RandomBytes. The RandomBytes is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.RandomBytes + :rtype: ~azure.keyvault.keys.models.RandomBytes :raises ~azure.core.exceptions.HttpResponseError: """ @@ -3106,9 +3106,9 @@ async def get_random_bytes( :param parameters: The request object to get random bytes. Is one of the following types: GetRandomBytesRequest, JSON, IO[bytes] Required. - :type parameters: ~azure.keyvault.keys._generated.models.GetRandomBytesRequest or JSON or IO[bytes] + :type parameters: ~azure.keyvault.keys.models.GetRandomBytesRequest or JSON or IO[bytes] :return: RandomBytes. The RandomBytes is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.RandomBytes + :rtype: ~azure.keyvault.keys.models.RandomBytes :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -3191,7 +3191,7 @@ async def get_key_attestation(self, key_name: str, key_version: str, **kwargs: A key attestation blob is returned. Required. :type key_version: str :return: KeyBundle. The KeyBundle is compatible with MutableMapping - :rtype: ~azure.keyvault.keys._generated.models.KeyBundle + :rtype: ~azure.keyvault.keys.models.KeyBundle :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_patch.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_operations/_patch.py similarity index 61% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_patch.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_operations/_patch.py index f7dd32510333..8bcb627aa475 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/_patch.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_operations/_patch.py @@ -1,7 +1,8 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------- """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_patch.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_patch.py similarity index 61% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_patch.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_patch.py index f7dd32510333..8bcb627aa475 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_patch.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_patch.py @@ -1,7 +1,8 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------- """Customize generated code here. Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_vendor.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_vendor.py similarity index 100% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/aio/_vendor.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/aio/_vendor.py diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/__init__.py deleted file mode 100644 index 9e931898fc8e..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from ._models import ( - DecryptResult, - EncryptResult, - KeyVaultRSAPrivateKey, - KeyVaultRSAPublicKey, - SignResult, - WrapResult, - VerifyResult, - UnwrapResult, -) -from ._enums import EncryptionAlgorithm, KeyWrapAlgorithm, SignatureAlgorithm -from ._client import CryptographyClient - - -__all__ = [ - "CryptographyClient", - "DecryptResult", - "EncryptionAlgorithm", - "EncryptResult", - "KeyVaultRSAPrivateKey", - "KeyVaultRSAPublicKey", - "KeyWrapAlgorithm", - "SignatureAlgorithm", - "SignResult", - "WrapResult", - "VerifyResult", - "UnwrapResult", -] diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_client.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_client.py deleted file mode 100644 index d3a27fee66df..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_client.py +++ /dev/null @@ -1,581 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from datetime import datetime -import logging -from typing import Any, cast, Dict, Optional, Union - -from azure.core.credentials import TokenCredential -from azure.core.exceptions import HttpResponseError -from azure.core.tracing.decorator import distributed_trace - -from . import ( - DecryptResult, - EncryptionAlgorithm, - EncryptResult, - KeyWrapAlgorithm, - SignatureAlgorithm, - SignResult, - VerifyResult, - UnwrapResult, - WrapResult, -) -from ._key_validity import raise_if_time_invalid -from ._models import KeyVaultRSAPrivateKey, KeyVaultRSAPublicKey -from ._providers import get_local_cryptography_provider, NoLocalCryptography -from .. import KeyOperation -from .._models import JsonWebKey, KeyVaultKey -from .._shared import KeyVaultClientBase, KeyVaultResourceId, parse_key_vault_id - -_LOGGER = logging.getLogger(__name__) - - -def _validate_arguments( - operation: KeyOperation, - algorithm: EncryptionAlgorithm, - *, - iv: Optional[bytes] = None, - tag: Optional[bytes] = None, - aad: Optional[bytes] = None, - ) -> None: - """Validates the arguments passed to perform an operation with a provided algorithm. - - :param KeyOperation operation: the type of operation being requested - :param EncryptionAlgorithm algorithm: the encryption algorithm to use for the operation - - :keyword iv: initialization vector - :paramtype iv: bytes or None - :keyword tag: authentication tag returned from an encryption - :paramtype tag: bytes or None - :keyword aad: data that is authenticated but not encrypted - :paramtype aad: bytes or None - - :raises ValueError: if parameters that are incompatible with the specified algorithm are provided. - """ - if operation == KeyOperation.encrypt: - if iv and "CBC" not in algorithm: - raise ValueError( - f"iv should only be provided with AES-CBC algorithms; {algorithm} does not accept an iv" - ) - if iv is None and "CBC" in algorithm: - raise ValueError("iv is a required parameter for encryption with AES-CBC algorithms.") - if aad and not ("CBC" in algorithm or "GCM" in algorithm): - raise ValueError( - f"additional_authenticated_data should only be provided with AES algorithms; {algorithm} does not " - "accept additional authenticated data" - ) - - if operation == KeyOperation.decrypt: - if iv and not ("CBC" in algorithm or "GCM" in algorithm): - raise ValueError( - f"iv should only be provided with AES algorithms; {algorithm} does not accept an iv" - ) - if iv is None and ("CBC" in algorithm or "GCM" in algorithm): - raise ValueError("iv is a required parameter for decryption with AES algorithms.") - if tag and "GCM" not in algorithm: - raise ValueError( - f"authentication_tag should only be provided with AES-GCM algorithms; {algorithm} does not accept a tag" - ) - if tag is None and "GCM" in algorithm: - raise ValueError("authentication_tag is a required parameter for AES-GCM decryption.") - if aad and not ("CBC" in algorithm or "GCM" in algorithm): - raise ValueError( - f"additional_authenticated_data should only be provided with AES algorithms; {algorithm} does not " - "accept additional authenticated data" - ) - - -class CryptographyClient(KeyVaultClientBase): - """Performs cryptographic operations using Azure Key Vault keys. - - This client will perform operations locally when it's intialized with the necessary key material or is able to get - that material from Key Vault. When the required key material is unavailable, cryptographic operations are performed - by the Key Vault service. - - :param key: Either a azure.keyvault.keys.KeyVaultKey instance as returned by - :func:`~azure.keyvault.keys.KeyClient.get_key`, or a string. - If a string, the value must be the identifier of an Azure Key Vault key. Including a version is recommended. - :type key: str or azure.keyvault.keys.KeyVaultKey - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity` - :type credential: ~azure.core.credentials.TokenCredential - - :keyword api_version: Version of the service API to use. Defaults to the most recent. - :paramtype api_version: ~azure.keyvault.keys.ApiVersion or str - :keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key - Vault or Managed HSM domain. Defaults to True. - - .. literalinclude:: ../tests/test_examples_crypto.py - :start-after: [START create_client] - :end-before: [END create_client] - :caption: Create a CryptographyClient - :language: python - :dedent: 8 - """ - - # pylint:disable=protected-access - - def __init__(self, key: Union[KeyVaultKey, str], credential: TokenCredential, **kwargs: Any) -> None: - self._jwk = kwargs.pop("_jwk", False) - self._not_before: Optional[datetime] = None - self._expires_on: Optional[datetime] = None - self._key_id: Optional[KeyVaultResourceId] = None - - if isinstance(key, KeyVaultKey): - self._key: Union[JsonWebKey, KeyVaultKey, str, None] = key.key - self._key_id = parse_key_vault_id(key.id) - if key.properties._attributes: - self._not_before = key.properties.not_before - self._expires_on = key.properties.expires_on - elif isinstance(key, str): - self._key = None - self._key_id = parse_key_vault_id(key) - if self._key_id.version is None: - self._key_id.version = "" # to avoid an error and get the latest version when getting the key - self._keys_get_forbidden = False - elif self._jwk: - self._key = key - else: - raise ValueError("'key' must be a KeyVaultKey instance or a key ID string") - - if self._jwk: - try: - self._local_provider = get_local_cryptography_provider(cast(JsonWebKey, self._key)) - self._initialized = True - except Exception as ex: - raise ValueError("The provided jwk is not valid for local cryptography") from ex - else: - self._local_provider = NoLocalCryptography() - self._initialized = False - - self._vault_url = None if (self._jwk or self._key_id is None) else self._key_id.vault_url # type: ignore - super(CryptographyClient, self).__init__( - vault_url=self._vault_url or "vault_url", credential=credential, **kwargs - ) - - @property - def key_id(self) -> Optional[str]: - """The full identifier of the client's key. - - This property may be None when a client is constructed with :func:`from_jwk`. - - :returns: The full identifier of the client's key. - :rtype: str or None - """ - if not self._jwk: - return self._key_id.source_id if self._key_id else None - return cast(JsonWebKey, self._key).kid # type: ignore[attr-defined] - - @property - def vault_url(self) -> Optional[str]: # type: ignore - """The base vault URL of the client's key. - - This property may be None when a client is constructed with :func:`from_jwk`. - - :returns: The base vault URL of the client's key. - :rtype: str or None - """ - return self._vault_url - - @classmethod - def from_jwk(cls, jwk: Union[JsonWebKey, Dict[str, Any]]) -> "CryptographyClient": - """Creates a client that can only perform cryptographic operations locally. - - :param jwk: the key's cryptographic material, as a JsonWebKey or dictionary. - :type jwk: JsonWebKey or Dict[str, Any] - - :returns: A client that can only perform local cryptographic operations. - :rtype: CryptographyClient - """ - if not isinstance(jwk, JsonWebKey): - jwk = JsonWebKey(**jwk) - return cls(jwk, object(), _jwk=True) # type: ignore - - @distributed_trace - def _initialize(self, **kwargs: Any) -> None: - if self._initialized: - return - - # try to get the key material, if we don't have it and aren't forbidden to do so - if not (self._key or self._keys_get_forbidden): - try: - key_bundle = self._client.get_key( - self._key_id.name if self._key_id else None, - self._key_id.version if self._key_id else None, - **kwargs - ) - key = KeyVaultKey._from_key_bundle(key_bundle) - self._key = key.key - self._key_id = parse_key_vault_id(key.id) # update the key ID in case we didn't have the version before - except HttpResponseError as ex: - # if we got a 403, we don't have keys/get permission and won't try to get the key again - # (other errors may be transient) - self._keys_get_forbidden = ex.status_code == 403 - - # if we have the key material, create a local crypto provider with it - if self._key: - self._local_provider = get_local_cryptography_provider(cast(JsonWebKey, self._key)) - self._initialized = True - else: - # try to get the key again next time unless we know we're forbidden to do so - self._initialized = self._keys_get_forbidden - - @distributed_trace - def create_rsa_private_key(self) -> KeyVaultRSAPrivateKey: # pylint:disable=client-method-missing-kwargs - """Create an `RSAPrivateKey` implementation backed by this `CryptographyClient`, as a `KeyVaultRSAPrivateKey`. - - The `CryptographyClient` will attempt to download the key, if it hasn't been already, as part of this operation. - - :returns: A `KeyVaultRSAPrivateKey`, which implements `cryptography`'s `RSAPrivateKey` interface. - :rtype: ~azure.keyvault.keys.crypto.KeyVaultRSAPrivateKey - """ - self._initialize() - return KeyVaultRSAPrivateKey(client=self, key_material=cast(JsonWebKey, self._key)) - - @distributed_trace - def create_rsa_public_key(self) -> KeyVaultRSAPublicKey: # pylint:disable=client-method-missing-kwargs - """Create an `RSAPublicKey` implementation backed by this `CryptographyClient`, as a `KeyVaultRSAPublicKey`. - - The `CryptographyClient` will attempt to download the key, if it hasn't been already, as part of this operation. - - :returns: A `KeyVaultRSAPublicKey`, which implements `cryptography`'s `RSAPublicKey` interface. - :rtype: ~azure.keyvault.keys.crypto.KeyVaultRSAPublicKey - """ - self._initialize() - return KeyVaultRSAPublicKey(client=self, key_material=cast(JsonWebKey, self._key)) - - @distributed_trace - def encrypt( - self, - algorithm: EncryptionAlgorithm, - plaintext: bytes, - *, - iv: Optional[bytes] = None, - additional_authenticated_data: Optional[bytes] = None, - **kwargs: Any, - ) -> EncryptResult: - """Encrypt bytes using the client's key. - - Requires the keys/encrypt permission. This method encrypts only a single block of data, whose size depends on - the key and encryption algorithm. - - :param algorithm: Encryption algorithm to use - :type algorithm: ~azure.keyvault.keys.crypto.EncryptionAlgorithm - :param bytes plaintext: Bytes to encrypt - - :keyword iv: Initialization vector. Required for only AES-CBC(PAD) encryption. If you pass your own IV, - make sure you use a cryptographically random, non-repeating IV. If omitted, an attempt will be made to - generate an IV via `os.urandom `_ for local - cryptography; for remote cryptography, Key Vault will generate an IV. - :paramtype iv: bytes or None - :keyword additional_authenticated_data: Optional data that is authenticated but not encrypted. For use - with AES-GCM encryption. - :paramtype additional_authenticated_data: bytes or None - - :returns: The result of the encryption operation. - :rtype: ~azure.keyvault.keys.crypto.EncryptResult - - :raises ValueError: if parameters that are incompatible with the specified algorithm are provided, or if - generating an IV fails on the current platform. - - .. literalinclude:: ../tests/test_examples_crypto.py - :start-after: [START encrypt] - :end-before: [END encrypt] - :caption: Encrypt bytes - :language: python - :dedent: 8 - """ - _validate_arguments( - operation=KeyOperation.encrypt, algorithm=algorithm, iv=iv, aad=additional_authenticated_data - ) - self._initialize(**kwargs) - - if self._local_provider.supports(KeyOperation.encrypt, algorithm): - raise_if_time_invalid(self._not_before, self._expires_on) - try: - return self._local_provider.encrypt(algorithm, plaintext, iv=iv) - except Exception as ex: # pylint:disable=broad-except - _LOGGER.warning("Local encrypt operation failed: %s", ex, exc_info=_LOGGER.isEnabledFor(logging.DEBUG)) - if self._jwk: - raise - elif self._jwk: - raise NotImplementedError( - f'This key does not support the "{KeyOperation.encrypt}" operation with algorithm "{algorithm}"' - ) - - operation_result = self._client.encrypt( - key_name=self._key_id.name if self._key_id else None, - key_version=self._key_id.version if self._key_id else None, - parameters=self._models.KeyOperationsParameters( - algorithm=algorithm, value=plaintext, iv=iv, aad=additional_authenticated_data - ), - **kwargs - ) - - result_iv = operation_result.iv if hasattr(operation_result, "iv") else None - result_tag = operation_result.authentication_tag if hasattr(operation_result, "authentication_tag") else None - result_aad = ( - operation_result.additional_authenticated_data - if hasattr(operation_result, "additional_authenticated_data") - else None - ) - - return EncryptResult( - key_id=self.key_id, - algorithm=algorithm, - ciphertext=operation_result.result, - iv=result_iv, - authentication_tag=result_tag, - additional_authenticated_data=result_aad, - ) - - @distributed_trace - def decrypt( - self, - algorithm: EncryptionAlgorithm, - ciphertext: bytes, - *, - iv: Optional[bytes] = None, - authentication_tag: Optional[bytes] = None, - additional_authenticated_data: Optional[bytes] = None, - **kwargs: Any, - ) -> DecryptResult: - """Decrypt a single block of encrypted data using the client's key. - - Requires the keys/decrypt permission. This method decrypts only a single block of data, whose size depends on - the key and encryption algorithm. - - :param algorithm: Encryption algorithm to use - :type algorithm: ~azure.keyvault.keys.crypto.EncryptionAlgorithm - :param bytes ciphertext: Encrypted bytes to decrypt. Microsoft recommends you not use CBC without first ensuring - the integrity of the ciphertext using, for example, an HMAC. See - https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode for more information. - - :keyword iv: The initialization vector used during encryption. Required for AES decryption. - :paramtype iv: bytes or None - :keyword authentication_tag: The authentication tag generated during encryption. Required for only AES-GCM - decryption. - :paramtype authentication_tag: bytes or None - :keyword additional_authenticated_data: Optional data that is authenticated but not encrypted. For use - with AES-GCM decryption. - :paramtype additional_authenticated_data: bytes or None - - :returns: The result of the decryption operation. - :rtype: ~azure.keyvault.keys.crypto.DecryptResult - - :raises ValueError: If parameters that are incompatible with the specified algorithm are provided. - - .. literalinclude:: ../tests/test_examples_crypto.py - :start-after: [START decrypt] - :end-before: [END decrypt] - :caption: Decrypt bytes - :language: python - :dedent: 8 - """ - _validate_arguments( - operation=KeyOperation.decrypt, - algorithm=algorithm, - iv=iv, - tag=authentication_tag, - aad=additional_authenticated_data, - ) - self._initialize(**kwargs) - - if self._local_provider.supports(KeyOperation.decrypt, algorithm): - try: - return self._local_provider.decrypt(algorithm, ciphertext, iv=iv) - except Exception as ex: # pylint:disable=broad-except - _LOGGER.warning("Local decrypt operation failed: %s", ex, exc_info=_LOGGER.isEnabledFor(logging.DEBUG)) - if self._jwk: - raise - elif self._jwk: - raise NotImplementedError( - f'This key does not support the "{KeyOperation.decrypt}" operation with algorithm "{algorithm}"' - ) - - operation_result = self._client.decrypt( - key_name=self._key_id.name if self._key_id else None, - key_version=self._key_id.version if self._key_id else None, - parameters=self._models.KeyOperationsParameters( - algorithm=algorithm, value=ciphertext, iv=iv, tag=authentication_tag, aad=additional_authenticated_data - ), - **kwargs - ) - - return DecryptResult(key_id=self.key_id, algorithm=algorithm, plaintext=operation_result.result) - - @distributed_trace - def wrap_key(self, algorithm: KeyWrapAlgorithm, key: bytes, **kwargs: Any) -> WrapResult: - """Wrap a key with the client's key. - - Requires the keys/wrapKey permission. - - :param algorithm: wrapping algorithm to use - :type algorithm: ~azure.keyvault.keys.crypto.KeyWrapAlgorithm - :param bytes key: key to wrap - - :returns: The result of the wrapping operation. - :rtype: ~azure.keyvault.keys.crypto.WrapResult - - .. literalinclude:: ../tests/test_examples_crypto.py - :start-after: [START wrap_key] - :end-before: [END wrap_key] - :caption: Wrap a key - :language: python - :dedent: 8 - """ - self._initialize(**kwargs) - if self._local_provider.supports(KeyOperation.wrap_key, algorithm): - raise_if_time_invalid(self._not_before, self._expires_on) - try: - return self._local_provider.wrap_key(algorithm, key) - except Exception as ex: # pylint:disable=broad-except - _LOGGER.warning("Local wrap operation failed: %s", ex, exc_info=_LOGGER.isEnabledFor(logging.DEBUG)) - if self._jwk: - raise - elif self._jwk: - raise NotImplementedError( - f'This key does not support the "{KeyOperation.wrap_key}" operation with algorithm "{algorithm}"' - ) - - operation_result = self._client.wrap_key( - key_name=self._key_id.name if self._key_id else None, - key_version=self._key_id.version if self._key_id else None, - parameters=self._models.KeyOperationsParameters(algorithm=algorithm, value=key), - **kwargs - ) - - return WrapResult(key_id=self.key_id, algorithm=algorithm, encrypted_key=operation_result.result) - - @distributed_trace - def unwrap_key(self, algorithm: KeyWrapAlgorithm, encrypted_key: bytes, **kwargs: Any) -> UnwrapResult: - """Unwrap a key previously wrapped with the client's key. - - Requires the keys/unwrapKey permission. - - :param algorithm: wrapping algorithm to use - :type algorithm: ~azure.keyvault.keys.crypto.KeyWrapAlgorithm - :param bytes encrypted_key: the wrapped key - - :returns: The result of the unwrapping operation. - :rtype: ~azure.keyvault.keys.crypto.UnwrapResult - - .. literalinclude:: ../tests/test_examples_crypto.py - :start-after: [START unwrap_key] - :end-before: [END unwrap_key] - :caption: Unwrap a key - :language: python - :dedent: 8 - """ - self._initialize(**kwargs) - if self._local_provider.supports(KeyOperation.unwrap_key, algorithm): - try: - return self._local_provider.unwrap_key(algorithm, encrypted_key) - except Exception as ex: # pylint:disable=broad-except - _LOGGER.warning("Local unwrap operation failed: %s", ex, exc_info=_LOGGER.isEnabledFor(logging.DEBUG)) - if self._jwk: - raise - elif self._jwk: - raise NotImplementedError( - f'This key does not support the "{KeyOperation.unwrap_key}" operation with algorithm "{algorithm}"' - ) - - operation_result = self._client.unwrap_key( - key_name=self._key_id.name if self._key_id else None, - key_version=self._key_id.version if self._key_id else None, - parameters=self._models.KeyOperationsParameters(algorithm=algorithm, value=encrypted_key), - **kwargs - ) - return UnwrapResult(key_id=self.key_id, algorithm=algorithm, key=operation_result.result) - - @distributed_trace - def sign(self, algorithm: SignatureAlgorithm, digest: bytes, **kwargs: Any) -> SignResult: - """Create a signature from a digest using the client's key. - - Requires the keys/sign permission. - - :param algorithm: signing algorithm - :type algorithm: ~azure.keyvault.keys.crypto.SignatureAlgorithm - :param bytes digest: hashed bytes to sign - - :returns: The result of the signing operation. - :rtype: ~azure.keyvault.keys.crypto.SignResult - - .. literalinclude:: ../tests/test_examples_crypto.py - :start-after: [START sign] - :end-before: [END sign] - :caption: Sign bytes - :language: python - :dedent: 8 - """ - self._initialize(**kwargs) - if self._local_provider.supports(KeyOperation.sign, algorithm): - raise_if_time_invalid(self._not_before, self._expires_on) - try: - return self._local_provider.sign(algorithm, digest) - except Exception as ex: # pylint:disable=broad-except - _LOGGER.warning("Local sign operation failed: %s", ex, exc_info=_LOGGER.isEnabledFor(logging.DEBUG)) - if self._jwk: - raise - elif self._jwk: - raise NotImplementedError( - f'This key does not support the "{KeyOperation.sign}" operation with algorithm "{algorithm}"' - ) - - operation_result = self._client.sign( - key_name=self._key_id.name if self._key_id else None, - key_version=self._key_id.version if self._key_id else None, - parameters=self._models.KeySignParameters(algorithm=algorithm, value=digest), - **kwargs - ) - - return SignResult(key_id=self.key_id, algorithm=algorithm, signature=operation_result.result) - - @distributed_trace - def verify(self, algorithm: SignatureAlgorithm, digest: bytes, signature: bytes, **kwargs: Any) -> VerifyResult: - """Verify a signature using the client's key. - - Requires the keys/verify permission. - - :param algorithm: verification algorithm - :type algorithm: ~azure.keyvault.keys.crypto.SignatureAlgorithm - :param bytes digest: Pre-hashed digest corresponding to **signature**. The hash algorithm used must be - compatible with ``algorithm``. - :param bytes signature: signature to verify - - :returns: The result of the verifying operation. - :rtype: ~azure.keyvault.keys.crypto.VerifyResult - - .. literalinclude:: ../tests/test_examples_crypto.py - :start-after: [START verify] - :end-before: [END verify] - :caption: Verify a signature - :language: python - :dedent: 8 - """ - self._initialize(**kwargs) - if self._local_provider.supports(KeyOperation.verify, algorithm): - try: - return self._local_provider.verify(algorithm, digest, signature) - except Exception as ex: # pylint:disable=broad-except - _LOGGER.warning("Local verify operation failed: %s", ex, exc_info=_LOGGER.isEnabledFor(logging.DEBUG)) - if self._jwk: - raise - elif self._jwk: - raise NotImplementedError( - f'This key does not support the "{KeyOperation.verify}" operation with algorithm "{algorithm}"' - ) - - operation_result = self._client.verify( - key_name=self._key_id.name if self._key_id else None, - key_version=self._key_id.version if self._key_id else None, - parameters=self._models.KeyVerifyParameters(algorithm=algorithm, digest=digest, signature=signature), - **kwargs - ) - - return VerifyResult(key_id=self.key_id, algorithm=algorithm, is_valid=operation_result.value) - - def __enter__(self) -> "CryptographyClient": - self._client.__enter__() - return self diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_enums.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_enums.py deleted file mode 100644 index 82c22ad25b1c..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_enums.py +++ /dev/null @@ -1,66 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from enum import Enum -from azure.core import CaseInsensitiveEnumMeta - -# pylint: disable=enum-must-be-uppercase -class KeyWrapAlgorithm(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Key wrapping algorithms""" - - aes_128 = "A128KW" - aes_192 = "A192KW" - aes_256 = "A256KW" - # [Not recommended] Microsoft recommends using RSA_OAEP_256 or stronger algorithms for enhanced security. - # Microsoft does *not* recommend RSA_OAEP, which is included solely for backwards compatibility. - # RSA_OAEP utilizes SHA1, which has known collision problems. - rsa_oaep = "RSA-OAEP" - rsa_oaep_256 = "RSA-OAEP-256" - # [Not recommended] Microsoft recommends using RSA_OAEP_256 or stronger algorithms for enhanced security. - # Microsoft does *not* recommend RSA_1_5, which is included solely for backwards compatibility. - # Cryptographic standards no longer consider RSA with the PKCS#1 v1.5 padding scheme secure for encryption. - rsa1_5 = "RSA1_5" - - -class EncryptionAlgorithm(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Encryption algorithms""" - - # [Not recommended] Microsoft recommends using RSA_OAEP_256 or stronger algorithms for enhanced security. - # Microsoft does *not* recommend RSA_OAEP, which is included solely for backwards compatibility. - # RSA_OAEP utilizes SHA1, which has known collision problems. - rsa_oaep = "RSA-OAEP" - rsa_oaep_256 = "RSA-OAEP-256" - # [Not recommended] Microsoft recommends using RSA_OAEP_256 or stronger algorithms for enhanced security. - # Microsoft does *not* recommend RSA_1_5, which is included solely for backwards compatibility. - # Cryptographic standards no longer consider RSA with the PKCS#1 v1.5 padding scheme secure for encryption. - rsa1_5 = "RSA1_5" - a128_gcm = "A128GCM" - a192_gcm = "A192GCM" - a256_gcm = "A256GCM" - a128_cbc = "A128CBC" - a192_cbc = "A192CBC" - a256_cbc = "A256CBC" - a128_cbcpad = "A128CBCPAD" - a192_cbcpad = "A192CBCPAD" - a256_cbcpad = "A256CBCPAD" - ckm_aes_key_wrap = "CKM_AES_KEY_WRAP" - ckm_aes_key_wrap_pad = "CKM_AES_KEY_WRAP_PAD" - - -class SignatureAlgorithm(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Signature algorithms, described in https://tools.ietf.org/html/rfc7518""" - - ps256 = "PS256" #: RSASSA-PSS using SHA-256 and MGF1 with SHA-256 - ps384 = "PS384" #: RSASSA-PSS using SHA-384 and MGF1 with SHA-384 - ps512 = "PS512" #: RSASSA-PSS using SHA-512 and MGF1 with SHA-512 - rs256 = "RS256" #: RSASSA-PKCS1-v1_5 using SHA-256 - rs384 = "RS384" #: RSASSA-PKCS1-v1_5 using SHA-384 - rs512 = "RS512" #: RSASSA-PKCS1-v1_5 using SHA-512 - es256 = "ES256" #: ECDSA using P-256 and SHA-256 - es384 = "ES384" #: ECDSA using P-384 and SHA-384 - es512 = "ES512" #: ECDSA using P-521 and SHA-512 - es256_k = "ES256K" #: ECDSA using P-256K and SHA-256 - hs256 = "HS256" #: HMAC using SHA-256 - hs384 = "HS384" #: HMAC using SHA-384 - hs512 = "HS512" #: HMAC using SHA-512 diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/__init__.py deleted file mode 100644 index 880d4cdeb7ae..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from .algorithm import ( - Algorithm, - AsymmetricEncryptionAlgorithm, - SymmetricEncryptionAlgorithm, - AuthenticatedSymmetricEncryptionAlgorithm, - SignatureAlgorithm, -) -from .ec_key import EllipticCurveKey -from .key import Key -from .rsa_key import RsaKey -from .symmetric_key import SymmetricKey -from .transform import CryptoTransform, BlockCryptoTransform, AuthenticatedCryptoTransform, SignatureTransform - -__all__ = [ - "Key", - "EllipticCurveKey", - "RsaKey", - "Algorithm", - "AsymmetricEncryptionAlgorithm", - "SymmetricEncryptionAlgorithm", - "AuthenticatedCryptoTransform", - "SignatureAlgorithm", - "CryptoTransform", - "BlockCryptoTransform", - "AuthenticatedSymmetricEncryptionAlgorithm", - "SignatureTransform", - "SymmetricKey", -] diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/_internal.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/_internal.py deleted file mode 100644 index f19eb2cb0ee0..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/_internal.py +++ /dev/null @@ -1,131 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import codecs -from base64 import b64encode, b64decode - -from cryptography.hazmat.primitives.asymmetric import utils - - -def _bytes_to_int(b): - if not b or not isinstance(b, bytes): - raise ValueError("b must be non-empty byte string") - - return int(codecs.encode(b, "hex"), 16) - - -def _int_to_bytes(i): - h = hex(i) - if len(h) > 1 and h[0:2] == "0x": - h = h[2:] - - # need to strip L in python 2.x - h = h.strip("L") - - if len(h) % 2: - h = "0" + h - return codecs.decode(h, "hex") - - -def _bstr_to_b64url(bstr): - """Serialize bytes into base-64 string. - - :param bytes bstr: Object to be serialized. - - :returns: The base-64 URL encoded string. - :rtype: str - """ - encoded = b64encode(bstr).decode() - return encoded.strip("=").replace("+", "-").replace("/", "_") - - -def _str_to_b64url(s): - """Serialize str into base-64 string. - - :param str s: Object to be serialized. - - :returns: The base-64 URL encoded string. - :rtype: str - """ - return _bstr_to_b64url(s.encode(encoding="utf8")) - - -def _b64_to_bstr(b64str): - """Deserialize base-64 encoded string into string. - - :param str b64str: response string to be deserialized. - - :returns: The decoded bytes. - :rtype: bytes - - :raises: TypeError if string format invalid. - """ - padding = "=" * (3 - (len(b64str) + 3) % 4) - b64str = b64str + padding - encoded = b64str.replace("-", "+").replace("_", "/") - return b64decode(encoded) - - -def _b64_to_str(b64str): - """Deserialize base-64 encoded string into string. - - :param str b64str: response string to be deserialized. - - :returns: The decoded string. - :rtype: str - - :raises: TypeError if string format invalid. - """ - return _b64_to_bstr(b64str).decode("utf8") - - -def _int_to_fixed_length_bigendian_bytes(i, length): - """Convert an integer to a bigendian byte string left-padded with zeroes to a fixed length. - - :param int i: The integer to convert. - :param int length: The length of the desired byte string. - - :returns: A bigendian byte string of length `length`, representing integer `i`. - :rtype: bytes - """ - - b = _int_to_bytes(i) - - if len(b) > length: - raise ValueError(f"{i} is too large to be represented by {length} bytes") - - if len(b) < length: - b = (b"\0" * (length - len(b))) + b - - return b - - -def ecdsa_to_asn1_der(signature): - """ASN.1 DER encode an ECDSA signature. - - :param bytes signature: ECDSA signature encoded according to RFC 7518, i.e. the concatenated big-endian bytes of - two integers (as produced by Key Vault) - - :returns: signature, ASN.1 DER encoded (as expected by ``cryptography``) - :rtype: bytes - """ - mid = len(signature) // 2 - r = _bytes_to_int(signature[:mid]) - s = _bytes_to_int(signature[mid:]) - return utils.encode_dss_signature(r, s) - - -def asn1_der_to_ecdsa(signature, algorithm): - """Convert an ASN.1 DER encoded signature to ECDSA encoding. - - :param bytes signature: an ASN.1 DER encoded ECDSA signature (as produced by ``cryptography``) - :param _Ecdsa algorithm: signing algorithm which produced ``signature`` - - :returns: signature encoded according to RFC 7518 (as expected by Key Vault) - :rtype: bytes - """ - r, s = utils.decode_dss_signature(signature) - r_bytes = _int_to_fixed_length_bigendian_bytes(r, algorithm.coordinate_length) - s_bytes = _int_to_fixed_length_bigendian_bytes(s, algorithm.coordinate_length) - return r_bytes + s_bytes diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithm.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithm.py deleted file mode 100644 index 1b2c2446ed6b..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithm.py +++ /dev/null @@ -1,78 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from abc import abstractmethod -from typing import Optional, TYPE_CHECKING, Union - -if TYPE_CHECKING: - from cryptography.hazmat.primitives import hashes - - -_alg_registry = {} - - -class Algorithm(object): - _name: Optional[str] = None - - @classmethod - def name(cls): - return cls._name - - @classmethod - def register(cls): - _alg_registry[cls._name] = cls - - @staticmethod - def resolve(name): - if name not in _alg_registry: - return None - return _alg_registry[name]() - - -class AsymmetricEncryptionAlgorithm(Algorithm): - @abstractmethod - def create_encryptor(self, key): - raise NotImplementedError() - - @abstractmethod - def create_decryptor(self, key): - raise NotImplementedError() - - -class SymmetricEncryptionAlgorithm(Algorithm): - @abstractmethod - def create_encryptor(self, key, iv): - raise NotImplementedError() - - @abstractmethod - def create_decryptor(self, key, iv): - raise NotImplementedError() - - -class AuthenticatedSymmetricEncryptionAlgorithm(Algorithm): # pylint:disable=bad-option-value,name-too-long - @abstractmethod - def create_encryptor(self, key, iv, auth_data, auth_tag): - raise NotImplementedError() - - @abstractmethod - def create_decryptor(self, key, iv, auth_data, auth_tag): - raise NotImplementedError() - - -class SignatureAlgorithm(Algorithm): - _default_hash_algorithm: "Union[hashes.SHA256, hashes.SHA384, hashes.SHA512, None]" = None - - @property - def default_hash_algorithm(self): - return self._default_hash_algorithm - - @abstractmethod - def create_signature_transform(self, key): - raise NotImplementedError() - - -class HashAlgorithm(Algorithm): - @abstractmethod - def create_digest(self): - raise NotImplementedError() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/__init__.py deleted file mode 100644 index 76c0368acdcf..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/__init__.py +++ /dev/null @@ -1,38 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from .aes_cbc import Aes128Cbc, Aes192Cbc, Aes256Cbc, Aes128CbcPad, Aes192CbcPad, Aes256CbcPad -from .aes_cbc_hmac import Aes128CbcHmacSha256, Aes192CbcHmacSha384, Aes256CbcHmacSha512 -from .aes_kw import AesKw128, AesKw192, AesKw256 -from .ecdsa import Ecdsa256, Es256, Es384, Es512 -from .rsa_encryption import Rsa1_5, RsaOaep, RsaOaep256 -from .rsa_signing import Ps256, Ps384, Ps512, Rs256, Rs384, Rs512 - -__all__ = [ - "Aes128Cbc", - "Aes192Cbc", - "Aes256Cbc", - "Aes128CbcPad", - "Aes192CbcPad", - "Aes256CbcPad", - "Aes128CbcHmacSha256", - "Aes192CbcHmacSha384", - "Aes256CbcHmacSha512", - "AesKw128", - "AesKw192", - "AesKw256", - "Ecdsa256", - "Es256", - "Es384", - "Es512", - "Ps256", - "Ps384", - "Ps512", - "Rsa1_5", - "Rs256", - "Rs384", - "Rs512", - "RsaOaep", - "RsaOaep256", -] diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/aes_cbc.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/aes_cbc.py deleted file mode 100644 index 618ffaf370ae..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/aes_cbc.py +++ /dev/null @@ -1,145 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives import padding - -from ..algorithm import SymmetricEncryptionAlgorithm -from ..transform import BlockCryptoTransform - - -# pylint: disable=W0223 - -_CBC_BLOCK_SIZE = 128 - - -class _AesCbcCryptoTransform(BlockCryptoTransform): - def __init__(self, key, iv): - super(_AesCbcCryptoTransform, self).__init__(key) - self._cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) - - def transform(self, data): - return self.update(data) + self.finalize() - - def block_size(self): - return _CBC_BLOCK_SIZE - - -class _AesCbcDecryptor(_AesCbcCryptoTransform): - def __init__(self, key, iv, padding_mode): - super(_AesCbcDecryptor, self).__init__(key, iv) - self._ctx = self._cipher.decryptor() - self._padder = padding_mode.unpadder() - - def update(self, data): - decrypted = self._ctx.update(data) + self._ctx.finalize() - return self._padder.update(decrypted) - - def finalize(self): - return self._padder.finalize() - - -class _AesCbcEncryptor(_AesCbcCryptoTransform): - def __init__(self, key, iv, padding_mode): - super(_AesCbcEncryptor, self).__init__(key, iv) - self._ctx = self._cipher.encryptor() - self._padder = padding_mode.padder() - - def update(self, data): - padded = self._padder.update(data) + self._padder.finalize() - return self._ctx.update(padded) - - def finalize(self): - return self._ctx.finalize() - - -class _AesCbc(SymmetricEncryptionAlgorithm): - _key_size = 256 - _block_size = _CBC_BLOCK_SIZE - - def block_size(self): - return self._block_size - - def block_size_in_bytes(self): - return self._block_size >> 3 - - def key_size(self): - return self._key_size - - def key_size_in_bytes(self): - return self._key_size >> 3 - - def create_encryptor(self, key, iv): - key, iv = self._validate_input(key, iv) - - return _AesCbcEncryptor(key, iv, padding.PKCS7(self._block_size)) - - def create_decryptor(self, key, iv): - key, iv = self._validate_input(key, iv) - - return _AesCbcDecryptor(key, iv, padding.PKCS7(self._block_size)) - - def _validate_input(self, key, iv): - if not key: - raise ValueError("A key is required for AES-CBC and AES-CBCPAD encryption and decryption") - if len(key) < self.key_size_in_bytes(): - raise ValueError(f"key must be at least {self.key_size} bits") - - if not iv: - raise ValueError("A 16-byte iv is required for AES-CBC and AES-CBCPAD encryption and decryption") - if not len(iv) == self.block_size_in_bytes(): - raise ValueError(f"iv must be {self.block_size} bits") - - return key[: self.key_size_in_bytes()], iv - - -class _AesCbcPad(_AesCbc): - def create_encryptor(self, key, iv): - key, iv = self._validate_input(key, iv) - - return _AesCbcEncryptor(key, iv, padding.PKCS7(self._block_size)) - - def create_decryptor(self, key, iv): - key, iv = self._validate_input(key, iv) - - return _AesCbcDecryptor(key, iv, padding.PKCS7(self._block_size)) - - -class Aes128Cbc(_AesCbc): - _name = "A128CBC" - _key_size = 128 - - -class Aes128CbcPad(_AesCbcPad): - _name = "A128CBCPAD" - _key_size = 128 - - -class Aes192Cbc(_AesCbc): - _name = "A192CBC" - _key_size = 192 - - -class Aes192CbcPad(_AesCbcPad): - _name = "A192CBCPAD" - _key_size = 192 - - -class Aes256Cbc(_AesCbc): - _name = "A256CBC" - _key_size = 256 - - -class Aes256CbcPad(_AesCbcPad): - _name = "A256CBCPAD" - _key_size = 256 - - -Aes128Cbc.register() -Aes128CbcPad.register() -Aes192Cbc.register() -Aes192CbcPad.register() -Aes256Cbc.register() -Aes256CbcPad.register() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/aes_cbc_hmac.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/aes_cbc_hmac.py deleted file mode 100644 index 4fad959fade9..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/aes_cbc_hmac.py +++ /dev/null @@ -1,149 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from abc import abstractmethod - -from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives import padding, hashes, hmac - -from ..algorithm import AuthenticatedSymmetricEncryptionAlgorithm -from ..transform import AuthenticatedCryptoTransform -from .._internal import _int_to_fixed_length_bigendian_bytes - - -class _AesCbcHmacCryptoTransform(AuthenticatedCryptoTransform): - def __init__(self, key, iv, auth_data, auth_tag): - super(_AesCbcHmacCryptoTransform, self).__init__() - - self._aes_key = key[: len(key) // 2] - self._hmac_key = key[len(key) // 2 :] - hash_algorithm = {256: hashes.SHA256(), 384: hashes.SHA384(), 512: hashes.SHA512()}[len(key) * 8] - - self._cipher = Cipher(algorithms.AES(self._aes_key), modes.CBC(iv), backend=default_backend()) - self._tag = auth_tag or bytearray() - self._hmac = hmac.HMAC(self._hmac_key, hash_algorithm, backend=default_backend()) - self._auth_data_length = _int_to_fixed_length_bigendian_bytes(len(auth_data) * 8, 8) - - # prime the hash - self._hmac.update(auth_data) - self._hmac.update(iv) - - def tag(self): - return self._tag - - def block_size(self): - # return self._cipher.block_size - raise NotImplementedError() - - @abstractmethod - def update(self, data): - raise NotImplementedError() - - @abstractmethod - def finalize(self): - raise NotImplementedError() - - def transform(self, data): - return self.update(data) + self.finalize() - - -class _AesCbcHmacEncryptor(_AesCbcHmacCryptoTransform): - def __init__(self, key, iv, auth_data, auth_tag): - super(_AesCbcHmacEncryptor, self).__init__(key, iv, auth_data, auth_tag) - self._ctx = self._cipher.encryptor() - self._padder = padding.PKCS7(self.block_size).padder() - self._tag[:] = [] - - def update(self, data): - padded = self._padder.update(data) - cipher_text = self._ctx.update(padded) - self._hmac.update(cipher_text) - return cipher_text - - def finalize(self): - padded = self._padder.finalize() - cipher_text = self._ctx.update(padded) + self._ctx.finalize() - self._hmac.update(cipher_text) - self._hmac.update(self._auth_data_length) - self._tag.extend(self._hmac.finalize()[: len(self._hmac_key)]) - return cipher_text - - def block_size(self): - raise NotImplementedError() - - -class _AesCbcHmacDecryptor(_AesCbcHmacCryptoTransform): - def __init__(self, key, iv, auth_data, auth_tag): - super(_AesCbcHmacDecryptor, self).__init__(key, iv, auth_data, auth_tag) - self._ctx = self._cipher.decryptor() - self._padder = padding.PKCS7(self.block_size).unpadder() - - def update(self, data): - self._hmac.update(data) - padded = self._ctx.update(data) - return self._padder.update(padded) - - def finalize(self): - self._hmac.update(self._auth_data_length) - self._hmac.verify(self.tag) - padded = self._ctx.finalize() - return self._padder.update(padded) + self._padder.finalize() - - # override transform from the base so we can verify the entire hash before we start decrypting - def transform(self, data): - self._hmac.update(data) - self._hmac.update(self._auth_data_length) - self._hmac.verify(self.tag) - padded = self._ctx.update(data) + self._ctx.finalize() - return self._padder.update(padded) + self._padder.finalize() - - def block_size(self): - raise NotImplementedError() - - -class _AesCbcHmac(AuthenticatedSymmetricEncryptionAlgorithm): - _key_size = 256 - - @property - def block_size(self): - return self._key_size // 2 - - @property - def block_size_in_bytes(self): - return self.block_size >> 3 - - @property - def key_size(self): - return self._key_size - - @property - def key_size_in_bytes(self): - return self._key_size >> 3 - - def create_encryptor(self, key, iv, auth_data, auth_tag=None): - return _AesCbcHmacEncryptor(key, iv, auth_data, auth_tag) - - def create_decryptor(self, key, iv, auth_data, auth_tag): - return _AesCbcHmacDecryptor(key, iv, auth_data, auth_tag) - - -class Aes128CbcHmacSha256(_AesCbcHmac): - _key_size = 256 - _name = "A128CBC-HS256" - - -class Aes192CbcHmacSha384(_AesCbcHmac): - _key_size = 384 - _name = "A192CBC-HS384" - - -class Aes256CbcHmacSha512(_AesCbcHmac): - _key_size = 512 - _name = "A256CBC-HS512" - - -Aes128CbcHmacSha256.register() -Aes192CbcHmacSha384.register() -Aes256CbcHmacSha512.register() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/aes_kw.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/aes_kw.py deleted file mode 100644 index 4990de7331bb..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/aes_kw.py +++ /dev/null @@ -1,68 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from cryptography.hazmat.primitives.keywrap import aes_key_wrap, aes_key_unwrap -from cryptography.hazmat.backends import default_backend - -from ..algorithm import AsymmetricEncryptionAlgorithm -from ..transform import CryptoTransform -from ..._enums import KeyWrapAlgorithm - - -class _AesKeyWrapTransform(CryptoTransform): - def transform(self, data): - return aes_key_wrap(self._key, data, default_backend()) - - -class _AesKeyUnwrapTransform(CryptoTransform): - def transform(self, data): - return aes_key_unwrap(self._key, data, default_backend()) - - -class _AesKeyWrap(AsymmetricEncryptionAlgorithm): - _key_size = 256 - - @property - def key_size(self): - return self._key_size - - @property - def key_size_in_bytes(self): - return self._key_size >> 3 - - def create_encryptor(self, key): - key = self._validate_input(key) - return _AesKeyWrapTransform(key) - - def create_decryptor(self, key): - key = self._validate_input(key) - return _AesKeyUnwrapTransform(key) - - def _validate_input(self, key): - if not key: - raise ValueError("key") - if len(key) < self.key_size_in_bytes: - raise ValueError(f"key must be at least {self.key_size} bits") - - return key[: self.key_size_in_bytes] - - -class AesKw128(_AesKeyWrap): - _key_size = 128 - _name = "A128KW" - - -class AesKw192(_AesKeyWrap): - _key_size = 192 - _name = "A192KW" - - -class AesKw256(_AesKeyWrap): - _key_size = 256 - _name = KeyWrapAlgorithm.aes_256 - - -AesKw128.register() -AesKw192.register() -AesKw256.register() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/ecdsa.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/ecdsa.py deleted file mode 100644 index 2c3a6c8bd132..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/ecdsa.py +++ /dev/null @@ -1,60 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.asymmetric import ec -from cryptography.hazmat.primitives.asymmetric import utils - -from ..algorithm import SignatureAlgorithm -from ..transform import SignatureTransform -from ..._enums import SignatureAlgorithm as KeyVaultSignatureAlgorithm - - -class _EcdsaSignatureTransform(SignatureTransform): - def __init__(self, key, hash_algorithm): - super(_EcdsaSignatureTransform, self).__init__() - - self._key = key - self._hash_algorithm = hash_algorithm - - def sign(self, digest): - return self._key.sign(digest, ec.ECDSA(utils.Prehashed(self._hash_algorithm))) - - def verify(self, digest, signature): - return self._key.verify(signature, digest, ec.ECDSA(utils.Prehashed(self._hash_algorithm))) - - -class _Ecdsa(SignatureAlgorithm): - def create_signature_transform(self, key): - return _EcdsaSignatureTransform(key, self.default_hash_algorithm) - - -class Ecdsa256(_Ecdsa): - _name = KeyVaultSignatureAlgorithm.es256_k - _default_hash_algorithm = hashes.SHA256() - coordinate_length = 32 - - -class Es256(_Ecdsa): - _name = KeyVaultSignatureAlgorithm.es256 - _default_hash_algorithm = hashes.SHA256() - coordinate_length = 32 - - -class Es384(_Ecdsa): - _name = KeyVaultSignatureAlgorithm.es384 - _default_hash_algorithm = hashes.SHA384() - coordinate_length = 48 - - -class Es512(_Ecdsa): - _name = KeyVaultSignatureAlgorithm.es512 - _default_hash_algorithm = hashes.SHA512() - coordinate_length = 66 - - -Ecdsa256.register() -Es256.register() -Es384.register() -Es512.register() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/rsa_encryption.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/rsa_encryption.py deleted file mode 100644 index df83c67365d2..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/rsa_encryption.py +++ /dev/null @@ -1,79 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.asymmetric import padding - -from ..algorithm import AsymmetricEncryptionAlgorithm -from ..transform import CryptoTransform -from ..._enums import EncryptionAlgorithm - - -class _Rsa1_5Encryptor(CryptoTransform): - def transform(self, data): - return self._key.encrypt(data, padding.PKCS1v15()) - - -class _Rsa1_5Decryptor(CryptoTransform): - def transform(self, data): - return self._key.decrypt(data, padding.PKCS1v15()) - - -class Rsa1_5(AsymmetricEncryptionAlgorithm): # pylint:disable=client-incorrect-naming-convention - _name = EncryptionAlgorithm.rsa1_5 - - def create_encryptor(self, key): - return _Rsa1_5Encryptor(key) - - def create_decryptor(self, key): - return _Rsa1_5Decryptor(key) - - -class _RsaOaepDecryptor(CryptoTransform): - def __init__(self, key, hash_cls): - self._hash_cls = hash_cls - super(_RsaOaepDecryptor, self).__init__(key) - - def transform(self, data): - oaep_padding = padding.OAEP( - mgf=padding.MGF1(algorithm=self._hash_cls()), algorithm=self._hash_cls(), label=None - ) - return self._key.decrypt(data, oaep_padding) - - -class _RsaOaepEncryptor(CryptoTransform): - def __init__(self, key, hash_cls): - self._hash_cls = hash_cls - super(_RsaOaepEncryptor, self).__init__(key) - - def transform(self, data): - oaep_padding = padding.OAEP( - mgf=padding.MGF1(algorithm=self._hash_cls()), algorithm=self._hash_cls(), label=None - ) - return self._key.encrypt(data, oaep_padding) - - -class RsaOaep(AsymmetricEncryptionAlgorithm): - _name = EncryptionAlgorithm.rsa_oaep - - def create_encryptor(self, key): - return _RsaOaepEncryptor(key, hashes.SHA1) - - def create_decryptor(self, key): - return _RsaOaepDecryptor(key, hashes.SHA1) - - -class RsaOaep256(AsymmetricEncryptionAlgorithm): - _name = EncryptionAlgorithm.rsa_oaep_256 - - def create_encryptor(self, key): - return _RsaOaepEncryptor(key, hashes.SHA256) - - def create_decryptor(self, key): - return _RsaOaepDecryptor(key, hashes.SHA256) - - -Rsa1_5.register() -RsaOaep.register() -RsaOaep256.register() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/rsa_signing.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/rsa_signing.py deleted file mode 100644 index 984befca583a..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/rsa_signing.py +++ /dev/null @@ -1,75 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.asymmetric import padding, utils - -from ..algorithm import SignatureAlgorithm -from ..transform import SignatureTransform -from ..._enums import SignatureAlgorithm as KeyVaultSignatureAlgorithm - - -class RsaSignatureTransform(SignatureTransform): - def __init__(self, key, padding_function, hash_algorithm): - super(RsaSignatureTransform, self).__init__() - self._key = key - self._padding_function = padding_function - self._hash_algorithm = hash_algorithm - - def sign(self, digest): - return self._key.sign(digest, self._padding_function(digest), utils.Prehashed(self._hash_algorithm)) - - def verify(self, digest, signature): - self._key.verify(signature, digest, self._padding_function(digest), utils.Prehashed(self._hash_algorithm)) - - -class RsaSsaPkcs1v15(SignatureAlgorithm): - def create_signature_transform(self, key): - return RsaSignatureTransform(key, lambda _: padding.PKCS1v15(), self._default_hash_algorithm) - - -class RsaSsaPss(SignatureAlgorithm): - def create_signature_transform(self, key): - return RsaSignatureTransform(key, self._get_padding, self._default_hash_algorithm) - - def _get_padding(self, digest): - return padding.PSS(mgf=padding.MGF1(self._default_hash_algorithm), salt_length=len(digest)) - - -class Ps256(RsaSsaPss): - _name = KeyVaultSignatureAlgorithm.ps256 - _default_hash_algorithm = hashes.SHA256() - - -class Ps384(RsaSsaPss): - _name = KeyVaultSignatureAlgorithm.ps384 - _default_hash_algorithm = hashes.SHA384() - - -class Ps512(RsaSsaPss): - _name = KeyVaultSignatureAlgorithm.ps512 - _default_hash_algorithm = hashes.SHA512() - - -class Rs256(RsaSsaPkcs1v15): - _name = KeyVaultSignatureAlgorithm.rs256 - _default_hash_algorithm = hashes.SHA256() - - -class Rs384(RsaSsaPkcs1v15): - _name = KeyVaultSignatureAlgorithm.rs384 - _default_hash_algorithm = hashes.SHA384() - - -class Rs512(RsaSsaPkcs1v15): - _name = KeyVaultSignatureAlgorithm.rs512 - _default_hash_algorithm = hashes.SHA512() - - -Ps256.register() -Ps384.register() -Ps512.register() -Rs256.register() -Rs384.register() -Rs512.register() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/sha_2.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/sha_2.py deleted file mode 100644 index 34e4a0bc3bbc..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/algorithms/sha_2.py +++ /dev/null @@ -1,53 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import Union, Type - -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives import hashes - -from ..algorithm import HashAlgorithm -from ..transform import DigestTransform - - -class _Sha2DigestTransform(DigestTransform): - def __init__(self, algorithm): - super(_Sha2DigestTransform, self).__init__() - self._digest = hashes.Hash(algorithm=algorithm, backend=default_backend()) - - def update(self, data): - return self._digest.update(data) - - def finalize(self, data): - return self._digest.finalize() - - -class _Sha2HashAlgorithm(HashAlgorithm): - - _algorithm_cls: Union[Type[hashes.SHA256], Type[hashes.SHA384], Type[hashes.SHA512], None] = None - - def create_digest(self): - return _Sha2DigestTransform(self._algorithm_cls()) # pylint:disable=not-callable - - -class Sha256(_Sha2HashAlgorithm): - _algorithm_cls = hashes.SHA256 - _name = "SHA256" - - -class Sha384(_Sha2HashAlgorithm): - _algorithm_cls = hashes.SHA384 - _name = "SHA384" - - -class Sha512(_Sha2HashAlgorithm): - _algorithm_cls = hashes.SHA512 - _name = "SHA512" - - -Sha256.register() - -Sha384.register() - -Sha512.register() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/ec_key.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/ec_key.py deleted file mode 100644 index 481a6fd45241..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/ec_key.py +++ /dev/null @@ -1,106 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import uuid - -from cryptography.exceptions import InvalidSignature -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives.asymmetric.ec import ( - EllipticCurvePrivateKey, - EllipticCurvePrivateNumbers, - EllipticCurvePublicNumbers, - SECP256R1, - SECP384R1, - SECP521R1, - SECP256K1, -) - -from ._internal import _bytes_to_int, asn1_der_to_ecdsa, ecdsa_to_asn1_der -from .key import Key -from .algorithms.ecdsa import Es256, Es512, Es384, Ecdsa256 -from ... import KeyCurveName - -_crypto_crv_to_kv_crv = { - "secp256r1": KeyCurveName.p_256, - "secp384r1": KeyCurveName.p_384, - "secp521r1": KeyCurveName.p_521, - "secp256k1": KeyCurveName.p_256_k, -} -_kv_crv_to_crypto_cls = { - KeyCurveName.p_256: SECP256R1, - KeyCurveName.p_256_k: SECP256K1, - KeyCurveName.p_384: SECP384R1, - KeyCurveName.p_521: SECP521R1, - "SECP256K1": SECP256K1, # "SECP256K1" is from Key Vault 2016-10-01 -} -_curve_to_default_algorithm = { - KeyCurveName.p_256: Es256.name(), - KeyCurveName.p_256_k: Ecdsa256.name(), - KeyCurveName.p_384: Es384.name(), - KeyCurveName.p_521: Es512.name(), - "SECP256K1": Ecdsa256.name(), # "SECP256K1" is from Key Vault 2016-10-01 -} - - -class EllipticCurveKey(Key): - _supported_signature_algorithms = frozenset(_curve_to_default_algorithm.values()) - - def __init__(self, x, y, d=None, kid=None, curve=None): - super(EllipticCurveKey, self).__init__() - - self._kid = kid or str(uuid.uuid4()) - self._default_algorithm = _curve_to_default_algorithm[curve] - curve_cls = _kv_crv_to_crypto_cls[curve] - - public_numbers = EllipticCurvePublicNumbers(x, y, curve_cls()) - self._public_key = public_numbers.public_key(default_backend()) - self._private_key = None - if d is not None: - private_numbers = EllipticCurvePrivateNumbers(d, public_numbers) - self._private_key = private_numbers.private_key(default_backend()) - - @classmethod - def from_jwk(cls, jwk): - if jwk.kty not in ("EC", "EC-HSM"): - raise ValueError("The specified key must be of type 'EC' or 'EC-HSM'") - - if not jwk.x or not jwk.y: - raise ValueError("jwk must have values for 'x' and 'y'") - - x = _bytes_to_int(jwk.x) - y = _bytes_to_int(jwk.y) - d = _bytes_to_int(jwk.d) if jwk.d is not None else None - return cls(x, y, d, kid=jwk.kid, curve=jwk.crv) - - def is_private_key(self): - return isinstance(self._private_key, EllipticCurvePrivateKey) - - def decrypt(self, cipher_text, **kwargs): - raise NotImplementedError("Local decryption isn't supported with elliptic curve keys") - - def encrypt(self, plain_text, **kwargs): - raise NotImplementedError("Local encryption isn't supported with elliptic curve keys") - - def wrap_key(self, key, **kwargs): - raise NotImplementedError("Local key wrapping isn't supported with elliptic curve keys") - - def unwrap_key(self, encrypted_key, **kwargs): - raise NotImplementedError("Local key unwrapping isn't supported with elliptic curve keys") - - def sign(self, digest, **kwargs): - algorithm = self._get_algorithm("sign", **kwargs) - signer = algorithm.create_signature_transform(self._private_key) - signature = signer.sign(digest) - ecdsa_signature = asn1_der_to_ecdsa(signature, algorithm) - return ecdsa_signature - - def verify(self, digest, signature, **kwargs): - algorithm = self._get_algorithm("verify", **kwargs) - signer = algorithm.create_signature_transform(self._public_key) - asn1_signature = ecdsa_to_asn1_der(signature) - try: - signer.verify(digest, asn1_signature) - return True - except InvalidSignature: - return False diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/key.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/key.py deleted file mode 100644 index 82298feb1654..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/key.py +++ /dev/null @@ -1,94 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ - -from abc import ABCMeta, abstractmethod -from typing import Any, FrozenSet - -from .algorithm import Algorithm - - -class Key(object, metaclass=ABCMeta): - _supported_encryption_algorithms: FrozenSet[Any] = frozenset([]) - _supported_key_wrap_algorithms: FrozenSet[Any] = frozenset([]) - _supported_signature_algorithms: FrozenSet[Any] = frozenset([]) - - def __init__(self): - self._kid = None - - @property - def default_encryption_algorithm(self): - return None - - @property - def default_key_wrap_algorithm(self): - return None - - @property - def default_signature_algorithm(self): - return None - - @property - def supported_encryption_algorithms(self): - return self._supported_encryption_algorithms - - @property - def supported_key_wrap_algorithms(self): - return self._supported_key_wrap_algorithms - - @property - def supported_signature_algorithms(self): - return self._supported_signature_algorithms - - @property - def kid(self): - return self._kid - - @abstractmethod - def is_private_key(self): - pass - - @abstractmethod - def decrypt(self, cipher_text, **kwargs): - raise NotImplementedError() - - @abstractmethod - def encrypt(self, plain_text, **kwargs): - raise NotImplementedError() - - @abstractmethod - def wrap_key(self, key, **kwargs): - raise NotImplementedError() - - @abstractmethod - def unwrap_key(self, encrypted_key, **kwargs): - raise NotImplementedError() - - @abstractmethod - def sign(self, digest, **kwargs): - raise NotImplementedError() - - @abstractmethod - def verify(self, digest, signature, **kwargs): - raise NotImplementedError() - - def _get_algorithm(self, op, **kwargs): - default_algorithm, supported_algorithms = { - "encrypt": (self.default_encryption_algorithm, self.supported_encryption_algorithms), - "decrypt": (self.default_encryption_algorithm, self.supported_encryption_algorithms), - "wrapKey": (self.default_key_wrap_algorithm, self.supported_key_wrap_algorithms), - "unwrapKey": (self.default_key_wrap_algorithm, self.supported_key_wrap_algorithms), - "sign": (self.default_signature_algorithm, self.supported_signature_algorithms), - "verify": (self.default_signature_algorithm, self.supported_signature_algorithms), - }[op] - - algorithm = kwargs.get("algorithm", default_algorithm) - - if not isinstance(algorithm, Algorithm): - algorithm = Algorithm.resolve(algorithm) - - if not algorithm or not supported_algorithms or algorithm.name() not in supported_algorithms: - raise ValueError(f"unsupported algorithm '{algorithm}'") - - return algorithm diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/rsa_key.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/rsa_key.py deleted file mode 100644 index e1325894bccc..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/rsa_key.py +++ /dev/null @@ -1,221 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import uuid - -from cryptography.exceptions import InvalidSignature -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives.asymmetric.rsa import ( - RSAPrivateKey, - RSAPrivateNumbers, - RSAPublicNumbers, - generate_private_key, - rsa_crt_dmp1, - rsa_crt_dmq1, - rsa_crt_iqmp, -) - -from ._internal import _bytes_to_int, _int_to_bytes -from .key import Key -from .algorithms import Ps256, Ps384, Ps512, Rsa1_5, RsaOaep, RsaOaep256, Rs256, Rs384, Rs512 -from ... import JsonWebKey, KeyOperation - - -class RsaKey(Key): # pylint:disable=too-many-public-methods - PUBLIC_KEY_DEFAULT_OPS = [KeyOperation.encrypt, KeyOperation.wrap_key, KeyOperation.verify] - PRIVATE_KEY_DEFAULT_OPS = PUBLIC_KEY_DEFAULT_OPS + [ - KeyOperation.decrypt, - KeyOperation.unwrap_key, - KeyOperation.sign, - ] - - _supported_encryption_algorithms = frozenset((Rsa1_5.name(), RsaOaep.name(), RsaOaep256.name())) - _supported_key_wrap_algorithms = frozenset((Rsa1_5.name(), RsaOaep.name(), RsaOaep256.name())) - _supported_signature_algorithms = frozenset( - (Ps256.name(), Ps384.name(), Ps512.name(), Rs256.name(), Rs384.name(), Rs512.name(),) - ) - - def __init__(self, kid=None): - super(RsaKey, self).__init__() - self._kid = kid - self.kty = None - self.key_ops = None - self._rsa_impl = None - - @property - def n(self): - return _int_to_bytes(self._public_key_material().n) - - @property - def e(self): - return _int_to_bytes(self._public_key_material().e) - - @property - def p(self): - return _int_to_bytes(self._private_key_material().p) if self.is_private_key() else None - - @property - def q(self): - return _int_to_bytes(self._private_key_material().q) if self.is_private_key() else None - - @property - def b(self): - return _int_to_bytes(self._private_key_material().b) if self.is_private_key() else None - - @property - def d(self): - return _int_to_bytes(self._private_key_material().d) if self.is_private_key() else None - - @property - def dq(self): - return _int_to_bytes(self._private_key_material().dmq1) if self.is_private_key() else None - - @property - def dp(self): - return _int_to_bytes(self._private_key_material().dmp1) if self.is_private_key() else None - - @property - def qi(self): - return _int_to_bytes(self._private_key_material().iqmp) if self.is_private_key() else None - - @property - def private_key(self): - return self._rsa_impl if self.is_private_key() else None - - @property - def public_key(self): - return self._rsa_impl.public_key() if self.is_private_key() else self._rsa_impl - - @staticmethod - def generate(kid=None, kty="RSA", size=2048, e=65537): - key = RsaKey() - key.kid = kid or str(uuid.uuid4()) - key.kty = kty - key.key_ops = RsaKey.PRIVATE_KEY_DEFAULT_OPS - # pylint:disable=protected-access - key._rsa_impl = generate_private_key(public_exponent=e, key_size=size, backend=default_backend()) - return key - - @classmethod - def from_jwk(cls, jwk): - if jwk.kty not in ("RSA", "RSA-HSM"): - raise ValueError('The specified jwk must have a key type of "RSA" or "RSA-HSM"') - - if not jwk.n or not jwk.e: - raise ValueError("Invalid RSA jwk, both n and e must be have values") - - rsa_key = cls(kid=jwk.kid) - rsa_key.kty = jwk.kty - rsa_key.key_ops = jwk.key_ops - - pub = RSAPublicNumbers(n=_bytes_to_int(jwk.n), e=_bytes_to_int(jwk.e)) - - # if the private key values are specified construct a private key - # only the secret primes and private exponent are needed as other fields can be calculated - if jwk.p and jwk.q and jwk.d: - # convert the values of p, q, and d from bytes to int - p = _bytes_to_int(jwk.p) - q = _bytes_to_int(jwk.q) - d = _bytes_to_int(jwk.d) - - # convert or compute the remaining private key numbers - dmp1 = _bytes_to_int(jwk.dp) if jwk.dp else rsa_crt_dmp1(private_exponent=d, p=p) - dmq1 = _bytes_to_int(jwk.dq) if jwk.dq else rsa_crt_dmq1(private_exponent=d, q=q) - iqmp = _bytes_to_int(jwk.qi) if jwk.qi else rsa_crt_iqmp(p=p, q=q) - - # create the private key from the jwk key values - priv = RSAPrivateNumbers(p=p, q=q, d=d, dmp1=dmp1, dmq1=dmq1, iqmp=iqmp, public_numbers=pub) - key_impl = priv.private_key(default_backend()) - - # if the necessary private key values are not specified create the public key - else: - key_impl = pub.public_key(default_backend()) - - rsa_key._rsa_impl = key_impl - - return rsa_key - - def to_jwk(self, include_private=False): - jwk = JsonWebKey( - kid=self.kid, - kty=self.kty, - key_ops=self.key_ops if include_private else RsaKey.PUBLIC_KEY_DEFAULT_OPS, - n=self.n, - e=self.e, - ) - - if include_private: - jwk.q = self.q - jwk.p = self.p - jwk.d = self.d - jwk.dq = self.dq - jwk.dp = self.dp - jwk.qi = self.qi - - return jwk - - @property - def default_encryption_algorithm(self): - return RsaOaep.name() - - @property - def default_key_wrap_algorithm(self): - return RsaOaep.name() - - @property - def default_signature_algorithm(self): - return Rs256.name() - - def encrypt(self, plain_text, **kwargs): - algorithm = self._get_algorithm("encrypt", **kwargs) - encryptor = algorithm.create_encryptor(self.public_key) - return encryptor.transform(plain_text) - - def decrypt(self, cipher_text, **kwargs): - if not self.is_private_key(): - raise NotImplementedError("The current RsaKey does not support decrypt") - - algorithm = self._get_algorithm("decrypt", **kwargs) - decryptor = algorithm.create_decryptor(self.private_key) - return decryptor.transform(cipher_text) - - def sign(self, digest, **kwargs): - if not self.is_private_key(): - raise NotImplementedError("The current RsaKey does not support sign") - - algorithm = self._get_algorithm("sign", **kwargs) - signer = algorithm.create_signature_transform(self.private_key) - return signer.sign(digest) - - def verify(self, digest, signature, **kwargs): - algorithm = self._get_algorithm("verify", **kwargs) - signer = algorithm.create_signature_transform(self.public_key) - try: - # cryptography's verify methods return None, and raise when verification fails - signer.verify(digest, signature) - return True - except InvalidSignature: - return False - - def wrap_key(self, key, **kwargs): - algorithm = self._get_algorithm("wrapKey", **kwargs) - encryptor = algorithm.create_encryptor(self.public_key) - return encryptor.transform(key) - - def unwrap_key(self, encrypted_key, **kwargs): - if not self.is_private_key(): - raise NotImplementedError("The current RsaKey does not support unwrap") - - algorithm = self._get_algorithm("unwrapKey", **kwargs) - decryptor = algorithm.create_decryptor(self.private_key) - return decryptor.transform(encrypted_key) - - def is_private_key(self): - return isinstance(self._rsa_impl, RSAPrivateKey) - - def _public_key_material(self): - return self.public_key.public_numbers() - - def _private_key_material(self): - return self.private_key.private_numbers() if self.private_key else None diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/symmetric_key.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/symmetric_key.py deleted file mode 100644 index 1682b1ac4bd0..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/symmetric_key.py +++ /dev/null @@ -1,125 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import uuid -import os - -from azure.core.exceptions import AzureError -from .key import Key -from .algorithms.aes_cbc import Aes256CbcPad, Aes192CbcPad, Aes128CbcPad -from .algorithms.aes_cbc_hmac import Aes256CbcHmacSha512, Aes192CbcHmacSha384 -from .algorithms.aes_kw import AesKw256, AesKw192, AesKw128 - -key_size_128 = 128 >> 3 -key_size_192 = 192 >> 3 -key_size_256 = 256 >> 3 -key_size_384 = 384 >> 3 -key_size_512 = 512 >> 3 - -_default_key_size = key_size_256 - -_supported_key_sizes = [key_size_128, key_size_192, key_size_256, key_size_384, key_size_512] - -_default_enc_alg_by_size = { - key_size_128: Aes128CbcPad.name(), - key_size_192: Aes192CbcPad.name(), - key_size_256: Aes256CbcPad.name(), - key_size_384: Aes192CbcHmacSha384.name(), - key_size_512: Aes256CbcHmacSha512.name(), -} - -_default_kw_alg_by_size = { - key_size_128: AesKw128.name(), - key_size_192: AesKw192.name(), - key_size_256: AesKw256.name(), - key_size_384: AesKw256.name(), - key_size_512: AesKw256.name(), -} - - -def raise_if_incorrect_key_size(algorithm, key_size): - if algorithm._key_size >> 3 != key_size: # pylint:disable=protected-access - raise AzureError("Invalid AES encryption algorithm for key size. The algorithm must match the size of the key.") - - -class SymmetricKey(Key): - def __init__(self, kid=None, key_bytes=None, key_size=None): - super(SymmetricKey, self).__init__() - - self._kid = kid or str(uuid.uuid4()) - - if not key_bytes: - key_size = key_size or _default_key_size - - if key_size not in _supported_key_sizes: - raise ValueError("The key size must be 128, 192, 256, 384 or 512 bits of data") - - key_bytes = os.urandom(key_size) - - if len(key_bytes) not in _supported_key_sizes: - raise ValueError("The key size must be 128, 192, 256, 384 or 512 bits of data") - - self._key = key_bytes - - supported_encryption_algorithms = [] - supported_key_wrap_algorithms = [] - key_size = len(self._key) - if key_size >= key_size_128: - supported_encryption_algorithms.append(Aes128CbcPad.name()) - supported_key_wrap_algorithms.append(AesKw128.name()) - if key_size >= key_size_192: - supported_encryption_algorithms.append(Aes192CbcPad.name()) - supported_key_wrap_algorithms.append(AesKw192.name()) - if key_size >= key_size_256: - supported_encryption_algorithms.append(Aes256CbcPad.name()) - supported_key_wrap_algorithms.append(AesKw256.name()) - self._supported_encryption_algorithms = frozenset(supported_encryption_algorithms) - self._supported_key_wrap_algorithms = frozenset(supported_key_wrap_algorithms) - - def is_private_key(self): - return True - - @classmethod - def from_jwk(cls, jwk): - return cls(kid=jwk.kid, key_bytes=jwk.k) - - @property - def kid(self): - return self._kid - - @property - def default_encryption_algorithm(self): - return _default_enc_alg_by_size[len(self._key)] - - @property - def default_key_wrap_algorithm(self): - return _default_kw_alg_by_size[len(self._key)] - - def encrypt(self, plain_text, iv, **kwargs): # pylint:disable=arguments-differ - algorithm = self._get_algorithm("encrypt", **kwargs) - raise_if_incorrect_key_size(algorithm, len(self._key)) - encryptor = algorithm.create_encryptor(key=self._key, iv=iv) - return encryptor.transform(plain_text) - - def decrypt(self, cipher_text, iv, **kwargs): # pylint:disable=arguments-differ - algorithm = self._get_algorithm("decrypt", **kwargs) - raise_if_incorrect_key_size(algorithm, len(self._key)) - decryptor = algorithm.create_decryptor(key=self._key, iv=iv) - return decryptor.transform(cipher_text) - - def wrap_key(self, key, **kwargs): - algorithm = self._get_algorithm("wrapKey", **kwargs) - encryptor = algorithm.create_encryptor(key=self._key) - return encryptor.transform(key) - - def unwrap_key(self, encrypted_key, **kwargs): - algorithm = self._get_algorithm("unwrapKey", **kwargs) - decryptor = algorithm.create_decryptor(key=self._key) - return decryptor.transform(encrypted_key) - - def sign(self, digest, **kwargs): - raise NotImplementedError("Local signing isn't supported with symmetric keys") - - def verify(self, digest, signature, **kwargs): - raise NotImplementedError("Local signature verification isn't supported with symmetric keys") diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/transform.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/transform.py deleted file mode 100644 index 3a24f7ab1a7f..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_internal/transform.py +++ /dev/null @@ -1,61 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ - -from abc import ABCMeta, abstractmethod - - -class CryptoTransform(object, metaclass=ABCMeta): - def __init__(self, key): - self._key = key - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self._key = None - - @abstractmethod - def transform(self, data): - raise NotImplementedError() - - -class BlockCryptoTransform(CryptoTransform): - @abstractmethod - def block_size(self): - raise NotImplementedError() - - @abstractmethod - def update(self, data): - raise NotImplementedError() - - @abstractmethod - def finalize(self): - raise NotImplementedError() - - -class AuthenticatedCryptoTransform(object, metaclass=ABCMeta): - @abstractmethod - def tag(self): - raise NotImplementedError() - - -class SignatureTransform(object, metaclass=ABCMeta): - @abstractmethod - def sign(self, digest): - raise NotImplementedError() - - @abstractmethod - def verify(self, digest, signature): - raise NotImplementedError() - - -class DigestTransform(object, metaclass=ABCMeta): - @abstractmethod - def update(self, data): - raise NotImplementedError() - - @abstractmethod - def finalize(self, data): - raise NotImplementedError() diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_key_validity.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_key_validity.py deleted file mode 100644 index 4e879040759b..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_key_validity.py +++ /dev/null @@ -1,16 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from datetime import datetime, timezone -from typing import Optional - - -def raise_if_time_invalid(not_before: Optional[datetime], expires_on: Optional[datetime]) -> None: - now = datetime.now(timezone.utc) - if (not_before and expires_on) and not not_before <= now <= expires_on: - raise ValueError(f"This client's key is useable only between {not_before} and {expires_on} (UTC)") - if not_before and not_before > now: - raise ValueError(f"This client's key is not useable until {not_before} (UTC)") - if expires_on and expires_on <= now: - raise ValueError(f"This client's key expired at {expires_on} (UTC)") diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_models.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_models.py deleted file mode 100644 index e673940f1fa4..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_models.py +++ /dev/null @@ -1,582 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import Any, cast, Optional, NoReturn, Union, TYPE_CHECKING - -from cryptography.exceptions import InvalidSignature -from cryptography.hazmat.primitives.asymmetric.padding import AsymmetricPadding, OAEP, PKCS1v15, PSS, MGF1 -from cryptography.hazmat.primitives.asymmetric.rsa import ( - rsa_crt_dmp1, - rsa_crt_dmq1, - rsa_crt_iqmp, - rsa_recover_prime_factors, - RSAPrivateKey, - RSAPrivateNumbers, - RSAPublicKey, - RSAPublicNumbers, -) -from cryptography.hazmat.primitives.asymmetric.utils import Prehashed -from cryptography.hazmat.primitives.hashes import Hash, HashAlgorithm, SHA1, SHA256, SHA384, SHA512 -from cryptography.hazmat.primitives.serialization import ( - Encoding, - KeySerializationEncryption, - PrivateFormat, - PublicFormat, -) - -from ._enums import EncryptionAlgorithm, KeyWrapAlgorithm, SignatureAlgorithm -from .._models import JsonWebKey - -if TYPE_CHECKING: - # Import client only during TYPE_CHECKING to avoid circular dependency - from ._client import CryptographyClient - - -SIGN_ALGORITHM_MAP = { - SHA256: SignatureAlgorithm.rs256, - SHA384: SignatureAlgorithm.rs384, - SHA512: SignatureAlgorithm.rs512, -} -OAEP_MAP = {SHA1: EncryptionAlgorithm.rsa_oaep, SHA256: EncryptionAlgorithm.rsa_oaep_256} -PSS_MAP = { - SignatureAlgorithm.rs256: SignatureAlgorithm.ps256, - SignatureAlgorithm.rs384: SignatureAlgorithm.ps384, - SignatureAlgorithm.rs512: SignatureAlgorithm.ps512, -} - - -def get_encryption_algorithm(padding: AsymmetricPadding) -> EncryptionAlgorithm: - """Maps an `AsymmetricPadding` to an encryption algorithm. - - :param padding: The padding to use. - :type padding: ~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding - - :returns: The corresponding Key Vault encryption algorithm. - :rtype: EncryptionAlgorithm - """ - if isinstance(padding, OAEP): - # Public algorithm property was only added in https://github.com/pyca/cryptography/pull/9582 - # _algorithm property has been available in every version of the OAEP class, so we use it as a backup - try: - algorithm = padding.algorithm # type: ignore[attr-defined] - except AttributeError: - algorithm = padding._algorithm # pylint:disable=protected-access - mapped_algorithm = OAEP_MAP.get(type(algorithm)) - if mapped_algorithm is None: - raise ValueError(f"Unsupported algorithm: {algorithm.name}") - - # Public mgf property was added at the same time as algorithm - try: - mgf = padding.mgf # type: ignore[attr-defined] - except AttributeError: - mgf = padding._mgf # pylint:disable=protected-access - if not isinstance(mgf, MGF1): - raise ValueError(f"Unsupported MGF: {mgf}") - - elif isinstance(padding, PKCS1v15): - mapped_algorithm = EncryptionAlgorithm.rsa1_5 - else: - raise ValueError(f"Unsupported padding: {padding.name}") - - return mapped_algorithm - - -def get_signature_algorithm(padding: AsymmetricPadding, algorithm: HashAlgorithm) -> SignatureAlgorithm: - """Maps an `AsymmetricPadding` and `HashAlgorithm` to a signature algorithm. - - :param padding: The padding to use. - :type padding: ~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding - :param algorithm: The algorithm to use. - :type algorithm: ~cryptography.hazmat.primitives.hashes.HashAlgorithm - - :returns: The corresponding Key Vault signature algorithm. - :rtype: SignatureAlgorithm - """ - mapped_algorithm = SIGN_ALGORITHM_MAP.get(type(algorithm)) - if mapped_algorithm is None: - raise ValueError(f"Unsupported algorithm: {algorithm.name}") - - # If PSS padding is requested, use the PSS equivalent algorithm - if isinstance(padding, PSS): - mapped_algorithm = PSS_MAP.get(mapped_algorithm) - - # Public mgf property was only added in https://github.com/pyca/cryptography/pull/9582 - # _mgf property has been available in every version of the PSS class, so we use it as a backup - try: - mgf = padding.mgf # type: ignore[attr-defined] - except AttributeError: - mgf = padding._mgf # pylint:disable=protected-access - if not isinstance(mgf, MGF1): - raise ValueError(f"Unsupported MGF: {mgf}") - - # The only other padding accepted is PKCS1v15 - elif not isinstance(padding, PKCS1v15): - raise ValueError(f"Unsupported padding: {padding.name}") - - return cast(SignatureAlgorithm, mapped_algorithm) - - -class KeyVaultRSAPublicKey(RSAPublicKey): - """An `RSAPublicKey` implementation based on a key managed by Key Vault. - - This class should not be instantiated directly. Instead, use the - :func:`~azure.keyvault.keys.crypto.CryptographyClient.create_rsa_public_key` method to create a key based on the - client's key. Only synchronous clients and operations are supported at this time. - """ - - def __init__(self, client: "CryptographyClient", key_material: Optional[JsonWebKey] = None) -> None: - self._client: "CryptographyClient" = client - self._key: Optional[JsonWebKey] = key_material - - def encrypt(self, plaintext: bytes, padding: AsymmetricPadding) -> bytes: - """Encrypts the given plaintext. - - :param bytes plaintext: Plaintext to encrypt. - :param padding: The padding to use. Supported paddings are `OAEP` and `PKCS1v15`. For `OAEP` padding, supported - hash algorithms are `SHA1` and `SHA256`. The only supported mask generation function is `MGF1`. See - https://learn.microsoft.com/azure/key-vault/keys/about-keys-details for details. - :type padding: ~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding - - :returns: The encrypted ciphertext, as bytes. - :rtype: bytes - """ - mapped_algorithm = get_encryption_algorithm(padding) - result = self._client.encrypt(mapped_algorithm, plaintext) - return result.ciphertext - - @property - def key_size(self) -> int: - """The bit length of the public modulus. - - :returns: The key's size. - :rtype: int - - :raises ValueError: if the client is unable to obtain the key material from Key Vault. - """ - if self._key is None: - raise ValueError( - "Key material could not be obtained from Key Vault. Only remote cryptographic operations " - "(encrypt, verify) can be performed." - ) - - public_key = self.public_numbers().public_key() - return public_key.key_size - - def public_numbers(self) -> RSAPublicNumbers: - """Returns an `RSAPublicNumbers` representing the key's public numbers. - - :returns: The public numbers of the key. - :rtype: RSAPublicNumbers - - :raises ValueError: if the client is unable to obtain the key material from Key Vault. - """ - if self._key is None: - raise ValueError( - "Key material could not be obtained from Key Vault. Only remote cryptographic operations " - "(encrypt, verify) can be performed." - ) - - e = int.from_bytes(self._key.e, "big") # type: ignore[attr-defined] - n = int.from_bytes(self._key.n, "big") # type: ignore[attr-defined] - return RSAPublicNumbers(e, n) - - def public_bytes(self, encoding: Encoding, format: PublicFormat) -> bytes: - """Allows serialization of the key to bytes. - - This function uses the `cryptography` library's implementation. - Encoding (`PEM` or `DER`) and format (`SubjectPublicKeyInfo` or `PKCS1`) are chosen to define the exact - serialization. - - :param encoding: A value from the `Encoding` enum. - :type encoding: ~cryptography.hazmat.primitives.serialization.Encoding - :param format: A value from the `PublicFormat` enum. - :type format: ~cryptography.hazmat.primitives.serialization.PublicFormat - - :returns: The serialized key. - :rtype: bytes - - :raises ValueError: if the client is unable to obtain the key material from Key Vault. - """ - if self._key is None: - raise ValueError( - "Key material could not be obtained from Key Vault. Only remote cryptographic operations " - "(encrypt, verify) can be performed." - ) - - public_key = self.public_numbers().public_key() - return public_key.public_bytes(encoding=encoding, format=format) - - def verify( - self, - signature: bytes, - data: bytes, - padding: AsymmetricPadding, - algorithm: Union[Prehashed, HashAlgorithm], - ) -> None: - """Verifies the signature of the data. - - :param bytes signature: The signature to sign, as bytes. - :param bytes data: The message string that was signed., as bytes. - :param padding: The padding to use. Supported paddings are `PKCS1v15` and `PSS`. For `PSS`, the only supported - mask generation function is `MGF1`. See https://learn.microsoft.com/azure/key-vault/keys/about-keys-details - for details. - :type padding: ~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding - :param algorithm: The algorithm to sign with. Only `HashAlgorithm`s are supported -- specifically, `SHA256`, - `SHA384`, and `SHA512`. - :type algorithm: ~cryptography.hazmat.primitives.asymmetric.utils.Prehashed or - cryptography.hazmat.primitives.hashes.HashAlgorithm - - :raises InvalidSignature: If the signature does not validate. - """ - if isinstance(algorithm, Prehashed): - raise ValueError("`Prehashed` algorithms are unsupported. Please provide a `HashAlgorithm` instead.") - mapped_algorithm = get_signature_algorithm(padding, algorithm) - digest = Hash(algorithm) - digest.update(data) - result = self._client.verify(mapped_algorithm, digest.finalize(), signature) - if not result.is_valid: - raise InvalidSignature(f"The provided signature '{signature!r}' is invalid.") - - def recover_data_from_signature( - self, signature: bytes, padding: AsymmetricPadding, algorithm: Optional[HashAlgorithm] - ) -> bytes: - # pylint: disable=line-too-long - """Recovers the signed data from the signature. Only supported with `cryptography` version 3.3 and above. - - This function uses the `cryptography` library's implementation. - The data typically contains the digest of the original message string. The `padding` and `algorithm` parameters - must match the ones used when the signature was created for the recovery to succeed. - The `algorithm` parameter can also be set to None to recover all the data present in the signature, without - regard to its format or the hash algorithm used for its creation. - - For `PKCS1v15` padding, this method returns the data after removing the padding layer. For standard signatures - the data contains the full `DigestInfo` structure. For non-standard signatures, any data can be returned, - including zero-length data. - - Normally you should use the `verify()` function to validate the signature. But for some non-standard signature - formats you may need to explicitly recover and validate the signed data. The following are some examples: - - * Some old Thawte and Verisign timestamp certificates without `DigestInfo`. - * Signed MD5/SHA1 hashes in TLS 1.1 or earlier (`RFC 4346 `_, section 4.7). - * IKE version 1 signatures without `DigestInfo` (`RFC 2409 `_, section 5.1). - - :param bytes signature: The signature. - :param padding: An instance of `AsymmetricPadding`. Recovery is only supported with some of the padding types. - :type padding: ~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding - :param algorithm: An instance of `HashAlgorithm`. Can be None to return all the data present in the signature. - :type algorithm: ~cryptography.hazmat.primitives.hashes.HashAlgorithm - - :returns: The signed data. - :rtype: bytes - :raises NotImplementedError: if the local version of `cryptography` doesn't support this method. - :raises ~cryptography.exceptions.InvalidSignature: if the signature is invalid. - :raises ~cryptography.exceptions.UnsupportedAlgorithm: if the signature data recovery is not supported with - the provided `padding` type. - :raises ValueError: if the client is unable to obtain the key material from Key Vault. - """ - if self._key is None: - raise ValueError( - "Key material could not be obtained from Key Vault. Only remote cryptographic operations " - "(encrypt, verify) can be performed." - ) - - public_key = self.public_numbers().public_key() - try: - return public_key.recover_data_from_signature(signature=signature, padding=padding, algorithm=algorithm) - except AttributeError as exc: - raise NotImplementedError( - "This method is only available on `cryptography`>=3.3. Update your package version to use this method." - ) from exc - - def __eq__(self, other: object) -> bool: - """Checks equality. - - :param object other: Another object to compare with this instance. Currently, only comparisons with - `KeyVaultRSAPrivateKey` or `JsonWebKey` instances are supported. - - :returns: True if the objects are equal; False if the objects are unequal or if key material can't be obtained - from Key Vault for comparison. - :rtype: bool - """ - if self._key is None: - return False - - if isinstance(other, KeyVaultRSAPublicKey): - return all(getattr(self._key, field) == getattr(other._key, field) for field in self._key._FIELDS) - if isinstance(other, JsonWebKey): - return all(getattr(self._key, field) == getattr(other, field) for field in self._key._FIELDS) - return False - - def verifier( # pylint:disable=docstring-missing-param,docstring-missing-return,docstring-missing-rtype - self, signature: bytes, padding: AsymmetricPadding, algorithm: HashAlgorithm - ) -> NoReturn: - """Not implemented. This method was deprecated in `cryptography` 2.0 and removed in 37.0.0.""" - raise NotImplementedError() - - -class KeyVaultRSAPrivateKey(RSAPrivateKey): - """An `RSAPrivateKey` implementation based on a key managed by Key Vault. - - This class should not be instantiated directly. Instead, use the - :func:`~azure.keyvault.keys.crypto.CryptographyClient.create_rsa_private_key` method to create a key based on the - client's key. Only synchronous clients and operations are supported at this time. - """ - - def __init__(self, client: "CryptographyClient", key_material: Optional[JsonWebKey]) -> None: - self._client: "CryptographyClient" = client - self._key: Optional[JsonWebKey] = key_material - - def decrypt(self, ciphertext: bytes, padding: AsymmetricPadding) -> bytes: - """Decrypts the provided ciphertext. - - :param bytes ciphertext: Encrypted bytes to decrypt. - :param padding: The padding to use. Supported paddings are `OAEP` and `PKCS1v15`. For `OAEP` padding, supported - hash algorithms are `SHA1` and `SHA256`. The only supported mask generation function is `MGF1`. See - https://learn.microsoft.com/azure/key-vault/keys/about-keys-details for details. - :type padding: ~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding - - :returns: The decrypted plaintext, as bytes. - :rtype: bytes - """ - mapped_algorithm = get_encryption_algorithm(padding) - result = self._client.decrypt(mapped_algorithm, ciphertext) - return result.plaintext - - @property - def key_size(self) -> int: - """The bit length of the public modulus. - - :returns: The key's size. - :rtype: int - - :raises ValueError: if the client is unable to obtain the key material from Key Vault. - """ - if self._key is None: - raise ValueError( - "Key material could not be obtained from Key Vault. Only remote cryptographic operations " - "(decrypt, sign) can be performed." - ) - - # Key size only requires public modulus, which we can always get - # Relying on private numbers instead would cause issues for keys stored in KV (which doesn't return private key) - return self.public_key().key_size - - def public_key(self) -> KeyVaultRSAPublicKey: - """The `RSAPublicKey` associated with this private key, as a `KeyVaultRSAPublicKey`. - - The public key implementation will use the same underlying cryptography client as this private key. - - :returns: The `KeyVaultRSAPublicKey` associated with the key. - :rtype: ~azure.keyvault.keys.crypto.KeyVaultRSAPublicKey - """ - return KeyVaultRSAPublicKey(self._client, self._key) - - def sign( - self, - data: bytes, - padding: AsymmetricPadding, - algorithm: Union[Prehashed, HashAlgorithm], - ) -> bytes: - """Signs the data. - - :param bytes data: The data to sign, as bytes. - :param padding: The padding to use. Supported paddings are `PKCS1v15` and `PSS`. For `PSS`, the only supported - mask generation function is `MGF1`. See https://learn.microsoft.com/azure/key-vault/keys/about-keys-details - for details. - :type padding: ~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding - :param algorithm: The algorithm to sign with. Only `HashAlgorithm`s are supported -- specifically, `SHA256`, - `SHA384`, and `SHA512`. - :type algorithm: ~cryptography.hazmat.primitives.asymmetric.utils.Prehashed or - cryptography.hazmat.primitives.hashes.HashAlgorithm - - :returns: The signature, as bytes. - :rtype: bytes - """ - if isinstance(algorithm, Prehashed): - raise ValueError("`Prehashed` algorithms are unsupported. Please provide a `HashAlgorithm` instead.") - mapped_algorithm = get_signature_algorithm(padding, algorithm) - digest = Hash(algorithm) - digest.update(data) - result = self._client.sign(mapped_algorithm, digest.finalize()) - return result.signature - - def private_numbers(self) -> RSAPrivateNumbers: - """Returns an `RSAPrivateNumbers` representing the key's private numbers. - - :returns: The private numbers of the key. - :rtype: ~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers - - :raises ValueError: if the client is unable to obtain the key material from Key Vault. - """ - if self._key is None: - raise ValueError( - "Key material could not be obtained from Key Vault. Only remote cryptographic operations " - "(decrypt, sign) can be performed." - ) - - # Fetch public numbers from JWK - e = int.from_bytes(self._key.e, "big") # type: ignore[attr-defined] - n = int.from_bytes(self._key.n, "big") # type: ignore[attr-defined] - public_numbers = RSAPublicNumbers(e, n) - - # Fetch private numbers from JWK - p = int.from_bytes(self._key.p, "big") if self._key.p else None # type: ignore[attr-defined] - q = int.from_bytes(self._key.q, "big") if self._key.q else None # type: ignore[attr-defined] - d = int.from_bytes(self._key.d, "big") if self._key.d else None # type: ignore[attr-defined] - dmp1 = int.from_bytes(self._key.dp, "big") if self._key.dp else None # type: ignore[attr-defined] - dmq1 = int.from_bytes(self._key.dq, "big") if self._key.dq else None # type: ignore[attr-defined] - iqmp = int.from_bytes(self._key.qi, "big") if self._key.qi else None # type: ignore[attr-defined] - - # Calculate any missing attributes - if d is None: - raise ValueError("An 'RSAPrivateNumbers' couldn't be created with the available key material.") - if p is None or q is None: - p, q = rsa_recover_prime_factors(n, e, d) - if dmp1 is None: - dmp1 = rsa_crt_dmp1(d, p) - if dmq1 is None: - dmq1 = rsa_crt_dmq1(d, q) - if iqmp is None: - iqmp = rsa_crt_iqmp(p, q) - - return RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp, public_numbers) - - def private_bytes( - self, encoding: Encoding, format: PrivateFormat, encryption_algorithm: KeySerializationEncryption - ) -> bytes: - """Allows serialization of the key to bytes. - - This function uses the `cryptography` library's implementation. - Encoding (`PEM` or `DER`) and format (`TraditionalOpenSSL`, `OpenSSH`, or `PKCS8`) and encryption algorithm - (such as `BestAvailableEncryption` or `NoEncryption`) are chosen to define the exact serialization. - - :param encoding: A value from the `Encoding` enum. - :type encoding: ~cryptography.hazmat.primitives.serialization.Encoding - :param format: A value from the `PrivateFormat` enum. - :type format: ~cryptography.hazmat.primitives.serialization.PrivateFormat - :param encryption_algorithm: An instance of an object conforming to the `KeySerializationEncryption` interface. - :type encryption_algorithm: ~cryptography.hazmat.primitives.serialization.KeySerializationEncryption - - :returns: The serialized key. - :rtype: bytes - - :raises ValueError: if the client is unable to obtain the key material from Key Vault. - """ - if self._key is None: - raise ValueError( - "Key material could not be obtained from Key Vault. Only remote cryptographic operations " - "(decrypt, sign) can be performed." - ) - - try: - private_numbers = self.private_numbers() - except ValueError as exc: - raise ValueError("Insufficient key material to serialize the private key.") from exc - private_key = private_numbers.private_key() - return private_key.private_bytes(encoding=encoding, format=format, encryption_algorithm=encryption_algorithm) - - def signer( # pylint:disable=docstring-missing-param,docstring-missing-return,docstring-missing-rtype - self, padding: AsymmetricPadding, algorithm: HashAlgorithm - ) -> NoReturn: - """Not implemented. This method was deprecated in `cryptography` 2.0 and removed in 37.0.0.""" - raise NotImplementedError() - - -class DecryptResult: - """The result of a decrypt operation. - - :param str key_id: The encryption key's Key Vault identifier - :param algorithm: The encryption algorithm used - :type algorithm: ~azure.keyvault.keys.crypto.EncryptionAlgorithm - :param bytes plaintext: The decrypted bytes - """ - - def __init__(self, key_id: Optional[str], algorithm: EncryptionAlgorithm, plaintext: bytes) -> None: - self.key_id = key_id - self.algorithm = algorithm - self.plaintext = plaintext - - -class EncryptResult: - """The result of an encrypt operation. - - :param str key_id: The encryption key's Key Vault identifier - :param algorithm: The encryption algorithm used - :type algorithm: ~azure.keyvault.keys.crypto.EncryptionAlgorithm - :param bytes ciphertext: The encrypted bytes - - :keyword bytes iv: Initialization vector for symmetric algorithms - :keyword bytes authentication_tag: The tag to authenticate when performing decryption with an authenticated - algorithm - :keyword bytes additional_authenticated_data: Additional data to authenticate but not encrypt/decrypt when using an - authenticated algorithm - """ - - def __init__(self, key_id: Optional[str], algorithm: EncryptionAlgorithm, ciphertext: bytes, **kwargs: Any) -> None: - self.key_id = key_id - self.algorithm = algorithm - self.ciphertext = ciphertext - self.iv = kwargs.pop("iv", None) - self.tag = kwargs.pop("authentication_tag", None) - self.aad = kwargs.pop("additional_authenticated_data", None) - - -class SignResult: - """The result of a sign operation. - - :param str key_id: The signing key's Key Vault identifier - :param algorithm: The signature algorithm used - :type algorithm: ~azure.keyvault.keys.crypto.SignatureAlgorithm - :param bytes signature: - """ - - def __init__(self, key_id: Optional[str], algorithm: SignatureAlgorithm, signature: bytes) -> None: - self.key_id = key_id - self.algorithm = algorithm - self.signature = signature - - -class VerifyResult: - """The result of a verify operation. - - :param str key_id: The signing key's Key Vault identifier - :param bool is_valid: Whether the signature is valid - :param algorithm: The signature algorithm used - :type algorithm: ~azure.keyvault.keys.crypto.SignatureAlgorithm - """ - - def __init__(self, key_id: Optional[str], is_valid: bool, algorithm: SignatureAlgorithm) -> None: - self.key_id = key_id - self.is_valid = is_valid - self.algorithm = algorithm - - -class UnwrapResult: - """The result of an unwrap key operation. - - :param str key_id: Key encryption key's Key Vault identifier - :param algorithm: The key wrap algorithm used - :type algorithm: ~azure.keyvault.keys.crypto.KeyWrapAlgorithm - :param bytes key: The unwrapped key - """ - - def __init__(self, key_id: Optional[str], algorithm: KeyWrapAlgorithm, key: bytes) -> None: - self.key_id = key_id - self.algorithm = algorithm - self.key = key - - -class WrapResult: - """The result of a wrap key operation. - - :param str key_id: The wrapping key's Key Vault identifier - :param algorithm: The key wrap algorithm used - :type algorithm: ~azure.keyvault.keys.crypto.KeyWrapAlgorithm - :param bytes encrypted_key: The encrypted key bytes - """ - - def __init__(self, key_id: Optional[str], algorithm: KeyWrapAlgorithm, encrypted_key: bytes) -> None: - self.key_id = key_id - self.algorithm = algorithm - self.encrypted_key = encrypted_key diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/__init__.py deleted file mode 100644 index 8c146d1a1fca..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/__init__.py +++ /dev/null @@ -1,36 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import TYPE_CHECKING - -from .ec import EllipticCurveCryptographyProvider -from .local_provider import LocalCryptographyProvider -from .rsa import RsaCryptographyProvider -from .symmetric import SymmetricCryptographyProvider -from ... import KeyType - -if TYPE_CHECKING: - from ... import JsonWebKey - - -def get_local_cryptography_provider(key: "JsonWebKey") -> LocalCryptographyProvider: - if key.kty in (KeyType.ec, KeyType.ec_hsm): # type: ignore[attr-defined] - return EllipticCurveCryptographyProvider(key) - if key.kty in (KeyType.rsa, KeyType.rsa_hsm): # type: ignore[attr-defined] - return RsaCryptographyProvider(key) - if key.kty in (KeyType.oct, KeyType.oct_hsm): # type: ignore[attr-defined] - return SymmetricCryptographyProvider(key) - - raise ValueError(f'Unsupported key type "{key.kty}"') # type: ignore[attr-defined] - - -class NoLocalCryptography(LocalCryptographyProvider): - def __init__(self): # pylint:disable=super-init-not-called - return - - def supports(self, operation, algorithm): - return False - - def _get_internal_key(self, key): - return None diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/ec.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/ec.py deleted file mode 100644 index d72dd505a1a2..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/ec.py +++ /dev/null @@ -1,34 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import TYPE_CHECKING - -from .local_provider import LocalCryptographyProvider -from .._internal import EllipticCurveKey -from ... import KeyOperation, KeyType - -if TYPE_CHECKING: - from .local_provider import Algorithm - from .._internal import Key - from ... import JsonWebKey - -_PRIVATE_KEY_OPERATIONS = frozenset((KeyOperation.decrypt, KeyOperation.sign, KeyOperation.unwrap_key)) - - -class EllipticCurveCryptographyProvider(LocalCryptographyProvider): - def _get_internal_key(self, key: "JsonWebKey") -> "Key": - if key.kty not in (KeyType.ec, KeyType.ec_hsm): # type: ignore[attr-defined] - raise ValueError('"key" must be an EC or EC-HSM key') - return EllipticCurveKey.from_jwk(key) - - def supports(self, operation: KeyOperation, algorithm: "Algorithm") -> bool: - if operation in _PRIVATE_KEY_OPERATIONS and not self._internal_key.is_private_key(): - return False - if operation in (KeyOperation.decrypt, KeyOperation.encrypt): - return algorithm in self._internal_key.supported_encryption_algorithms - if operation in (KeyOperation.unwrap_key, KeyOperation.wrap_key): - return algorithm in self._internal_key.supported_key_wrap_algorithms - if operation in (KeyOperation.sign, KeyOperation.verify): - return algorithm in self._internal_key.supported_signature_algorithms - return False diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/local_provider.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/local_provider.py deleted file mode 100644 index 6e0edd2f526c..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/local_provider.py +++ /dev/null @@ -1,104 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import abc -import os -from typing import Optional, TYPE_CHECKING, Union - -from azure.core.exceptions import AzureError - -from .. import DecryptResult, EncryptResult, SignResult, UnwrapResult, VerifyResult, WrapResult -from ... import KeyOperation - -ABC = abc.ABC - -if TYPE_CHECKING: - from .._internal.key import Key - from .. import EncryptionAlgorithm, KeyWrapAlgorithm, SignatureAlgorithm - from ... import JsonWebKey - - Algorithm = Union[EncryptionAlgorithm, KeyWrapAlgorithm, SignatureAlgorithm] - - -class LocalCryptographyProvider(ABC): - def __init__(self, key: "JsonWebKey") -> None: - self._allowed_ops = frozenset(key.key_ops or []) # type: ignore[attr-defined] - self._internal_key = self._get_internal_key(key) - self._key = key - - @abc.abstractmethod - def _get_internal_key(self, key: "JsonWebKey") -> "Key": - pass - - @abc.abstractmethod - def supports(self, operation: KeyOperation, algorithm: "Algorithm") -> bool: - pass - - @property - def key_id(self) -> "Optional[str]": - """The full identifier of the provider's key. - - :returns: The full identifier of the provider's key. - :rtype: str or None - """ - return self._key.kid # type: ignore[attr-defined] - - def _raise_if_unsupported(self, operation: KeyOperation, algorithm: "Algorithm") -> None: - if not self.supports(operation, algorithm): - raise NotImplementedError( - f'This key does not support the "{operation}" operation with algorithm "{algorithm}"' - ) - if operation not in self._allowed_ops: - raise AzureError(f'This key does not allow the "{operation}" operation') - - def encrypt( - self, algorithm: "EncryptionAlgorithm", plaintext: bytes, iv: "Optional[bytes]" = None - ) -> EncryptResult: - self._raise_if_unsupported(KeyOperation.encrypt, algorithm) - - # If an IV isn't provided with AES-CBCPAD encryption, try to create one - if iv is None and algorithm.value.endswith("CBCPAD"): - try: - iv = os.urandom(16) - except NotImplementedError as ex: - raise ValueError( - "An IV could not be generated on this OS. Please provide your own cryptographically random, " - "non-repeating IV for local cryptography." - ) from ex - - ciphertext = self._internal_key.encrypt(plaintext, algorithm=algorithm.value, iv=iv) - return EncryptResult( - key_id=self._key.kid, algorithm=algorithm, ciphertext=ciphertext, iv=iv # type: ignore[attr-defined] - ) - - def decrypt( - self, algorithm: "EncryptionAlgorithm", ciphertext: bytes, iv: "Optional[bytes]" = None - ) -> DecryptResult: - self._raise_if_unsupported(KeyOperation.decrypt, algorithm) - plaintext = self._internal_key.decrypt(ciphertext, iv=iv, algorithm=algorithm.value) - return DecryptResult( - key_id=self._key.kid, algorithm=algorithm, plaintext=plaintext # type: ignore[attr-defined] - ) - - def wrap_key(self, algorithm: "KeyWrapAlgorithm", key: bytes) -> "WrapResult": - self._raise_if_unsupported(KeyOperation.wrap_key, algorithm) - encrypted_key = self._internal_key.wrap_key(key, algorithm=algorithm.value) - return WrapResult( - key_id=self._key.kid, algorithm=algorithm, encrypted_key=encrypted_key # type: ignore[attr-defined] - ) - - def unwrap_key(self, algorithm: "KeyWrapAlgorithm", encrypted_key: bytes) -> "UnwrapResult": - self._raise_if_unsupported(KeyOperation.unwrap_key, algorithm) - unwrapped_key = self._internal_key.unwrap_key(encrypted_key, algorithm=algorithm.value) - return UnwrapResult(key_id=self._key.kid, algorithm=algorithm, key=unwrapped_key) # type: ignore[attr-defined] - - def sign(self, algorithm: "SignatureAlgorithm", digest: bytes) -> "SignResult": - self._raise_if_unsupported(KeyOperation.sign, algorithm) - signature = self._internal_key.sign(digest, algorithm=algorithm.value) - return SignResult(key_id=self._key.kid, algorithm=algorithm, signature=signature) # type: ignore[attr-defined] - - def verify(self, algorithm: "SignatureAlgorithm", digest: bytes, signature: bytes) -> "VerifyResult": - self._raise_if_unsupported(KeyOperation.verify, algorithm) - is_valid = self._internal_key.verify(digest, signature, algorithm=algorithm.value) - return VerifyResult(key_id=self._key.kid, algorithm=algorithm, is_valid=is_valid) # type: ignore[attr-defined] diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/rsa.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/rsa.py deleted file mode 100644 index 4394cc2a9b51..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/rsa.py +++ /dev/null @@ -1,34 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import TYPE_CHECKING - -from .local_provider import LocalCryptographyProvider -from .._internal import RsaKey -from ... import KeyOperation, KeyType - -if TYPE_CHECKING: - from .local_provider import Algorithm - from .._internal import Key - from ... import JsonWebKey - -_PRIVATE_KEY_OPERATIONS = frozenset((KeyOperation.decrypt, KeyOperation.sign, KeyOperation.unwrap_key)) - - -class RsaCryptographyProvider(LocalCryptographyProvider): - def _get_internal_key(self, key: "JsonWebKey") -> "Key": - if key.kty not in (KeyType.rsa, KeyType.rsa_hsm): # type: ignore[attr-defined] - raise ValueError('"key" must be an RSA or RSA-HSM key') - return RsaKey.from_jwk(key) - - def supports(self, operation: KeyOperation, algorithm: "Algorithm") -> bool: - if operation in _PRIVATE_KEY_OPERATIONS and not self._internal_key.is_private_key(): - return False - if operation in (KeyOperation.decrypt, KeyOperation.encrypt): - return algorithm in self._internal_key.supported_encryption_algorithms - if operation in (KeyOperation.unwrap_key, KeyOperation.wrap_key): - return algorithm in self._internal_key.supported_key_wrap_algorithms - if operation in (KeyOperation.sign, KeyOperation.verify): - return algorithm in self._internal_key.supported_signature_algorithms - return False diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/symmetric.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/symmetric.py deleted file mode 100644 index 3a5f473b36c1..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/_providers/symmetric.py +++ /dev/null @@ -1,28 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import TYPE_CHECKING - -from .local_provider import LocalCryptographyProvider -from .._internal import SymmetricKey -from ... import KeyOperation, KeyType - -if TYPE_CHECKING: - from .local_provider import Algorithm - from .._internal import Key - from ... import JsonWebKey - - -class SymmetricCryptographyProvider(LocalCryptographyProvider): - def _get_internal_key(self, key: "JsonWebKey") -> "Key": - if key.kty not in (KeyType.oct, KeyType.oct_hsm): # type: ignore[attr-defined] - raise ValueError('"key" must be an oct or oct-HSM (symmetric) key') - return SymmetricKey.from_jwk(key) - - def supports(self, operation: KeyOperation, algorithm: "Algorithm") -> bool: - if operation in (KeyOperation.decrypt, KeyOperation.encrypt): - return algorithm in self._internal_key.supported_encryption_algorithms - if operation in (KeyOperation.unwrap_key, KeyOperation.wrap_key): - return algorithm in self._internal_key.supported_key_wrap_algorithms - return False diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/aio/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/aio/__init__.py deleted file mode 100644 index 3a8c0f5ee127..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/aio/__init__.py +++ /dev/null @@ -1,50 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import Any, List, Optional - -from ._client import CryptographyClient - - -__all__ = [ - "CryptographyClient", -] - - -def __dir__() -> List[str]: - return __all__ - - -# Allow importing these types for backwards compatibility, but exclude indexing types that shouldn't be in aio namespace - - -def __getattr__(name: str): - requested: Optional[Any] = None - if name == "EncryptionAlgorithm": - from .. import EncryptionAlgorithm - - requested = EncryptionAlgorithm - if name == "KeyWrapAlgorithm": - from .. import KeyWrapAlgorithm - - requested = KeyWrapAlgorithm - if name == "SignatureAlgorithm": - from .. import SignatureAlgorithm - - requested = SignatureAlgorithm - if name == "EncryptResult": - from .. import EncryptResult - - requested = EncryptResult - if name == "SignResult": - from .. import SignResult - - requested = SignResult - if name == "WrapResult": - from .. import WrapResult - - requested = WrapResult - if requested: - return requested - raise AttributeError(f"module 'azure.keyvault.keys.crypto.aio' has no attribute {name}") diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/aio/_client.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/aio/_client.py deleted file mode 100644 index 9f7e370e983f..000000000000 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/crypto/aio/_client.py +++ /dev/null @@ -1,503 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from datetime import datetime -import logging -from typing import Any, cast, Dict, Optional, Union - -from azure.core.credentials_async import AsyncTokenCredential -from azure.core.exceptions import HttpResponseError -from azure.core.tracing.decorator_async import distributed_trace_async - -from .. import ( - DecryptResult, - EncryptionAlgorithm, - EncryptResult, - KeyWrapAlgorithm, - SignatureAlgorithm, - SignResult, - VerifyResult, - UnwrapResult, - WrapResult, -) -from .._client import _validate_arguments -from .._key_validity import raise_if_time_invalid -from .._providers import get_local_cryptography_provider, NoLocalCryptography -from ... import KeyOperation -from ..._models import JsonWebKey, KeyVaultKey -from ..._shared import AsyncKeyVaultClientBase, KeyVaultResourceId, parse_key_vault_id - -_LOGGER = logging.getLogger(__name__) - - -class CryptographyClient(AsyncKeyVaultClientBase): - """Performs cryptographic operations using Azure Key Vault keys. - - This client will perform operations locally when it's intialized with the necessary key material or is able to get - that material from Key Vault. When the required key material is unavailable, cryptographic operations are performed - by the Key Vault service. - - :param key: Either a azure.keyvault.keys.KeyVaultKey instance as returned by - :func:`~azure.keyvault.keys.aio.KeyClient.get_key`, or a string. - If a string, the value must be the identifier of an Azure Key Vault key. Including a version is recommended. - :type key: str or azure.keyvault.keys.KeyVaultKey - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity.aio` - :type credential: ~azure.core.credentials_async.AsyncTokenCredential - - :keyword api_version: Version of the service API to use. Defaults to the most recent. - :paramtype api_version: ~azure.keyvault.keys.ApiVersion or str - :keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key - Vault or Managed HSM domain. Defaults to True. - - .. literalinclude:: ../tests/test_examples_crypto_async.py - :start-after: [START create_client] - :end-before: [END create_client] - :caption: Create a CryptographyClient - :language: python - :dedent: 8 - """ - - # pylint:disable=protected-access - - def __init__(self, key: Union[KeyVaultKey, str], credential: AsyncTokenCredential, **kwargs: Any) -> None: - self._jwk = kwargs.pop("_jwk", False) - self._not_before: Optional[datetime] = None - self._expires_on: Optional[datetime] = None - self._key_id: Optional[KeyVaultResourceId] = None - - if isinstance(key, KeyVaultKey): - self._key: Union[JsonWebKey, KeyVaultKey, str, None] = key.key - self._key_id = parse_key_vault_id(key.id) - if key.properties._attributes: - self._not_before = key.properties.not_before - self._expires_on = key.properties.expires_on - elif isinstance(key, str): - self._key = None - self._key_id = parse_key_vault_id(key) - if self._key_id.version is None: - self._key_id.version = "" # to avoid an error and get the latest version when getting the key - self._keys_get_forbidden = False - elif self._jwk: - self._key = key - else: - raise ValueError("'key' must be a KeyVaultKey instance or a key ID string") - - if self._jwk: - try: - self._local_provider = get_local_cryptography_provider(cast(JsonWebKey, self._key)) - self._initialized = True - except Exception as ex: - raise ValueError("The provided jwk is not valid for local cryptography") from ex - else: - self._local_provider = NoLocalCryptography() - self._initialized = False - - self._vault_url = None if (self._jwk or self._key_id is None) else self._key_id.vault_url # type: ignore - super().__init__(vault_url=self._vault_url or "vault_url", credential=credential, **kwargs) - - @property - def key_id(self) -> Optional[str]: - """The full identifier of the client's key. - - This property may be None when a client is constructed with :func:`from_jwk`. - - :returns: The full identifier of the client's key. - :rtype: str or None - """ - if not self._jwk: - return self._key_id.source_id if self._key_id else None - return cast(JsonWebKey, self._key).kid # type: ignore[attr-defined] - - @property - def vault_url(self) -> Optional[str]: # type: ignore - """The base vault URL of the client's key. - - This property may be None when a client is constructed with :func:`from_jwk`. - - :returns: The base vault URL of the client's key. - :rtype: str or None - """ - return self._vault_url - - @classmethod - def from_jwk(cls, jwk: Union[JsonWebKey, Dict[str, Any]]) -> "CryptographyClient": - """Creates a client that can only perform cryptographic operations locally. - - :param jwk: the key's cryptographic material, as a JsonWebKey or dictionary. - :type jwk: JsonWebKey or Dict[str, Any] - - :returns: A client that can only perform local cryptographic operations. - :rtype: CryptographyClient - """ - if not isinstance(jwk, JsonWebKey): - jwk = JsonWebKey(**jwk) - return cls(jwk, object(), _jwk=True) # type: ignore - - @distributed_trace_async - async def _initialize(self, **kwargs: Any) -> None: - if self._initialized: - return - - # try to get the key material, if we don't have it and aren't forbidden to do so - if not (self._key or self._keys_get_forbidden): - try: - key_bundle = await self._client.get_key( - self._key_id.name if self._key_id else None, - self._key_id.version if self._key_id else None, - **kwargs - ) - key = KeyVaultKey._from_key_bundle(key_bundle) - self._key = key.key - self._key_id = parse_key_vault_id(key.id) # update the key ID in case we didn't have the version before - except HttpResponseError as ex: - # if we got a 403, we don't have keys/get permission and won't try to get the key again - # (other errors may be transient) - self._keys_get_forbidden = ex.status_code == 403 - - # if we have the key material, create a local crypto provider with it - if self._key: - self._local_provider = get_local_cryptography_provider(cast(JsonWebKey, self._key)) - self._initialized = True - else: - # try to get the key again next time unless we know we're forbidden to do so - self._initialized = self._keys_get_forbidden - - @distributed_trace_async - async def encrypt( - self, - algorithm: EncryptionAlgorithm, - plaintext: bytes, - *, - iv: Optional[bytes] = None, - additional_authenticated_data: Optional[bytes] = None, - **kwargs: Any, - ) -> EncryptResult: - """Encrypt bytes using the client's key. - - Requires the keys/encrypt permission. This method encrypts only a single block of data, whose size depends on - the key and encryption algorithm. - - :param algorithm: Encryption algorithm to use - :type algorithm: ~azure.keyvault.keys.crypto.EncryptionAlgorithm - :param bytes plaintext: Bytes to encrypt - - :keyword iv: Initialization vector. Required for only AES-CBC(PAD) encryption. If you pass your own IV, - make sure you use a cryptographically random, non-repeating IV. If omitted, an attempt will be made to - generate an IV via `os.urandom `_ for local - cryptography; for remote cryptography, Key Vault will generate an IV. - :paramtype iv: bytes or None - :keyword additional_authenticated_data: Optional data that is authenticated but not encrypted. For use - with AES-GCM encryption. - :paramtype additional_authenticated_data: bytes or None - - :returns: The result of the encryption operation. - :rtype: ~azure.keyvault.keys.crypto.EncryptResult - - :raises ValueError: if parameters that are incompatible with the specified algorithm are provided, or if - generating an IV fails on the current platform. - - .. literalinclude:: ../tests/test_examples_crypto_async.py - :start-after: [START encrypt] - :end-before: [END encrypt] - :caption: Encrypt bytes - :language: python - :dedent: 8 - """ - _validate_arguments( - operation=KeyOperation.encrypt, algorithm=algorithm, iv=iv, aad=additional_authenticated_data - ) - await self._initialize(**kwargs) - - if self._local_provider.supports(KeyOperation.encrypt, algorithm): - raise_if_time_invalid(self._not_before, self._expires_on) - try: - return self._local_provider.encrypt(algorithm, plaintext, iv=iv) - except Exception as ex: # pylint:disable=broad-except - _LOGGER.warning("Local encrypt operation failed: %s", ex, exc_info=_LOGGER.isEnabledFor(logging.DEBUG)) - if self._jwk: - raise - elif self._jwk: - raise NotImplementedError( - f'This key does not support the "{KeyOperation.encrypt}" operation with algorithm "{algorithm}"' - ) - - operation_result = await self._client.encrypt( - key_name=self._key_id.name if self._key_id else None, - key_version=self._key_id.version if self._key_id else None, - parameters=self._models.KeyOperationsParameters( - algorithm=algorithm, value=plaintext, iv=iv, aad=additional_authenticated_data - ), - **kwargs - ) - - result_iv = operation_result.iv if hasattr(operation_result, "iv") else None - result_tag = operation_result.authentication_tag if hasattr(operation_result, "authentication_tag") else None - result_aad = ( - operation_result.additional_authenticated_data - if hasattr(operation_result, "additional_authenticated_data") - else None - ) - - return EncryptResult( - key_id=self.key_id, - algorithm=algorithm, - ciphertext=operation_result.result, - iv=result_iv, - authentication_tag=result_tag, - additional_authenticated_data=result_aad, - ) - - @distributed_trace_async - async def decrypt( - self, - algorithm: EncryptionAlgorithm, - ciphertext: bytes, - *, - iv: Optional[bytes] = None, - authentication_tag: Optional[bytes] = None, - additional_authenticated_data: Optional[bytes] = None, - **kwargs: Any, - ) -> DecryptResult: - """Decrypt a single block of encrypted data using the client's key. - - Requires the keys/decrypt permission. This method decrypts only a single block of data, whose size depends on - the key and encryption algorithm. - - :param algorithm: Encryption algorithm to use - :type algorithm: ~azure.keyvault.keys.crypto.EncryptionAlgorithm - :param bytes ciphertext: Encrypted bytes to decrypt. Microsoft recommends you not use CBC without first ensuring - the integrity of the ciphertext using, for example, an HMAC. See - https://learn.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode for more information. - - :keyword iv: The initialization vector used during encryption. Required for AES decryption. - :paramtype iv: bytes or None - :keyword authentication_tag: The authentication tag generated during encryption. Required for only AES-GCM - decryption. - :paramtype authentication_tag: bytes or None - :keyword additional_authenticated_data: Optional data that is authenticated but not encrypted. For use - with AES-GCM decryption. - :paramtype additional_authenticated_data: bytes or None - - :returns: The result of the decryption operation. - :rtype: ~azure.keyvault.keys.crypto.DecryptResult - - :raises ValueError: If parameters that are incompatible with the specified algorithm are provided. - - .. literalinclude:: ../tests/test_examples_crypto_async.py - :start-after: [START decrypt] - :end-before: [END decrypt] - :caption: Decrypt bytes - :language: python - :dedent: 8 - """ - _validate_arguments( - operation=KeyOperation.decrypt, - algorithm=algorithm, - iv=iv, - tag=authentication_tag, - aad=additional_authenticated_data, - ) - await self._initialize(**kwargs) - - if self._local_provider.supports(KeyOperation.decrypt, algorithm): - try: - return self._local_provider.decrypt(algorithm, ciphertext, iv=iv) - except Exception as ex: # pylint:disable=broad-except - _LOGGER.warning("Local decrypt operation failed: %s", ex, exc_info=_LOGGER.isEnabledFor(logging.DEBUG)) - if self._jwk: - raise - elif self._jwk: - raise NotImplementedError( - f'This key does not support the "{KeyOperation.decrypt}" operation with algorithm "{algorithm}"' - ) - - operation_result = await self._client.decrypt( - key_name=self._key_id.name if self._key_id else None, - key_version=self._key_id.version if self._key_id else None, - parameters=self._models.KeyOperationsParameters( - algorithm=algorithm, value=ciphertext, iv=iv, tag=authentication_tag, aad=additional_authenticated_data - ), - **kwargs - ) - - return DecryptResult(key_id=self.key_id, algorithm=algorithm, plaintext=operation_result.result) - - @distributed_trace_async - async def wrap_key(self, algorithm: KeyWrapAlgorithm, key: bytes, **kwargs: Any) -> WrapResult: - """Wrap a key with the client's key. - - Requires the keys/wrapKey permission. - - :param algorithm: wrapping algorithm to use - :type algorithm: ~azure.keyvault.keys.crypto.KeyWrapAlgorithm - :param bytes key: key to wrap - - :returns: The result of the wrapping operation. - :rtype: ~azure.keyvault.keys.crypto.WrapResult - - .. literalinclude:: ../tests/test_examples_crypto_async.py - :start-after: [START wrap_key] - :end-before: [END wrap_key] - :caption: Wrap a key - :language: python - :dedent: 8 - """ - await self._initialize(**kwargs) - if self._local_provider.supports(KeyOperation.wrap_key, algorithm): - raise_if_time_invalid(self._not_before, self._expires_on) - try: - return self._local_provider.wrap_key(algorithm, key) - except Exception as ex: # pylint:disable=broad-except - _LOGGER.warning("Local wrap operation failed: %s", ex, exc_info=_LOGGER.isEnabledFor(logging.DEBUG)) - if self._jwk: - raise - elif self._jwk: - raise NotImplementedError( - f'This key does not support the "{KeyOperation.wrap_key}" operation with algorithm "{algorithm}"' - ) - - operation_result = await self._client.wrap_key( - key_name=self._key_id.name if self._key_id else None, - key_version=self._key_id.version if self._key_id else None, - parameters=self._models.KeyOperationsParameters(algorithm=algorithm, value=key), - **kwargs - ) - - return WrapResult(key_id=self.key_id, algorithm=algorithm, encrypted_key=operation_result.result) - - @distributed_trace_async - async def unwrap_key(self, algorithm: KeyWrapAlgorithm, encrypted_key: bytes, **kwargs: Any) -> UnwrapResult: - """Unwrap a key previously wrapped with the client's key. - - Requires the keys/unwrapKey permission. - - :param algorithm: wrapping algorithm to use - :type algorithm: ~azure.keyvault.keys.crypto.KeyWrapAlgorithm - :param bytes encrypted_key: the wrapped key - - :returns: The result of the unwrapping operation. - :rtype: ~azure.keyvault.keys.crypto.UnwrapResult - - .. literalinclude:: ../tests/test_examples_crypto_async.py - :start-after: [START unwrap_key] - :end-before: [END unwrap_key] - :caption: Unwrap a key - :language: python - :dedent: 8 - """ - await self._initialize(**kwargs) - if self._local_provider.supports(KeyOperation.unwrap_key, algorithm): - try: - return self._local_provider.unwrap_key(algorithm, encrypted_key) - except Exception as ex: # pylint:disable=broad-except - _LOGGER.warning("Local unwrap operation failed: %s", ex, exc_info=_LOGGER.isEnabledFor(logging.DEBUG)) - if self._jwk: - raise - elif self._jwk: - raise NotImplementedError( - f'This key does not support the "{KeyOperation.unwrap_key}" operation with algorithm "{algorithm}"' - ) - - operation_result = await self._client.unwrap_key( - key_name=self._key_id.name if self._key_id else None, - key_version=self._key_id.version if self._key_id else None, - parameters=self._models.KeyOperationsParameters(algorithm=algorithm, value=encrypted_key), - **kwargs - ) - - return UnwrapResult(key_id=self.key_id, algorithm=algorithm, key=operation_result.result) - - @distributed_trace_async - async def sign(self, algorithm: SignatureAlgorithm, digest: bytes, **kwargs: Any) -> SignResult: - """Create a signature from a digest using the client's key. - - Requires the keys/sign permission. - - :param algorithm: signing algorithm - :type algorithm: ~azure.keyvault.keys.crypto.SignatureAlgorithm - :param bytes digest: hashed bytes to sign - - :returns: The result of the signing operation. - :rtype: ~azure.keyvault.keys.crypto.SignResult - - .. literalinclude:: ../tests/test_examples_crypto_async.py - :start-after: [START sign] - :end-before: [END sign] - :caption: Sign bytes - :language: python - :dedent: 8 - """ - await self._initialize(**kwargs) - if self._local_provider.supports(KeyOperation.sign, algorithm): - raise_if_time_invalid(self._not_before, self._expires_on) - try: - return self._local_provider.sign(algorithm, digest) - except Exception as ex: # pylint:disable=broad-except - _LOGGER.warning("Local sign operation failed: %s", ex, exc_info=_LOGGER.isEnabledFor(logging.DEBUG)) - if self._jwk: - raise - elif self._jwk: - raise NotImplementedError( - f'This key does not support the "{KeyOperation.sign}" operation with algorithm "{algorithm}"' - ) - - operation_result = await self._client.sign( - key_name=self._key_id.name if self._key_id else None, - key_version=self._key_id.version if self._key_id else None, - parameters=self._models.KeySignParameters(algorithm=algorithm, value=digest), - **kwargs - ) - - return SignResult(key_id=self.key_id, algorithm=algorithm, signature=operation_result.result) - - @distributed_trace_async - async def verify( - self, algorithm: SignatureAlgorithm, digest: bytes, signature: bytes, **kwargs: Any - ) -> VerifyResult: - """Verify a signature using the client's key. - - Requires the keys/verify permission. - - :param algorithm: verification algorithm - :type algorithm: ~azure.keyvault.keys.crypto.SignatureAlgorithm - :param bytes digest: Pre-hashed digest corresponding to **signature**. The hash algorithm used must be - compatible with ``algorithm``. - :param bytes signature: signature to verify - - :returns: The result of the verifying operation. - :rtype: ~azure.keyvault.keys.crypto.VerifyResult - - .. literalinclude:: ../tests/test_examples_crypto_async.py - :start-after: [START verify] - :end-before: [END verify] - :caption: Verify a signature - :language: python - :dedent: 8 - """ - await self._initialize(**kwargs) - if self._local_provider.supports(KeyOperation.verify, algorithm): - try: - return self._local_provider.verify(algorithm, digest, signature) - except Exception as ex: # pylint:disable=broad-except - _LOGGER.warning("Local verify operation failed: %s", ex, exc_info=_LOGGER.isEnabledFor(logging.DEBUG)) - if self._jwk: - raise - elif self._jwk: - raise NotImplementedError( - f'This key does not support the "{KeyOperation.verify}" operation with algorithm "{algorithm}"' - ) - - operation_result = await self._client.verify( - key_name=self._key_id.name if self._key_id else None, - key_version=self._key_id.version if self._key_id else None, - parameters=self._models.KeyVerifyParameters(algorithm=algorithm, digest=digest, signature=signature), - **kwargs - ) - - return VerifyResult(key_id=self.key_id, algorithm=algorithm, is_valid=operation_result.value) - - async def __aenter__(self) -> "CryptographyClient": - await self._client.__aenter__() - return self diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/__init__.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/__init__.py similarity index 98% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/__init__.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/__init__.py index 9cc503f26c60..20a824d9b566 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/__init__.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/__init__.py @@ -17,6 +17,7 @@ BackupKeyResult, DeletedKeyBundle, DeletedKeyItem, + Error, GetRandomBytesRequest, JsonWebKey, KeyAttestation, @@ -36,7 +37,6 @@ KeySignParameters, KeyUpdateParameters, KeyVaultError, - KeyVaultErrorError, KeyVerifyParameters, KeyVerifyResult, LifetimeActions, @@ -63,6 +63,7 @@ "BackupKeyResult", "DeletedKeyBundle", "DeletedKeyItem", + "Error", "GetRandomBytesRequest", "JsonWebKey", "KeyAttestation", @@ -82,7 +83,6 @@ "KeySignParameters", "KeyUpdateParameters", "KeyVaultError", - "KeyVaultErrorError", "KeyVerifyParameters", "KeyVerifyResult", "LifetimeActions", diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/_enums.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/_enums.py similarity index 76% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/_enums.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/_enums.py index 2a0d4678bf68..bbd39559553f 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/_enums.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/_enums.py @@ -72,20 +72,21 @@ class JsonWebKeyEncryptionAlgorithm(str, Enum, metaclass=CaseInsensitiveEnumMeta RSA_OAEP = "RSA-OAEP" """[Not recommended] RSAES using Optimal Asymmetric Encryption Padding (OAEP), as described in - https://tools.ietf.org/html/rfc3447, with the default parameters specified by RFC 3447 in - Section A.2.1. Those default parameters are using a hash function of SHA-1 and a mask - generation function of MGF1 with SHA-1. Microsoft recommends using RSA_OAEP_256 or stronger - algorithms for enhanced security. Microsoft does *not* recommend RSA_OAEP, which is included - solely for backwards compatibility. RSA_OAEP utilizes SHA1, which has known collision problems.""" + `https://tools.ietf.org/html/rfc3447 `_, with the default + parameters specified by RFC 3447 in Section A.2.1. Those default parameters are using a hash + function of SHA-1 and a mask generation function of MGF1 with SHA-1. Microsoft recommends using + RSA_OAEP_256 or stronger algorithms for enhanced security. Microsoft does *not* recommend + RSA_OAEP, which is included solely for backwards compatibility. RSA_OAEP utilizes SHA1, which + has known collision problems.""" RSA_OAEP256 = "RSA-OAEP-256" """RSAES using Optimal Asymmetric Encryption Padding with a hash function of SHA-256 and a mask generation function of MGF1 with SHA-256.""" RSA1_5 = "RSA1_5" """[Not recommended] RSAES-PKCS1-V1_5 key encryption, as described in - https://tools.ietf.org/html/rfc3447. Microsoft recommends using RSA_OAEP_256 or stronger - algorithms for enhanced security. Microsoft does *not* recommend RSA_1_5, which is included - solely for backwards compatibility. Cryptographic standards no longer consider RSA with the - PKCS#1 v1.5 padding scheme secure for encryption.""" + `https://tools.ietf.org/html/rfc3447 `_. Microsoft + recommends using RSA_OAEP_256 or stronger algorithms for enhanced security. Microsoft does + *not* recommend RSA_1_5, which is included solely for backwards compatibility. Cryptographic + standards no longer consider RSA with the PKCS#1 v1.5 padding scheme secure for encryption.""" A128_GCM = "A128GCM" """128-bit AES-GCM.""" A192_GCM = "A192GCM" @@ -144,40 +145,51 @@ class JsonWebKeySignatureAlgorithm(str, Enum, metaclass=CaseInsensitiveEnumMeta) PS256 = "PS256" """RSASSA-PSS using SHA-256 and MGF1 with SHA-256, as described in - https://tools.ietf.org/html/rfc7518""" + `https://tools.ietf.org/html/rfc7518 `_""" PS384 = "PS384" """RSASSA-PSS using SHA-384 and MGF1 with SHA-384, as described in - https://tools.ietf.org/html/rfc7518""" + `https://tools.ietf.org/html/rfc7518 `_""" PS512 = "PS512" """RSASSA-PSS using SHA-512 and MGF1 with SHA-512, as described in - https://tools.ietf.org/html/rfc7518""" + `https://tools.ietf.org/html/rfc7518 `_""" RS256 = "RS256" - """RSASSA-PKCS1-v1_5 using SHA-256, as described in https://tools.ietf.org/html/rfc7518""" + """RSASSA-PKCS1-v1_5 using SHA-256, as described in `https://tools.ietf.org/html/rfc7518 + `_""" RS384 = "RS384" - """RSASSA-PKCS1-v1_5 using SHA-384, as described in https://tools.ietf.org/html/rfc7518""" + """RSASSA-PKCS1-v1_5 using SHA-384, as described in `https://tools.ietf.org/html/rfc7518 + `_""" RS512 = "RS512" - """RSASSA-PKCS1-v1_5 using SHA-512, as described in https://tools.ietf.org/html/rfc7518""" + """RSASSA-PKCS1-v1_5 using SHA-512, as described in `https://tools.ietf.org/html/rfc7518 + `_""" HS256 = "HS256" - """HMAC using SHA-256, as described in https://tools.ietf.org/html/rfc7518""" + """HMAC using SHA-256, as described in `https://tools.ietf.org/html/rfc7518 + `_""" HS384 = "HS384" - """HMAC using SHA-384, as described in https://tools.ietf.org/html/rfc7518""" + """HMAC using SHA-384, as described in `https://tools.ietf.org/html/rfc7518 + `_""" HS512 = "HS512" - """HMAC using SHA-512, as described in https://tools.ietf.org/html/rfc7518""" + """HMAC using SHA-512, as described in `https://tools.ietf.org/html/rfc7518 + `_""" RSNULL = "RSNULL" """Reserved""" ES256 = "ES256" - """ECDSA using P-256 and SHA-256, as described in https://tools.ietf.org/html/rfc7518.""" + """ECDSA using P-256 and SHA-256, as described in `https://tools.ietf.org/html/rfc7518 + `_.""" ES384 = "ES384" - """ECDSA using P-384 and SHA-384, as described in https://tools.ietf.org/html/rfc7518""" + """ECDSA using P-384 and SHA-384, as described in `https://tools.ietf.org/html/rfc7518 + `_""" ES512 = "ES512" - """ECDSA using P-521 and SHA-512, as described in https://tools.ietf.org/html/rfc7518""" + """ECDSA using P-521 and SHA-512, as described in `https://tools.ietf.org/html/rfc7518 + `_""" ES256_K = "ES256K" - """ECDSA using P-256K and SHA-256, as described in https://tools.ietf.org/html/rfc7518""" + """ECDSA using P-256K and SHA-256, as described in `https://tools.ietf.org/html/rfc7518 + `_""" class JsonWebKeyType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """JsonWebKey Key Type (kty), as defined in - https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40. + `https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40 + `_. """ EC = "EC" @@ -185,7 +197,7 @@ class JsonWebKeyType(str, Enum, metaclass=CaseInsensitiveEnumMeta): EC_HSM = "EC-HSM" """Elliptic Curve with a private key which is stored in the HSM.""" RSA = "RSA" - """RSA (https://tools.ietf.org/html/rfc3447)""" + """RSA (`https://tools.ietf.org/html/rfc3447 `_)""" RSA_HSM = "RSA-HSM" """RSA with a private key which is stored in the HSM.""" OCT = "oct" diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/_models.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/_models.py similarity index 76% rename from sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/_models.py rename to sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/_models.py index aa146ef143b8..85ff18e40928 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/_generated/models/_models.py +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/_models.py @@ -21,8 +21,6 @@ class BackupKeyResult(_model_base.Model): """The backup key result, containing the backup blob. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar value: The backup blob containing the backed up key. :vartype value: bytes """ @@ -34,19 +32,17 @@ class BackupKeyResult(_model_base.Model): class DeletedKeyBundle(_model_base.Model): """A DeletedKeyBundle consisting of a WebKey plus its Attributes and deletion info. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar key: The Json web key. - :vartype key: ~azure.keyvault.keys._generated.models.JsonWebKey + :vartype key: ~azure.keyvault.keys.models.JsonWebKey :ivar attributes: The key management attributes. - :vartype attributes: ~azure.keyvault.keys._generated.models.KeyAttributes + :vartype attributes: ~azure.keyvault.keys.models.KeyAttributes :ivar tags: Application specific metadata in the form of key-value pairs. :vartype tags: dict[str, str] :ivar managed: True if the key's lifetime is managed by key vault. If this is a key backing a certificate, then managed will be true. :vartype managed: bool :ivar release_policy: The policy rules under which the key can be exported. - :vartype release_policy: ~azure.keyvault.keys._generated.models.KeyReleasePolicy + :vartype release_policy: ~azure.keyvault.keys.models.KeyReleasePolicy :ivar recovery_id: The url of the recovery object, used to identify and recover the deleted key. :vartype recovery_id: str @@ -56,18 +52,24 @@ class DeletedKeyBundle(_model_base.Model): :vartype deleted_date: ~datetime.datetime """ - key: Optional["_models.JsonWebKey"] = rest_field() + key: Optional["_models.JsonWebKey"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The Json web key.""" - attributes: Optional["_models.KeyAttributes"] = rest_field() + attributes: Optional["_models.KeyAttributes"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The key management attributes.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" managed: Optional[bool] = rest_field(visibility=["read"]) """True if the key's lifetime is managed by key vault. If this is a key backing a certificate, then managed will be true.""" - release_policy: Optional["_models.KeyReleasePolicy"] = rest_field() + release_policy: Optional["_models.KeyReleasePolicy"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The policy rules under which the key can be exported.""" - recovery_id: Optional[str] = rest_field(name="recoveryId") + recovery_id: Optional[str] = rest_field( + name="recoveryId", visibility=["read", "create", "update", "delete", "query"] + ) """The url of the recovery object, used to identify and recover the deleted key.""" scheduled_purge_date: Optional[datetime.datetime] = rest_field( name="scheduledPurgeDate", visibility=["read"], format="unix-timestamp" @@ -103,12 +105,10 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class DeletedKeyItem(_model_base.Model): """The deleted key item containing the deleted key metadata and information about deletion. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar kid: Key identifier. :vartype kid: str :ivar attributes: The key management attributes. - :vartype attributes: ~azure.keyvault.keys._generated.models.KeyAttributes + :vartype attributes: ~azure.keyvault.keys.models.KeyAttributes :ivar tags: Application specific metadata in the form of key-value pairs. :vartype tags: dict[str, str] :ivar managed: True if the key's lifetime is managed by key vault. If this is a key backing a @@ -123,16 +123,20 @@ class DeletedKeyItem(_model_base.Model): :vartype deleted_date: ~datetime.datetime """ - kid: Optional[str] = rest_field() + kid: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Key identifier.""" - attributes: Optional["_models.KeyAttributes"] = rest_field() + attributes: Optional["_models.KeyAttributes"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The key management attributes.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" managed: Optional[bool] = rest_field(visibility=["read"]) """True if the key's lifetime is managed by key vault. If this is a key backing a certificate, then managed will be true.""" - recovery_id: Optional[str] = rest_field(name="recoveryId") + recovery_id: Optional[str] = rest_field( + name="recoveryId", visibility=["read", "create", "update", "delete", "query"] + ) """The url of the recovery object, used to identify and recover the deleted key.""" scheduled_purge_date: Optional[datetime.datetime] = rest_field( name="scheduledPurgeDate", visibility=["read"], format="unix-timestamp" @@ -164,16 +168,33 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) +class Error(_model_base.Model): + """The key vault server error. + + :ivar code: The error code. + :vartype code: str + :ivar message: The error message. + :vartype message: str + :ivar inner_error: The key vault server error. + :vartype inner_error: ~azure.keyvault.keys.models.Error + """ + + code: Optional[str] = rest_field(visibility=["read"]) + """The error code.""" + message: Optional[str] = rest_field(visibility=["read"]) + """The error message.""" + inner_error: Optional["_models.Error"] = rest_field(name="innererror", visibility=["read"]) + """The key vault server error.""" + + class GetRandomBytesRequest(_model_base.Model): """The get random bytes request object. - All required parameters must be populated in order to send to server. - :ivar count: The requested number of random bytes. Required. :vartype count: int """ - count: int = rest_field() + count: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The requested number of random bytes. Required.""" @overload @@ -195,14 +216,16 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class JsonWebKey(_model_base.Model): - """As of http://tools.ietf.org/html/draft-ietf-jose-json-web-key-18. + """As of `http://tools.ietf.org/html/draft-ietf-jose-json-web-key-18 + `_. :ivar kid: Key identifier. :vartype kid: str :ivar kty: JsonWebKey Key Type (kty), as defined in - https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40. Known values are: "EC", + `https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40 + `_. Known values are: "EC", "EC-HSM", "RSA", "RSA-HSM", "oct", and "oct-HSM". - :vartype kty: str or ~azure.keyvault.keys._generated.models.JsonWebKeyType + :vartype kty: str or ~azure.keyvault.keys.models.JsonWebKeyType :ivar key_ops: Json web key operations. For more information on possible key operations, see JsonWebKeyOperation. :vartype key_ops: list[str] @@ -228,48 +251,55 @@ class JsonWebKey(_model_base.Model): :vartype t: bytes :ivar crv: Elliptic curve name. For valid values, see JsonWebKeyCurveName. Known values are: "P-256", "P-384", "P-521", and "P-256K". - :vartype crv: str or ~azure.keyvault.keys._generated.models.JsonWebKeyCurveName + :vartype crv: str or ~azure.keyvault.keys.models.JsonWebKeyCurveName :ivar x: X component of an EC public key. :vartype x: bytes :ivar y: Y component of an EC public key. :vartype y: bytes """ - kid: Optional[str] = rest_field() + kid: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Key identifier.""" - kty: Optional[Union[str, "_models.JsonWebKeyType"]] = rest_field() + kty: Optional[Union[str, "_models.JsonWebKeyType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """JsonWebKey Key Type (kty), as defined in - https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40. Known values are: \"EC\", - \"EC-HSM\", \"RSA\", \"RSA-HSM\", \"oct\", and \"oct-HSM\".""" - key_ops: Optional[List[str]] = rest_field() + `https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40 + `_. Known values are: + \"EC\", \"EC-HSM\", \"RSA\", \"RSA-HSM\", \"oct\", and \"oct-HSM\".""" + key_ops: Optional[List[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Json web key operations. For more information on possible key operations, see JsonWebKeyOperation.""" - n: Optional[bytes] = rest_field(format="base64url") + n: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """RSA modulus.""" - e: Optional[bytes] = rest_field(format="base64url") + e: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """RSA public exponent.""" - d: Optional[bytes] = rest_field(format="base64url") + d: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """RSA private exponent, or the D component of an EC private key.""" - dp: Optional[bytes] = rest_field(format="base64url") + dp: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """RSA private key parameter.""" - dq: Optional[bytes] = rest_field(format="base64url") + dq: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """RSA private key parameter.""" - qi: Optional[bytes] = rest_field(format="base64url") + qi: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """RSA private key parameter.""" - p: Optional[bytes] = rest_field(format="base64url") + p: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """RSA secret prime.""" - q: Optional[bytes] = rest_field(format="base64url") + q: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """RSA secret prime, with p < q.""" - k: Optional[bytes] = rest_field(format="base64url") + k: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """Symmetric key.""" - t: Optional[bytes] = rest_field(name="key_hsm", format="base64url") + t: Optional[bytes] = rest_field( + name="key_hsm", visibility=["read", "create", "update", "delete", "query"], format="base64url" + ) """Protected Key, used with 'Bring Your Own Key'.""" - crv: Optional[Union[str, "_models.JsonWebKeyCurveName"]] = rest_field() + crv: Optional[Union[str, "_models.JsonWebKeyCurveName"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """Elliptic curve name. For valid values, see JsonWebKeyCurveName. Known values are: \"P-256\", \"P-384\", \"P-521\", and \"P-256K\".""" - x: Optional[bytes] = rest_field(format="base64url") + x: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """X component of an EC public key.""" - y: Optional[bytes] = rest_field(format="base64url") + y: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """Y component of an EC public key.""" @overload @@ -321,15 +351,21 @@ class KeyAttestation(_model_base.Model): :vartype version: str """ - certificate_pem_file: Optional[bytes] = rest_field(name="certificatePemFile", format="base64url") + certificate_pem_file: Optional[bytes] = rest_field( + name="certificatePemFile", visibility=["read", "create", "update", "delete", "query"], format="base64url" + ) """A base64url-encoded string containing certificates in PEM format, used for attestation validation.""" - private_key_attestation: Optional[bytes] = rest_field(name="privateKeyAttestation", format="base64url") + private_key_attestation: Optional[bytes] = rest_field( + name="privateKeyAttestation", visibility=["read", "create", "update", "delete", "query"], format="base64url" + ) """The attestation blob bytes encoded as base64url string corresponding to a private key.""" - public_key_attestation: Optional[bytes] = rest_field(name="publicKeyAttestation", format="base64url") + public_key_attestation: Optional[bytes] = rest_field( + name="publicKeyAttestation", visibility=["read", "create", "update", "delete", "query"], format="base64url" + ) """The attestation blob bytes encoded as base64url string corresponding to a public key in case of asymmetric key.""" - version: Optional[str] = rest_field() + version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The version of the attestation.""" @overload @@ -356,8 +392,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeyAttributes(_model_base.Model): """The attributes of a key managed by the key vault service. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar enabled: Determines whether the object is enabled. :vartype enabled: bool :ivar not_before: Not before date in UTC. @@ -377,21 +411,25 @@ class KeyAttributes(_model_base.Model): values are: "Purgeable", "Recoverable+Purgeable", "Recoverable", "Recoverable+ProtectedSubscription", "CustomizedRecoverable+Purgeable", "CustomizedRecoverable", and "CustomizedRecoverable+ProtectedSubscription". - :vartype recovery_level: str or ~azure.keyvault.keys._generated.models.DeletionRecoveryLevel + :vartype recovery_level: str or ~azure.keyvault.keys.models.DeletionRecoveryLevel :ivar exportable: Indicates if the private key can be exported. Release policy must be provided when creating the first version of an exportable key. :vartype exportable: bool :ivar hsm_platform: The underlying HSM Platform. :vartype hsm_platform: str :ivar attestation: The key or key version attestation information. - :vartype attestation: ~azure.keyvault.keys._generated.models.KeyAttestation + :vartype attestation: ~azure.keyvault.keys.models.KeyAttestation """ - enabled: Optional[bool] = rest_field() + enabled: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Determines whether the object is enabled.""" - not_before: Optional[datetime.datetime] = rest_field(name="nbf", format="unix-timestamp") + not_before: Optional[datetime.datetime] = rest_field( + name="nbf", visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) """Not before date in UTC.""" - expires: Optional[datetime.datetime] = rest_field(name="exp", format="unix-timestamp") + expires: Optional[datetime.datetime] = rest_field( + name="exp", visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) """Expiry date in UTC.""" created: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") """Creation time in UTC.""" @@ -409,12 +447,12 @@ class KeyAttributes(_model_base.Model): \"Purgeable\", \"Recoverable+Purgeable\", \"Recoverable\", \"Recoverable+ProtectedSubscription\", \"CustomizedRecoverable+Purgeable\", \"CustomizedRecoverable\", and \"CustomizedRecoverable+ProtectedSubscription\".""" - exportable: Optional[bool] = rest_field() + exportable: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Indicates if the private key can be exported. Release policy must be provided when creating the first version of an exportable key.""" hsm_platform: Optional[str] = rest_field(name="hsmPlatform", visibility=["read"]) """The underlying HSM Platform.""" - attestation: Optional["_models.KeyAttestation"] = rest_field() + attestation: Optional["_models.KeyAttestation"] = rest_field(visibility=["read"]) """The key or key version attestation information.""" @overload @@ -425,7 +463,6 @@ def __init__( not_before: Optional[datetime.datetime] = None, expires: Optional[datetime.datetime] = None, exportable: Optional[bool] = None, - attestation: Optional["_models.KeyAttestation"] = None, ) -> None: ... @overload @@ -442,31 +479,33 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeyBundle(_model_base.Model): """A KeyBundle consisting of a WebKey plus its attributes. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar key: The Json web key. - :vartype key: ~azure.keyvault.keys._generated.models.JsonWebKey + :vartype key: ~azure.keyvault.keys.models.JsonWebKey :ivar attributes: The key management attributes. - :vartype attributes: ~azure.keyvault.keys._generated.models.KeyAttributes + :vartype attributes: ~azure.keyvault.keys.models.KeyAttributes :ivar tags: Application specific metadata in the form of key-value pairs. :vartype tags: dict[str, str] :ivar managed: True if the key's lifetime is managed by key vault. If this is a key backing a certificate, then managed will be true. :vartype managed: bool :ivar release_policy: The policy rules under which the key can be exported. - :vartype release_policy: ~azure.keyvault.keys._generated.models.KeyReleasePolicy + :vartype release_policy: ~azure.keyvault.keys.models.KeyReleasePolicy """ - key: Optional["_models.JsonWebKey"] = rest_field() + key: Optional["_models.JsonWebKey"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The Json web key.""" - attributes: Optional["_models.KeyAttributes"] = rest_field() + attributes: Optional["_models.KeyAttributes"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The key management attributes.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" managed: Optional[bool] = rest_field(visibility=["read"]) """True if the key's lifetime is managed by key vault. If this is a key backing a certificate, then managed will be true.""" - release_policy: Optional["_models.KeyReleasePolicy"] = rest_field() + release_policy: Optional["_models.KeyReleasePolicy"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The policy rules under which the key can be exported.""" @overload @@ -493,47 +532,53 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeyCreateParameters(_model_base.Model): """The key create parameters. - All required parameters must be populated in order to send to server. - :ivar kty: The type of key to create. For valid values, see JsonWebKeyType. Required. Known values are: "EC", "EC-HSM", "RSA", "RSA-HSM", "oct", and "oct-HSM". - :vartype kty: str or ~azure.keyvault.keys._generated.models.JsonWebKeyType + :vartype kty: str or ~azure.keyvault.keys.models.JsonWebKeyType :ivar key_size: The key size in bits. For example: 2048, 3072, or 4096 for RSA. :vartype key_size: int :ivar public_exponent: The public exponent for a RSA key. :vartype public_exponent: int :ivar key_ops: Json web key operations. For more information on possible key operations, see JsonWebKeyOperation. - :vartype key_ops: list[str or ~azure.keyvault.keys._generated.models.JsonWebKeyOperation] + :vartype key_ops: list[str or ~azure.keyvault.keys.models.JsonWebKeyOperation] :ivar key_attributes: The attributes of a key managed by the key vault service. - :vartype key_attributes: ~azure.keyvault.keys._generated.models.KeyAttributes + :vartype key_attributes: ~azure.keyvault.keys.models.KeyAttributes :ivar tags: Application specific metadata in the form of key-value pairs. :vartype tags: dict[str, str] :ivar curve: Elliptic curve name. For valid values, see JsonWebKeyCurveName. Known values are: "P-256", "P-384", "P-521", and "P-256K". - :vartype curve: str or ~azure.keyvault.keys._generated.models.JsonWebKeyCurveName + :vartype curve: str or ~azure.keyvault.keys.models.JsonWebKeyCurveName :ivar release_policy: The policy rules under which the key can be exported. - :vartype release_policy: ~azure.keyvault.keys._generated.models.KeyReleasePolicy + :vartype release_policy: ~azure.keyvault.keys.models.KeyReleasePolicy """ - kty: Union[str, "_models.JsonWebKeyType"] = rest_field() + kty: Union[str, "_models.JsonWebKeyType"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The type of key to create. For valid values, see JsonWebKeyType. Required. Known values are: \"EC\", \"EC-HSM\", \"RSA\", \"RSA-HSM\", \"oct\", and \"oct-HSM\".""" - key_size: Optional[int] = rest_field() + key_size: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The key size in bits. For example: 2048, 3072, or 4096 for RSA.""" - public_exponent: Optional[int] = rest_field() + public_exponent: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The public exponent for a RSA key.""" - key_ops: Optional[List[Union[str, "_models.JsonWebKeyOperation"]]] = rest_field() + key_ops: Optional[List[Union[str, "_models.JsonWebKeyOperation"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """Json web key operations. For more information on possible key operations, see JsonWebKeyOperation.""" - key_attributes: Optional["_models.KeyAttributes"] = rest_field(name="attributes") + key_attributes: Optional["_models.KeyAttributes"] = rest_field( + name="attributes", visibility=["read", "create", "update", "delete", "query"] + ) """The attributes of a key managed by the key vault service.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" - curve: Optional[Union[str, "_models.JsonWebKeyCurveName"]] = rest_field(name="crv") + curve: Optional[Union[str, "_models.JsonWebKeyCurveName"]] = rest_field( + name="crv", visibility=["read", "create", "update", "delete", "query"] + ) """Elliptic curve name. For valid values, see JsonWebKeyCurveName. Known values are: \"P-256\", \"P-384\", \"P-521\", and \"P-256K\".""" - release_policy: Optional["_models.KeyReleasePolicy"] = rest_field() + release_policy: Optional["_models.KeyReleasePolicy"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The policy rules under which the key can be exported.""" @overload @@ -564,29 +609,31 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeyImportParameters(_model_base.Model): """The key import parameters. - All required parameters must be populated in order to send to server. - :ivar hsm: Whether to import as a hardware key (HSM) or software key. :vartype hsm: bool :ivar key: The Json web key. Required. - :vartype key: ~azure.keyvault.keys._generated.models.JsonWebKey + :vartype key: ~azure.keyvault.keys.models.JsonWebKey :ivar key_attributes: The key management attributes. - :vartype key_attributes: ~azure.keyvault.keys._generated.models.KeyAttributes + :vartype key_attributes: ~azure.keyvault.keys.models.KeyAttributes :ivar tags: Application specific metadata in the form of key-value pairs. :vartype tags: dict[str, str] :ivar release_policy: The policy rules under which the key can be exported. - :vartype release_policy: ~azure.keyvault.keys._generated.models.KeyReleasePolicy + :vartype release_policy: ~azure.keyvault.keys.models.KeyReleasePolicy """ - hsm: Optional[bool] = rest_field(name="Hsm") + hsm: Optional[bool] = rest_field(name="Hsm", visibility=["read", "create", "update", "delete", "query"]) """Whether to import as a hardware key (HSM) or software key.""" - key: "_models.JsonWebKey" = rest_field() + key: "_models.JsonWebKey" = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The Json web key. Required.""" - key_attributes: Optional["_models.KeyAttributes"] = rest_field(name="attributes") + key_attributes: Optional["_models.KeyAttributes"] = rest_field( + name="attributes", visibility=["read", "create", "update", "delete", "query"] + ) """The key management attributes.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" - release_policy: Optional["_models.KeyReleasePolicy"] = rest_field() + release_policy: Optional["_models.KeyReleasePolicy"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The policy rules under which the key can be exported.""" @overload @@ -614,12 +661,10 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeyItem(_model_base.Model): """The key item containing key metadata. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar kid: Key identifier. :vartype kid: str :ivar attributes: The key management attributes. - :vartype attributes: ~azure.keyvault.keys._generated.models.KeyAttributes + :vartype attributes: ~azure.keyvault.keys.models.KeyAttributes :ivar tags: Application specific metadata in the form of key-value pairs. :vartype tags: dict[str, str] :ivar managed: True if the key's lifetime is managed by key vault. If this is a key backing a @@ -627,11 +672,13 @@ class KeyItem(_model_base.Model): :vartype managed: bool """ - kid: Optional[str] = rest_field() + kid: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Key identifier.""" - attributes: Optional["_models.KeyAttributes"] = rest_field() + attributes: Optional["_models.KeyAttributes"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The key management attributes.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" managed: Optional[bool] = rest_field(visibility=["read"]) """True if the key's lifetime is managed by key vault. If this is a key backing a certificate, @@ -660,8 +707,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeyOperationResult(_model_base.Model): """The key operation result. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar kid: Key identifier. :vartype kid: str :ivar result: The result of the operation. @@ -693,13 +738,11 @@ class KeyOperationResult(_model_base.Model): class KeyOperationsParameters(_model_base.Model): """The key operations parameters. - All required parameters must be populated in order to send to server. - :ivar algorithm: algorithm identifier. Required. Known values are: "RSA-OAEP", "RSA-OAEP-256", "RSA1_5", "A128GCM", "A192GCM", "A256GCM", "A128KW", "A192KW", "A256KW", "A128CBC", "A192CBC", "A256CBC", "A128CBCPAD", "A192CBCPAD", "A256CBCPAD", "CKM_AES_KEY_WRAP", and "CKM_AES_KEY_WRAP_PAD". - :vartype algorithm: str or ~azure.keyvault.keys._generated.models.JsonWebKeyEncryptionAlgorithm + :vartype algorithm: str or ~azure.keyvault.keys.models.JsonWebKeyEncryptionAlgorithm :ivar value: The value to operate on. Required. :vartype value: bytes :ivar iv: Cryptographically random, non-repeating initialization vector for symmetric @@ -712,19 +755,21 @@ class KeyOperationsParameters(_model_base.Model): :vartype tag: bytes """ - algorithm: Union[str, "_models.JsonWebKeyEncryptionAlgorithm"] = rest_field(name="alg") + algorithm: Union[str, "_models.JsonWebKeyEncryptionAlgorithm"] = rest_field( + name="alg", visibility=["read", "create", "update", "delete", "query"] + ) """algorithm identifier. Required. Known values are: \"RSA-OAEP\", \"RSA-OAEP-256\", \"RSA1_5\", \"A128GCM\", \"A192GCM\", \"A256GCM\", \"A128KW\", \"A192KW\", \"A256KW\", \"A128CBC\", \"A192CBC\", \"A256CBC\", \"A128CBCPAD\", \"A192CBCPAD\", \"A256CBCPAD\", \"CKM_AES_KEY_WRAP\", and \"CKM_AES_KEY_WRAP_PAD\".""" - value: bytes = rest_field(format="base64url") + value: bytes = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """The value to operate on. Required.""" - iv: Optional[bytes] = rest_field(format="base64url") + iv: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """Cryptographically random, non-repeating initialization vector for symmetric algorithms.""" - aad: Optional[bytes] = rest_field(format="base64url") + aad: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """Additional data to authenticate but not encrypt/decrypt when using authenticated crypto algorithms.""" - tag: Optional[bytes] = rest_field(format="base64url") + tag: Optional[bytes] = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """The tag to authenticate when performing decryption with an authenticated algorithm.""" @overload @@ -752,8 +797,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeyReleaseParameters(_model_base.Model): """The release key parameters. - All required parameters must be populated in order to send to server. - :ivar target_attestation_token: The attestation assertion for the target of the key release. Required. :vartype target_attestation_token: str @@ -761,14 +804,18 @@ class KeyReleaseParameters(_model_base.Model): :vartype nonce: str :ivar enc: The encryption algorithm to use to protected the exported key material. Known values are: "CKM_RSA_AES_KEY_WRAP", "RSA_AES_KEY_WRAP_256", and "RSA_AES_KEY_WRAP_384". - :vartype enc: str or ~azure.keyvault.keys._generated.models.KeyEncryptionAlgorithm + :vartype enc: str or ~azure.keyvault.keys.models.KeyEncryptionAlgorithm """ - target_attestation_token: str = rest_field(name="target") + target_attestation_token: str = rest_field( + name="target", visibility=["read", "create", "update", "delete", "query"] + ) """The attestation assertion for the target of the key release. Required.""" - nonce: Optional[str] = rest_field() + nonce: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """A client provided nonce for freshness.""" - enc: Optional[Union[str, "_models.KeyEncryptionAlgorithm"]] = rest_field() + enc: Optional[Union[str, "_models.KeyEncryptionAlgorithm"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The encryption algorithm to use to protected the exported key material. Known values are: \"CKM_RSA_AES_KEY_WRAP\", \"RSA_AES_KEY_WRAP_256\", and \"RSA_AES_KEY_WRAP_384\".""" @@ -805,12 +852,16 @@ class KeyReleasePolicy(_model_base.Model): :vartype encoded_policy: bytes """ - content_type: Optional[str] = rest_field(name="contentType") + content_type: Optional[str] = rest_field( + name="contentType", visibility=["read", "create", "update", "delete", "query"] + ) """Content type and version of key release policy.""" - immutable: Optional[bool] = rest_field() + immutable: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Defines the mutability state of the policy. Once marked immutable, this flag cannot be reset and the policy cannot be changed under any circumstances.""" - encoded_policy: Optional[bytes] = rest_field(name="data", format="base64url") + encoded_policy: Optional[bytes] = rest_field( + name="data", visibility=["read", "create", "update", "delete", "query"], format="base64url" + ) """Blob encoding the policy rules under which the key can be released. Blob must be base64 URL encoded.""" @@ -837,8 +888,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeyReleaseResult(_model_base.Model): """The release result, containing the released key. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar value: A signed object containing the released key. :vartype value: str """ @@ -850,13 +899,13 @@ class KeyReleaseResult(_model_base.Model): class KeyRestoreParameters(_model_base.Model): """The key restore parameters. - All required parameters must be populated in order to send to server. - :ivar key_bundle_backup: The backup blob associated with a key bundle. Required. :vartype key_bundle_backup: bytes """ - key_bundle_backup: bytes = rest_field(name="value", format="base64url") + key_bundle_backup: bytes = rest_field( + name="value", visibility=["read", "create", "update", "delete", "query"], format="base64url" + ) """The backup blob associated with a key bundle. Required.""" @overload @@ -880,25 +929,27 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeyRotationPolicy(_model_base.Model): """Management policy for a key. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar id: The key policy id. :vartype id: str :ivar lifetime_actions: Actions that will be performed by Key Vault over the lifetime of a key. For preview, lifetimeActions can only have two items at maximum: one for rotate, one for notify. Notification time would be default to 30 days before expiry and it is not configurable. - :vartype lifetime_actions: list[~azure.keyvault.keys._generated.models.LifetimeActions] + :vartype lifetime_actions: list[~azure.keyvault.keys.models.LifetimeActions] :ivar attributes: The key rotation policy attributes. - :vartype attributes: ~azure.keyvault.keys._generated.models.KeyRotationPolicyAttributes + :vartype attributes: ~azure.keyvault.keys.models.KeyRotationPolicyAttributes """ id: Optional[str] = rest_field(visibility=["read"]) """The key policy id.""" - lifetime_actions: Optional[List["_models.LifetimeActions"]] = rest_field(name="lifetimeActions") + lifetime_actions: Optional[List["_models.LifetimeActions"]] = rest_field( + name="lifetimeActions", visibility=["read", "create", "update", "delete", "query"] + ) """Actions that will be performed by Key Vault over the lifetime of a key. For preview, lifetimeActions can only have two items at maximum: one for rotate, one for notify. Notification time would be default to 30 days before expiry and it is not configurable.""" - attributes: Optional["_models.KeyRotationPolicyAttributes"] = rest_field() + attributes: Optional["_models.KeyRotationPolicyAttributes"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The key rotation policy attributes.""" @overload @@ -923,8 +974,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeyRotationPolicyAttributes(_model_base.Model): """The key rotation policy attributes. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar expiry_time: The expiryTime will be applied on the new key version. It should be at least 28 days. It will be in ISO 8601 Format. Examples: 90 days: P90D, 3 months: P3M, 48 hours: PT48H, 1 year and 10 days: P1Y10D. @@ -935,7 +984,9 @@ class KeyRotationPolicyAttributes(_model_base.Model): :vartype updated: ~datetime.datetime """ - expiry_time: Optional[str] = rest_field(name="expiryTime") + expiry_time: Optional[str] = rest_field( + name="expiryTime", visibility=["read", "create", "update", "delete", "query"] + ) """The expiryTime will be applied on the new key version. It should be at least 28 days. It will be in ISO 8601 Format. Examples: 90 days: P90D, 3 months: P3M, 48 hours: PT48H, 1 year and 10 days: P1Y10D.""" @@ -965,23 +1016,23 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeySignParameters(_model_base.Model): """The key operations parameters. - All required parameters must be populated in order to send to server. - :ivar algorithm: The signing/verification algorithm identifier. For more information on possible algorithm types, see JsonWebKeySignatureAlgorithm. Required. Known values are: "PS256", "PS384", "PS512", "RS256", "RS384", "RS512", "HS256", "HS384", "HS512", "RSNULL", "ES256", "ES384", "ES512", and "ES256K". - :vartype algorithm: str or ~azure.keyvault.keys._generated.models.JsonWebKeySignatureAlgorithm + :vartype algorithm: str or ~azure.keyvault.keys.models.JsonWebKeySignatureAlgorithm :ivar value: The value to operate on. Required. :vartype value: bytes """ - algorithm: Union[str, "_models.JsonWebKeySignatureAlgorithm"] = rest_field(name="alg") + algorithm: Union[str, "_models.JsonWebKeySignatureAlgorithm"] = rest_field( + name="alg", visibility=["read", "create", "update", "delete", "query"] + ) """The signing/verification algorithm identifier. For more information on possible algorithm types, see JsonWebKeySignatureAlgorithm. Required. Known values are: \"PS256\", \"PS384\", \"PS512\", \"RS256\", \"RS384\", \"RS512\", \"HS256\", \"HS384\", \"HS512\", \"RSNULL\", \"ES256\", \"ES384\", \"ES512\", and \"ES256K\".""" - value: bytes = rest_field(format="base64url") + value: bytes = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """The value to operate on. Required.""" @overload @@ -1008,23 +1059,29 @@ class KeyUpdateParameters(_model_base.Model): :ivar key_ops: Json web key operations. For more information on possible key operations, see JsonWebKeyOperation. - :vartype key_ops: list[str or ~azure.keyvault.keys._generated.models.JsonWebKeyOperation] + :vartype key_ops: list[str or ~azure.keyvault.keys.models.JsonWebKeyOperation] :ivar key_attributes: The attributes of a key managed by the key vault service. - :vartype key_attributes: ~azure.keyvault.keys._generated.models.KeyAttributes + :vartype key_attributes: ~azure.keyvault.keys.models.KeyAttributes :ivar tags: Application specific metadata in the form of key-value pairs. :vartype tags: dict[str, str] :ivar release_policy: The policy rules under which the key can be exported. - :vartype release_policy: ~azure.keyvault.keys._generated.models.KeyReleasePolicy + :vartype release_policy: ~azure.keyvault.keys.models.KeyReleasePolicy """ - key_ops: Optional[List[Union[str, "_models.JsonWebKeyOperation"]]] = rest_field() + key_ops: Optional[List[Union[str, "_models.JsonWebKeyOperation"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """Json web key operations. For more information on possible key operations, see JsonWebKeyOperation.""" - key_attributes: Optional["_models.KeyAttributes"] = rest_field(name="attributes") + key_attributes: Optional["_models.KeyAttributes"] = rest_field( + name="attributes", visibility=["read", "create", "update", "delete", "query"] + ) """The attributes of a key managed by the key vault service.""" - tags: Optional[Dict[str, str]] = rest_field() + tags: Optional[Dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Application specific metadata in the form of key-value pairs.""" - release_policy: Optional["_models.KeyReleasePolicy"] = rest_field() + release_policy: Optional["_models.KeyReleasePolicy"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The policy rules under which the key can be exported.""" @overload @@ -1051,61 +1108,40 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeyVaultError(_model_base.Model): """The key vault error exception. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar error: The key vault server error. - :vartype error: ~azure.keyvault.keys._generated.models.KeyVaultErrorError + :vartype error: ~azure.keyvault.keys.models.Error """ - error: Optional["_models.KeyVaultErrorError"] = rest_field(visibility=["read"]) - """The key vault server error.""" - - -class KeyVaultErrorError(_model_base.Model): - """KeyVaultErrorError. - - Readonly variables are only populated by the server, and will be ignored when sending a request. - - :ivar code: The error code. - :vartype code: str - :ivar message: The error message. - :vartype message: str - :ivar inner_error: The key vault server error. - :vartype inner_error: ~azure.keyvault.keys._generated.models.KeyVaultErrorError - """ - - code: Optional[str] = rest_field(visibility=["read"]) - """The error code.""" - message: Optional[str] = rest_field(visibility=["read"]) - """The error message.""" - inner_error: Optional["_models.KeyVaultErrorError"] = rest_field(name="innererror", visibility=["read"]) + error: Optional["_models.Error"] = rest_field(visibility=["read"]) """The key vault server error.""" class KeyVerifyParameters(_model_base.Model): """The key verify parameters. - All required parameters must be populated in order to send to server. - :ivar algorithm: The signing/verification algorithm. For more information on possible algorithm types, see JsonWebKeySignatureAlgorithm. Required. Known values are: "PS256", "PS384", "PS512", "RS256", "RS384", "RS512", "HS256", "HS384", "HS512", "RSNULL", "ES256", "ES384", "ES512", and "ES256K". - :vartype algorithm: str or ~azure.keyvault.keys._generated.models.JsonWebKeySignatureAlgorithm + :vartype algorithm: str or ~azure.keyvault.keys.models.JsonWebKeySignatureAlgorithm :ivar digest: The digest used for signing. Required. :vartype digest: bytes :ivar signature: The signature to be verified. Required. :vartype signature: bytes """ - algorithm: Union[str, "_models.JsonWebKeySignatureAlgorithm"] = rest_field(name="alg") + algorithm: Union[str, "_models.JsonWebKeySignatureAlgorithm"] = rest_field( + name="alg", visibility=["read", "create", "update", "delete", "query"] + ) """The signing/verification algorithm. For more information on possible algorithm types, see JsonWebKeySignatureAlgorithm. Required. Known values are: \"PS256\", \"PS384\", \"PS512\", \"RS256\", \"RS384\", \"RS512\", \"HS256\", \"HS384\", \"HS512\", \"RSNULL\", \"ES256\", \"ES384\", \"ES512\", and \"ES256K\".""" - digest: bytes = rest_field(format="base64url") + digest: bytes = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """The digest used for signing. Required.""" - signature: bytes = rest_field(name="value", format="base64url") + signature: bytes = rest_field( + name="value", visibility=["read", "create", "update", "delete", "query"], format="base64url" + ) """The signature to be verified. Required.""" @overload @@ -1131,8 +1167,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class KeyVerifyResult(_model_base.Model): """The key verify result. - Readonly variables are only populated by the server, and will be ignored when sending a request. - :ivar value: True if the signature is verified, otherwise false. :vartype value: bool """ @@ -1145,14 +1179,18 @@ class LifetimeActions(_model_base.Model): """Action and its trigger that will be performed by Key Vault over the lifetime of a key. :ivar trigger: The condition that will execute the action. - :vartype trigger: ~azure.keyvault.keys._generated.models.LifetimeActionsTrigger + :vartype trigger: ~azure.keyvault.keys.models.LifetimeActionsTrigger :ivar action: The action that will be executed. - :vartype action: ~azure.keyvault.keys._generated.models.LifetimeActionsType + :vartype action: ~azure.keyvault.keys.models.LifetimeActionsType """ - trigger: Optional["_models.LifetimeActionsTrigger"] = rest_field() + trigger: Optional["_models.LifetimeActionsTrigger"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The condition that will execute the action.""" - action: Optional["_models.LifetimeActionsType"] = rest_field() + action: Optional["_models.LifetimeActionsType"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The action that will be executed.""" @overload @@ -1185,10 +1223,14 @@ class LifetimeActionsTrigger(_model_base.Model): :vartype time_before_expiry: str """ - time_after_create: Optional[str] = rest_field(name="timeAfterCreate") + time_after_create: Optional[str] = rest_field( + name="timeAfterCreate", visibility=["read", "create", "update", "delete", "query"] + ) """Time after creation to attempt to rotate. It only applies to rotate. It will be in ISO 8601 duration format. Example: 90 days : \"P90D\".""" - time_before_expiry: Optional[str] = rest_field(name="timeBeforeExpiry") + time_before_expiry: Optional[str] = rest_field( + name="timeBeforeExpiry", visibility=["read", "create", "update", "delete", "query"] + ) """Time before expiry to attempt to rotate or notify. It will be in ISO 8601 duration format. Example: 90 days : \"P90D\".""" @@ -1216,10 +1258,12 @@ class LifetimeActionsType(_model_base.Model): :ivar type: The type of the action. The value should be compared case-insensitively. Known values are: "Rotate" and "Notify". - :vartype type: str or ~azure.keyvault.keys._generated.models.KeyRotationPolicyAction + :vartype type: str or ~azure.keyvault.keys.models.KeyRotationPolicyAction """ - type: Optional[Union[str, "_models.KeyRotationPolicyAction"]] = rest_field() + type: Optional[Union[str, "_models.KeyRotationPolicyAction"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) """The type of the action. The value should be compared case-insensitively. Known values are: \"Rotate\" and \"Notify\".""" @@ -1244,12 +1288,11 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: class RandomBytes(_model_base.Model): """The get random bytes response object containing the bytes. - :ivar value: The bytes encoded as a base64url string. Required. :vartype value: bytes """ - value: bytes = rest_field(format="base64url") + value: bytes = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64url") """The bytes encoded as a base64url string. Required.""" @overload diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/_patch.py b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/_patch.py new file mode 100644 index 000000000000..8bcb627aa475 --- /dev/null +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/models/_patch.py @@ -0,0 +1,21 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------- +"""Customize generated code here. + +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" +from typing import List + +__all__: List[str] = [] # Add all objects you want publicly available to users at this package level + + +def patch_sdk(): + """Do not remove from this file. + + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ diff --git a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/py.typed b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/py.typed index e69de29bb2d1..e5aff4f83af8 100644 --- a/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/py.typed +++ b/sdk/keyvault/azure-keyvault-keys/azure/keyvault/keys/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561. \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-keys/samples/backup_restore_operations.py b/sdk/keyvault/azure-keyvault-keys/samples/backup_restore_operations.py index bdf7d1305fd3..2e3f83c2ff66 100644 --- a/sdk/keyvault/azure-keyvault-keys/samples/backup_restore_operations.py +++ b/sdk/keyvault/azure-keyvault-keys/samples/backup_restore_operations.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -14,7 +15,7 @@ # 2. azure-keyvault-keys and azure-identity libraries (pip install these) # # 3. Set environment variable VAULT_URL with the URL of your key vault -# +# # 4. Set up your environment to use azure-identity's DefaultAzureCredential. For more information about how to configure # the DefaultAzureCredential, refer to https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential # diff --git a/sdk/keyvault/azure-keyvault-keys/samples/backup_restore_operations_async.py b/sdk/keyvault/azure-keyvault-keys/samples/backup_restore_operations_async.py index f6990ab87997..efef9cd89af4 100644 --- a/sdk/keyvault/azure-keyvault-keys/samples/backup_restore_operations_async.py +++ b/sdk/keyvault/azure-keyvault-keys/samples/backup_restore_operations_async.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -34,13 +35,14 @@ # 5. Restore a key (restore_key_backup) # ---------------------------------------------------------------------------------------------------------- + async def run_sample(): # Instantiate a key client that will be used to call the service. # Here we use the DefaultAzureCredential, but any azure-identity credential can be used. VAULT_URL = os.environ["VAULT_URL"] credential = DefaultAzureCredential() client = KeyClient(vault_url=VAULT_URL, credential=credential) - + # Let's create a Key of type RSA. # if the key already exists in the Key Vault, then a new version of the key is created. print("\n.. Create Key") diff --git a/sdk/keyvault/azure-keyvault-keys/samples/hello_world.py b/sdk/keyvault/azure-keyvault-keys/samples/hello_world.py index afb096383708..e323e555334f 100644 --- a/sdk/keyvault/azure-keyvault-keys/samples/hello_world.py +++ b/sdk/keyvault/azure-keyvault-keys/samples/hello_world.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -12,7 +13,7 @@ # 2. azure-keyvault-keys and azure-identity libraries (pip install these) # # 3. Set environment variable VAULT_URL with the URL of your key vault -# +# # 4. Set up your environment to use azure-identity's DefaultAzureCredential. For more information about how to configure # the DefaultAzureCredential, refer to https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential # @@ -70,9 +71,7 @@ # associated with a key previously stored within Key Vault. print("\n.. Update a Key by name") expires = datetime.datetime.utcnow() + datetime.timedelta(days=365) -updated_ec_key = client.update_key_properties( - ec_key.name, ec_key.properties.version, expires_on=expires, enabled=False -) +updated_ec_key = client.update_key_properties(ec_key.name, ec_key.properties.version, expires_on=expires, enabled=False) print(f"Key with name '{updated_ec_key.name}' was updated on date '{updated_ec_key.properties.updated_on}'") print(f"Key with name '{updated_ec_key.name}' was updated to expire on '{updated_ec_key.properties.expires_on}'") diff --git a/sdk/keyvault/azure-keyvault-keys/samples/hello_world_async.py b/sdk/keyvault/azure-keyvault-keys/samples/hello_world_async.py index 864f14750aaa..87d3728d5253 100644 --- a/sdk/keyvault/azure-keyvault-keys/samples/hello_world_async.py +++ b/sdk/keyvault/azure-keyvault-keys/samples/hello_world_async.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -35,6 +36,7 @@ # 5. Delete a key (delete_key) # ---------------------------------------------------------------------------------------------------------- + async def run_sample(): # Instantiate a key client that will be used to call the service. # Here we use the DefaultAzureCredential, but any azure-identity credential can be used. diff --git a/sdk/keyvault/azure-keyvault-keys/samples/key_rotation.py b/sdk/keyvault/azure-keyvault-keys/samples/key_rotation.py index 248ac051899e..731f4d743805 100644 --- a/sdk/keyvault/azure-keyvault-keys/samples/key_rotation.py +++ b/sdk/keyvault/azure-keyvault-keys/samples/key_rotation.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -14,7 +15,7 @@ # 2. azure-keyvault-keys and azure-identity libraries (pip install these) # # 3. Set environment variable VAULT_URL with the URL of your key vault -# +# # 4. Set up your environment to use azure-identity's DefaultAzureCredential. For more information about how to configure # the DefaultAzureCredential, refer to https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential # diff --git a/sdk/keyvault/azure-keyvault-keys/samples/key_rotation_async.py b/sdk/keyvault/azure-keyvault-keys/samples/key_rotation_async.py index c20f614943a7..4ebad1c8cf59 100644 --- a/sdk/keyvault/azure-keyvault-keys/samples/key_rotation_async.py +++ b/sdk/keyvault/azure-keyvault-keys/samples/key_rotation_async.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -36,6 +37,7 @@ # 5. Delete a key (delete_key) # ---------------------------------------------------------------------------------------------------------- + async def run_sample(): # Instantiate a key client that will be used to call the service. # Here we use the DefaultAzureCredential, but any azure-identity credential can be used. @@ -108,4 +110,4 @@ async def run_sample(): if __name__ == "__main__": - asyncio.run(run_sample()) \ No newline at end of file + asyncio.run(run_sample()) diff --git a/sdk/keyvault/azure-keyvault-keys/samples/list_operations.py b/sdk/keyvault/azure-keyvault-keys/samples/list_operations.py index f8b01807efc4..cf42f7006bb2 100644 --- a/sdk/keyvault/azure-keyvault-keys/samples/list_operations.py +++ b/sdk/keyvault/azure-keyvault-keys/samples/list_operations.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -13,7 +14,7 @@ # 2. azure-keyvault-keys and azure-identity libraries (pip install these) # # 3. Set environment variable VAULT_URL with the URL of your key vault -# +# # 4. Set up your environment to use azure-identity's DefaultAzureCredential. For more information about how to configure # the DefaultAzureCredential, refer to https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential # diff --git a/sdk/keyvault/azure-keyvault-keys/samples/list_operations_async.py b/sdk/keyvault/azure-keyvault-keys/samples/list_operations_async.py index 757017e45e00..e1a2c535508e 100644 --- a/sdk/keyvault/azure-keyvault-keys/samples/list_operations_async.py +++ b/sdk/keyvault/azure-keyvault-keys/samples/list_operations_async.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -35,6 +36,7 @@ # # ---------------------------------------------------------------------------------------------------------- + async def run_sample(): # Instantiate a key client that will be used to call the service. # Here we use the DefaultAzureCredential, but any azure-identity credential can be used. diff --git a/sdk/keyvault/azure-keyvault-keys/samples/recover_purge_operations.py b/sdk/keyvault/azure-keyvault-keys/samples/recover_purge_operations.py index 9b5b45985c97..7668cf456ac8 100644 --- a/sdk/keyvault/azure-keyvault-keys/samples/recover_purge_operations.py +++ b/sdk/keyvault/azure-keyvault-keys/samples/recover_purge_operations.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -13,7 +14,7 @@ # 2. azure-keyvault-keys and azure-identity libraries (pip install these) # # 3. Set environment variable VAULT_URL with the URL of your key vault -# +# # 4. Set up your environment to use azure-identity's DefaultAzureCredential. For more information about how to configure # the DefaultAzureCredential, refer to https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential # diff --git a/sdk/keyvault/azure-keyvault-keys/samples/recover_purge_operations_async.py b/sdk/keyvault/azure-keyvault-keys/samples/recover_purge_operations_async.py index bcb8eb588df3..8d4f1c138c36 100644 --- a/sdk/keyvault/azure-keyvault-keys/samples/recover_purge_operations_async.py +++ b/sdk/keyvault/azure-keyvault-keys/samples/recover_purge_operations_async.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -7,6 +8,7 @@ from azure.identity.aio import DefaultAzureCredential from azure.keyvault.keys.aio import KeyClient + # ---------------------------------------------------------------------------------------------------------- # Prerequisites: # 1. An Azure Key Vault (https://learn.microsoft.com/azure/key-vault/quick-create-cli) diff --git a/sdk/keyvault/azure-keyvault-keys/samples/send_request.py b/sdk/keyvault/azure-keyvault-keys/samples/send_request.py index 78d35dc3c8f2..c5e3f2b5a9c3 100644 --- a/sdk/keyvault/azure-keyvault-keys/samples/send_request.py +++ b/sdk/keyvault/azure-keyvault-keys/samples/send_request.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -14,7 +15,7 @@ # 2. azure-keyvault-keys and azure-identity libraries (pip install these) # # 3. Set environment variable VAULT_URL with the URL of your key vault -# +# # 4. Set up your environment to use azure-identity's DefaultAzureCredential. For more information about how to configure # the DefaultAzureCredential, refer to https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential # @@ -55,7 +56,7 @@ response = client.send_request(request) # The return value is an azure.core.rest.HttpResponse -- the key information is in the response body. -# We can get a dictionary of the body content with the `json` method. +# We can get a dictionary of the body content with the `json` method. response_body = response.json() print(f"\n.. Key with ID {response_body['key']['kid']} was found.") diff --git a/sdk/keyvault/azure-keyvault-keys/setup.py b/sdk/keyvault/azure-keyvault-keys/setup.py index cf1b6a7df883..0dcf8205f25f 100644 --- a/sdk/keyvault/azure-keyvault-keys/setup.py +++ b/sdk/keyvault/azure-keyvault-keys/setup.py @@ -1,55 +1,47 @@ -#!/usr/bin/env python +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -# pylint:disable=missing-docstring +import os import re -import os.path -from io import open -from setuptools import find_packages, setup +from setuptools import setup, find_packages + -# Change the PACKAGE_NAME only to change folder and different name PACKAGE_NAME = "azure-keyvault-keys" -PACKAGE_PPRINT_NAME = "Key Vault Keys" +PACKAGE_PPRINT_NAME = "Azure Keyvault Keys" # a-b-c => a/b/c -PACKAGE_FOLDER_PATH = PACKAGE_NAME.replace("-", "/") -# a-b-c => a.b.c -NAMESPACE_NAME = PACKAGE_NAME.replace("-", ".") +package_folder_path = PACKAGE_NAME.replace("-", "/") # Version extraction inspired from 'requests' -with open(os.path.join(PACKAGE_FOLDER_PATH, "_version.py"), "r") as fd: - VERSION = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE).group(1) +with open(os.path.join(package_folder_path, "_version.py"), "r") as fd: + version = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE).group(1) -if not VERSION: +if not version: raise RuntimeError("Cannot find version information") -with open("README.md", encoding="utf-8") as f: - README = f.read() -with open("CHANGELOG.md", encoding="utf-8") as f: - CHANGELOG = f.read() setup( name=PACKAGE_NAME, - version=VERSION, - include_package_data=True, - description=f"Microsoft Azure {PACKAGE_PPRINT_NAME} Client Library for Python", - long_description=README + "\n\n" + CHANGELOG, + version=version, + description="Microsoft Corporation {} Client Library for Python".format(PACKAGE_PPRINT_NAME), + long_description=open("README.md", "r").read(), long_description_content_type="text/markdown", license="MIT License", author="Microsoft Corporation", - author_email="azurekeyvault@microsoft.com", - url="https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys", + author_email="azpysdkhelp@microsoft.com", + url="https://github.com/Azure/azure-sdk-for-python/tree/main/sdk", keywords="azure, azure sdk", classifiers=[ "Development Status :: 4 - Beta", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -59,18 +51,20 @@ zip_safe=False, packages=find_packages( exclude=[ - "samples", "tests", # Exclude packages that will be covered by PEP420 or nspkg "azure", "azure.keyvault", ] ), - python_requires=">=3.8", + include_package_data=True, + package_data={ + "azure.keyvault.keys": ["py.typed"], + }, install_requires=[ - "azure-core>=1.31.0", - "cryptography>=2.1.4", "isodate>=0.6.1", + "azure-core>=1.30.0", "typing-extensions>=4.6.0", ], + python_requires=">=3.9", ) diff --git a/sdk/keyvault/azure-keyvault-keys/tests/_keys_test_case.py b/sdk/keyvault/azure-keyvault-keys/tests/_keys_test_case.py index d1e99ba811e3..d23ab5e15853 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/_keys_test_case.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/_keys_test_case.py @@ -13,7 +13,7 @@ def _get_attestation_uri(self): playback_uri = "https://fakeattestation.azurewebsites.net" if self.is_live: real_uri = os.environ.get("AZURE_KEYVAULT_ATTESTATION_URL") - real_uri = real_uri.rstrip('/') + real_uri = real_uri.rstrip("/") if real_uri is None: pytest.skip("No AZURE_KEYVAULT_ATTESTATION_URL environment variable") return real_uri @@ -22,9 +22,11 @@ def _get_attestation_uri(self): def create_crypto_client(self, key, **kwargs): if kwargs.pop("is_async", False): from azure.keyvault.keys.crypto.aio import CryptographyClient - credential = self.get_credential(CryptographyClient,is_async=True) + + credential = self.get_credential(CryptographyClient, is_async=True) else: from azure.keyvault.keys.crypto import CryptographyClient + credential = self.get_credential(CryptographyClient) return self.create_client_from_credential(CryptographyClient, credential=credential, key=key, **kwargs) diff --git a/sdk/keyvault/azure-keyvault-keys/tests/_shared/test_case.py b/sdk/keyvault/azure-keyvault-keys/tests/_shared/test_case.py index a67376fd53e1..87a1198ea5de 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/_shared/test_case.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/_shared/test_case.py @@ -8,8 +8,6 @@ from devtools_testutils import AzureRecordedTestCase - - class KeyVaultTestCase(AzureRecordedTestCase): def get_resource_name(self, name): """helper to create resources with a consistent, test-indicative prefix""" diff --git a/sdk/keyvault/azure-keyvault-keys/tests/_shared/test_case_async.py b/sdk/keyvault/azure-keyvault-keys/tests/_shared/test_case_async.py index 6059c528f1a3..fb26f89f3ab3 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/_shared/test_case_async.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/_shared/test_case_async.py @@ -36,7 +36,7 @@ async def _poll_until_exception(self, fn, expected_exception, max_retries=20, re except expected_exception: return self.fail("expected exception {expected_exception} was not raised") - + def teardown_method(self, method): HttpChallengeCache.clear() assert len(HttpChallengeCache._cache) == 0 diff --git a/sdk/keyvault/azure-keyvault-keys/tests/conftest.py b/sdk/keyvault/azure-keyvault-keys/tests/conftest.py index bfcd18356825..3db4bb782e44 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/conftest.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/conftest.py @@ -13,16 +13,22 @@ add_oauth_response_sanitizer, is_live, remove_batch_sanitizers, - set_custom_default_matcher + set_custom_default_matcher, ) from azure.keyvault.keys._shared.client_base import DEFAULT_VERSION, ApiVersion -os.environ['PYTHONHASHSEED'] = '0' +os.environ["PYTHONHASHSEED"] = "0" ALL_API_VERSIONS = "--all-api-versions" + def pytest_addoption(parser): - parser.addoption(ALL_API_VERSIONS, action="store_true", default=False, - help="Test all api version in live mode. Not applicable in playback mode.") + parser.addoption( + ALL_API_VERSIONS, + action="store_true", + default=False, + help="Test all api version in live mode. Not applicable in playback mode.", + ) + def pytest_configure(config): if is_live() and not config.getoption(ALL_API_VERSIONS): @@ -30,16 +36,19 @@ def pytest_configure(config): else: pytest.api_version = ApiVersion + @pytest.fixture(scope="session", autouse=True) def add_sanitizers(test_proxy): azure_keyvault_url = os.getenv("AZURE_KEYVAULT_URL", "https://vaultname.vault.azure.net") azure_keyvault_url = azure_keyvault_url.rstrip("/") keyvault_tenant_id = os.getenv("KEYVAULT_TENANT_ID", "keyvault_tenant_id") keyvault_subscription_id = os.getenv("KEYVAULT_SUBSCRIPTION_ID", "keyvault_subscription_id") - azure_managedhsm_url = os.environ.get("AZURE_MANAGEDHSM_URL","https://managedhsmvaultname.managedhsm.azure.net") + azure_managedhsm_url = os.environ.get("AZURE_MANAGEDHSM_URL", "https://managedhsmvaultname.managedhsm.azure.net") azure_managedhsm_url = azure_managedhsm_url.rstrip("/") - azure_attestation_uri = os.environ.get("AZURE_KEYVAULT_ATTESTATION_URL","https://fakeattestation.azurewebsites.net") - azure_attestation_uri = azure_attestation_uri.rstrip('/') + azure_attestation_uri = os.environ.get( + "AZURE_KEYVAULT_ATTESTATION_URL", "https://fakeattestation.azurewebsites.net" + ) + azure_attestation_uri = azure_attestation_uri.rstrip("/") add_general_string_sanitizer(target=azure_keyvault_url, value="https://vaultname.vault.azure.net") add_general_string_sanitizer(target=keyvault_tenant_id, value="00000000-0000-0000-0000-000000000000") @@ -52,7 +61,12 @@ def add_sanitizers(test_proxy): # Remove the following sanitizers since certain fields are needed in tests and are non-sensitive: # - AZSDK3430: $..id # - AZSDK3447: $.key - remove_batch_sanitizers(["AZSDK3430", "AZSDK3447",]) + remove_batch_sanitizers( + [ + "AZSDK3430", + "AZSDK3447", + ] + ) @pytest.fixture(scope="session", autouse=True) @@ -80,6 +94,7 @@ def immediate_return(_): else: yield + @pytest.fixture(scope="session") def event_loop(request): loop = asyncio.get_event_loop() diff --git a/sdk/keyvault/azure-keyvault-keys/tests/keys.py b/sdk/keyvault/azure-keyvault-keys/tests/keys.py index 80db438ae5f2..428b82eb21e0 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/keys.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/keys.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. diff --git a/sdk/keyvault/azure-keyvault-keys/tests/perfstress_tests/sign.py b/sdk/keyvault/azure-keyvault-keys/tests/perfstress_tests/sign.py index e98cbd1ce11c..469de42d8a35 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/perfstress_tests/sign.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/perfstress_tests/sign.py @@ -25,6 +25,7 @@ def __init__(self, arguments): super().__init__(arguments) from dotenv import load_dotenv + load_dotenv() # Auth configuration diff --git a/sdk/keyvault/azure-keyvault-keys/tests/test_challenge_auth.py b/sdk/keyvault/azure-keyvault-keys/tests/test_challenge_auth.py index de26cc59f07d..b889b052484f 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/test_challenge_auth.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/test_challenge_auth.py @@ -36,6 +36,7 @@ TOKEN_TYPES = [AccessToken, AccessTokenInfo] + class TestChallengeAuth(KeyVaultTestCase, KeysTestCase): @pytest.mark.parametrize("api_version,is_hsm", only_default_version) @KeysClientPreparer() @@ -125,7 +126,6 @@ def test_enforces_tls(): pipeline.run(HttpRequest("GET", url)) - def test_challenge_cache(): url_a = get_random_url() challenge_a = HttpChallenge(url_a, "Bearer authorization=authority A, resource=resource A") @@ -148,9 +148,7 @@ def test_challenge_parsing(): tenant = "tenant" authority = f"https://login.authority.net/{tenant}" resource = "https://challenge.resource" - challenge = HttpChallenge( - "https://request.uri", challenge=f"Bearer authorization={authority}, resource={resource}" - ) + challenge = HttpChallenge("https://request.uri", challenge=f"Bearer authorization={authority}, resource={resource}") assert challenge.get_authorization_server() == authority assert challenge.get_resource() == resource @@ -548,8 +546,8 @@ def get_token(*_, **__): mock_response( status_code=401, headers={"WWW-Authenticate": f'Bearer authorization="{url}", resource={resource}'} ), - mock_response(status_code=200, json_payload={"key": {"kid": f"{url}/key-name"}}) - ] + mock_response(status_code=200, json_payload={"key": {"kid": f"{url}/key-name"}}), + ], ) transport_2 = validating_transport( requests=[Request(), Request(required_headers={"Authorization": f"Bearer {token}"})], @@ -557,8 +555,8 @@ def get_token(*_, **__): mock_response( status_code=401, headers={"WWW-Authenticate": f'Bearer authorization="{url}", resource={resource}'} ), - mock_response(status_code=200, json_payload={"key": {"kid": f"{url}/key-name"}}) - ] + mock_response(status_code=200, json_payload={"key": {"kid": f"{url}/key-name"}}), + ], ) client = KeyClient(url, credential, transport=transport, verify_challenge_resource=verify_challenge_resource) @@ -603,8 +601,8 @@ def get_token(*_, **__): mock_response( status_code=401, headers={"WWW-Authenticate": f'Bearer authorization="{url}", resource={resource}'} ), - mock_response(status_code=200, json_payload={"key": {"kid": f"{url}/key-name"}}) - ] + mock_response(status_code=200, json_payload={"key": {"kid": f"{url}/key-name"}}), + ], ) client = KeyClient(url, credential, transport=transport, verify_challenge_resource=verify_challenge_resource) diff --git a/sdk/keyvault/azure-keyvault-keys/tests/test_challenge_auth_async.py b/sdk/keyvault/azure-keyvault-keys/tests/test_challenge_auth_async.py index 81ec711f6ad2..4834e9037d3a 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/test_challenge_auth_async.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/test_challenge_auth_async.py @@ -19,7 +19,7 @@ from azure.core.pipeline import AsyncPipeline from azure.core.pipeline.policies import SansIOHTTPPolicy from azure.core.rest import HttpRequest -from azure.keyvault.keys._shared import AsyncChallengeAuthPolicy,HttpChallenge, HttpChallengeCache +from azure.keyvault.keys._shared import AsyncChallengeAuthPolicy, HttpChallenge, HttpChallengeCache from azure.keyvault.keys._shared.client_base import DEFAULT_VERSION from azure.keyvault.keys.aio import KeyClient from devtools_testutils.aio import recorded_by_proxy_async @@ -45,7 +45,7 @@ class TestChallengeAuth(KeyVaultTestCase): @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_default_version) + @pytest.mark.parametrize("api_version,is_hsm", only_default_version) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_multitenant_authentication(self, client, is_hsm, **kwargs): @@ -131,9 +131,7 @@ async def get_token(*scopes, **_): credential = Mock(spec_set=["get_token"], get_token=Mock(wraps=get_token)) else: credential = Mock(spec_set=["get_token_info"], get_token_info=Mock(wraps=get_token)) - pipeline = AsyncPipeline( - policies=[AsyncChallengeAuthPolicy(credential=credential)], transport=Mock(send=send) - ) + pipeline = AsyncPipeline(policies=[AsyncChallengeAuthPolicy(credential=credential)], transport=Mock(send=send)) request = HttpRequest("POST", get_random_url()) request.set_bytes_body(expected_content) await pipeline.run(request) @@ -200,9 +198,7 @@ async def get_token(*_, options=None, **kwargs): credential = Mock(spec_set=["get_token"], get_token=Mock(wraps=get_token)) else: credential = Mock(spec_set=["get_token_info"], get_token_info=Mock(wraps=get_token)) - pipeline = AsyncPipeline( - policies=[AsyncChallengeAuthPolicy(credential=credential)], transport=Mock(send=send) - ) + pipeline = AsyncPipeline(policies=[AsyncChallengeAuthPolicy(credential=credential)], transport=Mock(send=send)) request = HttpRequest("POST", get_random_url()) request.set_bytes_body(expected_content) await pipeline.run(request) @@ -495,8 +491,8 @@ async def get_token(*_, **__): mock_response( status_code=401, headers={"WWW-Authenticate": f'Bearer authorization="{url}", resource={resource}'} ), - mock_response(status_code=200, json_payload={"key": {"kid": f"{url}/key-name"}}) - ] + mock_response(status_code=200, json_payload={"key": {"kid": f"{url}/key-name"}}), + ], ) transport_2 = async_validating_transport( requests=[Request(), Request(required_headers={"Authorization": f"Bearer {token}"})], @@ -504,8 +500,8 @@ async def get_token(*_, **__): mock_response( status_code=401, headers={"WWW-Authenticate": f'Bearer authorization="{url}", resource={resource}'} ), - mock_response(status_code=200, json_payload={"key": {"kid": f"{url}/key-name"}}) - ] + mock_response(status_code=200, json_payload={"key": {"kid": f"{url}/key-name"}}), + ], ) client = KeyClient(url, credential, transport=transport, verify_challenge_resource=verify_challenge_resource) @@ -550,8 +546,8 @@ async def get_token(*_, **__): mock_response( status_code=401, headers={"WWW-Authenticate": f'Bearer authorization="{url}", resource={resource}'} ), - mock_response(status_code=200, json_payload={"key": {"kid": f"{url}/key-name"}}) - ] + mock_response(status_code=200, json_payload={"key": {"kid": f"{url}/key-name"}}), + ], ) client = KeyClient(url, credential, transport=transport, verify_challenge_resource=verify_challenge_resource) diff --git a/sdk/keyvault/azure-keyvault-keys/tests/test_crypto_client.py b/sdk/keyvault/azure-keyvault-keys/tests/test_crypto_client.py index 45cb23d5b84b..382bee35dfb7 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/test_crypto_client.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/test_crypto_client.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression,too-many-lines # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -20,7 +21,7 @@ rsa_crt_dmq1, rsa_crt_iqmp, RSAPrivateNumbers, - RSAPublicNumbers + RSAPublicNumbers, ) from cryptography.hazmat.primitives.serialization import Encoding, NoEncryption, PrivateFormat, PublicFormat import pytest @@ -60,21 +61,21 @@ def _to_bytes(hex): # RSA key with private components so that the JWK can be used for private operations TEST_JWK = { - "kty":"RSA", - "key_ops":["decrypt", "verify", "unwrapKey"], - "n":_to_bytes( + "kty": "RSA", + "key_ops": ["decrypt", "verify", "unwrapKey"], + "n": _to_bytes( "00a0914d00234ac683b21b4c15d5bed887bdc959c2e57af54ae734e8f00720d775d275e455207e3784ceeb60a50a4655dd72a7a94d271e8ee8f7959a669ca6e775bf0e23badae991b4529d978528b4bd90521d32dd2656796ba82b6bbfc7668c8f5eeb5053747fd199319d29a8440d08f4412d527ff9311eda71825920b47b1c46b11ab3e91d7316407e89c7f340f7b85a34042ce51743b27d4718403d34c7b438af6181be05e4d11eb985d38253d7fe9bf53fc2f1b002d22d2d793fa79a504b6ab42d0492804d7071d727a06cf3a8893aa542b1503f832b296371b6707d4dc6e372f8fe67d8ded1c908fde45ce03bc086a71487fa75e43aa0e0679aa0d20efe35" ), - "e":_to_bytes("10001"), - "p":_to_bytes( + "e": _to_bytes("10001"), + "p": _to_bytes( "00d1deac8d68ddd2c1fd52d5999655b2cf1565260de5269e43fd2a85f39280e1708ffff0682166cb6106ee5ea5e9ffd9f98d0becc9ff2cda2febc97259215ad84b9051e563e14a051dce438bc6541a24ac4f014cf9732d36ebfc1e61a00d82cbe412090f7793cfbd4b7605be133dfc3991f7e1bed5786f337de5036fc1e2df4cf3" ), - "q":_to_bytes( + "q": _to_bytes( "00c3dc66b641a9b73cd833bc439cd34fc6574465ab5b7e8a92d32595a224d56d911e74624225b48c15a670282a51c40d1dad4bc2e9a3c8dab0c76f10052dfb053bc6ed42c65288a8e8bace7a8881184323f94d7db17ea6dfba651218f931a93b8f738f3d8fd3f6ba218d35b96861a0f584b0ab88ddcf446b9815f4d287d83a3237" ), - "d":_to_bytes( + "d": _to_bytes( "627c7d24668148fe2252c7fa649ea8a5a9ed44d75c766cda42b29b660e99404f0e862d4561a6c95af6a83d213e0a2244b03cd28576473215073785fb067f015da19084ade9f475e08b040a9a2c7ba00253bb8125508c9df140b75161d266be347a5e0f6900fe1d8bbf78ccc25eeb37e0c9d188d6e1fc15169ba4fe12276193d77790d2326928bd60d0d01d6ead8d6ac4861abadceec95358fd6689c50a1671a4a936d2376440a41445501da4e74bfb98f823bd19c45b94eb01d98fc0d2f284507f018ebd929b8180dbe6381fdd434bffb7800aaabdd973d55f9eaf9bb88a6ea7b28c2a80231e72de1ad244826d665582c2362761019de2e9f10cb8bcc2625649" - ) + ), } @@ -111,9 +112,10 @@ def _validate_rsa_key_bundle(self, key_attributes, vault, key_name, kty, key_ops assert key.kty == kty, f"kty should by '{key}', but is '{key.kty}'" assert key.n and key.e, "Bad RSA public material." assert sorted(key_ops) == sorted(key.key_ops), f"keyOps should be '{key_ops}', but is '{key.key_ops}'" - - assert key_attributes.properties.created_on and key_attributes.properties.updated_on, "Missing required date attributes." - + + assert ( + key_attributes.properties.created_on and key_attributes.properties.updated_on + ), "Missing required date attributes." def _validate_ec_key_bundle(self, key_curve, key_attributes, vault, key_name, kty): prefix = "/".join(s.strip("/") for s in [vault, "keys", key_name]) @@ -122,7 +124,9 @@ def _validate_ec_key_bundle(self, key_curve, key_attributes, vault, key_name, kt assert key_curve == key.crv assert kid.index(prefix) == 0, f"Key Id should start with '{prefix}', but value is '{kid}'" assert key.kty == kty, f"kty should by '{key}', but is '{key.kty}'" - assert key_attributes.properties.created_on and key_attributes.properties.updated_on,"Missing required date attributes." + assert ( + key_attributes.properties.created_on and key_attributes.properties.updated_on + ), "Missing required date attributes." def _import_test_key(self, client, name, hardware_protected=False): key = JsonWebKey( @@ -169,7 +173,7 @@ def _import_symmetric_test_key(self, client, name): assert key_vault_key.key.kid == imported_key.id == key_vault_key.id return key_vault_key - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_ec_key_id(self, key_client, is_hsm, **kwargs): @@ -185,7 +189,7 @@ def test_ec_key_id(self, key_client, is_hsm, **kwargs): crypto_client.verify(SignatureAlgorithm.es256_k, hashlib.sha256(self.plaintext).digest(), self.plaintext) - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_rsa_key_id(self, key_client, is_hsm, **kwargs): @@ -399,7 +403,7 @@ def test_symmetric_encrypt_and_decrypt(self, key_client, **kwargs): encrypt_result.ciphertext, iv=encrypt_result.iv, authentication_tag=encrypt_result.tag, - additional_authenticated_data=self.aad + additional_authenticated_data=self.aad, ) else: encrypt_result = crypto_client.encrypt( @@ -410,13 +414,15 @@ def test_symmetric_encrypt_and_decrypt(self, key_client, **kwargs): encrypt_result.algorithm, encrypt_result.ciphertext, iv=encrypt_result.iv, - additional_authenticated_data=None if "CBC" in algorithm else self.aad + additional_authenticated_data=None if "CBC" in algorithm else self.aad, ) assert decrypt_result.key_id == imported_key.id assert decrypt_result.algorithm == algorithm if algorithm.endswith("CBC"): - assert decrypt_result.plaintext.startswith(self.plaintext) # AES-CBC returns a zero-padded plaintext + assert decrypt_result.plaintext.startswith( + self.plaintext + ) # AES-CBC returns a zero-padded plaintext else: assert decrypt_result.plaintext == self.plaintext @@ -436,7 +442,7 @@ def test_symmetric_wrap_and_unwrap(self, key_client, **kwargs): result = crypto_client.unwrap_key(result.algorithm, result.encrypted_key) assert result.key == self.plaintext - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_encrypt_local(self, key_client, is_hsm, **kwargs): @@ -453,7 +459,7 @@ def test_encrypt_local(self, key_client, is_hsm, **kwargs): result = crypto_client.decrypt(result.algorithm, result.ciphertext) assert result.plaintext == self.plaintext - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_encrypt_local_from_jwk(self, key_client, is_hsm, **kwargs): @@ -470,8 +476,8 @@ def test_encrypt_local_from_jwk(self, key_client, is_hsm, **kwargs): result = crypto_client.decrypt(result.algorithm, result.ciphertext) assert result.plaintext == self.plaintext - - @pytest.mark.parametrize("api_version,is_hsm",only_hsm) + + @pytest.mark.parametrize("api_version,is_hsm", only_hsm) @KeysClientPreparer() @recorded_by_proxy def test_symmetric_encrypt_local(self, key_client, **kwargs): @@ -499,7 +505,7 @@ def test_symmetric_encrypt_local(self, key_client, **kwargs): assert decrypt_result.key_id == imported_key.id assert decrypt_result.algorithm == algorithm assert decrypt_result.plaintext == self.plaintext - + @pytest.mark.parametrize("api_version,is_hsm", only_hsm) @KeysClientPreparer() @recorded_by_proxy @@ -524,14 +530,14 @@ def test_symmetric_decrypt_local(self, key_client, **kwargs): encrypt_result.algorithm, encrypt_result.ciphertext, iv=encrypt_result.iv, - additional_authenticated_data=self.aad + additional_authenticated_data=self.aad, ) assert decrypt_result.key_id == imported_key.id assert decrypt_result.algorithm == algorithm assert decrypt_result.plaintext == self.plaintext - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_wrap_local(self, key_client, is_hsm, **kwargs): @@ -547,7 +553,7 @@ def test_wrap_local(self, key_client, is_hsm, **kwargs): result = crypto_client.unwrap_key(result.algorithm, result.encrypted_key) assert result.key == self.plaintext - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_wrap_local_from_jwk(self, key_client, is_hsm, **kwargs): @@ -564,7 +570,7 @@ def test_wrap_local_from_jwk(self, key_client, is_hsm, **kwargs): result = crypto_client.unwrap_key(result.algorithm, result.encrypted_key) assert result.key == self.plaintext - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_rsa_verify_local(self, key_client, is_hsm, **kwargs): @@ -589,7 +595,7 @@ def test_rsa_verify_local(self, key_client, is_hsm, **kwargs): result = crypto_client.verify(result.algorithm, digest, result.signature) assert result.is_valid - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_rsa_verify_local_from_jwk(self, key_client, is_hsm, **kwargs): @@ -600,12 +606,12 @@ def test_rsa_verify_local_from_jwk(self, key_client, is_hsm, **kwargs): crypto_client = self.create_crypto_client(key, api_version=key_client.api_version) local_client = CryptographyClient.from_jwk(key.key) for signature_algorithm, hash_function in ( - (SignatureAlgorithm.ps256, hashlib.sha256), - (SignatureAlgorithm.ps384, hashlib.sha384), - (SignatureAlgorithm.ps512, hashlib.sha512), - (SignatureAlgorithm.rs256, hashlib.sha256), - (SignatureAlgorithm.rs384, hashlib.sha384), - (SignatureAlgorithm.rs512, hashlib.sha512), + (SignatureAlgorithm.ps256, hashlib.sha256), + (SignatureAlgorithm.ps384, hashlib.sha384), + (SignatureAlgorithm.ps512, hashlib.sha512), + (SignatureAlgorithm.rs256, hashlib.sha256), + (SignatureAlgorithm.rs384, hashlib.sha384), + (SignatureAlgorithm.rs512, hashlib.sha512), ): digest = hash_function(self.plaintext).digest() @@ -615,7 +621,7 @@ def test_rsa_verify_local_from_jwk(self, key_client, is_hsm, **kwargs): result = local_client.verify(result.algorithm, digest, result.signature) assert result.is_valid - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_ec_verify_local(self, key_client, is_hsm, **kwargs): @@ -640,7 +646,7 @@ def test_ec_verify_local(self, key_client, is_hsm, **kwargs): result = crypto_client.verify(result.algorithm, digest, result.signature) assert result.is_valid - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_ec_verify_local_from_jwk(self, key_client, is_hsm, **kwargs): @@ -666,11 +672,12 @@ def test_ec_verify_local_from_jwk(self, key_client, is_hsm, **kwargs): result = local_client.verify(result.algorithm, digest, result.signature) assert result.is_valid - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_local_validity_period_enforcement(self, key_client, is_hsm, **kwargs): """Local crypto operations should respect a key's nbf and exp properties""" + def test_operations(key, expected_error_substrings, encrypt_algorithms, wrap_algorithms): crypto_client = self.create_crypto_client(key, api_version=key_client.api_version) for algorithm in encrypt_algorithms: @@ -713,7 +720,7 @@ def test_operations(key, expected_error_substrings, encrypt_algorithms, wrap_alg valid_key, (str(the_year_3000), str(the_year_3001)), rsa_encryption_algorithms, rsa_wrap_algorithms ) - @pytest.mark.parametrize("api_version,is_hsm",only_vault_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_vault_7_4_plus) @KeysClientPreparer() @recorded_by_proxy def test_send_request(self, key_client, is_hsm, **kwargs): @@ -734,7 +741,7 @@ def test_send_request(self, key_client, is_hsm, **kwargs): method="POST", url=f"keys/{key_name}/{imported_key.properties.version}/sign", headers={"Accept": "application/json"}, - json=json + json=json, ) response = crypto_client.send_request(request) response.raise_for_status() @@ -1081,7 +1088,7 @@ def test_rsa_public_key_public_bytes(): public_numbers = public_key.public_numbers() crypto_public_numbers = RSAPublicNumbers(e=public_numbers.e, n=public_numbers.n) crypto_public_bytes = crypto_public_numbers.public_key().public_bytes(Encoding.PEM, PublicFormat.PKCS1) - assert public_bytes == crypto_public_bytes + assert public_bytes == crypto_public_bytes def test_rsa_public_key_private_key_size(): diff --git a/sdk/keyvault/azure-keyvault-keys/tests/test_crypto_client_async.py b/sdk/keyvault/azure-keyvault-keys/tests/test_crypto_client_async.py index 18bd7007d5e6..ddbb2207e98f 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/test_crypto_client_async.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/test_crypto_client_async.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -70,8 +71,9 @@ def _validate_rsa_key_bundle(self, key_attributes, vault, key_name, kty, key_ops assert key.kty == kty, f"kty should by '{key}', but is '{key.kty}'" assert key.n and key.e, "Bad RSA public material." assert sorted(key_ops) == sorted(key.key_ops), f"keyOps should be '{key_ops}', but is '{key.key_ops}'" - assert key_attributes.properties.created_on and key_attributes.properties.updated_on,"Missing required date attributes." - + assert ( + key_attributes.properties.created_on and key_attributes.properties.updated_on + ), "Missing required date attributes." def _validate_ec_key_bundle(self, key_curve, key_attributes, vault, key_name, kty): prefix = "/".join(s.strip("/") for s in [vault, "keys", key_name]) @@ -80,7 +82,9 @@ def _validate_ec_key_bundle(self, key_curve, key_attributes, vault, key_name, kt assert key_curve == key.crv assert kid.index(prefix) == 0, f"Key Id should start with '{prefix}', but value is '{kid}'" assert key.kty == kty, f"kty should by '{key}', but is '{key.kty}'" - assert key_attributes.properties.created_on and key_attributes.properties.updated_on,"Missing required date attributes." + assert ( + key_attributes.properties.created_on and key_attributes.properties.updated_on + ), "Missing required date attributes." async def _import_test_key(self, client, name, hardware_protected=False): def _to_bytes(hex): @@ -133,7 +137,7 @@ async def _import_symmetric_test_key(self, client, name): return key_vault_key @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_ec_key_id(self, key_client, is_hsm, **kwargs): @@ -150,7 +154,7 @@ async def test_ec_key_id(self, key_client, is_hsm, **kwargs): await crypto_client.verify(SignatureAlgorithm.es256, hashlib.sha256(self.plaintext).digest(), self.plaintext) @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_rsa_key_id(self, key_client, is_hsm, **kwargs): @@ -169,7 +173,7 @@ async def test_rsa_key_id(self, key_client, is_hsm, **kwargs): await crypto_client.wrap_key(KeyWrapAlgorithm.rsa_oaep, self.plaintext) @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_encrypt_and_decrypt(self, key_client, is_hsm, **kwargs): @@ -188,7 +192,7 @@ async def test_encrypt_and_decrypt(self, key_client, is_hsm, **kwargs): assert self.plaintext == result.plaintext @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_sign_and_verify(self, key_client, is_hsm, **kwargs): @@ -211,7 +215,7 @@ async def test_sign_and_verify(self, key_client, is_hsm, **kwargs): assert verified.is_valid @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_wrap_and_unwrap(self, key_client, is_hsm, **kwargs): @@ -231,7 +235,7 @@ async def test_wrap_and_unwrap(self, key_client, is_hsm, **kwargs): assert key_bytes == result.key @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_hsm) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_symmetric_encrypt_and_decrypt(self, key_client, **kwargs): @@ -257,7 +261,7 @@ async def test_symmetric_encrypt_and_decrypt(self, key_client, **kwargs): result.ciphertext, iv=result.iv, authentication_tag=result.tag, - additional_authenticated_data=self.aad + additional_authenticated_data=self.aad, ) else: result = await crypto_client.encrypt( @@ -268,7 +272,7 @@ async def test_symmetric_encrypt_and_decrypt(self, key_client, **kwargs): result.algorithm, result.ciphertext, iv=self.iv, - additional_authenticated_data=None if "CBC" in algorithm else self.aad + additional_authenticated_data=None if "CBC" in algorithm else self.aad, ) assert result.key_id == imported_key.id @@ -279,7 +283,7 @@ async def test_symmetric_encrypt_and_decrypt(self, key_client, **kwargs): assert result.plaintext == self.plaintext @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_hsm) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_symmetric_wrap_and_unwrap(self, key_client, **kwargs): @@ -296,7 +300,7 @@ async def test_symmetric_wrap_and_unwrap(self, key_client, **kwargs): assert result.key == self.plaintext @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_encrypt_local(self, key_client, is_hsm, **kwargs): @@ -333,7 +337,7 @@ async def test_encrypt_local_from_jwk(self, key_client, is_hsm, **kwargs): assert result.plaintext, self.plaintext @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_hsm) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_symmetric_encrypt_local(self, key_client, **kwargs): @@ -363,7 +367,7 @@ async def test_symmetric_encrypt_local(self, key_client, **kwargs): assert decrypt_result.plaintext == self.plaintext @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_hsm) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_symmetric_decrypt_local(self, key_client, **kwargs): @@ -387,7 +391,7 @@ async def test_symmetric_decrypt_local(self, key_client, **kwargs): encrypt_result.algorithm, encrypt_result.ciphertext, iv=encrypt_result.iv, - additional_authenticated_data=self.aad + additional_authenticated_data=self.aad, ) assert decrypt_result.key_id == imported_key.id @@ -395,7 +399,7 @@ async def test_symmetric_decrypt_local(self, key_client, **kwargs): assert decrypt_result.plaintext == self.plaintext @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_wrap_local(self, key_client, is_hsm, **kwargs): @@ -412,7 +416,7 @@ async def test_wrap_local(self, key_client, is_hsm, **kwargs): assert result.key, self.plaintext @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_wrap_local_from_jwk(self, key_client, is_hsm, **kwargs): @@ -430,7 +434,7 @@ async def test_wrap_local_from_jwk(self, key_client, is_hsm, **kwargs): assert result.key, self.plaintext @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_rsa_verify_local(self, key_client, is_hsm, **kwargs): @@ -456,7 +460,7 @@ async def test_rsa_verify_local(self, key_client, is_hsm, **kwargs): assert result.is_valid @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_rsa_verify_local_from_jwk(self, key_client, is_hsm, **kwargs): @@ -467,12 +471,12 @@ async def test_rsa_verify_local_from_jwk(self, key_client, is_hsm, **kwargs): crypto_client = self.create_crypto_client(key, is_async=True, api_version=key_client.api_version) local_client = CryptographyClient.from_jwk(key.key) for signature_algorithm, hash_function in ( - (SignatureAlgorithm.ps256, hashlib.sha256), - (SignatureAlgorithm.ps384, hashlib.sha384), - (SignatureAlgorithm.ps512, hashlib.sha512), - (SignatureAlgorithm.rs256, hashlib.sha256), - (SignatureAlgorithm.rs384, hashlib.sha384), - (SignatureAlgorithm.rs512, hashlib.sha512), + (SignatureAlgorithm.ps256, hashlib.sha256), + (SignatureAlgorithm.ps384, hashlib.sha384), + (SignatureAlgorithm.ps512, hashlib.sha512), + (SignatureAlgorithm.rs256, hashlib.sha256), + (SignatureAlgorithm.rs384, hashlib.sha384), + (SignatureAlgorithm.rs512, hashlib.sha512), ): digest = hash_function(self.plaintext).digest() @@ -483,7 +487,7 @@ async def test_rsa_verify_local_from_jwk(self, key_client, is_hsm, **kwargs): assert result.is_valid @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_ec_verify_local(self, key_client, is_hsm, **kwargs): @@ -509,7 +513,7 @@ async def test_ec_verify_local(self, key_client, is_hsm, **kwargs): assert result.is_valid @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_ec_verify_local_from_jwk(self, key_client, is_hsm, **kwargs): @@ -536,11 +540,12 @@ async def test_ec_verify_local_from_jwk(self, key_client, is_hsm, **kwargs): assert result.is_valid @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_local_validity_period_enforcement(self, key_client, is_hsm, **kwargs): """Local crypto operations should respect a key's nbf and exp properties""" + async def test_operations(key, expected_error_substrings, encrypt_algorithms, wrap_algorithms): crypto_client = self.create_crypto_client(key, is_async=True, api_version=key_client.api_version) crypto_client._keys_get_forbidden = True # Prevent caching key material locally, to force remote ops @@ -587,7 +592,7 @@ async def test_operations(key, expected_error_substrings, encrypt_algorithms, wr ) @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_vault_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_vault_7_4_plus) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_send_request(self, key_client, is_hsm, **kwargs): @@ -608,7 +613,7 @@ async def test_send_request(self, key_client, is_hsm, **kwargs): method="POST", url=f"keys/{key_name}/{imported_key.properties.version}/sign", headers={"Accept": "application/json"}, - json=json + json=json, ) response = await crypto_client.send_request(request) response.raise_for_status() @@ -632,7 +637,10 @@ class CustomHookPolicy(SansIOHTTPPolicy): @pytest.mark.asyncio async def test_symmetric_wrap_and_unwrap_local(): key = KeyVaultKey( - key_id="http://localhost/keys/key/version", k=os.urandom(32), kty="oct", key_ops=["unwrapKey", "wrapKey"], + key_id="http://localhost/keys/key/version", + k=os.urandom(32), + kty="oct", + key_ops=["unwrapKey", "wrapKey"], ) crypto_client = CryptographyClient(key, credential=lambda *_: None) @@ -795,7 +803,7 @@ async def test_local_only_mode_no_service_calls(): async def test_local_only_mode_raise(): """A local-only CryptographyClient should raise an exception if an operation can't be performed locally""" - jwk = {"kty":"RSA", "key_ops":["decrypt", "verify", "unwrapKey"], "n":b"10011", "e":b"10001"} + jwk = {"kty": "RSA", "key_ops": ["decrypt", "verify", "unwrapKey"], "n": b"10011", "e": b"10001"} client = CryptographyClient.from_jwk(jwk=jwk) # Algorithm not supported locally @@ -908,7 +916,7 @@ async def test_aes_cbc_iv_validation(): @pytest.mark.asyncio async def test_encrypt_argument_validation(): """The client should raise an error when arguments don't work with the specified algorithm""" - + mock_client = mock.Mock() key = mock.Mock( spec=KeyVaultKey, diff --git a/sdk/keyvault/azure-keyvault-keys/tests/test_examples_crypto.py b/sdk/keyvault/azure-keyvault-keys/tests/test_examples_crypto.py index a1cdd20eeb4d..82f3aef073b2 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/test_examples_crypto.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/test_examples_crypto.py @@ -12,6 +12,7 @@ all_api_versions = get_decorator(only_vault=True) + class TestCryptoExamples(KeyVaultTestCase, KeysTestCase): @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @@ -59,7 +60,9 @@ def test_wrap_unwrap(self, key_client, **kwargs): key = key_client.create_rsa_key(key_name) client = CryptographyClient(key, credential, api_version=key_client.api_version) - key_bytes = b'\xc5\xb0\xfc\xf1C\x8a\x88pj\x11\x8d\xe5\x94\xe8\xff\x04\x0eY\xfeu\x8a\xe9<\x06(\xdb\x7f\xa9~\x85\x02\x04' + key_bytes = ( + b"\xc5\xb0\xfc\xf1C\x8a\x88pj\x11\x8d\xe5\x94\xe8\xff\x04\x0eY\xfeu\x8a\xe9<\x06(\xdb\x7f\xa9~\x85\x02\x04" + ) # [START wrap_key] from azure.keyvault.keys.crypto import KeyWrapAlgorithm diff --git a/sdk/keyvault/azure-keyvault-keys/tests/test_examples_crypto_async.py b/sdk/keyvault/azure-keyvault-keys/tests/test_examples_crypto_async.py index 287d673c65db..08320d36b5a4 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/test_examples_crypto_async.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/test_examples_crypto_async.py @@ -15,7 +15,7 @@ class TestCryptoExamples(KeyVaultTestCase): @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_encrypt_decrypt_async(self, key_client, **kwargs): @@ -58,7 +58,7 @@ async def test_encrypt_decrypt_async(self, key_client, **kwargs): # [END decrypt] @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_wrap_unwrap_async(self, key_client, **kwargs): @@ -67,7 +67,9 @@ async def test_wrap_unwrap_async(self, key_client, **kwargs): key = await key_client.create_rsa_key(key_name) client = CryptographyClient(key, credential, api_version=key_client.api_version) - key_bytes = b'\xc5\xb0\xfc\xf1C\x8a\x88pj\x11\x8d\xe5\x94\xe8\xff\x04\x0eY\xfeu\x8a\xe9<\x06(\xdb\x7f\xa9~\x85\x02\x04' + key_bytes = ( + b"\xc5\xb0\xfc\xf1C\x8a\x88pj\x11\x8d\xe5\x94\xe8\xff\x04\x0eY\xfeu\x8a\xe9<\x06(\xdb\x7f\xa9~\x85\x02\x04" + ) # [START wrap_key] from azure.keyvault.keys.crypto import KeyWrapAlgorithm @@ -86,7 +88,7 @@ async def test_wrap_unwrap_async(self, key_client, **kwargs): # [END unwrap_key] @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_sign_verify_async(self, key_client, **kwargs): diff --git a/sdk/keyvault/azure-keyvault-keys/tests/test_key_client.py b/sdk/keyvault/azure-keyvault-keys/tests/test_key_client.py index 9fe97370442c..18d2a9d8c8f2 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/test_key_client.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/test_key_client.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -23,7 +24,7 @@ KeyRotationLifetimeAction, KeyRotationPolicy, KeyRotationPolicyAction, - KeyType + KeyType, ) from azure.keyvault.keys._generated.models import KeyRotationPolicy as _KeyRotationPolicy from azure.keyvault.keys._shared.client_base import DEFAULT_VERSION @@ -54,6 +55,7 @@ def _assert_rotation_policies_equal(p1, p2): assert p1.updated_on == p2.updated_on assert len(p1.lifetime_actions) == len(p2.lifetime_actions) + def _assert_lifetime_actions_equal(a1, a2): assert a1.action == a2.action assert a1.time_after_create == a2.time_after_create @@ -115,8 +117,9 @@ def _validate_ec_key_bundle(self, key_curve, key_attributes, vault, key_name, kt assert key_curve == key.crv assert kid.index(prefix) == 0, f"Key Id should start with '{prefix}', but value is '{kid}'" assert key.kty == kty, f"kty should be '{kty}', but is '{key.kty}'" - assert key_attributes.properties.created_on and key_attributes.properties.updated_on,"Missing required date attributes." - + assert ( + key_attributes.properties.created_on and key_attributes.properties.updated_on + ), "Missing required date attributes." def _validate_rsa_key_bundle(self, key_attributes, vault, key_name, kty, key_ops): prefix = "/".join(s.strip("/") for s in [vault, "keys", key_name]) @@ -126,7 +129,9 @@ def _validate_rsa_key_bundle(self, key_attributes, vault, key_name, kty, key_ops assert key.kty == kty, f"kty should be '{kty}', but is '{key.kty}'" assert key.n and key.e, "Bad RSA public material." assert sorted(key_ops) == sorted(key.key_ops), f"keyOps should be '{key_ops}', but is '{key.key_ops}'" - assert key_attributes.properties.created_on and key_attributes.properties.updated_on, "Missing required date attributes." + assert ( + key_attributes.properties.created_on and key_attributes.properties.updated_on + ), "Missing required date attributes." def _update_key_properties(self, client, key, release_policy=None): expires = date_parse.parse("2050-01-02T08:00:00.000Z") @@ -184,7 +189,7 @@ def _to_bytes(hex): self._validate_rsa_key_bundle(imported_key, client.vault_url, name, key.kty, key.key_ops) return imported_key - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_key_crud_operations(self, client, is_hsm, **kwargs): @@ -210,7 +215,7 @@ def test_key_crud_operations(self, client, is_hsm, **kwargs): # create rsa key rsa_key_name = self.get_resource_name("crud-rsa-key") tags = {"purpose": "unit test", "test name ": "CreateRSAKeyTest"} - key_ops = ["encrypt","decrypt","sign","verify","wrapKey","unwrapKey"] + key_ops = ["encrypt", "decrypt", "sign", "verify", "wrapKey", "unwrapKey"] rsa_key = self._create_rsa_key( client, key_name=rsa_key_name, key_operations=key_ops, size=2048, tags=tags, hardware_protected=is_hsm ) @@ -239,8 +244,10 @@ def test_key_crud_operations(self, client, is_hsm, **kwargs): # aside from key_ops, the original updated keys should have the same JWKs self._assert_jwks_equal(rsa_key.key, deleted_key.key) assert deleted_key.id == rsa_key.id - assert deleted_key.recovery_id and deleted_key.deleted_date and deleted_key.scheduled_purge_date, "Missing required deleted key attributes." - + assert ( + deleted_key.recovery_id and deleted_key.deleted_date and deleted_key.scheduled_purge_date + ), "Missing required deleted key attributes." + deleted_key_poller.wait() # get the deleted key when soft deleted enabled @@ -248,7 +255,7 @@ def test_key_crud_operations(self, client, is_hsm, **kwargs): assert deleted_key is not None assert rsa_key.id == deleted_key.id - @pytest.mark.parametrize("api_version,is_hsm",only_hsm) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm) @KeysClientPreparer() @recorded_by_proxy def test_rsa_public_exponent(self, client, **kwargs): @@ -260,7 +267,7 @@ def test_rsa_public_exponent(self, client, **kwargs): public_exponent = key.key.e[0] assert public_exponent == 17 - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_backup_restore(self, client, is_hsm, **kwargs): @@ -286,7 +293,7 @@ def test_backup_restore(self, client, is_hsm, **kwargs): restored_key = self._poll_until_no_exception(restore_function, ResourceExistsError) self._assert_key_attributes_equal(created_bundle.properties, restored_key.properties) - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_key_list(self, client, is_hsm, **kwargs): @@ -309,7 +316,7 @@ def test_key_list(self, client, is_hsm, **kwargs): del expected[key.name] assert len(expected) == 0 - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_list_versions(self, client, is_hsm, **kwargs): @@ -336,7 +343,7 @@ def test_list_versions(self, client, is_hsm, **kwargs): assert 0 == len(expected) @pytest.mark.skip("Temporarily disabled due to service issue") - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_list_deleted_keys(self, client, is_hsm, **kwargs): @@ -367,7 +374,7 @@ def test_list_deleted_keys(self, client, is_hsm, **kwargs): del expected[key.name] @pytest.mark.skip("Temporarily disabled due to service issue") - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_recover(self, client, is_hsm, **kwargs): @@ -393,7 +400,7 @@ def test_recover(self, client, is_hsm, **kwargs): expected_key = keys[key_name] self._assert_key_attributes_equal(expected_key.properties, recovered_key.properties) - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_purge(self, client, is_hsm, **kwargs): @@ -424,8 +431,8 @@ def test_purge(self, client, is_hsm, **kwargs): deleted = [s.name for s in client.list_deleted_keys()] assert not any(s in deleted for s in key_names) - @pytest.mark.parametrize("api_version,is_hsm",logging_enabled) - @KeysClientPreparer(logging_enable = True) + @pytest.mark.parametrize("api_version,is_hsm", logging_enabled) + @KeysClientPreparer(logging_enable=True) @recorded_by_proxy def test_logging_enabled(self, client, is_hsm, **kwargs): mock_handler = MockHandler() @@ -459,8 +466,8 @@ def test_logging_enabled(self, client, is_hsm, **kwargs): mock_handler.close() assert False, "Expected request body wasn't logged" - @pytest.mark.parametrize("api_version,is_hsm",logging_enabled) - @KeysClientPreparer(logging_enable = False) + @pytest.mark.parametrize("api_version,is_hsm", logging_enabled) + @KeysClientPreparer(logging_enable=False) @recorded_by_proxy def test_logging_disabled(self, client, is_hsm, **kwargs): mock_handler = MockHandler() @@ -493,7 +500,7 @@ def test_logging_disabled(self, client, is_hsm, **kwargs): mock_handler.close() - @pytest.mark.parametrize("api_version,is_hsm",only_hsm_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm_7_4_plus) @KeysClientPreparer() @recorded_by_proxy def test_get_random_bytes(self, client, **kwargs): @@ -509,11 +516,11 @@ def test_get_random_bytes(self, client, **kwargs): assert all(random_bytes != rb for rb in generated_random_bytes) generated_random_bytes.append(random_bytes) - @pytest.mark.parametrize("api_version,is_hsm",only_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_7_4_plus) @KeysClientPreparer() @recorded_by_proxy def test_key_release(self, client, is_hsm, **kwargs): - if (self.is_live and os.environ["KEYVAULT_SKU"] != "premium"): + if self.is_live and os.environ["KEYVAULT_SKU"] != "premium": pytest.skip("This test is not supported on standard SKU vaults. Follow up with service team") if is_hsm and client.api_version == ApiVersion.V7_5: pytest.skip("Currently failing on 7.5-preview.1; skipping for now") @@ -538,7 +545,7 @@ def test_key_release(self, client, is_hsm, **kwargs): if self.is_live and "Target environment attestation statement cannot be verified" in ex.message: pytest.skip("Target environment attestation statement cannot be verified. Likely transient failure.") - @pytest.mark.parametrize("api_version,is_hsm",only_hsm_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm_7_4_plus) @KeysClientPreparer() @recorded_by_proxy def test_imported_key_release(self, client, **kwargs): @@ -560,11 +567,11 @@ def test_imported_key_release(self, client, **kwargs): release_result = client.release_key(imported_key_name, attestation) assert release_result.value - @pytest.mark.parametrize("api_version,is_hsm",only_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_7_4_plus) @KeysClientPreparer() @recorded_by_proxy def test_update_release_policy(self, client, **kwargs): - if (self.is_live and os.environ["KEYVAULT_SKU"] != "premium"): + if self.is_live and os.environ["KEYVAULT_SKU"] != "premium": pytest.skip("This test is not supported on standard SKU vaults. Follow up with service team") if client.api_version == ApiVersion.V7_5: pytest.skip("Currently failing on 7.5-preview.1; skipping for now") @@ -584,17 +591,9 @@ def test_update_release_policy(self, client, **kwargs): new_release_policy_json = { "anyOf": [ - { - "anyOf": [ - { - "claim": "sdk-test", - "equals": False - } - ], - "authority": attestation_uri.rstrip("/") + "/" - } + {"anyOf": [{"claim": "sdk-test", "equals": False}], "authority": attestation_uri.rstrip("/") + "/"} ], - "version": "1.0.0" + "version": "1.0.0", } policy_string = json.dumps(new_release_policy_json).encode() new_release_policy = KeyReleasePolicy(policy_string) @@ -605,12 +604,12 @@ def test_update_release_policy(self, client, **kwargs): claim_condition = claim_condition if isinstance(claim_condition, bool) else json.loads(claim_condition) assert claim_condition is False - #Immutable policies aren't currently supported on Managed HSM - @pytest.mark.parametrize("api_version,is_hsm",only_vault_7_4_plus) + # Immutable policies aren't currently supported on Managed HSM + @pytest.mark.parametrize("api_version,is_hsm", only_vault_7_4_plus) @KeysClientPreparer() @recorded_by_proxy def test_immutable_release_policy(self, client, **kwargs): - if (self.is_live and os.environ["KEYVAULT_SKU"] != "premium"): + if self.is_live and os.environ["KEYVAULT_SKU"] != "premium": pytest.skip("This test is not supported on standard SKU vaults. Follow up with service team") attestation_uri = self._get_attestation_uri() @@ -624,17 +623,9 @@ def test_immutable_release_policy(self, client, **kwargs): new_release_policy_json = { "anyOf": [ - { - "anyOf": [ - { - "claim": "sdk-test", - "equals": False - } - ], - "authority": attestation_uri.rstrip("/") + "/" - } + {"anyOf": [{"claim": "sdk-test", "equals": False}], "authority": attestation_uri.rstrip("/") + "/"} ], - "version": "1.0.0" + "version": "1.0.0", } policy_string = json.dumps(new_release_policy_json).encode() new_release_policy = KeyReleasePolicy(policy_string, immutable=True) @@ -642,11 +633,11 @@ def test_immutable_release_policy(self, client, **kwargs): with pytest.raises(HttpResponseError): self._update_key_properties(client, key, new_release_policy) - @pytest.mark.parametrize("api_version,is_hsm",only_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_7_4_plus) @KeysClientPreparer() @recorded_by_proxy def test_key_rotation(self, client, is_hsm, **kwargs): - if (not is_public_cloud() and self.is_live): + if not is_public_cloud() and self.is_live: pytest.skip("This test is not supported in usgov/china region. Follow up with service team.") key_name = self.get_resource_name("rotation-key") @@ -663,11 +654,11 @@ def test_key_rotation(self, client, is_hsm, **kwargs): assert key.properties.version != rotated_key.properties.version assert key.key.n != rotated_key.key.n - @pytest.mark.parametrize("api_version,is_hsm",only_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_7_4_plus) @KeysClientPreparer() @recorded_by_proxy def test_key_rotation_policy(self, client, is_hsm, **kwargs): - if (not is_public_cloud() and self.is_live): + if not is_public_cloud() and self.is_live: pytest.skip("This test is not supported in usgov/china region. Follow up with service team.") key_name = self.get_resource_name("rotation-key") @@ -720,7 +711,9 @@ def test_key_rotation_policy(self, client, is_hsm, **kwargs): if not is_hsm: # updating with a round-tripped policy and overriding lifetime_actions newest_actions = [KeyRotationLifetimeAction(KeyRotationPolicyAction.notify, time_before_expiry="P60D")] - newest_policy = client.update_key_rotation_policy(key_name, policy=new_policy, lifetime_actions=newest_actions) + newest_policy = client.update_key_rotation_policy( + key_name, policy=new_policy, lifetime_actions=newest_actions + ) newest_fetched_policy = client.get_key_rotation_policy(key_name) assert newest_policy.expires_in == "P90D" _assert_rotation_policies_equal(newest_policy, newest_fetched_policy) @@ -738,7 +731,7 @@ def test_key_rotation_policy(self, client, is_hsm, **kwargs): newest_fetched_policy_actions = newest_fetched_policy.lifetime_actions[i] _assert_lifetime_actions_equal(newest_policy_actions, newest_fetched_policy_actions) - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_get_cryptography_client(self, client, is_hsm, **kwargs): @@ -774,7 +767,7 @@ def test_get_cryptography_client(self, client, is_hsm, **kwargs): assert "RSA-OAEP" == result.algorithm assert plaintext == result.plaintext - @pytest.mark.parametrize("api_version,is_hsm",only_vault_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_vault_7_4_plus) @KeysClientPreparer() @recorded_by_proxy def test_send_request(self, client, is_hsm, **kwargs): @@ -790,7 +783,7 @@ def test_send_request(self, client, is_hsm, **kwargs): response = client.send_request(request) assert response.json()["key"]["kid"] == key.id - @pytest.mark.parametrize("api_version,is_hsm",only_hsm_default) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm_default) @KeysClientPreparer() @recorded_by_proxy def test_get_key_attestation(self, client, **kwargs): @@ -834,6 +827,7 @@ def test_40x_handling(self, client, **kwargs): # Test that 409 is raised correctly (`create_key` shouldn't actually trigger this, but for raising behavior) def run(*_, **__): return Mock(http_response=Mock(status_code=409)) + with patch.object(client._client._client._pipeline, "run", run): with pytest.raises(ResourceExistsError): client.create_key("...", "RSA") diff --git a/sdk/keyvault/azure-keyvault-keys/tests/test_keys_async.py b/sdk/keyvault/azure-keyvault-keys/tests/test_keys_async.py index f7a8c1fcf8c1..65b553d0b3f4 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/test_keys_async.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/test_keys_async.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # ------------------------------------ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. @@ -28,7 +29,13 @@ import pytest from _shared.test_case_async import KeyVaultTestCase -from _async_test_case import get_attestation_token, get_decorator, get_release_policy, is_public_cloud, AsyncKeysClientPreparer +from _async_test_case import ( + get_attestation_token, + get_decorator, + get_release_policy, + is_public_cloud, + AsyncKeysClientPreparer, +) from test_key_client import _assert_lifetime_actions_equal, _assert_rotation_policies_equal from devtools_testutils import set_bodiless_matcher from devtools_testutils.aio import recorded_by_proxy_async @@ -38,12 +45,8 @@ all_api_versions = get_decorator(is_async=True) only_hsm = get_decorator(only_hsm=True, is_async=True) only_hsm_default = get_decorator(only_hsm=True, is_async=True, api_versions=[DEFAULT_VERSION]) -only_hsm_7_4_plus = get_decorator( - only_hsm=True, is_async=True, api_versions=[ApiVersion.V7_4, ApiVersion.V7_5] -) -only_vault_7_4_plus = get_decorator( - only_vault=True, is_async=True, api_versions=[ApiVersion.V7_4, ApiVersion.V7_5] -) +only_hsm_7_4_plus = get_decorator(only_hsm=True, is_async=True, api_versions=[ApiVersion.V7_4, ApiVersion.V7_5]) +only_vault_7_4_plus = get_decorator(only_vault=True, is_async=True, api_versions=[ApiVersion.V7_4, ApiVersion.V7_5]) only_7_4_plus = get_decorator(is_async=True, api_versions=[ApiVersion.V7_4, ApiVersion.V7_5]) logging_enabled = get_decorator(is_async=True, logging_enable=True) logging_disabled = get_decorator(is_async=True, logging_enable=False) @@ -69,15 +72,15 @@ def _assert_jwks_equal(self, jwk1, jwk2): assert getattr(jwk1, field) == getattr(jwk2, field) def _assert_key_attributes_equal(self, k1: KeyProperties, k2: KeyProperties) -> None: - assert k1.name== k2.name - assert k1.vault_url== k2.vault_url - assert k1.enabled== k2.enabled - assert k1.not_before== k2.not_before - assert k1.expires_on== k2.expires_on - assert k1.created_on== k2.created_on - assert k1.updated_on== k2.updated_on - assert k1.tags== k2.tags - assert k1.recovery_level== k2.recovery_level + assert k1.name == k2.name + assert k1.vault_url == k2.vault_url + assert k1.enabled == k2.enabled + assert k1.not_before == k2.not_before + assert k1.expires_on == k2.expires_on + assert k1.created_on == k2.created_on + assert k1.updated_on == k2.updated_on + assert k1.tags == k2.tags + assert k1.recovery_level == k2.recovery_level assert k1.hsm_platform == k2.hsm_platform async def _create_rsa_key(self, client, key_name, **kwargs): @@ -107,7 +110,9 @@ def _validate_ec_key_bundle(self, key_curve, key_attributes, vault, key_name, kt assert key_curve == key.crv assert kid.index(prefix) == 0, f"Key Id should start with '{prefix}', but value is '{kid}'" assert key.kty == kty, f"kty should be '{kty}', but is '{key.kty}'" - assert key_attributes.properties.created_on and key_attributes.properties.updated_on,"Missing required date attributes." + assert ( + key_attributes.properties.created_on and key_attributes.properties.updated_on + ), "Missing required date attributes." def _validate_rsa_key_bundle(self, key_attributes, vault, key_name, kty, key_ops): prefix = "/".join(s.strip("/") for s in [vault, "keys", key_name]) @@ -117,7 +122,9 @@ def _validate_rsa_key_bundle(self, key_attributes, vault, key_name, kty, key_ops assert key.kty == kty, f"kty should be '{kty}', but is '{key.kty}'" assert key.n and key.e, "Bad RSA public material." assert sorted(key_ops) == sorted(key.key_ops), f"keyOps should be '{key_ops}', but is '{key.key_ops}'" - assert key_attributes.properties.created_on and key_attributes.properties.updated_on,"Missing required date attributes." + assert ( + key_attributes.properties.created_on and key_attributes.properties.updated_on + ), "Missing required date attributes." async def _update_key_properties(self, client, key, release_policy=None): expires = date_parse.parse("2050-01-02T08:00:00.000Z") @@ -183,7 +190,7 @@ def _to_bytes(hex): return imported_key @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_key_crud_operations(self, client, is_hsm, **kwargs): @@ -224,9 +231,7 @@ async def test_key_crud_operations(self, client, is_hsm, **kwargs): self._assert_key_attributes_equal(rsa_key.properties, key.properties) # get key without version - self._assert_key_attributes_equal( - rsa_key.properties, (await client.get_key(rsa_key.name)).properties - ) + self._assert_key_attributes_equal(rsa_key.properties, (await client.get_key(rsa_key.name)).properties) # update key with version if self.is_live: @@ -242,7 +247,9 @@ async def test_key_crud_operations(self, client, is_hsm, **kwargs): # aside from key_ops, the original updated keys should have the same JWKs self._assert_jwks_equal(rsa_key.key, deleted_key.key) assert deleted_key.id == rsa_key.id - assert deleted_key.recovery_id and deleted_key.deleted_date and deleted_key.scheduled_purge_date,"Missing required deleted key attributes." + assert ( + deleted_key.recovery_id and deleted_key.deleted_date and deleted_key.scheduled_purge_date + ), "Missing required deleted key attributes." # get the deleted key when soft deleted enabled deleted_key = await client.get_deleted_key(rsa_key.name) @@ -250,7 +257,7 @@ async def test_key_crud_operations(self, client, is_hsm, **kwargs): assert rsa_key.id == deleted_key.id @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_hsm) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_rsa_public_exponent(self, client, **kwargs): @@ -263,7 +270,7 @@ async def test_rsa_public_exponent(self, client, **kwargs): assert public_exponent == 17 @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_backup_restore(self, client, is_hsm, **kwargs): @@ -276,7 +283,7 @@ async def test_backup_restore(self, client, is_hsm, **kwargs): # backup key key_backup = await client.backup_key(created_bundle.name) - #self.assertIsNotNone(key_backup, "key_backup") + # self.assertIsNotNone(key_backup, "key_backup") assert key_backup is not None # delete key @@ -291,7 +298,7 @@ async def test_backup_restore(self, client, is_hsm, **kwargs): self._assert_key_attributes_equal(created_bundle.properties, restored_key.properties) @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_key_list(self, client, is_hsm, **kwargs): @@ -315,7 +322,7 @@ async def test_key_list(self, client, is_hsm, **kwargs): assert len(expected) == 0 @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_list_versions(self, client, is_hsm, **kwargs): @@ -343,7 +350,7 @@ async def test_list_versions(self, client, is_hsm, **kwargs): @pytest.mark.asyncio @pytest.mark.skip("Temporarily disabled due to service issue") - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_list_deleted_keys(self, client, is_hsm, **kwargs): @@ -376,7 +383,7 @@ async def test_list_deleted_keys(self, client, is_hsm, **kwargs): @pytest.mark.asyncio @pytest.mark.skip("Temporarily disabled due to service issue") - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_recover(self, client, is_hsm, **kwargs): @@ -407,7 +414,7 @@ async def test_recover(self, client, is_hsm, **kwargs): assert len(set(expected.keys()) & set(actual.keys())) == len(expected) @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_purge(self, client, is_hsm, **kwargs): @@ -435,8 +442,8 @@ async def test_purge(self, client, is_hsm, **kwargs): assert deleted_key.name not in key_names @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",logging_enabled) - @AsyncKeysClientPreparer(logging_enable = True) + @pytest.mark.parametrize("api_version,is_hsm", logging_enabled) + @AsyncKeysClientPreparer(logging_enable=True) @recorded_by_proxy_async async def test_logging_enabled(self, client, is_hsm, **kwargs): mock_handler = MockHandler() @@ -471,8 +478,8 @@ async def test_logging_enabled(self, client, is_hsm, **kwargs): assert False, "Expected request body wasn't logged" @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",logging_disabled) - @AsyncKeysClientPreparer(logging_enable = False) + @pytest.mark.parametrize("api_version,is_hsm", logging_disabled) + @AsyncKeysClientPreparer(logging_enable=False) @recorded_by_proxy_async async def test_logging_disabled(self, client, is_hsm, **kwargs): mock_handler = MockHandler() @@ -506,7 +513,7 @@ async def test_logging_disabled(self, client, is_hsm, **kwargs): mock_handler.close() @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_hsm_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm_7_4_plus) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_get_random_bytes(self, client, **kwargs): @@ -523,11 +530,11 @@ async def test_get_random_bytes(self, client, **kwargs): generated_random_bytes.append(random_bytes) @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_7_4_plus) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_key_release(self, client, is_hsm, **kwargs): - if (self.is_live and os.environ["KEYVAULT_SKU"] != "premium"): + if self.is_live and os.environ["KEYVAULT_SKU"] != "premium": pytest.skip("This test is not supported on standard SKU vaults. Follow up with service team") if is_hsm and client.api_version == ApiVersion.V7_5: pytest.skip("Currently failing on 7.5-preview.1; skipping for now") @@ -553,7 +560,7 @@ async def test_key_release(self, client, is_hsm, **kwargs): pytest.skip("Target environment attestation statement cannot be verified. Likely transient failure.") @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_hsm_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm_7_4_plus) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_imported_key_release(self, client, **kwargs): @@ -576,11 +583,11 @@ async def test_imported_key_release(self, client, **kwargs): assert release_result.value @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_7_4_plus) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_update_release_policy(self, client, **kwargs): - if (self.is_live and os.environ["KEYVAULT_SKU"] != "premium"): + if self.is_live and os.environ["KEYVAULT_SKU"] != "premium": pytest.skip("This test is not supported on standard SKU vaults. Follow up with service team") if client.api_version == ApiVersion.V7_5: pytest.skip("Currently failing on 7.5-preview.1; skipping for now") @@ -600,17 +607,9 @@ async def test_update_release_policy(self, client, **kwargs): new_release_policy_json = { "anyOf": [ - { - "anyOf": [ - { - "claim": "sdk-test", - "equals": False - } - ], - "authority": attestation_uri.rstrip("/") + "/" - } + {"anyOf": [{"claim": "sdk-test", "equals": False}], "authority": attestation_uri.rstrip("/") + "/"} ], - "version": "1.0.0" + "version": "1.0.0", } policy_string = json.dumps(new_release_policy_json).encode() new_release_policy = KeyReleasePolicy(policy_string) @@ -623,11 +622,11 @@ async def test_update_release_policy(self, client, **kwargs): # Immutable policies aren't currently supported on Managed HSM @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_vault_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_vault_7_4_plus) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_immutable_release_policy(self, client, **kwargs): - if (self.is_live and os.environ["KEYVAULT_SKU"] != "premium"): + if self.is_live and os.environ["KEYVAULT_SKU"] != "premium": pytest.skip("This test is not supported on standard SKU vaults. Follow up with service team") attestation_uri = self._get_attestation_uri() @@ -641,17 +640,9 @@ async def test_immutable_release_policy(self, client, **kwargs): new_release_policy_json = { "anyOf": [ - { - "anyOf": [ - { - "claim": "sdk-test", - "equals": False - } - ], - "authority": attestation_uri.rstrip("/") + "/" - } + {"anyOf": [{"claim": "sdk-test", "equals": False}], "authority": attestation_uri.rstrip("/") + "/"} ], - "version": "1.0.0" + "version": "1.0.0", } policy_string = json.dumps(new_release_policy_json).encode() new_release_policy = KeyReleasePolicy(policy_string, immutable=True) @@ -660,11 +651,11 @@ async def test_immutable_release_policy(self, client, **kwargs): await self._update_key_properties(client, key, new_release_policy) @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_7_4_plus) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_key_rotation(self, client, is_hsm, **kwargs): - if (not is_public_cloud() and self.is_live): + if not is_public_cloud() and self.is_live: pytest.skip("This test is not supported in usgov/china region. Follow up with service team.") key_name = self.get_resource_name("rotation-key") @@ -684,11 +675,11 @@ async def test_key_rotation(self, client, is_hsm, **kwargs): assert key.key.n != rotated_key.key.n @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_7_4_plus) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_key_rotation_policy(self, client, is_hsm, **kwargs): - if (not is_public_cloud() and self.is_live): + if not is_public_cloud() and self.is_live: pytest.skip("This test is not supported in usgov/china region. Follow up with service team.") key_name = self.get_resource_name("rotation-key") @@ -763,7 +754,7 @@ async def test_key_rotation_policy(self, client, is_hsm, **kwargs): _assert_lifetime_actions_equal(newest_policy_actions, newest_fetched_policy_actions) @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_get_cryptography_client(self, client, is_hsm, **kwargs): @@ -800,7 +791,7 @@ async def test_get_cryptography_client(self, client, is_hsm, **kwargs): assert plaintext == result.plaintext @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_vault_7_4_plus) + @pytest.mark.parametrize("api_version,is_hsm", only_vault_7_4_plus) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_send_request(self, client, is_hsm, **kwargs): @@ -817,7 +808,7 @@ async def test_send_request(self, client, is_hsm, **kwargs): assert response.json()["key"]["kid"] == key.id @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_hsm_default) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm_default) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_get_key_attestation(self, client, **kwargs): @@ -864,6 +855,7 @@ async def test_40x_handling(self, client, **kwargs): # Test that 409 is raised correctly (`create_key` shouldn't actually trigger this, but for raising behavior) async def run(*_, **__): return Mock(http_response=Mock(status_code=409)) + with patch.object(client._client._client._pipeline, "run", run): with pytest.raises(ResourceExistsError): await client.create_key("...", "RSA") diff --git a/sdk/keyvault/azure-keyvault-keys/tests/test_local_crypto.py b/sdk/keyvault/azure-keyvault-keys/tests/test_local_crypto.py index 52ec32992543..e9b2867fc08d 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/test_local_crypto.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/test_local_crypto.py @@ -7,10 +7,8 @@ import pytest from azure.keyvault.keys import KeyCurveName, KeyVaultKey -from azure.keyvault.keys.crypto import (EncryptionAlgorithm, KeyWrapAlgorithm, - SignatureAlgorithm) -from azure.keyvault.keys.crypto._providers import \ - get_local_cryptography_provider +from azure.keyvault.keys.crypto import EncryptionAlgorithm, KeyWrapAlgorithm, SignatureAlgorithm +from azure.keyvault.keys.crypto._providers import get_local_cryptography_provider from keys import EC_KEYS, RSA_KEYS @@ -48,14 +46,14 @@ def test_rsa_encrypt_decrypt(key, algorithm): (EncryptionAlgorithm.a256_cbcpad, 32), (EncryptionAlgorithm.a192_cbcpad, 24), (EncryptionAlgorithm.a128_cbcpad, 16), - ) + ), ) def test_symmetric_encrypt_decrypt(algorithm, key_size): jwk = { "k": os.urandom(key_size), - "kid":"http://localhost/keys/key/version", + "kid": "http://localhost/keys/key/version", "kty": "oct-HSM", - "key_ops": ("encrypt", "decrypt") + "key_ops": ("encrypt", "decrypt"), } key = KeyVaultKey(key_id="http://localhost/keys/key/version", jwk=jwk) provider = get_local_cryptography_provider(key.key) @@ -119,9 +117,9 @@ def test_rsa_wrap_unwrap(key, algorithm): def test_symmetric_wrap_unwrap(algorithm): jwk = { "k": os.urandom(32), - "kid":"http://localhost/keys/key/version", + "kid": "http://localhost/keys/key/version", "kty": "oct", - "key_ops": ("unwrapKey", "wrapKey") + "key_ops": ("unwrapKey", "wrapKey"), } key = KeyVaultKey(key_id="http://localhost/keys/key/version", jwk=jwk) provider = get_local_cryptography_provider(key.key) diff --git a/sdk/keyvault/azure-keyvault-keys/tests/test_parse_id.py b/sdk/keyvault/azure-keyvault-keys/tests/test_parse_id.py index 3f72b8cb9556..eb33db5f2860 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/test_parse_id.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/test_parse_id.py @@ -15,7 +15,7 @@ class TestParseId(KeyVaultTestCase, KeysTestCase): - @pytest.mark.parametrize("api_version,is_hsm",only_vault) + @pytest.mark.parametrize("api_version,is_hsm", only_vault) @KeysClientPreparer() @recorded_by_proxy def test_parse_key_id_with_version(self, client, **kwargs): diff --git a/sdk/keyvault/azure-keyvault-keys/tests/test_samples_keys.py b/sdk/keyvault/azure-keyvault-keys/tests/test_samples_keys.py index 68e2b6496d64..be044fe64650 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/test_samples_keys.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/test_samples_keys.py @@ -36,11 +36,11 @@ def test_create_key_client(): class TestExamplesKeyVault(KeyVaultTestCase, KeysTestCase): - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_example_key_crud_operations(self, key_client, **kwargs): - if (self.is_live and os.environ["KEYVAULT_SKU"] != "premium"): + if self.is_live and os.environ["KEYVAULT_SKU"] != "premium": pytest.skip("This test is not supported on standard SKU vaults. Follow up with service team") key_name = self.get_resource_name("key-name") @@ -131,7 +131,7 @@ def test_example_key_crud_operations(self, key_client, **kwargs): deleted_key_poller.wait() # [END delete_key] - @pytest.mark.parametrize("api_version,is_hsm",only_hsm) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm) @KeysClientPreparer() @recorded_by_proxy def test_example_create_oct_key(self, key_client, **kwargs): @@ -145,7 +145,7 @@ def test_example_create_oct_key(self, key_client, **kwargs): print(key.key_type) # [END create_oct_key] - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_example_key_list_operations(self, key_client, **kwargs): @@ -186,7 +186,7 @@ def test_example_key_list_operations(self, key_client, **kwargs): print(key.deleted_date) # [END list_deleted_keys] - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_example_keys_backup_restore(self, key_client, **kwargs): @@ -219,7 +219,7 @@ def test_example_keys_backup_restore(self, key_client, **kwargs): print(restored_key.properties.version) # [END restore_key_backup] - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @KeysClientPreparer() @recorded_by_proxy def test_example_keys_recover(self, key_client, **kwargs): diff --git a/sdk/keyvault/azure-keyvault-keys/tests/test_samples_keys_async.py b/sdk/keyvault/azure-keyvault-keys/tests/test_samples_keys_async.py index 0357017a4b44..e8e127c82d9e 100644 --- a/sdk/keyvault/azure-keyvault-keys/tests/test_samples_keys_async.py +++ b/sdk/keyvault/azure-keyvault-keys/tests/test_samples_keys_async.py @@ -42,11 +42,11 @@ async def test_create_key_client(): class TestExamplesKeyVault(KeyVaultTestCase): @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_example_key_crud_operations(self, key_client, **kwargs): - if (self.is_live and os.environ["KEYVAULT_SKU"] != "premium"): + if self.is_live and os.environ["KEYVAULT_SKU"] != "premium": pytest.skip("This test is not supported on standard SKU vaults. Follow up with service team") key_name = self.get_resource_name("key-name") @@ -132,7 +132,7 @@ async def test_example_key_crud_operations(self, key_client, **kwargs): # [END delete_key] @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",only_hsm) + @pytest.mark.parametrize("api_version,is_hsm", only_hsm) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_example_create_oct_key(self, key_client, **kwargs): @@ -147,7 +147,7 @@ async def test_example_create_oct_key(self, key_client, **kwargs): # [END create_oct_key] @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_example_key_list_operations(self, key_client, **kwargs): @@ -194,7 +194,7 @@ async def test_example_key_list_operations(self, key_client, **kwargs): # [END list_deleted_keys] @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_example_keys_backup_restore(self, key_client, **kwargs): @@ -229,7 +229,7 @@ async def test_example_keys_backup_restore(self, key_client, **kwargs): # [END restore_key_backup] @pytest.mark.asyncio - @pytest.mark.parametrize("api_version,is_hsm",all_api_versions) + @pytest.mark.parametrize("api_version,is_hsm", all_api_versions) @AsyncKeysClientPreparer() @recorded_by_proxy_async async def test_example_keys_recover(self, key_client, **kwargs): diff --git a/sdk/keyvault/azure-keyvault-keys/tsp-location.yaml b/sdk/keyvault/azure-keyvault-keys/tsp-location.yaml new file mode 100644 index 000000000000..e438449705de --- /dev/null +++ b/sdk/keyvault/azure-keyvault-keys/tsp-location.yaml @@ -0,0 +1,5 @@ +directory: specification/keyvault/Security.KeyVault.Keys +commit: 4465f2aaefeb75e8a088c7e0950979e03430a234 +repo: Azure/azure-rest-api-specs +additionalDirectories: +- specification/keyvault/Security.KeyVault.Common