Skip to content

Commit 0e7973d

Browse files
[Storage] Fix error handling for AAD error responses (#33505)
1 parent d8bcdc5 commit 0e7973d

File tree

11 files changed

+60
-5
lines changed

11 files changed

+60
-5
lines changed

sdk/storage/azure-storage-blob/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
### Bugs Fixed
88
- Bumped dependency of `typing-extensions` to `>=4.6.0` to avoid potential `TypeError` with `typing.TypeVar` on
99
Python 3.12.
10+
- Fixed an issue where authentication errors could raise `AttributeError` instead of `ClientAuthenticationError` when
11+
using async OAuth credentials.
1012

1113
## 12.19.0 (2023-11-07)
1214

sdk/storage/azure-storage-blob/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "python",
44
"TagPrefix": "python/storage/azure-storage-blob",
5-
"Tag": "python/storage/azure-storage-blob_12c8154ae2"
5+
"Tag": "python/storage/azure-storage-blob_ad4923b44f"
66
}

sdk/storage/azure-storage-blob/azure/storage/blob/_shared/response_handlers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ def process_storage_error(storage_error) -> NoReturn: # type: ignore [misc] # py
116116
error_dict = {'message': str(error_body)}
117117

118118
# If we extracted from a Json or XML response
119-
if error_dict:
119+
# There is a chance error_dict is just a string
120+
if error_dict and isinstance(error_dict, dict):
120121
error_code = error_dict.get('code')
121122
error_message = error_dict.get('message')
122123
additional_data = {k: v for k, v in error_dict.items() if k not in {'code', 'message'}}

sdk/storage/azure-storage-blob/tests/test_common_blob.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3335,4 +3335,26 @@ def test_storage_account_audience_blob_client(self, **kwargs):
33353335
response = blob.exists()
33363336
assert response is not None
33373337

3338+
@pytest.mark.live_test_only
3339+
@BlobPreparer()
3340+
def test_oauth_error_handling(self, **kwargs):
3341+
storage_account_name = kwargs.pop("storage_account_name")
3342+
3343+
# Arrange
3344+
from azure.identity import ClientSecretCredential
3345+
3346+
# Generate an invalid credential
3347+
creds = ClientSecretCredential(
3348+
self.get_settings_value("TENANT_ID"),
3349+
self.get_settings_value("CLIENT_ID"),
3350+
self.get_settings_value("CLIENT_SECRET") + 'a'
3351+
)
3352+
3353+
bsc = BlobServiceClient(self.account_url(storage_account_name, "blob"), credential=creds, retry_total=0)
3354+
container = bsc.get_container_client('testing')
3355+
3356+
# Act
3357+
with pytest.raises(ClientAuthenticationError):
3358+
container.exists()
3359+
33383360
# ------------------------------------------------------------------------------

sdk/storage/azure-storage-blob/tests/test_common_blob_async.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3260,4 +3260,25 @@ async def test_storage_account_audience_blob_client(self, **kwargs):
32603260
response = await blob.exists()
32613261
assert response is not None
32623262

3263+
@pytest.mark.live_test_only
3264+
@BlobPreparer()
3265+
async def test_oauth_error_handling(self, **kwargs):
3266+
storage_account_name = kwargs.pop("storage_account_name")
3267+
3268+
# Arrange
3269+
from azure.identity.aio import ClientSecretCredential
3270+
3271+
# Generate an invalid credential
3272+
creds = ClientSecretCredential(
3273+
self.get_settings_value("TENANT_ID"),
3274+
self.get_settings_value("CLIENT_ID"),
3275+
self.get_settings_value("CLIENT_SECRET") + 'a'
3276+
)
3277+
3278+
bsc = BlobServiceClient(self.account_url(storage_account_name, "blob"), credential=creds, retry_total=0)
3279+
container = bsc.get_container_client('testing')
3280+
3281+
# Act
3282+
with pytest.raises(ClientAuthenticationError):
3283+
await container.exists()
32633284
# ------------------------------------------------------------------------------

sdk/storage/azure-storage-file-datalake/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
### Bugs Fixed
88
- Bumped dependency of `typing-extensions` to `>=4.6.0` to avoid potential `TypeError` with `typing.TypeVar` on
99
Python 3.12.
10+
- Fixed an issue where authentication errors could raise `AttributeError` instead of `ClientAuthenticationError` when
11+
using async OAuth credentials.
1012

1113
## 12.14.0 (2023-11-07)
1214

sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/response_handlers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ def process_storage_error(storage_error) -> NoReturn: # type: ignore [misc] # py
116116
error_dict = {'message': str(error_body)}
117117

118118
# If we extracted from a Json or XML response
119-
if error_dict:
119+
# There is a chance error_dict is just a string
120+
if error_dict and isinstance(error_dict, dict):
120121
error_code = error_dict.get('code')
121122
error_message = error_dict.get('message')
122123
additional_data = {k: v for k, v in error_dict.items() if k not in {'code', 'message'}}

sdk/storage/azure-storage-file-share/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
pointing to the root of the file share would raise an `InvalidResourceName` on any operations.
1111
- Bumped dependency of `typing-extensions` to `>=4.6.0` to avoid potential `TypeError` with `typing.TypeVar` on
1212
Python 3.12.
13+
- Fixed an issue where authentication errors could raise `AttributeError` instead of `ClientAuthenticationError` when
14+
using async OAuth credentials.
1315

1416
## 12.15.0 (2023-11-07)
1517

sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/response_handlers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ def process_storage_error(storage_error) -> NoReturn: # type: ignore [misc] # py
116116
error_dict = {'message': str(error_body)}
117117

118118
# If we extracted from a Json or XML response
119-
if error_dict:
119+
# There is a chance error_dict is just a string
120+
if error_dict and isinstance(error_dict, dict):
120121
error_code = error_dict.get('code')
121122
error_message = error_dict.get('message')
122123
additional_data = {k: v for k, v in error_dict.items() if k not in {'code', 'message'}}

sdk/storage/azure-storage-queue/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
### Bugs Fixed
88
- Bumped dependency of `typing-extensions` to `>=4.6.0` to avoid potential `TypeError` with `typing.TypeVar` on
99
Python 3.12.
10+
- Fixed an issue where authentication errors could raise `AttributeError` instead of `ClientAuthenticationError` when
11+
using async OAuth credentials.
1012

1113
## 12.9.0 (2023-12-05)
1214

0 commit comments

Comments
 (0)