Skip to content

Commit 7cf8b83

Browse files
author
Yalin Li
authored
[Tables] Add sas token live tests (#30614)
1 parent b530b6a commit 7cf8b83

File tree

6 files changed

+108
-7
lines changed

6 files changed

+108
-7
lines changed

Diff for: sdk/tables/azure-data-tables/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
## 12.4.4 (Unreleased)
44

55
### Features Added
6+
* Enabled to specify resource type `container` in account SAS access.
67

78
### Breaking Changes
89

910
### Bugs Fixed
1011

1112
### Other Changes
13+
* Fixed a bug when creating `TableClient` from url with sas token in `azure-core`, so we bumped minimum dependency on `azure-core` to `>=1.27.1`. ([#28918](https://github.com/Azure/azure-sdk-for-python/issues/28918))
1214

1315
## 12.4.3 (2023-06-13)
1416

Diff for: sdk/tables/azure-data-tables/assets.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "python",
44
"TagPrefix": "python/tables/azure-data-tables",
5-
"Tag": "python/tables/azure-data-tables_a91b7254c8"
5+
"Tag": "python/tables/azure-data-tables_e1a287b0d2"
66
}

Diff for: sdk/tables/azure-data-tables/azure/data/tables/_models.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -536,12 +536,15 @@ class ResourceTypes(object):
536536
Get Service Stats, List Tables)
537537
:keyword bool object:
538538
Access to object-level APIs for tables (e.g. Get/Create/Query Entity etc.)
539+
:keyword bool container:
540+
Access to container-level APIs for tables (e.g. Create Tables etc.)
539541
"""
540542

541543
def __init__(self, **kwargs) -> None:
542544
self.service = kwargs.get('service', False)
543545
self.object = kwargs.get('object', False)
544-
self._str = ("s" if self.service else "") + ("o" if self.object else "")
546+
self.container = kwargs.get('container', False)
547+
self._str = ("s" if self.service else "") + ("o" if self.object else "") + ("c" if self.container else "")
545548

546549
def __str__(self):
547550
return self._str
@@ -561,8 +564,9 @@ def from_string(cls, string: str) -> 'ResourceTypes':
561564
"""
562565
res_service = "s" in string
563566
res_object = "o" in string
567+
res_container = "c" in string
564568

565-
parsed = cls(service=res_service, object=res_object)
569+
parsed = cls(service=res_service, object=res_object, container=res_container)
566570
parsed._str = string # pylint: disable = protected-access
567571
return parsed
568572

Diff for: sdk/tables/azure-data-tables/setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
]),
6666
python_requires=">=3.7",
6767
install_requires=[
68-
"azure-core<2.0.0,>=1.24.0",
68+
"azure-core<2.0.0,>=1.27.1",
6969
"yarl<2.0,>=1.0",
7070
"isodate<1.0.0,>=0.6.1",
7171
"typing-extensions>=4.3.0"

Diff for: sdk/tables/azure-data-tables/tests/test_table_client.py

+48-2
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
import platform
88
import os
99

10+
from datetime import datetime, timedelta
1011
from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy
1112

12-
from azure.data.tables._error import _validate_storage_tablename
13-
from azure.data.tables import TableServiceClient, TableClient
13+
from azure.data.tables import TableServiceClient, TableClient, AccountSasPermissions, ResourceTypes, generate_account_sas
1414
from azure.data.tables import __version__ as VERSION
1515
from azure.data.tables._constants import DEFAULT_STORAGE_ENDPOINT_SUFFIX
16+
from azure.data.tables._error import _validate_storage_tablename
1617
from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential
1718
from azure.core.exceptions import ResourceNotFoundError, HttpResponseError, ClientAuthenticationError
1819
from azure.identity import DefaultAzureCredential
@@ -188,6 +189,51 @@ def test_error_handling(self, tables_storage_account_name, tables_primary_storag
188189
) as service_client:
189190
with pytest.raises(ClientAuthenticationError):
190191
service_client.create_table_if_not_exists(table_name="TestInsert")
192+
193+
@tables_decorator
194+
@recorded_by_proxy
195+
def test_client_with_sas_token(self, tables_storage_account_name, tables_primary_storage_account_key):
196+
base_url = self.account_url(tables_storage_account_name, "table")
197+
table_name = self.get_resource_name("mytable")
198+
sas_token = self.generate_sas(
199+
generate_account_sas,
200+
tables_primary_storage_account_key,
201+
resource_types=ResourceTypes.from_string("sco"),
202+
permission=AccountSasPermissions.from_string("rwdlacu"),
203+
expiry=datetime.utcnow() + timedelta(hours=1),
204+
)
205+
206+
with TableServiceClient(base_url, credential=AzureSasCredential(sas_token)) as client:
207+
client.create_table(table_name)
208+
name_filter = "TableName eq '{}'".format(table_name)
209+
result = client.query_tables(name_filter)
210+
assert len(list(result)) == 1
211+
212+
with TableClient(base_url, table_name, credential=AzureSasCredential(sas_token)) as client:
213+
entities = client.query_entities(
214+
query_filter='PartitionKey eq @pk',
215+
parameters={'pk': 'dummy-pk'},
216+
)
217+
for e in entities:
218+
pass
219+
220+
with TableClient.from_table_url(f"{base_url}/{table_name}", credential=AzureSasCredential(sas_token)) as client:
221+
entities = client.query_entities(
222+
query_filter='PartitionKey eq @pk',
223+
parameters={'pk': 'dummy-pk'},
224+
)
225+
for e in entities:
226+
pass
227+
228+
sas_url = f"{base_url}/{table_name}?{sas_token}"
229+
with TableClient.from_table_url(sas_url) as client:
230+
entities = client.query_entities(
231+
query_filter='PartitionKey eq @pk',
232+
parameters={'pk': 'dummy-pk'},
233+
)
234+
for e in entities:
235+
pass
236+
client.delete_table()
191237

192238

193239
# --Helpers-----------------------------------------------------------------

Diff for: sdk/tables/azure-data-tables/tests/test_table_client_async.py

+50-1
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@
33
# Licensed under the MIT License. See License.txt in the project root for
44
# license information.
55
# --------------------------------------------------------------------------
6-
from azure.core.credentials import AzureNamedKeyCredential
76
import pytest
87
import platform
98
import os
109

10+
from datetime import datetime, timedelta
1111
from devtools_testutils import AzureRecordedTestCase
1212
from devtools_testutils.aio import recorded_by_proxy_async
1313

1414
from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential
1515
from azure.core.exceptions import ResourceNotFoundError, HttpResponseError, ClientAuthenticationError
1616
from azure.identity.aio import DefaultAzureCredential
17+
from azure.data.tables import AccountSasPermissions, ResourceTypes, generate_account_sas
1718
from azure.data.tables.aio import TableServiceClient, TableClient
1819
from azure.data.tables._version import VERSION
1920
from azure.data.tables._constants import DEFAULT_STORAGE_ENDPOINT_SUFFIX
@@ -189,6 +190,54 @@ async def test_error_handling(self, tables_storage_account_name, tables_primary_
189190
) as service_client:
190191
with pytest.raises(ClientAuthenticationError):
191192
await service_client.create_table_if_not_exists(table_name="TestInsert")
193+
194+
@tables_decorator_async
195+
@recorded_by_proxy_async
196+
async def test_client_with_sas_token(self, tables_storage_account_name, tables_primary_storage_account_key):
197+
base_url = self.account_url(tables_storage_account_name, "table")
198+
table_name = self.get_resource_name("mytable")
199+
sas_token = self.generate_sas(
200+
generate_account_sas,
201+
tables_primary_storage_account_key,
202+
resource_types=ResourceTypes.from_string("sco"),
203+
permission=AccountSasPermissions.from_string("rwdlacu"),
204+
expiry=datetime.utcnow() + timedelta(hours=1),
205+
)
206+
207+
async with TableServiceClient(base_url, credential=AzureSasCredential(sas_token)) as client:
208+
await client.create_table(table_name)
209+
name_filter = "TableName eq '{}'".format(table_name)
210+
count = 0
211+
result = client.query_tables(name_filter)
212+
async for table in result:
213+
count += 1
214+
assert count == 1
215+
216+
async with TableClient(base_url, table_name, credential=AzureSasCredential(sas_token)) as client:
217+
entities = client.query_entities(
218+
query_filter='PartitionKey eq @pk',
219+
parameters={'pk': 'dummy-pk'},
220+
)
221+
async for e in entities:
222+
pass
223+
224+
async with TableClient.from_table_url(f"{base_url}/{table_name}", credential=AzureSasCredential(sas_token)) as client:
225+
entities = client.query_entities(
226+
query_filter='PartitionKey eq @pk',
227+
parameters={'pk': 'dummy-pk'},
228+
)
229+
async for e in entities:
230+
pass
231+
232+
sas_url = f"{base_url}/{table_name}?{sas_token}"
233+
async with TableClient.from_table_url(sas_url) as client:
234+
entities = client.query_entities(
235+
query_filter='PartitionKey eq @pk',
236+
parameters={'pk': 'dummy-pk'},
237+
)
238+
async for e in entities:
239+
pass
240+
await client.delete_table()
192241

193242

194243
class TestTableClientAsyncUnitTests(AsyncTableTestCase):

0 commit comments

Comments
 (0)