Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-azure-keyvault-administration 
for openSUSE:Factory checked in at 2026-07-14 13:48:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-azure-keyvault-administration (Old)
 and      
/work/SRC/openSUSE:Factory/.python-azure-keyvault-administration.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-azure-keyvault-administration"

Tue Jul 14 13:48:50 2026 rev:16 rq:1365370 version:4.8.0~b2

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-azure-keyvault-administration/python-azure-keyvault-administration.changes
        2026-07-08 17:40:55.910659810 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-azure-keyvault-administration.new.1991/python-azure-keyvault-administration.changes
      2026-07-14 13:49:22.405833356 +0200
@@ -1,0 +2,8 @@
+Fri Jul 10 07:51:36 UTC 2026 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- New upstream release
+  + Version 4.8.0b2
+  + For detailed information about changes see the
+    CHANGELOG.md file provided with this package
+
+-------------------------------------------------------------------

Old:
----
  azure_keyvault_administration-4.8.0b1.tar.gz

New:
----
  azure_keyvault_administration-4.8.0b2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-azure-keyvault-administration.spec ++++++
--- /var/tmp/diff_new_pack.p0496d/_old  2026-07-14 13:49:23.125857972 +0200
+++ /var/tmp/diff_new_pack.p0496d/_new  2026-07-14 13:49:23.133858245 +0200
@@ -16,11 +16,11 @@
 #
 
 
-%define realversion 4.8.0b1
+%define realversion 4.8.0b2
 
 %{?sle15_python_module_pythons}
 Name:           python-azure-keyvault-administration
-Version:        4.8.0~b1
+Version:        4.8.0~b2
 Release:        0
 Summary:        Microsoft Azure Key Vault Administration Client Library for 
Python
 License:        MIT

++++++ azure_keyvault_administration-4.8.0b1.tar.gz -> 
azure_keyvault_administration-4.8.0b2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_keyvault_administration-4.8.0b1/CHANGELOG.md 
new/azure_keyvault_administration-4.8.0b2/CHANGELOG.md
--- old/azure_keyvault_administration-4.8.0b1/CHANGELOG.md      2026-05-29 
18:27:52.000000000 +0200
+++ new/azure_keyvault_administration-4.8.0b2/CHANGELOG.md      2026-07-08 
14:56:42.000000000 +0200
@@ -1,5 +1,11 @@
 # Release History
 
