Skip to content

Commit bf472e2

Browse files
[Storage] Expose services to be configurable for account SAS generation (#34389)
* Expose Services to be configurable for account SAS generation * Nit * Changelogs, tests for blob&file SAS token combo * Fix typehint to support str * Fix import * No network calls assert ss= * Remove service calls, unit test :D * Export Services, fix imports
1 parent 2b5c8b2 commit bf472e2

File tree

15 files changed

+141
-64
lines changed

15 files changed

+141
-64
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
This version and all future versions will require Python 3.8+. Python 3.7 is no longer supported.
66

77
### Features Added
8+
- The `services` parameter has been added to the `generate_account_sas` API, which enables the ability to generate SAS
9+
tokens to be used with multiple services. By default, the SAS token service scope will default to the current service.
810

911
### Bugs Fixed
1012
- Bumped dependency of `typing-extensions` to `>=4.6.0` to avoid potential `TypeError` with `typing.TypeVar` on
@@ -206,7 +208,7 @@ This version and all future versions will require Python 3.6+. Python 2.7 is no
206208
- `set_immutability_policy`
207209
- Encryption Scope is now supported for Sync Blob Copy (`copy_from_url()`).
208210
- Encryption Scope is now supported as a SAS permission.
209-
- Added support for blob names containing invalid XML characters.
211+
- Added support for blob names containing invalid XML characters.
210212
Previously \uFFFE and \uFFFF would fail if present in blob name.
211213
- Added support for listing system containers with get_blob_containers().
212214
- Added support for `find_blobs_by_tags()` on a container.
@@ -257,7 +259,7 @@ This version and all future versions will require Python 3.6+. Python 2.7 is no
257259

258260
**Fixes**
259261
- Blob Client Typing annotation issues have been resolved, specifically `invalid type inference` issues (#19906)
260-
- Duplicate type signature issue has been resolved (#19739)
262+
- Duplicate type signature issue has been resolved (#19739)
261263

262264
## 12.9.0 (2021-09-15)
263265
**Stable release of preview features**

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_ad4923b44f"
5+
"Tag": "python/storage/azure-storage-blob_cdf4374dd9"
66
}

sdk/storage/azure-storage-blob/azure/storage/blob/__init__.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
ResourceTypes,
2222
AccountSasPermissions,
2323
StorageErrorCode,
24-
UserDelegationKey
24+
UserDelegationKey,
25+
Services
2526
)
2627
from ._generated.models import (
2728
RehydratePriority,
@@ -60,7 +61,7 @@
6061
ArrowType,
6162
ObjectReplicationPolicy,
6263
ObjectReplicationRule,
63-
ImmutabilityPolicy
64+
ImmutabilityPolicy,
6465
)
6566
from ._list_blobs_helper import BlobPrefix
6667

@@ -246,5 +247,6 @@ def download_blob_from_url(
246247
'ArrowType',
247248
'BlobQueryReader',
248249
'ObjectReplicationPolicy',
249-
'ObjectReplicationRule'
250+
'ObjectReplicationRule',
251+
'Services',
250252
]

sdk/storage/azure-storage-blob/azure/storage/blob/_shared_access_signature.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -308,15 +308,17 @@ def get_token(self):
308308

309309

310310
def generate_account_sas(
311-
account_name, # type: str
312-
account_key, # type: str
313-
resource_types, # type: Union[ResourceTypes, str]
314-
permission, # type: Union[AccountSasPermissions, str]
315-
expiry, # type: Union[datetime, str]
316-
start=None, # type: Optional[Union[datetime, str]]
317-
ip=None, # type: Optional[str]
318-
**kwargs # type: Any
319-
): # type: (...) -> str
311+
account_name: str,
312+
account_key: str,
313+
resource_types: Union["ResourceTypes", str],
314+
permission: Union["AccountSasPermissions", str],
315+
expiry: Union["datetime", str],
316+
start: Optional[Union["datetime", str]] = None,
317+
ip: Optional[str] = None,
318+
*,
319+
services: Union[Services, str] = Services(blob=True),
320+
**kwargs: Any
321+
) -> str:
320322
"""Generates a shared access signature for the blob service.
321323
322324
Use the returned signature with the credential parameter of any BlobServiceClient,
@@ -351,6 +353,9 @@ def generate_account_sas(
351353
or address range specified on the SAS token, the request is not authenticated.
352354
For example, specifying ip=168.1.5.65 or ip=168.1.5.60-168.1.5.70 on the SAS
353355
restricts the request to those IP addresses.
356+
:keyword Union[Services, str] services:
357+
Specifies the services that the Shared Access Signature (sas) token will be able to be utilized with.
358+
Will default to only this package (i.e. blobs) if not provided.
354359
:keyword str protocol:
355360
Specifies the protocol permitted for a request made. The default value is https.
356361
:keyword str encryption_scope:
@@ -369,7 +374,7 @@ def generate_account_sas(
369374
"""
370375
sas = SharedAccessSignature(account_name, account_key)
371376
return sas.generate_account(
372-
services=Services(blob=True),
377+
services=services,
373378
resource_types=resource_types,
374379
permission=permission,
375380
expiry=expiry,

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
LinearRetry,
4141
ResourceTypes,
4242
RetentionPolicy,
43+
Services,
4344
StandardBlobTier,
4445
StorageErrorCode,
4546
download_blob_from_url,
@@ -2139,6 +2140,25 @@ def test_blob_service_sas(self, **kwargs):
21392140
assert blob_list is not None
21402141
assert blob_props is not None
21412142

2143+
@BlobPreparer()
2144+
def test_multiple_services_sas(self, **kwargs):
2145+
storage_account_name = kwargs.pop("storage_account_name")
2146+
storage_account_key = kwargs.pop("storage_account_key")
2147+
2148+
# Act
2149+
token = self.generate_sas(
2150+
generate_account_sas,
2151+
storage_account_name,
2152+
storage_account_key,
2153+
ResourceTypes(container=True, object=True, service=True),
2154+
AccountSasPermissions(read=True, list=True),
2155+
datetime.utcnow() + timedelta(hours=1),
2156+
services=Services(blob=True, fileshare=True)
2157+
)
2158+
2159+
# Assert
2160+
assert 'ss=bf' in token
2161+
21422162
@pytest.mark.live_test_only
21432163
@BlobPreparer()
21442164
def test_set_immutability_policy_using_sas(self, **kwargs):
@@ -2225,7 +2245,7 @@ def test_set_immutability_policy_using_sas(self, **kwargs):
22252245
# Assert response using blob sas
22262246
assert resp_with_blob_sas['immutability_policy_until_date'] is not None
22272247
assert resp_with_blob_sas['immutability_policy_mode'] is not None
2228-
2248+
22292249
if self.is_live:
22302250
blob_client.delete_immutability_policy()
22312251
blob_client.set_legal_hold(False)

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@
4343
RehydratePriority,
4444
ResourceTypes,
4545
RetentionPolicy,
46+
Services,
4647
StandardBlobTier,
4748
StorageErrorCode,
4849
generate_account_sas,
4950
generate_container_sas,
5051
generate_blob_sas)
51-
5252
from devtools_testutils.aio import recorded_by_proxy_async
5353
from devtools_testutils.storage.aio import AsyncStorageRecordedTestCase
5454
from settings.testcase import BlobPreparer
@@ -2315,6 +2315,25 @@ async def test_account_sas_credential(self, **kwargs):
23152315
assert blob_name == blob_properties.name
23162316
assert self.container_name == container_properties.name
23172317

2318+
@BlobPreparer()
2319+
async def test_multiple_services_sas(self, **kwargs):
2320+
storage_account_name = kwargs.pop("storage_account_name")
2321+
storage_account_key = kwargs.pop("storage_account_key")
2322+
2323+
# Act
2324+
token = self.generate_sas(
2325+
generate_account_sas,
2326+
storage_account_name,
2327+
storage_account_key,
2328+
ResourceTypes(container=True, object=True, service=True),
2329+
AccountSasPermissions(read=True, list=True),
2330+
datetime.utcnow() + timedelta(hours=1),
2331+
services=Services(blob=True, fileshare=True)
2332+
)
2333+
2334+
# Assert
2335+
assert 'ss=bf' in token
2336+
23182337
@BlobPreparer()
23192338
@recorded_by_proxy_async
23202339
async def test_azure_named_key_credential_access(self, **kwargs):

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
This version and all future versions will require Python 3.8+. Python 3.7 is no longer supported.
66

77
### Features Added
8+
- The `services` parameter has been added to the `generate_account_sas` API, which enables the ability to generate SAS
9+
tokens to be used with multiple services. By default, the SAS token service scope will default to the current service.
810

911
### Bugs Fixed
1012
- Bumped dependency of `typing-extensions` to `>=4.6.0` to avoid potential `TypeError` with `typing.TypeVar` on
@@ -190,7 +192,7 @@ in a future release.
190192
- `permanent_delete`
191193
- `set_immutability_policy`
192194
**Fixes**
193-
- `FileSystemProperties` was not subscriptable. Now it is both subscriptable and attributes can also be accessed directly (#20772)
195+
- `FileSystemProperties` was not subscriptable. Now it is both subscriptable and attributes can also be accessed directly (#20772)
194196
- Datalake Client Typing annotation issues have been resolved (#19906)
195197

196198
## 12.5.0 (2021-09-15)

sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@
4444
ResourceTypes,
4545
RetentionPolicy,
4646
StaticWebsite,
47-
UserDelegationKey
47+
UserDelegationKey,
4848
)
4949

5050
from ._shared_access_signature import generate_account_sas, generate_file_system_sas, generate_directory_sas, \
5151
generate_file_sas
5252

5353
from ._shared.policies import ExponentialRetry, LinearRetry
54-
from ._shared.models import StorageErrorCode
54+
from ._shared.models import StorageErrorCode, Services
5555
from ._version import VERSION
5656

5757
__version__ = VERSION
@@ -105,5 +105,6 @@
105105
'StorageErrorCode',
106106
'StorageStreamDownloader',
107107
'UserDelegationKey',
108-
'VERSION'
108+
'VERSION',
109+
'Services'
109110
]

sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared_access_signature.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from azure.storage.blob import generate_account_sas as generate_blob_account_sas
1212
from azure.storage.blob import generate_container_sas, generate_blob_sas
13+
from ._shared.models import Services
1314
from ._shared.shared_access_signature import QueryStringConstants
1415

1516

@@ -26,13 +27,15 @@
2627

2728

2829
def generate_account_sas(
29-
account_name, # type: str
30-
account_key, # type: str
31-
resource_types, # type: Union[ResourceTypes, str]
32-
permission, # type: Union[AccountSasPermissions, str]
33-
expiry, # type: Union[datetime, str]
34-
**kwargs # type: Any
35-
): # type: (...) -> str
30+
account_name: str,
31+
account_key: str,
32+
resource_types: Union["ResourceTypes", str],
33+
permission: Union["AccountSasPermissions", str],
34+
expiry: Union["datetime", str],
35+
*,
36+
services: Union[Services, str] = Services(blob=True),
37+
**kwargs: Any
38+
) -> str:
3639
"""Generates a shared access signature for the DataLake service.
3740
3841
Use the returned signature as the credential parameter of any DataLakeServiceClient,
@@ -67,6 +70,9 @@ def generate_account_sas(
6770
or address range specified on the SAS token, the request is not authenticated.
6871
For example, specifying ip=168.1.5.65 or ip=168.1.5.60-168.1.5.70 on the SAS
6972
restricts the request to those IP addresses.
73+
:keyword Union[Services, str] services:
74+
Specifies the services that the Shared Access Signature (sas) token will be able to be utilized with.
75+
Will default to only this package (i.e. blobs) if not provided.
7076
:keyword str protocol:
7177
Specifies the protocol permitted for a request made. The default value is https.
7278
:keyword str encryption_scope:
@@ -80,6 +86,7 @@ def generate_account_sas(
8086
resource_types=resource_types,
8187
permission=permission,
8288
expiry=expiry,
89+
services=services,
8390
**kwargs
8491
)
8592

0 commit comments

Comments
 (0)