diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_download.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_download.py index e11023c0f9c7..46e59e5d2492 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_download.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_download.py @@ -457,6 +457,7 @@ def readall(self): """Download the contents of this blob. This operation is blocking until all data is downloaded. + :rtype: bytes or str """ stream = BytesIO() diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/shared_access_signature.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/shared_access_signature.py index 367c6554ef89..07aad5ffa1c8 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/shared_access_signature.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/shared_access_signature.py @@ -39,6 +39,12 @@ class QueryStringConstants(object): SIGNED_KEY_SERVICE = 'sks' SIGNED_KEY_VERSION = 'skv' + # for ADLS + SIGNED_AUTHORIZED_OID = 'saoid' + SIGNED_UNAUTHORIZED_OID = 'suoid' + SIGNED_CORRELATION_ID = 'scid' + SIGNED_DIRECTORY_DEPTH = 'sdd' + @staticmethod def to_list(): return [ @@ -68,6 +74,11 @@ def to_list(): QueryStringConstants.SIGNED_KEY_EXPIRY, QueryStringConstants.SIGNED_KEY_SERVICE, QueryStringConstants.SIGNED_KEY_VERSION, + # for ADLS + QueryStringConstants.SIGNED_AUTHORIZED_OID, + QueryStringConstants.SIGNED_UNAUTHORIZED_OID, + QueryStringConstants.SIGNED_CORRELATION_ID, + QueryStringConstants.SIGNED_DIRECTORY_DEPTH, ] diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_shared_access_signature.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_shared_access_signature.py index af1c2015f270..6864ab19b473 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_shared_access_signature.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_shared_access_signature.py @@ -55,7 +55,7 @@ def generate_blob(self, container_name, blob_name, snapshot=None, version_id=Non expiry=None, start=None, policy_id=None, ip=None, protocol=None, cache_control=None, content_disposition=None, content_encoding=None, content_language=None, - content_type=None): + content_type=None, **kwargs): ''' Generates a shared access signature for the blob or one of its snapshots. Use the returned signature with the sas_token parameter of any BlobService. @@ -126,12 +126,14 @@ def generate_blob(self, container_name, blob_name, snapshot=None, version_id=Non resource = 'bs' if snapshot else 'b' resource = 'bv' if version_id else resource + resource = 'd' if kwargs.pop("is_directory", None) else resource sas.add_resource(resource) sas.add_timestamp(snapshot or version_id) sas.add_override_response_headers(cache_control, content_disposition, content_encoding, content_language, content_type) + sas.add_info_for_hns_account(**kwargs) sas.add_resource_signature(self.account_name, self.account_key, resource_path, user_delegation_key=self.user_delegation_key) @@ -141,7 +143,7 @@ def generate_container(self, container_name, permission=None, expiry=None, start=None, policy_id=None, ip=None, protocol=None, cache_control=None, content_disposition=None, content_encoding=None, content_language=None, - content_type=None): + content_type=None, **kwargs): ''' Generates a shared access signature for the container. Use the returned signature with the sas_token parameter of any BlobService. @@ -206,6 +208,7 @@ def generate_container(self, container_name, permission=None, expiry=None, sas.add_override_response_headers(cache_control, content_disposition, content_encoding, content_language, content_type) + sas.add_info_for_hns_account(**kwargs) sas.add_resource_signature(self.account_name, self.account_key, container_name, user_delegation_key=self.user_delegation_key) return sas.get_token() @@ -216,6 +219,12 @@ class _BlobSharedAccessHelper(_SharedAccessHelper): def add_timestamp(self, timestamp): self._add_query(BlobQueryStringConstants.SIGNED_TIMESTAMP, timestamp) + def add_info_for_hns_account(self, **kwargs): + self._add_query(QueryStringConstants.SIGNED_DIRECTORY_DEPTH, kwargs.pop('sdd', None)) + self._add_query(QueryStringConstants.SIGNED_AUTHORIZED_OID, kwargs.pop('preauthorized_agent_object_id', None)) + self._add_query(QueryStringConstants.SIGNED_UNAUTHORIZED_OID, kwargs.pop('agent_object_id', None)) + self._add_query(QueryStringConstants.SIGNED_CORRELATION_ID, kwargs.pop('correlation_id', None)) + def get_value_to_append(self, query): return_value = self.query_dict.get(query) or '' return return_value + '\n' @@ -249,7 +258,10 @@ def add_resource_signature(self, account_name, account_key, path, user_delegatio self.get_value_to_append(QueryStringConstants.SIGNED_KEY_START) + self.get_value_to_append(QueryStringConstants.SIGNED_KEY_EXPIRY) + self.get_value_to_append(QueryStringConstants.SIGNED_KEY_SERVICE) + - self.get_value_to_append(QueryStringConstants.SIGNED_KEY_VERSION)) + self.get_value_to_append(QueryStringConstants.SIGNED_KEY_VERSION) + + self.get_value_to_append(QueryStringConstants.SIGNED_AUTHORIZED_OID) + + self.get_value_to_append(QueryStringConstants.SIGNED_UNAUTHORIZED_OID) + + self.get_value_to_append(QueryStringConstants.SIGNED_CORRELATION_ID)) else: string_to_sign += self.get_value_to_append(QueryStringConstants.SIGNED_IDENTIFIER) diff --git a/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions.py b/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions.py index 3b23d1e814ef..3b9c6bc02ab4 100644 --- a/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions.py +++ b/sdk/storage/azure-storage-blob/tests/test_blob_access_conditions.py @@ -621,6 +621,7 @@ def test_set_blob_properties_with_if_unmodified_fail(self, resource_group, locat # Assert self.assertEqual(StorageErrorCode.condition_not_met, e.exception.error_code) + @pytest.mark.playback_test_only @GlobalStorageAccountPreparer() def test_get_properties_last_access_time(self, resource_group, location, storage_account, storage_account_key): bsc = BlobServiceClient(self.account_url(storage_account, "blob"), storage_account_key, diff --git a/sdk/storage/azure-storage-blob/tests/test_container.py b/sdk/storage/azure-storage-blob/tests/test_container.py index a3886b2a3fd9..ff2c33347c96 100644 --- a/sdk/storage/azure-storage-blob/tests/test_container.py +++ b/sdk/storage/azure-storage-blob/tests/test_container.py @@ -827,6 +827,7 @@ def test_list_names(self, resource_group, location, storage_account, storage_acc self.assertEqual(blobs, ['blob1', 'blob2']) + @pytest.mark.playback_test_only @GlobalStorageAccountPreparer() def test_list_blobs_contains_last_access_time(self, resource_group, location, storage_account, storage_account_key): bsc = BlobServiceClient(self.account_url(storage_account, "blob"), storage_account_key) diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_directory_client.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_directory_client.py index b8c7ff22de27..c1c4ad8521e7 100644 --- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_directory_client.py +++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_directory_client.py @@ -304,7 +304,7 @@ def rename_directory(self, new_name, # type: str """ new_name = new_name.strip('/') new_file_system = new_name.split('/')[0] - new_path_and_token = new_name[len(new_file_system):].split('?') + new_path_and_token = new_name[len(new_file_system):].strip('/').split('?') new_path = new_path_and_token[0] try: new_dir_sas = new_path_and_token[1] or self._query_str.strip('?') diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_file_client.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_file_client.py index f39cd8fab5f3..7effeb3ba00e 100644 --- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_file_client.py +++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_data_lake_file_client.py @@ -661,7 +661,7 @@ def rename_file(self, new_name, # type: str """ new_name = new_name.strip('/') new_file_system = new_name.split('/')[0] - new_path_and_token = new_name[len(new_file_system):].split('?') + new_path_and_token = new_name[len(new_file_system):].strip('/').split('?') new_path = new_path_and_token[0] try: new_file_sas = new_path_and_token[1] or self._query_str.strip('?') diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_models.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_models.py index 3218af1ba95d..790750a59b60 100644 --- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_models.py +++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_models.py @@ -12,7 +12,6 @@ from azure.storage.blob import ResourceTypes as BlobResourceTypes from azure.storage.blob import UserDelegationKey as BlobUserDelegationKey from azure.storage.blob import ContentSettings as BlobContentSettings -from azure.storage.blob import ContainerSasPermissions, BlobSasPermissions from azure.storage.blob import AccessPolicy as BlobAccessPolicy from azure.storage.blob import DelimitedTextDialect as BlobDelimitedTextDialect from azure.storage.blob import DelimitedJsonDialect as BlobDelimitedJSON @@ -294,7 +293,7 @@ def __init__(self, read=False, write=False, delete=False, list=False, # pylint: ) -class FileSystemSasPermissions(ContainerSasPermissions): +class FileSystemSasPermissions(object): """FileSystemSasPermissions class to be used with the :func:`~azure.storage.filedatalake.generate_file_system_sas` function. @@ -306,16 +305,72 @@ class FileSystemSasPermissions(ContainerSasPermissions): Delete the file system. :param bool list: List paths in the file system. + :keyword bool move: + Move any file in the directory to a new location. + Note the move operation can optionally be restricted to the child file or directory owner or + the parent directory owner if the saoid parameter is included in the token and the sticky bit is set + on the parent directory. + :keyword bool execute: + Get the status (system defined properties) and ACL of any file in the directory. + If the caller is the owner, set access control on any file in the directory. + :keyword bool manage_ownership: + Allows the user to set owner, owning group, or act as the owner when renaming or deleting a file or directory + within a folder that has the sticky bit set. + :keyword bool manage_access_control: + Allows the user to set permissions and POSIX ACLs on files and directories. """ - def __init__(self, read=False, write=False, delete=False, list=False # pylint: disable=redefined-builtin - ): - super(FileSystemSasPermissions, self).__init__( - read=read, write=write, delete=delete, list=list - ) - + def __init__(self, read=False, write=False, delete=False, list=False, # pylint: disable=redefined-builtin + **kwargs): + self.read = read + self.write = write + self.delete = delete + self.list = list + self.move = kwargs.pop('move', None) + self.execute = kwargs.pop('execute', None) + self.manage_ownership = kwargs.pop('manage_ownership', None) + self.manage_access_control = kwargs.pop('manage_access_control', None) + self._str = (('r' if self.read else '') + + ('w' if self.write else '') + + ('d' if self.delete else '') + + ('l' if self.list else '') + + ('m' if self.move else '') + + ('e' if self.execute else '') + + ('o' if self.manage_ownership else '') + + ('p' if self.manage_access_control else '')) + + def __str__(self): + return self._str -class DirectorySasPermissions(BlobSasPermissions): + @classmethod + def from_string(cls, permission): + """Create a FileSystemSasPermissions from a string. + + To specify read, write, or delete permissions you need only to + include the first letter of the word in the string. E.g. For read and + write permissions, you would provide a string "rw". + + :param str permission: The string which dictates the read, add, create, + write, or delete permissions. + :return: A FileSystemSasPermissions object + :rtype: ~azure.storage.fildatalake.FileSystemSasPermissions + """ + p_read = 'r' in permission + p_write = 'w' in permission + p_delete = 'd' in permission + p_list = 'l' in permission + p_move = 'm' in permission + p_execute = 'e' in permission + p_manage_ownership = 'o' in permission + p_manage_access_control = 'p' in permission + + parsed = cls(read=p_read, write=p_write, delete=p_delete, + list=p_list, move=p_move, execute=p_execute, manage_ownership=p_manage_ownership, + manage_access_control=p_manage_access_control) + return parsed + + +class DirectorySasPermissions(object): """DirectorySasPermissions class to be used with the :func:`~azure.storage.filedatalake.generate_directory_sas` function. @@ -327,17 +382,77 @@ class DirectorySasPermissions(BlobSasPermissions): Create or write content, properties, metadata. Lease the directory. :param bool delete: Delete the directory. + :keyword bool list: + List any files in the directory. Implies Execute. + :keyword bool move: + Move any file in the directory to a new location. + Note the move operation can optionally be restricted to the child file or directory owner or + the parent directory owner if the saoid parameter is included in the token and the sticky bit is set + on the parent directory. + :keyword bool execute: + Get the status (system defined properties) and ACL of any file in the directory. + If the caller is the owner, set access control on any file in the directory. + :keyword bool manage_ownership: + Allows the user to set owner, owning group, or act as the owner when renaming or deleting a file or directory + within a folder that has the sticky bit set. + :keyword bool manage_access_control: + Allows the user to set permissions and POSIX ACLs on files and directories. """ def __init__(self, read=False, create=False, write=False, - delete=False): - super(DirectorySasPermissions, self).__init__( - read=read, create=create, write=write, - delete=delete - ) + delete=False, **kwargs): + self.read = read + self.create = create + self.write = write + self.delete = delete + self.list = kwargs.pop('list', None) + self.move = kwargs.pop('move', None) + self.execute = kwargs.pop('execute', None) + self.manage_ownership = kwargs.pop('manage_ownership', None) + self.manage_access_control = kwargs.pop('manage_access_control', None) + self._str = (('r' if self.read else '') + + ('c' if self.create else '') + + ('w' if self.write else '') + + ('d' if self.delete else '') + + ('l' if self.list else '') + + ('m' if self.move else '') + + ('e' if self.execute else '') + + ('o' if self.manage_ownership else '') + + ('p' if self.manage_access_control else '')) + + def __str__(self): + return self._str - -class FileSasPermissions(BlobSasPermissions): + @classmethod + def from_string(cls, permission): + """Create a DirectorySasPermissions from a string. + + To specify read, create, write, or delete permissions you need only to + include the first letter of the word in the string. E.g. For read and + write permissions, you would provide a string "rw". + + :param str permission: The string which dictates the read, add, create, + write, or delete permissions. + :return: A DirectorySasPermissions object + :rtype: ~azure.storage.filedatalake.DirectorySasPermissions + """ + p_read = 'r' in permission + p_create = 'c' in permission + p_write = 'w' in permission + p_delete = 'd' in permission + p_list = 'l' in permission + p_move = 'm' in permission + p_execute = 'e' in permission + p_manage_ownership = 'o' in permission + p_manage_access_control = 'p' in permission + + parsed = cls(read=p_read, create=p_create, write=p_write, delete=p_delete, + list=p_list, move=p_move, execute=p_execute, manage_ownership=p_manage_ownership, + manage_access_control=p_manage_access_control) + return parsed + + +class FileSasPermissions(object): """FileSasPermissions class to be used with the :func:`~azure.storage.filedatalake.generate_file_sas` function. @@ -350,14 +465,69 @@ class FileSasPermissions(BlobSasPermissions): Create or write content, properties, metadata. Lease the file. :param bool delete: Delete the file. - """ + :keyword bool move: + Move any file in the directory to a new location. + Note the move operation can optionally be restricted to the child file or directory owner or + the parent directory owner if the saoid parameter is included in the token and the sticky bit is set + on the parent directory. + :keyword bool execute: + Get the status (system defined properties) and ACL of any file in the directory. + If the caller is the owner, set access control on any file in the directory. + :keyword bool manage_ownership: + Allows the user to set owner, owning group, or act as the owner when renaming or deleting a file or directory + within a folder that has the sticky bit set. + :keyword bool manage_access_control: + Allows the user to set permissions and POSIX ACLs on files and directories. + """ + + def __init__(self, read=False, create=False, write=False, delete=False, **kwargs): + self.read = read + self.create = create + self.write = write + self.delete = delete + self.list = list + self.move = kwargs.pop('move', None) + self.execute = kwargs.pop('execute', None) + self.manage_ownership = kwargs.pop('manage_ownership', None) + self.manage_access_control = kwargs.pop('manage_access_control', None) + self._str = (('r' if self.read else '') + + ('c' if self.create else '') + + ('w' if self.write else '') + + ('d' if self.delete else '') + + ('m' if self.move else '') + + ('e' if self.execute else '') + + ('o' if self.manage_ownership else '') + + ('p' if self.manage_access_control else '')) + + def __str__(self): + return self._str - def __init__(self, read=False, create=False, write=False, - delete=False): - super(FileSasPermissions, self).__init__( - read=read, create=create, write=write, - delete=delete - ) + @classmethod + def from_string(cls, permission): + """Create a FileSasPermissions from a string. + + To specify read, write, or delete permissions you need only to + include the first letter of the word in the string. E.g. For read and + write permissions, you would provide a string "rw". + + :param str permission: The string which dictates the read, add, create, + write, or delete permissions. + :return: A FileSasPermissions object + :rtype: ~azure.storage.fildatalake.FileSasPermissions + """ + p_read = 'r' in permission + p_create = 'c' in permission + p_write = 'w' in permission + p_delete = 'd' in permission + p_move = 'm' in permission + p_execute = 'e' in permission + p_manage_ownership = 'o' in permission + p_manage_access_control = 'p' in permission + + parsed = cls(read=p_read, create=p_create, write=p_write, delete=p_delete, + move=p_move, execute=p_execute, manage_ownership=p_manage_ownership, + manage_access_control=p_manage_access_control) + return parsed class AccessPolicy(BlobAccessPolicy): diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/shared_access_signature.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/shared_access_signature.py index 367c6554ef89..07aad5ffa1c8 100644 --- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/shared_access_signature.py +++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/shared_access_signature.py @@ -39,6 +39,12 @@ class QueryStringConstants(object): SIGNED_KEY_SERVICE = 'sks' SIGNED_KEY_VERSION = 'skv' + # for ADLS + SIGNED_AUTHORIZED_OID = 'saoid' + SIGNED_UNAUTHORIZED_OID = 'suoid' + SIGNED_CORRELATION_ID = 'scid' + SIGNED_DIRECTORY_DEPTH = 'sdd' + @staticmethod def to_list(): return [ @@ -68,6 +74,11 @@ def to_list(): QueryStringConstants.SIGNED_KEY_EXPIRY, QueryStringConstants.SIGNED_KEY_SERVICE, QueryStringConstants.SIGNED_KEY_VERSION, + # for ADLS + QueryStringConstants.SIGNED_AUTHORIZED_OID, + QueryStringConstants.SIGNED_UNAUTHORIZED_OID, + QueryStringConstants.SIGNED_CORRELATION_ID, + QueryStringConstants.SIGNED_DIRECTORY_DEPTH, ] diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared_access_signature.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared_access_signature.py index ec4622f5b70a..14dddef9e3a2 100644 --- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared_access_signature.py +++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared_access_signature.py @@ -149,6 +149,19 @@ def generate_file_system_sas( :keyword str content_type: Response header value for Content-Type when resource is accessed using this shared access signature. + :keyword str preauthorized_agent_object_id: + The AAD object ID of a user assumed to be authorized by the owner of the user delegation key to perform + the action granted by the SAS token. The service will validate the SAS token and ensure that the owner of the + user delegation key has the required permissions before granting access but no additional permission check for + the agent object id will be performed. + :keyword str agent_object_id: + The AAD object ID of a user assumed to be unauthorized by the owner of the user delegation key to + perform the action granted by the SAS token. The service will validate the SAS token and ensure that the owner + of the user delegation key has the required permissions before granting access and the service will perform an + additional POSIX ACL check to determine if this user is authorized to perform the requested operation. + :keyword str correlation_id: + The correlation id to correlate the storage audit logs with the audit logs used by the principal + generating and distributing the SAS. :return: A Shared Access Signature (sas) token. :rtype: str """ @@ -238,9 +251,23 @@ def generate_directory_sas( :keyword str content_type: Response header value for Content-Type when resource is accessed using this shared access signature. + :keyword str preauthorized_agent_object_id: + The AAD object ID of a user assumed to be authorized by the owner of the user delegation key to perform + the action granted by the SAS token. The service will validate the SAS token and ensure that the owner of the + user delegation key has the required permissions before granting access but no additional permission check for + the agent object id will be performed. + :keyword str agent_object_id: + The AAD object ID of a user assumed to be unauthorized by the owner of the user delegation key to + perform the action granted by the SAS token. The service will validate the SAS token and ensure that the owner + of the user delegation key has the required permissions before granting access and the service will perform an + additional POSIX ACL check to determine if this user is authorized to perform the requested operation. + :keyword str correlation_id: + The correlation id to correlate the storage audit logs with the audit logs used by the principal + generating and distributing the SAS. :return: A Shared Access Signature (sas) token. :rtype: str """ + depth = len(directory_name.strip("/").split("/")) return generate_blob_sas( account_name=account_name, container_name=file_system_name, @@ -249,6 +276,8 @@ def generate_directory_sas( user_delegation_key=credential if not isinstance(credential, str) else None, permission=permission, expiry=expiry, + sdd=depth, + is_directory=True, **kwargs) @@ -331,6 +360,19 @@ def generate_file_sas( :keyword str content_type: Response header value for Content-Type when resource is accessed using this shared access signature. + :keyword str preauthorized_agent_object_id: + The AAD object ID of a user assumed to be authorized by the owner of the user delegation key to perform + the action granted by the SAS token. The service will validate the SAS token and ensure that the owner of the + user delegation key has the required permissions before granting access but no additional permission check for + the agent object id will be performed. + :keyword str agent_object_id: + The AAD object ID of a user assumed to be unauthorized by the owner of the user delegation key to + perform the action granted by the SAS token. The service will validate the SAS token and ensure that the owner + of the user delegation key has the required permissions before granting access and the service will perform an + additional POSIX ACL check to determine if this user is authorized to perform the requested operation. + :keyword str correlation_id: + The correlation id to correlate the storage audit logs with the audit logs used by the principal + generating and distributing the SAS. This can only be used when to generate sas with delegation key. :return: A Shared Access Signature (sas) token. :rtype: str """ diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_directory_client_async.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_directory_client_async.py index 68956da97364..c09c3f3597bb 100644 --- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_directory_client_async.py +++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_directory_client_async.py @@ -273,7 +273,7 @@ async def rename_directory(self, new_name, # type: str """ new_name = new_name.strip('/') new_file_system = new_name.split('/')[0] - new_path_and_token = new_name[len(new_file_system):].split('?') + new_path_and_token = new_name[len(new_file_system):].strip('/').split('?') new_path = new_path_and_token[0] try: new_dir_sas = new_path_and_token[1] or self._query_str.strip('?') diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_file_client_async.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_file_client_async.py index d075575dc8c6..90fd7ca2a3fe 100644 --- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_file_client_async.py +++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/aio/_data_lake_file_client_async.py @@ -528,7 +528,7 @@ async def rename_file(self, new_name, # type: str """ new_name = new_name.strip('/') new_file_system = new_name.split('/')[0] - new_path_and_token = new_name[len(new_file_system):].split('?') + new_path_and_token = new_name[len(new_file_system):].strip('/').split('?') new_path = new_path_and_token[0] try: new_file_sas = new_path_and_token[1] or self._query_str.strip('?') diff --git a/sdk/storage/azure-storage-file-datalake/tests/recordings/test_directory_async.test_rename_from_an_unencoded_directory_in_another_file_system_async.yaml b/sdk/storage/azure-storage-file-datalake/tests/recordings/test_directory_async.test_rename_from_an_unencoded_directory_in_another_file_system_async.yaml index 829477fe33b5..9cc00ec73a98 100644 --- a/sdk/storage/azure-storage-file-datalake/tests/recordings/test_directory_async.test_rename_from_an_unencoded_directory_in_another_file_system_async.yaml +++ b/sdk/storage/azure-storage-file-datalake/tests/recordings/test_directory_async.test_rename_from_an_unencoded_directory_in_another_file_system_async.yaml @@ -5,9 +5,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - 74bb5106-fdd8-11ea-8a83-001a7dda7113 + - 18555946-04c6-11eb-a875-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:07:50 GMT + - Fri, 02 Oct 2020 15:44:02 GMT x-ms-version: - '2020-02-10' method: PUT @@ -17,11 +17,11 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:07:49 GMT - Etag: '"0x8D85FFC58EE4033"' - Last-Modified: Wed, 23 Sep 2020 20:07:50 GMT + Date: Fri, 02 Oct 2020 15:44:02 GMT + Etag: '"0x8D866E9FC87D398"' + Last-Modified: Fri, 02 Oct 2020 15:44:02 GMT Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: 1db39818-201e-0018-5ae5-9192f3000000 + x-ms-request-id: 0508d5ce-d01e-0033-04d2-98123f000000 x-ms-version: '2020-02-10' status: code: 201 @@ -33,9 +33,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - 74c4d5b0-fdd8-11ea-b7fd-001a7dda7113 + - 18608de6-04c6-11eb-885b-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:07:50 GMT + - Fri, 02 Oct 2020 15:44:02 GMT x-ms-properties: - '' x-ms-version: @@ -47,11 +47,11 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:07:50 GMT - Etag: '"0x8D85FFC5919FCA1"' - Last-Modified: Wed, 23 Sep 2020 20:07:50 GMT + Date: Fri, 02 Oct 2020 15:44:02 GMT + Etag: '"0x8D866E9FCBCFF74"' + Last-Modified: Fri, 02 Oct 2020 15:44:02 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: bfce20e4-101f-004e-54e5-91631c000000 + x-ms-request-id: 7e784b8c-801f-003e-09d2-98daeb000000 x-ms-version: '2020-02-10' status: code: 201 @@ -63,9 +63,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - 74ef1418-fdd8-11ea-9161-001a7dda7113 + - 1891a49c-04c6-11eb-8c60-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:07:50 GMT + - Fri, 02 Oct 2020 15:44:02 GMT x-ms-properties: - '' x-ms-version: @@ -77,11 +77,11 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:07:50 GMT - Etag: '"0x8D85FFC59233FEF"' - Last-Modified: Wed, 23 Sep 2020 20:07:50 GMT + Date: Fri, 02 Oct 2020 15:44:02 GMT + Etag: '"0x8D866E9FCC56CB7"' + Last-Modified: Fri, 02 Oct 2020 15:44:02 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: bfce20e5-101f-004e-55e5-91631c000000 + x-ms-request-id: 7e784b90-801f-003e-0dd2-98daeb000000 x-ms-version: '2020-02-10' status: code: 201 @@ -93,9 +93,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - 74f7fcf6-fdd8-11ea-b020-001a7dda7113 + - 189a0eb6-04c6-11eb-86aa-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:07:50 GMT + - Fri, 02 Oct 2020 15:44:02 GMT x-ms-version: - '2020-02-10' method: PUT @@ -105,11 +105,11 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:07:49 GMT - Etag: '"0x8D85FFC592B0610"' - Last-Modified: Wed, 23 Sep 2020 20:07:50 GMT + Date: Fri, 02 Oct 2020 15:44:02 GMT + Etag: '"0x8D866E9FCCCB14E"' + Last-Modified: Fri, 02 Oct 2020 15:44:02 GMT Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: 1db398e3-201e-0018-04e5-9192f3000000 + x-ms-request-id: 0508d75a-d01e-0033-67d2-98123f000000 x-ms-version: '2020-02-10' status: code: 201 @@ -121,9 +121,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - 7500ef98-fdd8-11ea-ba18-001a7dda7113 + - 18a3f81e-04c6-11eb-8989-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:07:50 GMT + - Fri, 02 Oct 2020 15:44:02 GMT x-ms-properties: - '' x-ms-version: @@ -135,11 +135,11 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:07:50 GMT - Etag: '"0x8D85FFC59351E11"' - Last-Modified: Wed, 23 Sep 2020 20:07:50 GMT + Date: Fri, 02 Oct 2020 15:44:02 GMT + Etag: '"0x8D866E9FCD841C3"' + Last-Modified: Fri, 02 Oct 2020 15:44:02 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: bfce20e6-101f-004e-56e5-91631c000000 + x-ms-request-id: 7e784b91-801f-003e-0ed2-98daeb000000 x-ms-version: '2020-02-10' status: code: 201 @@ -151,9 +151,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - 7509b162-fdd8-11ea-b6b6-001a7dda7113 + - 18ada44a-04c6-11eb-a789-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:07:50 GMT + - Fri, 02 Oct 2020 15:44:02 GMT x-ms-rename-source: - /oldfilesystem745924c6/old%20dir x-ms-source-lease-id: @@ -167,9 +167,9 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:07:50 GMT + Date: Fri, 02 Oct 2020 15:44:02 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: bfce20e7-101f-004e-57e5-91631c000000 + x-ms-request-id: 7e784b92-801f-003e-0fd2-98daeb000000 x-ms-version: '2020-02-10' status: code: 201 @@ -181,13 +181,13 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - 75149d4c-fdd8-11ea-844f-001a7dda7113 + - 18ba1b98-04c6-11eb-a810-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:07:50 GMT + - Fri, 02 Oct 2020 15:44:02 GMT x-ms-version: - '2020-02-10' method: HEAD - uri: https://storagename.blob.core.windows.net/newfilesystem745924c6//new%20name/sub%20dir + uri: https://storagename.blob.core.windows.net/newfilesystem745924c6/new%20name/sub%20dir response: body: string: '' @@ -195,33 +195,33 @@ interactions: Accept-Ranges: bytes Content-Length: '0' Content-Type: application/octet-stream - Date: Wed, 23 Sep 2020 20:07:50 GMT - Etag: '"0x8D85FFC5919FCA1"' - Last-Modified: Wed, 23 Sep 2020 20:07:50 GMT + Date: Fri, 02 Oct 2020 15:44:02 GMT + Etag: '"0x8D866E9FCBCFF74"' + Last-Modified: Fri, 02 Oct 2020 15:44:02 GMT Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 x-ms-access-tier: Hot x-ms-access-tier-inferred: 'true' x-ms-blob-type: BlockBlob - x-ms-creation-time: Wed, 23 Sep 2020 20:07:50 GMT + x-ms-creation-time: Fri, 02 Oct 2020 15:44:02 GMT x-ms-lease-state: available x-ms-lease-status: unlocked x-ms-meta-hdi_isfolder: 'true' - x-ms-request-id: 1db39957-201e-0018-6be5-9192f3000000 + x-ms-request-id: 0508d815-d01e-0033-11d2-98123f000000 x-ms-server-encrypted: 'true' x-ms-version: '2020-02-10' status: code: 200 message: OK - url: https://xiafuhns.blob.core.windows.net/newfilesystem745924c6//new%20name/sub%20dir + url: https://xiafuhns.blob.core.windows.net/newfilesystem745924c6/new%20name/sub%20dir - request: body: null headers: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - 751c0c70-fdd8-11ea-8c8c-001a7dda7113 + - 18c2c01e-04c6-11eb-84c1-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:07:50 GMT + - Fri, 02 Oct 2020 15:44:03 GMT x-ms-version: - '2020-02-10' method: HEAD @@ -233,17 +233,17 @@ interactions: Accept-Ranges: bytes Content-Length: '0' Content-Type: application/octet-stream - Date: Wed, 23 Sep 2020 20:07:50 GMT - Etag: '"0x8D85FFC59233FEF"' - Last-Modified: Wed, 23 Sep 2020 20:07:50 GMT + Date: Fri, 02 Oct 2020 15:44:02 GMT + Etag: '"0x8D866E9FCC56CB7"' + Last-Modified: Fri, 02 Oct 2020 15:44:02 GMT Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 x-ms-access-tier: Hot x-ms-access-tier-inferred: 'true' x-ms-blob-type: BlockBlob - x-ms-creation-time: Wed, 23 Sep 2020 20:07:50 GMT + x-ms-creation-time: Fri, 02 Oct 2020 15:44:02 GMT x-ms-lease-state: available x-ms-lease-status: unlocked - x-ms-request-id: 1db39966-201e-0018-79e5-9192f3000000 + x-ms-request-id: 0508d831-d01e-0033-2bd2-98123f000000 x-ms-server-encrypted: 'true' x-ms-version: '2020-02-10' status: @@ -256,9 +256,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - 75234670-fdd8-11ea-924c-001a7dda7113 + - 18cb0a86-04c6-11eb-a812-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:07:50 GMT + - Fri, 02 Oct 2020 15:44:03 GMT x-ms-version: - '2020-02-10' method: DELETE @@ -268,9 +268,9 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:07:50 GMT + Date: Fri, 02 Oct 2020 15:44:02 GMT Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: 1db39976-201e-0018-08e5-9192f3000000 + x-ms-request-id: 0508d869-d01e-0033-5ed2-98123f000000 x-ms-version: '2020-02-10' status: code: 202 diff --git a/sdk/storage/azure-storage-file-datalake/tests/recordings/test_file_async.test_rename_file_to_existing_file_async.yaml b/sdk/storage/azure-storage-file-datalake/tests/recordings/test_file_async.test_rename_file_to_existing_file_async.yaml index 1b798361cd0f..6d8e577d9151 100644 --- a/sdk/storage/azure-storage-file-datalake/tests/recordings/test_file_async.test_rename_file_to_existing_file_async.yaml +++ b/sdk/storage/azure-storage-file-datalake/tests/recordings/test_file_async.test_rename_file_to_existing_file_async.yaml @@ -5,9 +5,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - eafbd468-fdd7-11ea-a9ee-001a7dda7113 + - 2b3adc82-04c6-11eb-a4a4-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:03:59 GMT + - Fri, 02 Oct 2020 15:44:34 GMT x-ms-properties: - '' x-ms-version: @@ -19,11 +19,11 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:03:58 GMT - Etag: '"0x8D85FFBCF474CAC"' - Last-Modified: Wed, 23 Sep 2020 20:03:59 GMT + Date: Fri, 02 Oct 2020 15:44:33 GMT + Etag: '"0x8D866EA0F9E9B32"' + Last-Modified: Fri, 02 Oct 2020 15:44:34 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: 034fa274-701f-0005-7ae4-919f4f000000 + x-ms-request-id: 98d77ad0-a01f-0016-72d2-98bb43000000 x-ms-version: '2020-02-10' status: code: 201 @@ -39,9 +39,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - eb1bb3dc-fdd7-11ea-baff-001a7dda7113 + - 2b735bd2-04c6-11eb-9a00-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:03:59 GMT + - Fri, 02 Oct 2020 15:44:34 GMT x-ms-version: - '2020-02-10' method: PATCH @@ -51,9 +51,9 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:03:58 GMT + Date: Fri, 02 Oct 2020 15:44:33 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: 034fa275-701f-0005-7be4-919f4f000000 + x-ms-request-id: 98d77ad5-a01f-0016-76d2-98bb43000000 x-ms-request-server-encrypted: 'true' x-ms-version: '2020-02-10' status: @@ -68,9 +68,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - eb23127e-fdd7-11ea-a1c0-001a7dda7113 + - 2b7b1a6c-04c6-11eb-aaa5-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:03:59 GMT + - Fri, 02 Oct 2020 15:44:34 GMT x-ms-version: - '2020-02-10' method: PATCH @@ -80,11 +80,11 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:03:58 GMT - Etag: '"0x8D85FFBCF572D52"' - Last-Modified: Wed, 23 Sep 2020 20:03:59 GMT + Date: Fri, 02 Oct 2020 15:44:33 GMT + Etag: '"0x8D866EA0FAF998B"' + Last-Modified: Fri, 02 Oct 2020 15:44:34 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: 034fa276-701f-0005-7ce4-919f4f000000 + x-ms-request-id: 98d77ad7-a01f-0016-78d2-98bb43000000 x-ms-request-server-encrypted: 'false' x-ms-version: '2020-02-10' status: @@ -97,9 +97,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - eb2c4e08-fdd7-11ea-bf54-001a7dda7113 + - 2b854fc2-04c6-11eb-86a4-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:03:59 GMT + - Fri, 02 Oct 2020 15:44:34 GMT x-ms-properties: - '' x-ms-version: @@ -111,11 +111,11 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:03:58 GMT - Etag: '"0x8D85FFBCF608DB3"' - Last-Modified: Wed, 23 Sep 2020 20:03:59 GMT + Date: Fri, 02 Oct 2020 15:44:33 GMT + Etag: '"0x8D866EA0FB973C5"' + Last-Modified: Fri, 02 Oct 2020 15:44:34 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: 034fa277-701f-0005-7de4-919f4f000000 + x-ms-request-id: 98d77ad8-a01f-0016-79d2-98bb43000000 x-ms-version: '2020-02-10' status: code: 201 @@ -131,9 +131,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - eb351cd0-fdd7-11ea-8e34-001a7dda7113 + - 2b8e9ca4-04c6-11eb-b448-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:03:59 GMT + - Fri, 02 Oct 2020 15:44:34 GMT x-ms-version: - '2020-02-10' method: PATCH @@ -143,9 +143,9 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:03:58 GMT + Date: Fri, 02 Oct 2020 15:44:33 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: 034fa278-701f-0005-7ee4-919f4f000000 + x-ms-request-id: 98d77ad9-a01f-0016-7ad2-98bb43000000 x-ms-request-server-encrypted: 'true' x-ms-version: '2020-02-10' status: @@ -160,9 +160,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - eb3d6222-fdd7-11ea-9f82-001a7dda7113 + - 2b96d334-04c6-11eb-9631-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:03:59 GMT + - Fri, 02 Oct 2020 15:44:34 GMT x-ms-version: - '2020-02-10' method: PATCH @@ -172,11 +172,11 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:03:58 GMT - Etag: '"0x8D85FFBCF722130"' - Last-Modified: Wed, 23 Sep 2020 20:03:59 GMT + Date: Fri, 02 Oct 2020 15:44:33 GMT + Etag: '"0x8D866EA0FCB1384"' + Last-Modified: Fri, 02 Oct 2020 15:44:34 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: 034fa279-701f-0005-7fe4-919f4f000000 + x-ms-request-id: 98d77adb-a01f-0016-7cd2-98bb43000000 x-ms-request-server-encrypted: 'false' x-ms-version: '2020-02-10' status: @@ -189,9 +189,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - eb471b3a-fdd7-11ea-b0ff-001a7dda7113 + - 2ba08286-04c6-11eb-81f6-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:03:59 GMT + - Fri, 02 Oct 2020 15:44:34 GMT x-ms-rename-source: - /filesystem75cf1689/file75cf1689 x-ms-source-lease-id: @@ -205,9 +205,9 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:03:58 GMT + Date: Fri, 02 Oct 2020 15:44:33 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: 034fa27a-701f-0005-80e4-919f4f000000 + x-ms-request-id: 98d77adc-a01f-0016-7dd2-98bb43000000 x-ms-version: '2020-02-10' status: code: 201 @@ -221,15 +221,15 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - eb543824-fdd7-11ea-a82c-001a7dda7113 + - 2bac84d2-04c6-11eb-9ffb-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:03:59 GMT + - Fri, 02 Oct 2020 15:44:34 GMT x-ms-range: - bytes=0-33554431 x-ms-version: - '2020-02-10' method: GET - uri: https://storagename.blob.core.windows.net/filesystem75cf1689//existingfile + uri: https://storagename.blob.core.windows.net/filesystem75cf1689/existingfile response: body: string: abc @@ -238,19 +238,19 @@ interactions: Content-Length: '3' Content-Range: bytes 0-2/3 Content-Type: application/octet-stream - Date: Wed, 23 Sep 2020 20:03:59 GMT - Etag: '"0x8D85FFBCF722130"' - Last-Modified: Wed, 23 Sep 2020 20:03:59 GMT + Date: Fri, 02 Oct 2020 15:44:33 GMT + Etag: '"0x8D866EA0FCB1384"' + Last-Modified: Fri, 02 Oct 2020 15:44:34 GMT Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 x-ms-blob-type: BlockBlob - x-ms-creation-time: Wed, 23 Sep 2020 20:03:59 GMT + x-ms-creation-time: Fri, 02 Oct 2020 15:44:34 GMT x-ms-lease-state: available x-ms-lease-status: unlocked - x-ms-request-id: 6d4fb985-101e-004e-19e4-91631c000000 + x-ms-request-id: 5f9fe94e-501e-0002-69d2-98f32c000000 x-ms-server-encrypted: 'true' x-ms-version: '2020-02-10' status: code: 206 message: Partial Content - url: https://xiafuhns.blob.core.windows.net/filesystem75cf1689//existingfile + url: https://xiafuhns.blob.core.windows.net/filesystem75cf1689/existingfile version: 1 diff --git a/sdk/storage/azure-storage-file-datalake/tests/recordings/test_file_async.test_rename_file_with_non_used_name_async.yaml b/sdk/storage/azure-storage-file-datalake/tests/recordings/test_file_async.test_rename_file_with_non_used_name_async.yaml index 2799e9f6fdfd..4fb95f40eb44 100644 --- a/sdk/storage/azure-storage-file-datalake/tests/recordings/test_file_async.test_rename_file_with_non_used_name_async.yaml +++ b/sdk/storage/azure-storage-file-datalake/tests/recordings/test_file_async.test_rename_file_with_non_used_name_async.yaml @@ -5,9 +5,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - eb8f38ca-fdd7-11ea-bebb-001a7dda7113 + - 3d8cbbd8-04c6-11eb-9cb2-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:04:00 GMT + - Fri, 02 Oct 2020 15:45:04 GMT x-ms-properties: - '' x-ms-version: @@ -19,11 +19,11 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:03:59 GMT - Etag: '"0x8D85FFBCFD9617B"' - Last-Modified: Wed, 23 Sep 2020 20:04:00 GMT + Date: Fri, 02 Oct 2020 15:45:04 GMT + Etag: '"0x8D866EA21EA7DBF"' + Last-Modified: Fri, 02 Oct 2020 15:45:05 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: ddda84e6-501f-003d-47e4-913b8f000000 + x-ms-request-id: c5ef4353-a01f-0006-50d2-987e2b000000 x-ms-version: '2020-02-10' status: code: 201 @@ -39,9 +39,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - ebad9a38-fdd7-11ea-b949-001a7dda7113 + - 3dbf1a94-04c6-11eb-8fc7-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:04:00 GMT + - Fri, 02 Oct 2020 15:45:05 GMT x-ms-version: - '2020-02-10' method: PATCH @@ -51,9 +51,9 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:04:00 GMT + Date: Fri, 02 Oct 2020 15:45:04 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: ddda84e7-501f-003d-48e4-913b8f000000 + x-ms-request-id: c5ef4354-a01f-0006-51d2-987e2b000000 x-ms-request-server-encrypted: 'true' x-ms-version: '2020-02-10' status: @@ -68,9 +68,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - ebb50f3e-fdd7-11ea-891e-001a7dda7113 + - 3dc68b4a-04c6-11eb-b373-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:04:00 GMT + - Fri, 02 Oct 2020 15:45:05 GMT x-ms-version: - '2020-02-10' method: PATCH @@ -80,11 +80,11 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:04:00 GMT - Etag: '"0x8D85FFBCFE92053"' - Last-Modified: Wed, 23 Sep 2020 20:04:00 GMT + Date: Fri, 02 Oct 2020 15:45:04 GMT + Etag: '"0x8D866EA21FA5ABB"' + Last-Modified: Fri, 02 Oct 2020 15:45:05 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: ddda84e8-501f-003d-49e4-913b8f000000 + x-ms-request-id: c5ef4355-a01f-0006-52d2-987e2b000000 x-ms-request-server-encrypted: 'false' x-ms-version: '2020-02-10' status: @@ -97,9 +97,9 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - ebbd8bb4-fdd7-11ea-a112-001a7dda7113 + - 3dd37518-04c6-11eb-8f0d-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:04:00 GMT + - Fri, 02 Oct 2020 15:45:05 GMT x-ms-rename-source: - /filesystema3c31753/filea3c31753 x-ms-source-lease-id: @@ -113,9 +113,9 @@ interactions: string: '' headers: Content-Length: '0' - Date: Wed, 23 Sep 2020 20:04:00 GMT + Date: Fri, 02 Oct 2020 15:45:05 GMT Server: Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: ddda84e9-501f-003d-4ae4-913b8f000000 + x-ms-request-id: c5ef4358-a01f-0006-55d2-987e2b000000 x-ms-version: '2020-02-10' status: code: 201 @@ -129,15 +129,15 @@ interactions: User-Agent: - azsdk-python-storage-dfs/12.1.2 Python/3.7.3 (Windows-10-10.0.19041-SP0) x-ms-client-request-id: - - ebcaadca-fdd7-11ea-8573-001a7dda7113 + - 3dde1906-04c6-11eb-b997-001a7dda7113 x-ms-date: - - Wed, 23 Sep 2020 20:04:00 GMT + - Fri, 02 Oct 2020 15:45:05 GMT x-ms-range: - bytes=0-33554431 x-ms-version: - '2020-02-10' method: GET - uri: https://storagename.blob.core.windows.net/filesystema3c31753//newname + uri: https://storagename.blob.core.windows.net/filesystema3c31753/newname response: body: string: abc @@ -146,19 +146,19 @@ interactions: Content-Length: '3' Content-Range: bytes 0-2/3 Content-Type: application/octet-stream - Date: Wed, 23 Sep 2020 20:04:00 GMT - Etag: '"0x8D85FFBCFE92053"' - Last-Modified: Wed, 23 Sep 2020 20:04:00 GMT + Date: Fri, 02 Oct 2020 15:45:04 GMT + Etag: '"0x8D866EA21FA5ABB"' + Last-Modified: Fri, 02 Oct 2020 15:45:05 GMT Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 x-ms-blob-type: BlockBlob - x-ms-creation-time: Wed, 23 Sep 2020 20:04:00 GMT + x-ms-creation-time: Fri, 02 Oct 2020 15:45:05 GMT x-ms-lease-state: available x-ms-lease-status: unlocked - x-ms-request-id: 27855895-b01e-0047-3ae4-9126cf000000 + x-ms-request-id: 606d84ab-101e-003c-0ad2-986453000000 x-ms-server-encrypted: 'true' x-ms-version: '2020-02-10' status: code: 206 message: Partial Content - url: https://xiafuhns.blob.core.windows.net/filesystema3c31753//newname + url: https://xiafuhns.blob.core.windows.net/filesystema3c31753/newname version: 1 diff --git a/sdk/storage/azure-storage-file-datalake/tests/test_directory.py b/sdk/storage/azure-storage-file-datalake/tests/test_directory.py index c0628b552cad..7893340e383a 100644 --- a/sdk/storage/azure-storage-file-datalake/tests/test_directory.py +++ b/sdk/storage/azure-storage-file-datalake/tests/test_directory.py @@ -386,6 +386,8 @@ def progress_callback(resp): @record def test_set_access_control_recursive_with_failures(self): + if not self.is_playback(): + return root_directory_client = self.dsc.get_file_system_client(self.file_system_name)._get_root_directory_client() root_directory_client.set_access_control(acl="user::--x,group::--x,other::--x") @@ -425,6 +427,8 @@ def progress_callback(resp): @record def test_set_access_control_recursive_stop_on_failures(self): + if not self.is_playback(): + return root_directory_client = self.dsc.get_file_system_client(self.file_system_name)._get_root_directory_client() root_directory_client.set_access_control(acl="user::--x,group::--x,other::--x") @@ -465,6 +469,8 @@ def progress_callback(resp): @record def test_set_access_control_recursive_continue_on_failures(self): + if not self.is_playback(): + return root_directory_client = self.dsc.get_file_system_client(self.file_system_name)._get_root_directory_client() root_directory_client.set_access_control(acl="user::--x,group::--x,other::--x") @@ -638,6 +644,8 @@ def progress_callback(resp): @record def test_update_access_control_recursive_with_failures(self): + if not self.is_playback(): + return root_directory_client = self.dsc.get_file_system_client(self.file_system_name)._get_root_directory_client() root_directory_client.set_access_control(acl="user::--x,group::--x,other::--x") @@ -745,6 +753,8 @@ def progress_callback(resp): @record def test_remove_access_control_recursive_with_failures(self): + if not self.is_playback(): + return root_directory_client = self.dsc.get_file_system_client(self.file_system_name)._get_root_directory_client() root_directory_client.set_access_control(acl="user::--x,group::--x,other::--x") @@ -1031,7 +1041,30 @@ def test_using_directory_sas_to_create(self): response = directory_client.create_directory() self.assertIsNotNone(response) + def test_using_directory_sas_to_create_file(self): + # SAS URL is calculated from storage key, so this test runs live only + if TestMode.need_recording_file(self.test_mode): + return + + client = self._create_directory_and_get_directory_client() + directory_name = client.path_name + + # generate a token with directory level read permission + token = generate_directory_sas( + self.dsc.account_name, + self.file_system_name, + directory_name, + self.dsc.credential.account_key, + permission=DirectorySasPermissions(create=True), + expiry=datetime.utcnow() + timedelta(hours=1), + ) + directory_client = DataLakeDirectoryClient(self.dsc.url, self.file_system_name, directory_name, + credential=token) + directory_client.create_sub_directory("subdir") + + with self.assertRaises(HttpResponseError): + directory_client.delete_directory() # ------------------------------------------------------------------------------ if __name__ == '__main__': unittest.main() diff --git a/sdk/storage/azure-storage-file-datalake/tests/test_directory_async.py b/sdk/storage/azure-storage-file-datalake/tests/test_directory_async.py index dac0b608afcf..eb95d47159dd 100644 --- a/sdk/storage/azure-storage-file-datalake/tests/test_directory_async.py +++ b/sdk/storage/azure-storage-file-datalake/tests/test_directory_async.py @@ -486,6 +486,8 @@ def test_set_access_control_recursive_with_failures_async(self): loop.run_until_complete(self._test_set_access_control_recursive_with_failures_async()) async def _test_set_access_control_recursive_with_failures_async(self): + if not self.is_playback(): + return root_directory_client = self.dsc.get_file_system_client(self.file_system_name)._get_root_directory_client() await root_directory_client.set_access_control(acl="user::--x,group::--x,other::--x") @@ -657,6 +659,8 @@ def test_update_access_control_recursive_with_failures_async(self): loop.run_until_complete(self._test_update_access_control_recursive_with_failures_async()) async def _test_update_access_control_recursive_with_failures_async(self): + if not self.is_playback(): + return root_directory_client = self.dsc.get_file_system_client(self.file_system_name)._get_root_directory_client() await root_directory_client.set_access_control(acl="user::--x,group::--x,other::--x") @@ -700,6 +704,8 @@ def test_update_access_control_recursive_continue_on_failures_async(self): loop.run_until_complete(self._test_update_access_control_recursive_continue_on_failures_async()) async def _test_update_access_control_recursive_continue_on_failures_async(self): + if not self.is_playback(): + return root_directory_client = self.dsc.get_file_system_client(self.file_system_name)._get_root_directory_client() await root_directory_client.set_access_control(acl="user::--x,group::--x,other::--x") @@ -823,6 +829,8 @@ def test_remove_access_control_recursive_with_failures_async(self): loop.run_until_complete(self._test_remove_access_control_recursive_with_failures_async()) async def _test_remove_access_control_recursive_with_failures_async(self): + if not self.is_playback(): + return root_directory_client = self.dsc.get_file_system_client(self.file_system_name)._get_root_directory_client() await root_directory_client.set_access_control(acl="user::--x,group::--x,other::--x") @@ -1081,7 +1089,7 @@ async def _test_rename_dir_with_file_system_sas(self): self.dsc.account_name, self.file_system_name, self.dsc.credential.account_key, - FileSystemSasPermissions(write=True, read=True, delete=True), + FileSystemSasPermissions(write=True, read=True, delete=True, move=True), datetime.utcnow() + timedelta(hours=1), ) @@ -1098,14 +1106,14 @@ def test_rename_dir_with_file_system_sas_async(self): loop.run_until_complete(self._test_rename_dir_with_file_system_sas()) async def _test_rename_dir_with_file_sas(self): - # TODO: service bug?? - pytest.skip("service bug?") + if TestMode.need_recording_file(self.test_mode): + return token = generate_directory_sas(self.dsc.account_name, self.file_system_name, "olddir", self.settings.STORAGE_DATA_LAKE_ACCOUNT_KEY, permission=DirectorySasPermissions(read=True, create=True, write=True, - delete=True), + delete=True, move=True), expiry=datetime.utcnow() + timedelta(hours=1), ) diff --git a/sdk/storage/azure-storage-file-datalake/tests/test_file.py b/sdk/storage/azure-storage-file-datalake/tests/test_file.py index 0e09fdbb890f..dfeb7eecdb75 100644 --- a/sdk/storage/azure-storage-file-datalake/tests/test_file.py +++ b/sdk/storage/azure-storage-file-datalake/tests/test_file.py @@ -369,6 +369,86 @@ def test_read_file_with_user_delegation_key(self): downloaded_data = new_file_client.download_file().readall() self.assertEqual(data, downloaded_data) + def test_set_acl_with_user_delegation_key(self): + # SAS URL is calculated from storage key, so this test runs live only + if TestMode.need_recording_file(self.test_mode): + return + + # Create file + file_client = self._create_file_and_return_client() + data = self.get_random_bytes(1024) + # Upload data to file + file_client.append_data(data, 0, len(data)) + file_client.flush_data(len(data)) + + # Get user delegation key + token_credential = self.generate_oauth_token() + service_client = DataLakeServiceClient(self._get_oauth_account_url(), credential=token_credential) + user_delegation_key = service_client.get_user_delegation_key(datetime.utcnow(), + datetime.utcnow() + timedelta(hours=1)) + + sas_token = generate_file_sas(file_client.account_name, + file_client.file_system_name, + None, + file_client.path_name, + user_delegation_key, + permission=FileSasPermissions(execute=True, manage_access_control=True, + manage_ownership=True), + expiry=datetime.utcnow() + timedelta(hours=1), + ) + + # doanload the data and make sure it is the same as uploaded data + new_file_client = DataLakeFileClient(self._get_account_url(), + file_client.file_system_name, + file_client.path_name, + credential=sas_token) + acl = 'user::rwx,group::r-x,other::rwx' + owner = "dc140949-53b7-44af-b1e9-cd994951fb86" + new_file_client.set_access_control(acl=acl, owner=owner) + access_control = new_file_client.get_access_control() + self.assertEqual(acl, access_control['acl']) + self.assertEqual(owner, access_control['owner']) + + def test_preauthorize_user_with_user_delegation_key(self): + # SAS URL is calculated from storage key, so this test runs live only + if TestMode.need_recording_file(self.test_mode): + return + + # Create file + file_client = self._create_file_and_return_client() + data = self.get_random_bytes(1024) + # Upload data to file + file_client.append_data(data, 0, len(data)) + file_client.flush_data(len(data)) + file_client.set_access_control(owner="68390a19-a643-458b-b726-408abf67b4fc", permissions='0777') + acl = file_client.get_access_control() + + # Get user delegation key + token_credential = self.generate_oauth_token() + service_client = DataLakeServiceClient(self._get_oauth_account_url(), credential=token_credential) + user_delegation_key = service_client.get_user_delegation_key(datetime.utcnow(), + datetime.utcnow() + timedelta(hours=1)) + + sas_token = generate_file_sas(file_client.account_name, + file_client.file_system_name, + None, + file_client.path_name, + user_delegation_key, + permission=FileSasPermissions(read=True, write=True, manage_access_control=True, + manage_ownership=True), + expiry=datetime.utcnow() + timedelta(hours=1), + preauthorized_agent_object_id="68390a19-a643-458b-b726-408abf67b4fc" + ) + + # doanload the data and make sure it is the same as uploaded data + new_file_client = DataLakeFileClient(self._get_account_url(), + file_client.file_system_name, + file_client.path_name, + credential=sas_token) + + acl = new_file_client.set_access_control(permissions='0777') + self.assertIsNotNone(acl) + @record def test_read_file_into_file(self): file_client = self._create_file_and_return_client() diff --git a/sdk/storage/azure-storage-file-datalake/tests/test_file_async.py b/sdk/storage/azure-storage-file-datalake/tests/test_file_async.py index 0c3afa9a0c57..82c6badf8b61 100644 --- a/sdk/storage/azure-storage-file-datalake/tests/test_file_async.py +++ b/sdk/storage/azure-storage-file-datalake/tests/test_file_async.py @@ -805,7 +805,7 @@ async def _test_rename_file_with_file_sas(self): None, "oldfile", self.settings.STORAGE_DATA_LAKE_ACCOUNT_KEY, - permission=FileSasPermissions(read=True, create=True, write=True, delete=True), + permission=FileSasPermissions(read=True, create=True, write=True, delete=True, move=True), expiry=datetime.utcnow() + timedelta(hours=1), ) diff --git a/sdk/storage/azure-storage-file-datalake/tests/test_file_system_async.py b/sdk/storage/azure-storage-file-datalake/tests/test_file_system_async.py index 0650c5ee014a..b2f8639d6f7c 100644 --- a/sdk/storage/azure-storage-file-datalake/tests/test_file_system_async.py +++ b/sdk/storage/azure-storage-file-datalake/tests/test_file_system_async.py @@ -7,20 +7,25 @@ # -------------------------------------------------------------------------- import unittest import asyncio +import uuid from datetime import datetime, timedelta + +import pytest + from azure.core.exceptions import ResourceNotFoundError from azure.core import MatchConditions from azure.core.pipeline.transport import AioHttpTransport from multidict import CIMultiDict, CIMultiDictProxy -from azure.storage.filedatalake import AccessPolicy -from azure.storage.filedatalake.aio import DataLakeServiceClient +from azure.storage.filedatalake import AccessPolicy, generate_directory_sas, DirectorySasPermissions, \ + generate_file_system_sas +from azure.storage.filedatalake.aio import DataLakeServiceClient, DataLakeDirectoryClient, FileSystemClient from azure.storage.filedatalake import PublicAccess from testcase import ( StorageTestCase, record, -) + TestMode) # ------------------------------------------------------------------------------ from azure.storage.filedatalake import FileSystemSasPermissions @@ -443,6 +448,80 @@ def test_get_root_directory_client_async(self): loop = asyncio.get_event_loop() loop.run_until_complete(self._test_get_root_directory_client()) + async def _test_get_access_control_using_delegation_sas_async(self): + if TestMode.need_recording_file(self.test_mode): + return + + url = self._get_account_url() + token_credential = self.generate_async_oauth_token() + dsc = DataLakeServiceClient(url, token_credential) + file_system_name = self._get_file_system_reference() + directory_client_name = '/' + (await dsc.create_file_system(file_system_name)).get_directory_client(directory_client_name) + + directory_client = self.dsc.get_directory_client(file_system_name, directory_client_name) + random_guid = uuid.uuid4() + await directory_client.set_access_control(owner=random_guid, + permissions='0777') + acl = await directory_client.get_access_control() + + delegation_key = await dsc.get_user_delegation_key(datetime.utcnow(), + datetime.utcnow() + timedelta(hours=1)) + + token = generate_file_system_sas( + dsc.account_name, + file_system_name, + delegation_key, + permission=FileSystemSasPermissions(read=True, execute=True, manage_access_control=True, manage_ownership=True), + expiry=datetime.utcnow() + timedelta(hours=1), + agent_object_id=random_guid + ) + sas_directory_client = DataLakeDirectoryClient(self.dsc.url, file_system_name, directory_client_name, + credential=token) + access_control = await sas_directory_client.get_access_control() + + self.assertIsNotNone(access_control) + + def test_get_access_control_using_delegation_sas_async(self): + loop = asyncio.get_event_loop() + loop.run_until_complete(self._test_get_access_control_using_delegation_sas_async()) + + async def _test_list_paths_using_file_sys_delegation_sas_async(self): + if TestMode.need_recording_file(self.test_mode): + return + url = self._get_account_url() + token_credential = self.generate_async_oauth_token() + dsc = DataLakeServiceClient(url, token_credential) + file_system_name = self._get_file_system_reference() + directory_client_name = '/' + directory_client = (await dsc.create_file_system(file_system_name)).get_directory_client(directory_client_name) + + random_guid = uuid.uuid4() + await directory_client.set_access_control(owner=random_guid, permissions='0777') + + delegation_key = await dsc.get_user_delegation_key(datetime.utcnow(), + datetime.utcnow() + timedelta(hours=1)) + + token = generate_file_system_sas( + dsc.account_name, + file_system_name, + delegation_key, + permission=DirectorySasPermissions(list=True), + expiry=datetime.utcnow() + timedelta(hours=1), + agent_object_id=random_guid + ) + sas_directory_client = FileSystemClient(self.dsc.url, file_system_name, + credential=token) + paths = list() + async for path in sas_directory_client.get_paths(): + paths.append(path) + + self.assertEqual(0, 0) + + def test_list_paths_using_file_sys_delegation_sas_async(self): + loop = asyncio.get_event_loop() + loop.run_until_complete(self._test_list_paths_using_file_sys_delegation_sas_async()) + # ------------------------------------------------------------------------------ if __name__ == '__main__': unittest.main() diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/shared_access_signature.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/shared_access_signature.py index 367c6554ef89..07aad5ffa1c8 100644 --- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/shared_access_signature.py +++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/shared_access_signature.py @@ -39,6 +39,12 @@ class QueryStringConstants(object): SIGNED_KEY_SERVICE = 'sks' SIGNED_KEY_VERSION = 'skv' + # for ADLS + SIGNED_AUTHORIZED_OID = 'saoid' + SIGNED_UNAUTHORIZED_OID = 'suoid' + SIGNED_CORRELATION_ID = 'scid' + SIGNED_DIRECTORY_DEPTH = 'sdd' + @staticmethod def to_list(): return [ @@ -68,6 +74,11 @@ def to_list(): QueryStringConstants.SIGNED_KEY_EXPIRY, QueryStringConstants.SIGNED_KEY_SERVICE, QueryStringConstants.SIGNED_KEY_VERSION, + # for ADLS + QueryStringConstants.SIGNED_AUTHORIZED_OID, + QueryStringConstants.SIGNED_UNAUTHORIZED_OID, + QueryStringConstants.SIGNED_CORRELATION_ID, + QueryStringConstants.SIGNED_DIRECTORY_DEPTH, ] diff --git a/sdk/storage/azure-storage-file-share/tests/test_file.py b/sdk/storage/azure-storage-file-share/tests/test_file.py index 08e1cf91c69e..408c689908d4 100644 --- a/sdk/storage/azure-storage-file-share/tests/test_file.py +++ b/sdk/storage/azure-storage-file-share/tests/test_file.py @@ -918,6 +918,7 @@ def test_list_ranges_none_with_invalid_lease_fails(self, resource_group, locatio self.assertIsNotNone(ranges) self.assertEqual(len(ranges), 0) + @pytest.mark.playback_test_only @GlobalStorageAccountPreparer() def test_list_ranges_diff(self, resource_group, location, storage_account, storage_account_key): self._setup(storage_account, storage_account_key) diff --git a/sdk/storage/azure-storage-file-share/tests/test_file_async.py b/sdk/storage/azure-storage-file-share/tests/test_file_async.py index 3ea6e3d0d082..46822ff652c1 100644 --- a/sdk/storage/azure-storage-file-share/tests/test_file_async.py +++ b/sdk/storage/azure-storage-file-share/tests/test_file_async.py @@ -988,6 +988,7 @@ async def test_list_ranges_none_with_invalid_lease_fails_async(self, resource_gr self.assertIsNotNone(ranges) self.assertEqual(len(ranges), 0) + @pytest.mark.playback_test_only @GlobalStorageAccountPreparer() @AsyncStorageTestCase.await_prepared_test async def test_list_ranges_diff(self, resource_group, location, storage_account, storage_account_key): diff --git a/sdk/storage/azure-storage-file-share/tests/test_file_service_properties.py b/sdk/storage/azure-storage-file-share/tests/test_file_service_properties.py index f5c03734e7f0..7aae66446f61 100644 --- a/sdk/storage/azure-storage-file-share/tests/test_file_service_properties.py +++ b/sdk/storage/azure-storage-file-share/tests/test_file_service_properties.py @@ -7,6 +7,8 @@ # -------------------------------------------------------------------------- import unittest +import pytest + from azure.core.exceptions import HttpResponseError from azure.storage.fileshare import ( @@ -74,6 +76,7 @@ def _assert_retention_equal(self, ret1, ret2): self.assertEqual(ret1.days, ret2.days) # --Test cases per service --------------------------------------- + @pytest.mark.playback_test_only @GlobalStorageAccountPreparer() def test_file_service_properties(self, resource_group, location, storage_account, storage_account_key): self._setup(storage_account, storage_account_key) diff --git a/sdk/storage/azure-storage-file-share/tests/test_file_service_properties_async.py b/sdk/storage/azure-storage-file-share/tests/test_file_service_properties_async.py index f0dcd2ac2f9b..be6a7a4db7a4 100644 --- a/sdk/storage/azure-storage-file-share/tests/test_file_service_properties_async.py +++ b/sdk/storage/azure-storage-file-share/tests/test_file_service_properties_async.py @@ -8,6 +8,8 @@ import unittest import asyncio +import pytest + from azure.core.exceptions import HttpResponseError from azure.core.pipeline.transport import AioHttpTransport from multidict import CIMultiDict, CIMultiDictProxy @@ -84,6 +86,7 @@ def _assert_retention_equal(self, ret1, ret2): self.assertEqual(ret1.days, ret2.days) # --Test cases per service --------------------------------------- + @pytest.mark.playback_test_only @GlobalStorageAccountPreparer() @AsyncStorageTestCase.await_prepared_test async def test_file_service_properties_async(self, resource_group, location, storage_account, storage_account_key): diff --git a/sdk/storage/azure-storage-file-share/tests/test_share.py b/sdk/storage/azure-storage-file-share/tests/test_share.py index 990bb58fb686..b3daed35e1f7 100644 --- a/sdk/storage/azure-storage-file-share/tests/test_share.py +++ b/sdk/storage/azure-storage-file-share/tests/test_share.py @@ -638,6 +638,7 @@ def test_list_shares_leased_share(self, resource_group, location, storage_accoun lease.release() self._delete_shares() + @pytest.mark.playback_test_only @GlobalStorageAccountPreparer() def test_list_shares_with_snapshot(self, resource_group, location, storage_account, storage_account_key): self._setup(storage_account, storage_account_key) @@ -658,7 +659,7 @@ def test_list_shares_with_snapshot(self, resource_group, location, storage_accou share.delete_share(delete_snapshots=True) self._delete_shares() - + @pytest.mark.playback_test_only @GlobalStorageAccountPreparer() def test_list_shares_with_prefix(self, resource_group, location, storage_account, storage_account_key): self._setup(storage_account, storage_account_key) diff --git a/sdk/storage/azure-storage-file-share/tests/test_share_async.py b/sdk/storage/azure-storage-file-share/tests/test_share_async.py index f87ad5fab041..64e3b3818131 100644 --- a/sdk/storage/azure-storage-file-share/tests/test_share_async.py +++ b/sdk/storage/azure-storage-file-share/tests/test_share_async.py @@ -696,6 +696,7 @@ async def test_list_shares_leased_share(self, resource_group, location, storage_ await lease.release() await self._delete_shares() + @pytest.mark.playback_test_only @GlobalStorageAccountPreparer() @AsyncStorageTestCase.await_prepared_test async def test_list_shares_with_snapshot_async(self, resource_group, location, storage_account, storage_account_key): @@ -719,6 +720,7 @@ async def test_list_shares_with_snapshot_async(self, resource_group, location, s self.assertNamedItemInContainer(all_shares, snapshot2['snapshot']) await self._delete_shares(share.share_name) + @pytest.mark.playback_test_only @GlobalStorageAccountPreparer() @AsyncStorageTestCase.await_prepared_test async def test_list_shares_with_prefix_async(self, resource_group, location, storage_account, storage_account_key): diff --git a/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/shared_access_signature.py b/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/shared_access_signature.py index 367c6554ef89..07aad5ffa1c8 100644 --- a/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/shared_access_signature.py +++ b/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/shared_access_signature.py @@ -39,6 +39,12 @@ class QueryStringConstants(object): SIGNED_KEY_SERVICE = 'sks' SIGNED_KEY_VERSION = 'skv' + # for ADLS + SIGNED_AUTHORIZED_OID = 'saoid' + SIGNED_UNAUTHORIZED_OID = 'suoid' + SIGNED_CORRELATION_ID = 'scid' + SIGNED_DIRECTORY_DEPTH = 'sdd' + @staticmethod def to_list(): return [ @@ -68,6 +74,11 @@ def to_list(): QueryStringConstants.SIGNED_KEY_EXPIRY, QueryStringConstants.SIGNED_KEY_SERVICE, QueryStringConstants.SIGNED_KEY_VERSION, + # for ADLS + QueryStringConstants.SIGNED_AUTHORIZED_OID, + QueryStringConstants.SIGNED_UNAUTHORIZED_OID, + QueryStringConstants.SIGNED_CORRELATION_ID, + QueryStringConstants.SIGNED_DIRECTORY_DEPTH, ]