+## 4.8.0b2 (2026-07-08)
+
+### Bugs Fixed
+
+- Fixed a replay bug in challenge authentication policy. The original request 
is now stored at the request level instead of the client level. 
[#47742](https://github.com/Azure/azure-sdk-for-python/pull/47742)
+
 ## 4.8.0b1 (2026-05-29)
 
 ### Features Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_keyvault_administration-4.8.0b1/PKG-INFO 
new/azure_keyvault_administration-4.8.0b2/PKG-INFO
--- old/azure_keyvault_administration-4.8.0b1/PKG-INFO  2026-05-29 
18:29:01.517442200 +0200
+++ new/azure_keyvault_administration-4.8.0b2/PKG-INFO  2026-07-08 
14:57:40.448423400 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: azure-keyvault-administration
-Version: 4.8.0b1
+Version: 4.8.0b2
 Summary: Microsoft Corporation Key Vault Administration Client Library for 
Python
 Home-page: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk
 Author: Microsoft Corporation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_keyvault_administration-4.8.0b1/api.md 
new/azure_keyvault_administration-4.8.0b2/api.md
--- old/azure_keyvault_administration-4.8.0b1/api.md    1970-01-01 
01:00:00.000000000 +0100
+++ new/azure_keyvault_administration-4.8.0b2/api.md    2026-07-08 
14:56:42.000000000 +0200
@@ -0,0 +1,758 @@
+```py
+namespace azure.keyvault.administration
+
+    class azure.keyvault.administration.ApiVersion(str, Enum, 
metaclass=CaseInsensitiveEnumMeta):
+        V2025_07_01 = "2025-07-01"
+        V2026_01_01_PREVIEW = "2026-01-01-preview"
+        V7_2 = "7.2"
+        V7_3 = "7.3"
+        V7_4 = "7.4"
+        V7_5 = "7.5"
+        V7_6 = "7.6"
+
+
+    class 
azure.keyvault.administration.KeyVaultAccessControlClient(KeyVaultClientBase): 
implements ContextManager 
+        property vault_url: str    # Read-only
+
+        def __init__(
+                self, 
+                vault_url: str, 
+                credential: TokenCredential, 
+                *, 
+                api_version: Union[ApiVersion, str] = ..., 
+                verify_challenge_resource: Optional[bool] = ..., 
+                **kwargs: Any
+            ) -> None: ...
+
+        def close(self) -> None: ...
+
+        @distributed_trace
+        def create_role_assignment(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                definition_id: str, 
+                principal_id: str, 
+                *, 
+                name: Optional[Union[str, UUID]] = ..., 
+                **kwargs: Any
+            ) -> KeyVaultRoleAssignment: ...
+
+        @distributed_trace
+        def delete_role_assignment(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                name: Union[str, UUID], 
+                **kwargs: Any
+            ) -> None: ...
+
+        @distributed_trace
+        def delete_role_definition(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                name: Union[str, UUID], 
+                **kwargs: Any
+            ) -> None: ...
+
+        @distributed_trace
+        def get_role_assignment(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                name: Union[str, UUID], 
+                **kwargs: Any
+            ) -> KeyVaultRoleAssignment: ...
+
+        @distributed_trace
+        def get_role_definition(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                name: Union[str, UUID], 
+                **kwargs: Any
+            ) -> KeyVaultRoleDefinition: ...
+
+        @distributed_trace
+        def list_role_assignments(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                **kwargs: Any
+            ) -> ItemPaged[KeyVaultRoleAssignment]: ...
+
+        @distributed_trace
+        def list_role_definitions(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                **kwargs: Any
+            ) -> ItemPaged[KeyVaultRoleDefinition]: ...
+
+        @distributed_trace
+        def send_request(
+                self, 
+                request: HttpRequest, 
+                *, 
+                stream: bool = False, 
+                **kwargs: Any
+            ) -> HttpResponse: ...
+
+        @distributed_trace
+        def set_role_definition(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                *, 
+                assignable_scopes: Optional[List[Union[str, 
KeyVaultRoleScope]]] = ..., 
+                description: Optional[str] = ..., 
+                name: Optional[Union[str, UUID]] = ..., 
+                permissions: Optional[List[KeyVaultPermission]] = ..., 
+                role_name: Optional[str] = ..., 
+                **kwargs: Any
+            ) -> KeyVaultRoleDefinition: ...
+
+
+    class 
azure.keyvault.administration.KeyVaultBackupClient(KeyVaultClientBase): 
implements ContextManager 
+        property vault_url: str    # Read-only
+
+        def __init__(
+                self, 
+                vault_url: str, 
+                credential: TokenCredential, 
+                *, 
+                api_version: Union[ApiVersion, str] = ..., 
+                verify_challenge_resource: Optional[bool] = ..., 
+                **kwargs: Any
+            ) -> None: ...
+
+        @overload
+        def begin_backup(
+                self, 
+                blob_storage_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                use_managed_identity: Literal[True], 
+                **kwargs: Any
+            ) -> LROPoller[KeyVaultBackupResult]: ...
+
+        @overload
+        def begin_backup(
+                self, 
+                blob_storage_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                sas_token: str, 
+                **kwargs: Any
+            ) -> LROPoller[KeyVaultBackupResult]: ...
+
+        @overload
+        def begin_pre_backup(
+                self, 
+                blob_storage_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                use_managed_identity: Literal[True], 
+                **kwargs: Any
+            ) -> LROPoller[None]: ...
+
+        @overload
+        def begin_pre_backup(
+                self, 
+                blob_storage_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                sas_token: str, 
+                **kwargs: Any
+            ) -> LROPoller[None]: ...
+
+        @overload
+        def begin_pre_restore(
+                self, 
+                folder_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                use_managed_identity: Literal[True], 
+                **kwargs: Any
+            ) -> LROPoller[None]: ...
+
+        @overload
+        def begin_pre_restore(
+                self, 
+                folder_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                sas_token: str, 
+                **kwargs: Any
+            ) -> LROPoller[None]: ...
+
+        @overload
+        def begin_restore(
+                self, 
+                folder_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                key_name: Optional[str] = ..., 
+                use_managed_identity: Literal[True], 
+                **kwargs: Any
+            ) -> LROPoller[None]: ...
+
+        @overload
+        def begin_restore(
+                self, 
+                folder_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                key_name: Optional[str] = ..., 
+                sas_token: str, 
+                **kwargs: Any
+            ) -> LROPoller[None]: ...
+
+        def close(self) -> None: ...
+
+        @distributed_trace
+        def send_request(
+                self, 
+                request: HttpRequest, 
+                *, 
+                stream: bool = False, 
+                **kwargs: Any
+            ) -> HttpResponse: ...
+
+
+    class azure.keyvault.administration.KeyVaultBackupResult:
+        folder_url: str
+
+        def __init__(self, **kwargs: Any) -> None: ...
+
+
+    class azure.keyvault.administration.KeyVaultDataAction(str, Enum, 
metaclass=CaseInsensitiveEnumMeta):
+        BACKUP_HSM_KEYS = "Microsoft.KeyVault/managedHsm/keys/backup/action"
+        CREATE_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/create"
+        DECRYPT_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/decrypt/action"
+        DELETE_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/delete"
+        DELETE_ROLE_ASSIGNMENT = 
"Microsoft.KeyVault/managedHsm/roleAssignments/delete/action"
+        DELETE_ROLE_DEFINITION = 
"Microsoft.KeyVault/managedHsm/roleDefinitions/delete/action"
+        DOWNLOAD_HSM_SECURITY_DOMAIN = 
"Microsoft.KeyVault/managedHsm/securitydomain/download/action"
+        DOWNLOAD_HSM_SECURITY_DOMAIN_STATUS = 
"Microsoft.KeyVault/managedHsm/securitydomain/download/read"
+        ENCRYPT_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/encrypt/action"
+        EXPORT_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/export/action"
+        GET_ROLE_ASSIGNMENT = 
"Microsoft.KeyVault/managedHsm/roleAssignments/read/action"
+        IMPORT_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/import/action"
+        PURGE_DELETED_HSM_KEY = 
"Microsoft.KeyVault/managedHsm/keys/deletedKeys/delete"
+        RANDOM_NUMBERS_GENERATE = "Microsoft.KeyVault/managedHsm/rng/action"
+        READ_DELETED_HSM_KEY = 
"Microsoft.KeyVault/managedHsm/keys/deletedKeys/read/action"
+        READ_HSM_BACKUP_STATUS = 
"Microsoft.KeyVault/managedHsm/backup/status/action"
+        READ_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/read/action"
+        READ_HSM_RESTORE_STATUS = 
"Microsoft.KeyVault/managedHsm/restore/status/action"
+        READ_HSM_SECURITY_DOMAIN_STATUS = 
"Microsoft.KeyVault/managedHsm/securitydomain/upload/read"
+        READ_HSM_SECURITY_DOMAIN_TRANSFER_KEY = 
"Microsoft.KeyVault/managedHsm/securitydomain/transferkey/read"
+        READ_ROLE_DEFINITION = 
"Microsoft.KeyVault/managedHsm/roleDefinitions/read/action"
+        RECOVER_DELETED_HSM_KEY = 
"Microsoft.KeyVault/managedHsm/keys/deletedKeys/recover/action"
+        RELEASE_KEY = "Microsoft.KeyVault/managedHsm/keys/release/action"
+        RESTORE_HSM_KEYS = "Microsoft.KeyVault/managedHsm/keys/restore/action"
+        SIGN_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/sign/action"
+        START_HSM_BACKUP = "Microsoft.KeyVault/managedHsm/backup/start/action"
+        START_HSM_RESTORE = 
"Microsoft.KeyVault/managedHsm/restore/start/action"
+        UNWRAP_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/unwrap/action"
+        UPLOAD_HSM_SECURITY_DOMAIN = 
"Microsoft.KeyVault/managedHsm/securitydomain/upload/action"
+        VERIFY_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/verify/action"
+        WRAP_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/wrap/action"
+        WRITE_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/write/action"
+        WRITE_ROLE_ASSIGNMENT = 
"Microsoft.KeyVault/managedHsm/roleAssignments/write/action"
+        WRITE_ROLE_DEFINITION = 
"Microsoft.KeyVault/managedHsm/roleDefinitions/write/action"
+
+
+    class azure.keyvault.administration.KeyVaultEkmClient(KeyVaultClientBase): 
implements ContextManager 
+        property vault_url: str    # Read-only
+
+        def __init__(
+                self, 
+                vault_url: str, 
+                credential: TokenCredential, 
+                *, 
+                api_version: Union[ApiVersion, str] = ..., 
+                verify_challenge_resource: Optional[bool] = ..., 
+                **kwargs: Any
+            ) -> None: ...
+
+        @distributed_trace
+        def check_ekm_connection(self, **kwargs: Any) -> KeyVaultEkmProxyInfo: 
...
+
+        def close(self) -> None: ...
+
+        @distributed_trace
+        def create_ekm_connection(
+                self, 
+                connection: KeyVaultEkmConnection, 
+                **kwargs: Any
+            ) -> KeyVaultEkmConnection: ...
+
+        @distributed_trace
+        def delete_ekm_connection(self, **kwargs: Any) -> 
KeyVaultEkmConnection: ...
+
+        @distributed_trace
+        def get_ekm_certificate(self, **kwargs: Any) -> 
KeyVaultEkmProxyClientCertificateInfo: ...
+
+        @distributed_trace
+        def get_ekm_connection(self, **kwargs: Any) -> KeyVaultEkmConnection: 
...
+
+        @distributed_trace
+        def send_request(
+                self, 
+                request: HttpRequest, 
+                *, 
+                stream: bool = False, 
+                **kwargs: Any
+            ) -> HttpResponse: ...
+
+        @distributed_trace
+        def update_ekm_connection(
+                self, 
+                connection: KeyVaultEkmConnection, 
+                **kwargs: Any
+            ) -> KeyVaultEkmConnection: ...
+
+
+    class azure.keyvault.administration.KeyVaultEkmConnection:
+        host: str
+        path_prefix: Union[str, None]
+        server_ca_certificates: list[bytes]
+        server_subject_common_name: Union[str, None]
+
+        def __init__(
+                self, 
+                host: str, 
+                server_ca_certificates: List[bytes], 
+                *, 
+                path_prefix: Optional[str] = ..., 
+                server_subject_common_name: Optional[str] = ...
+            ) -> None: ...
+
+        def __repr__(self) -> str: ...
+
+
+    class azure.keyvault.administration.KeyVaultEkmProxyClientCertificateInfo:
+        ca_certificates: Union[list[bytes], None]
+        subject_common_name: Union[str, None]
+
+        def __init__(self, **kwargs: Any) -> None: ...
+
+        def __repr__(self) -> str: ...
+
+
+    class azure.keyvault.administration.KeyVaultEkmProxyInfo:
+        api_version: Union[str, None]
+        ekm_product: Union[str, None]
+        ekm_vendor: Union[str, None]
+        proxy_name: Union[str, None]
+        proxy_vendor: Union[str, None]
+
+        def __init__(self, **kwargs: Any) -> None: ...
+
+        def __repr__(self) -> str: ...
+
+
+    class azure.keyvault.administration.KeyVaultPermission:
+        actions: list[str]
+        data_actions: list[str]
+        not_actions: list[str]
+        not_data_actions: list[str]
+
+        def __init__(self, **kwargs: Any) -> None: ...
+
+
+    class azure.keyvault.administration.KeyVaultRoleAssignment:
+        name: str
+        properties: KeyVaultRoleAssignmentProperties
+        role_assignment_id: str
+        type: str
+
+        def __init__(self, **kwargs: Any) -> None: ...
+
+        def __repr__(self) -> str: ...
+
+
+    class azure.keyvault.administration.KeyVaultRoleAssignmentProperties:
+        principal_id: str
+        role_definition_id: str
+        scope: str
+
+        def __init__(self, **kwargs: Any) -> None: ...
+
+        def __repr__(self) -> str: ...
+
+
+    class azure.keyvault.administration.KeyVaultRoleDefinition:
+        assignable_scopes: list[str]
+        description: str
+        id: str
+        name: str
+        permissions: list[KeyVaultPermission]
+        role_name: str
+        role_type: str
+        type: str
+
+        def __init__(self, **kwargs: Any) -> None: ...
+
+        def __repr__(self) -> str: ...
+
+
+    class azure.keyvault.administration.KeyVaultRoleScope(str, Enum, 
metaclass=CaseInsensitiveEnumMeta):
+        GLOBAL = "/"
+        KEYS = "/keys"
+
+
+    class azure.keyvault.administration.KeyVaultSetting:
+        name: str
+        setting_type: Union[str, KeyVaultSettingType, None]
+        value: str
+
+        def __init__(
+                self, 
+                name: str, 
+                value: Union[str, bool], 
+                setting_type: Optional[Union[str, KeyVaultSettingType]] = 
None, 
+                **kwargs
+            ) -> None: ...
+
+        def getboolean(self) -> bool: ...
+
+
+    class azure.keyvault.administration.KeyVaultSettingType(str, Enum, 
metaclass=CaseInsensitiveEnumMeta):
+        BOOLEAN = "boolean"
+
+
+    class 
azure.keyvault.administration.KeyVaultSettingsClient(KeyVaultClientBase): 
implements ContextManager 
+        property vault_url: str    # Read-only
+
+        def __init__(
+                self, 
+                vault_url: str, 
+                credential: TokenCredential, 
+                *, 
+                api_version: Union[ApiVersion, str] = ..., 
+                verify_challenge_resource: Optional[bool] = ..., 
+                **kwargs: Any
+            ) -> None: ...
+
+        def close(self) -> None: ...
+
+        @distributed_trace
+        def get_setting(
+                self, 
+                name: str, 
+                **kwargs: Any
+            ) -> KeyVaultSetting: ...
+
+        @distributed_trace
+        def list_settings(self, **kwargs: Any) -> ItemPaged[KeyVaultSetting]: 
...
+
+        @distributed_trace
+        def send_request(
+                self, 
+                request: HttpRequest, 
+                *, 
+                stream: bool = False, 
+                **kwargs: Any
+            ) -> HttpResponse: ...
+
+        @distributed_trace
+        def update_setting(
+                self, 
+                setting: KeyVaultSetting, 
+                **kwargs: Any
+            ) -> KeyVaultSetting: ...
+
+
+namespace azure.keyvault.administration.aio
+
+    class 
azure.keyvault.administration.aio.KeyVaultAccessControlClient(AsyncKeyVaultClientBase):
 implements AsyncContextManager 
+        property vault_url: str    # Read-only
+
+        def __init__(
+                self, 
+                vault_url: str, 
+                credential: AsyncTokenCredential, 
+                *, 
+                api_version: Union[ApiVersion, str] = ..., 
+                verify_challenge_resource: Optional[bool] = ..., 
+                **kwargs: Any
+            ) -> None: ...
+
+        async def close(self) -> None: ...
+
+        @distributed_trace_async
+        async def create_role_assignment(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                definition_id: str, 
+                principal_id: str, 
+                *, 
+                name: Optional[Union[str, UUID]] = ..., 
+                **kwargs: Any
+            ) -> KeyVaultRoleAssignment: ...
+
+        @distributed_trace_async
+        async def delete_role_assignment(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                name: Union[str, UUID], 
+                **kwargs: Any
+            ) -> None: ...
+
+        @distributed_trace_async
+        async def delete_role_definition(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                name: Union[str, UUID], 
+                **kwargs: Any
+            ) -> None: ...
+
+        @distributed_trace_async
+        async def get_role_assignment(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                name: Union[str, UUID], 
+                **kwargs: Any
+            ) -> KeyVaultRoleAssignment: ...
+
+        @distributed_trace_async
+        async def get_role_definition(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                name: Union[str, UUID], 
+                **kwargs: Any
+            ) -> KeyVaultRoleDefinition: ...
+
+        @distributed_trace
+        def list_role_assignments(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                **kwargs: Any
+            ) -> AsyncItemPaged[KeyVaultRoleAssignment]: ...
+
+        @distributed_trace
+        def list_role_definitions(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                **kwargs: Any
+            ) -> AsyncItemPaged[KeyVaultRoleDefinition]: ...
+
+        @distributed_trace_async
+        def send_request(
+                self, 
+                request: HttpRequest, 
+                *, 
+                stream: bool = False, 
+                **kwargs: Any
+            ) -> Awaitable[AsyncHttpResponse]: ...
+
+        @distributed_trace_async
+        async def set_role_definition(
+                self, 
+                scope: Union[str, KeyVaultRoleScope], 
+                *, 
+                assignable_scopes: Optional[List[Union[str, 
KeyVaultRoleScope]]] = ..., 
+                description: Optional[str] = ..., 
+                name: Optional[Union[str, UUID]] = ..., 
+                permissions: Optional[List[KeyVaultPermission]] = ..., 
+                role_name: Optional[str] = ..., 
+                **kwargs: Any
+            ) -> KeyVaultRoleDefinition: ...
+
+
+    class 
azure.keyvault.administration.aio.KeyVaultBackupClient(AsyncKeyVaultClientBase):
 implements AsyncContextManager 
+        property vault_url: str    # Read-only
+
+        def __init__(
+                self, 
+                vault_url: str, 
+                credential: AsyncTokenCredential, 
+                *, 
+                api_version: Union[ApiVersion, str] = ..., 
+                verify_challenge_resource: Optional[bool] = ..., 
+                **kwargs: Any
+            ) -> None: ...
+
+        @overload
+        async def begin_backup(
+                self, 
+                blob_storage_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                use_managed_identity: Literal[True], 
+                **kwargs: Any
+            ) -> AsyncLROPoller[KeyVaultBackupResult]: ...
+
+        @overload
+        async def begin_backup(
+                self, 
+                blob_storage_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                sas_token: str, 
+                **kwargs: Any
+            ) -> AsyncLROPoller[KeyVaultBackupResult]: ...
+
+        @overload
+        async def begin_pre_backup(
+                self, 
+                blob_storage_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                use_managed_identity: Literal[True], 
+                **kwargs: Any
+            ) -> AsyncLROPoller[None]: ...
+
+        @overload
+        async def begin_pre_backup(
+                self, 
+                blob_storage_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                sas_token: str, 
+                **kwargs: Any
+            ) -> AsyncLROPoller[None]: ...
+
+        @overload
+        async def begin_pre_restore(
+                self, 
+                folder_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                use_managed_identity: Literal[True], 
+                **kwargs: Any
+            ) -> AsyncLROPoller[None]: ...
+
+        @overload
+        async def begin_pre_restore(
+                self, 
+                folder_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                sas_token: str, 
+                **kwargs: Any
+            ) -> AsyncLROPoller[None]: ...
+
+        @overload
+        async def begin_restore(
+                self, 
+                folder_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                key_name: Optional[str] = ..., 
+                use_managed_identity: Literal[True], 
+                **kwargs: Any
+            ) -> AsyncLROPoller[None]: ...
+
+        @overload
+        async def begin_restore(
+                self, 
+                folder_url: str, 
+                *, 
+                continuation_token: Optional[str] = ..., 
+                key_name: Optional[str] = ..., 
+                sas_token: str, 
+                **kwargs: Any
+            ) -> AsyncLROPoller[None]: ...
+
+        async def close(self) -> None: ...
+
+        @distributed_trace_async
+        def send_request(
+                self, 
+                request: HttpRequest, 
+                *, 
+                stream: bool = False, 
+                **kwargs: Any
+            ) -> Awaitable[AsyncHttpResponse]: ...
+
+
+    class 
azure.keyvault.administration.aio.KeyVaultEkmClient(AsyncKeyVaultClientBase): 
implements AsyncContextManager 
+        property vault_url: str    # Read-only
+
+        def __init__(
+                self, 
+                vault_url: str, 
+                credential: AsyncTokenCredential, 
+                *, 
+                api_version: Union[ApiVersion, str] = ..., 
+                verify_challenge_resource: Optional[bool] = ..., 
+                **kwargs: Any
+            ) -> None: ...
+
+        @distributed_trace_async
+        async def check_ekm_connection(self, **kwargs: Any) -> 
KeyVaultEkmProxyInfo: ...
+
+        async def close(self) -> None: ...
+
+        @distributed_trace_async
+        async def create_ekm_connection(
+                self, 
+                connection: KeyVaultEkmConnection, 
+                **kwargs: Any
+            ) -> KeyVaultEkmConnection: ...
+
+        @distributed_trace_async
+        async def delete_ekm_connection(self, **kwargs: Any) -> 
KeyVaultEkmConnection: ...
+
+        @distributed_trace_async
+        async def get_ekm_certificate(self, **kwargs: Any) -> 
KeyVaultEkmProxyClientCertificateInfo: ...
+
+        @distributed_trace_async
+        async def get_ekm_connection(self, **kwargs: Any) -> 
KeyVaultEkmConnection: ...
+
+        @distributed_trace_async
+        def send_request(
+                self, 
+                request: HttpRequest, 
+                *, 
+                stream: bool = False, 
+                **kwargs: Any
+            ) -> Awaitable[AsyncHttpResponse]: ...
+
+        @distributed_trace_async
+        async def update_ekm_connection(
+                self, 
+                connection: KeyVaultEkmConnection, 
+                **kwargs: Any
+            ) -> KeyVaultEkmConnection: ...
+
+
+    class 
azure.keyvault.administration.aio.KeyVaultSettingsClient(AsyncKeyVaultClientBase):
 implements AsyncContextManager 
+        property vault_url: str    # Read-only
+
+        def __init__(
+                self, 
+                vault_url: str, 
+                credential: AsyncTokenCredential, 
+                *, 
+                api_version: Union[ApiVersion, str] = ..., 
+                verify_challenge_resource: Optional[bool] = ..., 
+                **kwargs: Any
+            ) -> None: ...
+
+        async def close(self) -> None: ...
+
+        @distributed_trace_async
+        async def get_setting(
+                self, 
+                name: str, 
+                **kwargs: Any
+            ) -> KeyVaultSetting: ...
+
+        @distributed_trace
+        def list_settings(self, **kwargs: Any) -> 
AsyncItemPaged[KeyVaultSetting]: ...
+
+        @distributed_trace_async
+        def send_request(
+                self, 
+                request: HttpRequest, 
+                *, 
+                stream: bool = False, 
+                **kwargs: Any
+            ) -> Awaitable[AsyncHttpResponse]: ...
+
+        @distributed_trace_async
+        async def update_setting(
+                self, 
+                setting: KeyVaultSetting, 
+                **kwargs: Any
+            ) -> KeyVaultSetting: ...
+
+
+```
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_keyvault_administration-4.8.0b1/azure/keyvault/administration/_internal/async_challenge_auth_policy.py
 
new/azure_keyvault_administration-4.8.0b2/azure/keyvault/administration/_internal/async_challenge_auth_policy.py
--- 
old/azure_keyvault_administration-4.8.0b1/azure/keyvault/administration/_internal/async_challenge_auth_policy.py
    2026-05-29 18:27:52.000000000 +0200
+++ 
new/azure_keyvault_administration-4.8.0b2/azure/keyvault/administration/_internal/async_challenge_auth_policy.py
    2026-07-08 14:56:42.000000000 +0200
@@ -30,7 +30,7 @@
 
 from .http_challenge import HttpChallenge
 from . import http_challenge_cache as ChallengeCache
-from .challenge_auth_policy import _enforce_tls, _has_claims, _update_challenge
+from .challenge_auth_policy import _enforce_tls, _has_claims, 
_update_challenge, _REQUEST_COPY_KEY
 
 if sys.version_info < (3, 9):
     from typing import Awaitable
@@ -80,7 +80,6 @@
         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.
@@ -171,8 +170,10 @@
         # 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
+        # The original request is stashed on the request's context 
(per-request), so it cannot leak into a later
+        # request made by the same client. Don't overwrite a previously 
stashed copy if this is a retry.
+        if request.http_request.content and _REQUEST_COPY_KEY not in 
request.context:
+            request.context[_REQUEST_COPY_KEY] = request.http_request
             bodiless_request = HttpRequest(
                 method=request.http_request.method,
                 url=request.http_request.url,
@@ -214,9 +215,10 @@
                     "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
+        # If we stashed the original request in on_request, use it now to send 
along the original body content
+        request_copy = request.context.get(_REQUEST_COPY_KEY)
+        if request_copy:
+            request.http_request = 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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_keyvault_administration-4.8.0b1/azure/keyvault/administration/_internal/challenge_auth_policy.py
 
new/azure_keyvault_administration-4.8.0b2/azure/keyvault/administration/_internal/challenge_auth_policy.py
--- 
old/azure_keyvault_administration-4.8.0b1/azure/keyvault/administration/_internal/challenge_auth_policy.py
  2026-05-29 18:27:52.000000000 +0200
+++ 
new/azure_keyvault_administration-4.8.0b2/azure/keyvault/administration/_internal/challenge_auth_policy.py
  2026-07-08 14:56:42.000000000 +0200
@@ -36,6 +36,12 @@
 from . import http_challenge_cache as ChallengeCache
 
 
+# Key under which the original request is stashed on the per-request pipeline 
context during the challenge flow.
+# Storing this per-request (rather than on the policy instance) prevents the 
body of one request from leaking into a
+# subsequent request made by the same client.
+_REQUEST_COPY_KEY = "key_vault_request_copy"
+
+
 def _enforce_tls(request: PipelineRequest) -> None:
     if not request.http_request.url.lower().startswith("https"):
         raise ServiceRequestError(
@@ -93,7 +99,6 @@
         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.
@@ -184,8 +189,10 @@
         # 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
+        # The original request is stashed on the request's context 
(per-request), so it cannot leak into a later
+        # request made by the same client. Don't overwrite a previously 
stashed copy if this is a retry.
+        if request.http_request.content and _REQUEST_COPY_KEY not in 
request.context:
+            request.context[_REQUEST_COPY_KEY] = request.http_request
             bodiless_request = HttpRequest(
                 method=request.http_request.method,
                 url=request.http_request.url,
@@ -227,9 +234,10 @@
                     "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
+        # If we stashed the original request in on_request, use it now to send 
along the original body content
+        request_copy = request.context.get(_REQUEST_COPY_KEY)
+        if request_copy:
+            request.http_request = 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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_keyvault_administration-4.8.0b1/azure/keyvault/administration/_version.py
 
new/azure_keyvault_administration-4.8.0b2/azure/keyvault/administration/_version.py
--- 
old/azure_keyvault_administration-4.8.0b1/azure/keyvault/administration/_version.py
 2026-05-29 18:27:52.000000000 +0200
+++ 
new/azure_keyvault_administration-4.8.0b2/azure/keyvault/administration/_version.py
 2026-07-08 14:56:42.000000000 +0200
@@ -3,4 +3,4 @@
 # Licensed under the MIT License.
 # ------------------------------------
 
-VERSION = "4.8.0b1"
+VERSION = "4.8.0b2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_keyvault_administration-4.8.0b1/azure_keyvault_administration.egg-info/PKG-INFO
 
new/azure_keyvault_administration-4.8.0b2/azure_keyvault_administration.egg-info/PKG-INFO
--- 
old/azure_keyvault_administration-4.8.0b1/azure_keyvault_administration.egg-info/PKG-INFO
   2026-05-29 18:29:01.000000000 +0200
+++ 
new/azure_keyvault_administration-4.8.0b2/azure_keyvault_administration.egg-info/PKG-INFO
   2026-07-08 14:57:40.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: azure-keyvault-administration
-Version: 4.8.0b1
+Version: 4.8.0b2
 Summary: Microsoft Corporation Key Vault Administration Client Library for 
Python
 Home-page: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk
 Author: Microsoft Corporation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_keyvault_administration-4.8.0b1/azure_keyvault_administration.egg-info/SOURCES.txt
 
new/azure_keyvault_administration-4.8.0b2/azure_keyvault_administration.egg-info/SOURCES.txt
--- 
old/azure_keyvault_administration-4.8.0b1/azure_keyvault_administration.egg-info/SOURCES.txt
        2026-05-29 18:29:01.000000000 +0200
+++ 
new/azure_keyvault_administration-4.8.0b2/azure_keyvault_administration.egg-info/SOURCES.txt
        2026-07-08 14:57:40.000000000 +0200
@@ -3,6 +3,7 @@
 MANIFEST.in
 README.md
 TROUBLESHOOTING.md
+api.md
 pyproject.toml
 setup.py
 azure/__init__.py
@@ -78,6 +79,7 @@
 tests/test_access_control_async.py
 tests/test_backup_client.py
 tests/test_backup_client_async.py
+tests/test_challenge_auth.py
 tests/test_ekm_client.py
 tests/test_ekm_client_async.py
 tests/test_examples_administration.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_keyvault_administration-4.8.0b1/tests/conftest.py 
new/azure_keyvault_administration-4.8.0b2/tests/conftest.py
--- old/azure_keyvault_administration-4.8.0b1/tests/conftest.py 2026-05-29 
18:27:52.000000000 +0200
+++ new/azure_keyvault_administration-4.8.0b2/tests/conftest.py 2026-07-08 
14:56:42.000000000 +0200
@@ -14,6 +14,7 @@
     add_uri_regex_sanitizer,
     is_live,
     remove_batch_sanitizers,
+    set_custom_default_matcher,
 )
 
 os.environ["PYTHONHASHSEED"] = "0"
@@ -21,6 +22,7 @@
 
 @pytest.fixture(scope="session", autouse=True)
 def add_sanitizers(test_proxy):
+    set_custom_default_matcher(compare_bodies=False, 
ignore_query_ordering=True, ignored_headers="Accept")
     azure_keyvault_url = os.getenv("AZURE_KEYVAULT_URL", 
"https://Sanitized.vault.azure.net";)
     azure_keyvault_url = azure_keyvault_url.rstrip("/")
     keyvault_tenant_id = os.getenv("KEYVAULT_TENANT_ID", "keyvault_tenant_id")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_keyvault_administration-4.8.0b1/tests/test_backup_client.py 
new/azure_keyvault_administration-4.8.0b2/tests/test_backup_client.py
--- old/azure_keyvault_administration-4.8.0b1/tests/test_backup_client.py       
2026-05-29 18:27:52.000000000 +0200
+++ new/azure_keyvault_administration-4.8.0b2/tests/test_backup_client.py       
2026-07-08 14:56:42.000000000 +0200
@@ -93,7 +93,6 @@
     @KeyVaultBackupClientPreparer()
     @recorded_by_proxy
     def test_selective_key_restore(self, client, **kwargs):
-        set_bodiless_matcher()
         # create a key to selectively restore
         managed_hsm_url = kwargs.pop("managed_hsm_url")
         key_client = self.create_key_client(managed_hsm_url)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_keyvault_administration-4.8.0b1/tests/test_backup_client_async.py 
new/azure_keyvault_administration-4.8.0b2/tests/test_backup_client_async.py
--- old/azure_keyvault_administration-4.8.0b1/tests/test_backup_client_async.py 
2026-05-29 18:27:52.000000000 +0200
+++ new/azure_keyvault_administration-4.8.0b2/tests/test_backup_client_async.py 
2026-07-08 14:56:42.000000000 +0200
@@ -94,7 +94,6 @@
     @KeyVaultBackupClientPreparer()
     @recorded_by_proxy_async
     async def test_selective_key_restore(self, client, **kwargs):
-        set_bodiless_matcher()
         # create a key to selectively restore
         managed_hsm_url = kwargs.pop("managed_hsm_url")
         key_client = self.create_key_client(managed_hsm_url, is_async=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_keyvault_administration-4.8.0b1/tests/test_challenge_auth.py 
new/azure_keyvault_administration-4.8.0b2/tests/test_challenge_auth.py
--- old/azure_keyvault_administration-4.8.0b1/tests/test_challenge_auth.py      
1970-01-01 01:00:00.000000000 +0100
+++ new/azure_keyvault_administration-4.8.0b2/tests/test_challenge_auth.py      
2026-07-08 14:56:42.000000000 +0200
@@ -0,0 +1,190 @@
+# ------------------------------------
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+# ------------------------------------
+"""
+Tests for the HTTP challenge authentication implementation.
+"""
+
+import functools
+import time
+from unittest.mock import Mock
+from uuid import uuid4
+
+import pytest
+from azure.core.credentials import AccessToken, AccessTokenInfo
+from azure.core.pipeline import AsyncPipeline, Pipeline
+from azure.core.rest import HttpRequest
+from azure.keyvault.administration._internal import ChallengeAuthPolicy, 
HttpChallengeCache
+from azure.keyvault.administration._internal.async_challenge_auth_policy 
import AsyncChallengeAuthPolicy
+
+TOKEN_TYPES = [AccessToken, AccessTokenInfo]
+
+
+def empty_challenge_cache(fn):
+    @functools.wraps(fn)
+    def wrapper(**kwargs):
+        HttpChallengeCache.clear()
+        assert len(HttpChallengeCache._cache) == 0
+        return fn(**kwargs)
+
+    return wrapper
+
+
+def async_empty_challenge_cache(fn):
+    @functools.wraps(fn)
+    async def wrapper(**kwargs):
+        HttpChallengeCache.clear()
+        assert len(HttpChallengeCache._cache) == 0
+        return await fn(**kwargs)
+
+    return wrapper
+
+
+def get_random_url():
+    """The challenge cache is keyed on URLs. Random URLs defend against tests 
interfering with each other."""
+
+    return f"https://{uuid4()}.vault.azure.net/{uuid4()}".replace("-", "")
+
+
+@empty_challenge_cache
[email protected]("token_type", TOKEN_TYPES)
+def test_request_body_not_reused_across_requests(token_type):
+    """A request's body must not leak into a later request made by the same 
client.
+
+    Regression test for the replay bug: the original request used to be 
stashed on the policy instance and was
+    never cleared, so a subsequent bodiless request (e.g. a polling GET during 
a backup/restore operation) that
+    triggered its own challenge would have the earlier request's body (and 
method/URL) replayed onto it. The copy
+    is now stored per-request on the pipeline context, so it cannot leak 
across requests. See
+    https://github.com/Azure/azure-sdk-for-python/pull/47742.
+    """
+
+    expected_token = "expected_token"
+    first_content = b"a duck"
+    first_url = get_random_url()
+    second_url = get_random_url()
+    challenge = Mock(
+        status_code=401,
+        headers={
+            "WWW-Authenticate": 'Bearer 
authorization="https://authority.net/tenant";, resource=https://vault.azure.net'
+        },
+    )
+
+    class Requests:
+        count = 0
+
+    def send(request):
+        Requests.count += 1
+        if Requests.count == 1:
+            # first request (POST with body): the body is stripped to elicit a 
challenge
+            assert not request.body
+            assert request.headers["Content-Length"] == "0"
+            return challenge
+        elif Requests.count == 2:
+            # first request is retried with its original body and authorization
+            assert request.body == first_content
+            assert expected_token in request.headers["Authorization"]
+            return Mock(status_code=200)
+        elif Requests.count == 3:
+            # second request (bodiless GET): elicits its own challenge and 
must have no body
+            assert not request.body
+            return challenge
+        elif Requests.count == 4:
+            # second request is retried: it must remain a bodiless GET, i.e. 
the first request's body and
+            # method/URL must NOT be replayed onto it
+            assert not request.body
+            assert request.method == "GET"
+            assert request.url == second_url
+            assert expected_token in request.headers["Authorization"]
+            return Mock(status_code=200)
+        raise ValueError("unexpected request")
+
+    def get_token(*_, **__):
+        return token_type(expected_token, time.time() + 3600)
+
+    if token_type == AccessToken:
+        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))
+
+    # a single policy instance handles both requests; the fix prevents state 
from one request leaking into the next
+    policy = ChallengeAuthPolicy(credential=credential)
+    pipeline = Pipeline(policies=[policy], transport=Mock(send=send))
+
+    first_request = HttpRequest("POST", first_url)
+    first_request.set_bytes_body(first_content)
+    pipeline.run(first_request)
+
+    pipeline.run(HttpRequest("GET", second_url))
+
+
[email protected]
+@async_empty_challenge_cache
[email protected]("token_type", TOKEN_TYPES)
+async def test_request_body_not_reused_across_requests_async(token_type):
+    """A request's body must not leak into a later request made by the same 
client (async).
+
+    Regression test for the replay bug: the original request used to be 
stashed on the policy instance and was
+    never cleared, so a subsequent bodiless request (e.g. a polling GET during 
a backup/restore operation) that
+    triggered its own challenge would have the earlier request's body (and 
method/URL) replayed onto it. The copy
+    is now stored per-request on the pipeline context, so it cannot leak 
across requests. See
+    https://github.com/Azure/azure-sdk-for-python/pull/47742.
+    """
+
+    expected_token = "expected_token"
+    first_content = b"a duck"
+    first_url = get_random_url()
+    second_url = get_random_url()
+    challenge = Mock(
+        status_code=401,
+        headers={
+            "WWW-Authenticate": 'Bearer 
authorization="https://authority.net/tenant";, resource=https://vault.azure.net'
+        },
+    )
+
+    class Requests:
+        count = 0
+
+    async def send(request):
+        Requests.count += 1
+        if Requests.count == 1:
+            # first request (POST with body): the body is stripped to elicit a 
challenge
+            assert not request.body
+            assert request.headers["Content-Length"] == "0"
+            return challenge
+        elif Requests.count == 2:
+            # first request is retried with its original body and authorization
+            assert request.body == first_content
+            assert expected_token in request.headers["Authorization"]
+            return Mock(status_code=200)
+        elif Requests.count == 3:
+            # second request (bodiless GET): elicits its own challenge and 
must have no body
+            assert not request.body
+            return challenge
+        elif Requests.count == 4:
+            # second request is retried: it must remain a bodiless GET, i.e. 
the first request's body and
+            # method/URL must NOT be replayed onto it
+            assert not request.body
+            assert request.method == "GET"
+            assert request.url == second_url
+            assert expected_token in request.headers["Authorization"]
+            return Mock(status_code=200)
+        raise ValueError("unexpected request")
+
+    async def get_token(*_, **__):
+        return token_type(expected_token, time.time() + 3600)
+
+    if token_type == AccessToken:
+        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))
+
+    # a single policy instance handles both requests; the fix prevents state 
from one request leaking into the next
+    policy = AsyncChallengeAuthPolicy(credential=credential)
+    pipeline = AsyncPipeline(policies=[policy], transport=Mock(send=send))
+
+    first_request = HttpRequest("POST", first_url)
+    first_request.set_bytes_body(first_content)
+    await pipeline.run(first_request)
+
+    await pipeline.run(HttpRequest("GET", second_url))

Reply via email to