7272 _parse_account_information ,
7373 _convert_xml_to_user_delegation_key ,
7474 _parse_continuation_token ,
75+ _parse_path_permission_and_acl ,
7576)
7677from ._download_chunking import _download_blob_chunks
7778from ._error import (
@@ -1545,7 +1546,6 @@ def set_blob_service_properties(
15451546 '''
15461547 if all (parameter is None for parameter in [logging , hour_metrics , minute_metrics , cors , target_version ,
15471548 delete_retention_policy , static_website ]):
1548-
15491549 raise ValueError ("set_blob_service_properties should be called with at least one parameter" )
15501550
15511551 request = HTTPRequest ()
@@ -3549,19 +3549,19 @@ def delete_directory(self, container_name, directory_path, fail_not_exist=False,
35493549 else :
35503550 return True , self ._perform_request (request , parser = _parse_continuation_token )
35513551
3552- def rename_directory (self , container_name , new_directory_path , source_directory_path ,
3553- mode = None , marker = None , lease_id = None , source_lease_id = None ,
3554- metadata = None , source_if_modified_since = None , source_if_unmodified_since = None ,
3555- source_if_match = None , source_if_none_match = None , timeout = None ):
3552+ def rename_path (self , container_name , new_path , source_path ,
3553+ mode = None , marker = None , lease_id = None , source_lease_id = None ,
3554+ metadata = None , source_if_modified_since = None , source_if_unmodified_since = None ,
3555+ source_if_match = None , source_if_none_match = None , timeout = None ):
35563556 """
3557- Rename a directory which can contain other directories or blobs.
3557+ Rename a blob or directory( which can contain other directories or blobs) .
35583558
35593559 :param str container_name:
35603560 Name of existing container.
3561- :param str new_directory_path :
3562- New path for source_directory_path . Ex: 'dirfoo/dirsubfoo'.
3563- :param str source_directory_path :
3564- Directory to be renamed. Ex: 'dirfoo/dirbar'.
3561+ :param str new_path :
3562+ New path for source_path . Ex: 'dirfoo/dirsubfoo'.
3563+ :param str source_path :
3564+ Path to be renamed. Ex: 'dirfoo/dirbar'.
35653565 :param mode:
35663566 Optional. Valid only when namespace is enabled.
35673567 This parameter determines the behavior of the rename operation.
@@ -3573,13 +3573,13 @@ def rename_directory(self, container_name, new_directory_path, source_directory_
35733573 a continuation token is returned. When a continuation token is returned,
35743574 it must be specified in a subsequent invocation of the rename operation to continue renaming the directory.
35753575 :param str lease_id:
3576- Optional. A lease ID for the new_directory_path .
3577- The new_directory_path must have an active lease and the lease ID must match.
3576+ Optional. A lease ID for the new_path .
3577+ The new_path must have an active lease and the lease ID must match.
35783578 :param str source_lease_id:
3579- Optional. A lease ID for the source_directory_path .
3580- The source_directory_path must have an active lease and the lease ID must match.
3579+ Optional. A lease ID for the source_path .
3580+ The source_path must have an active lease and the lease ID must match.
35813581 :param metadata:
3582- Optional. A dict with name_value pairs to associate with the directory as metadata.
3582+ Optional. A dict with name_value pairs to associate with the path as metadata.
35833583 Example:{'Category':'test'}.
35843584 If metadata is specified, it will overwrite the existing metadata;
35853585 otherwise, the existing metadata will be preserved.
@@ -3603,21 +3603,21 @@ def rename_directory(self, container_name, new_directory_path, source_directory_
36033603 A continuation marker if applicable. Otherwise return None.
36043604 :rtype: str
36053605 """
3606- _validate_not_none ('source_directory_path ' , source_directory_path )
3607- _validate_not_none ('new_directory_path ' , new_directory_path )
3606+ _validate_not_none ('source_path ' , source_path )
3607+ _validate_not_none ('new_path ' , new_path )
36083608
36093609 request = HTTPRequest ()
36103610 # TODO remove endpoint swapping after service update
36113611 request .host_locations = self ._swap_blob_endpoints (self ._get_host_locations ())
36123612 request .method = 'PUT'
3613- request .path = _get_path (container_name , new_directory_path )
3613+ request .path = _get_path (container_name , new_path )
36143614 request .query = {
36153615 'mode' : mode ,
36163616 'continuation' : _to_str (marker ),
36173617 'timeout' : _int_to_str (timeout ),
36183618 }
36193619 request .headers = {
3620- 'x-ms-rename-source' : _get_path (container_name , source_directory_path ),
3620+ 'x-ms-rename-source' : _get_path (container_name , source_path ),
36213621 'x-ms-lease-id' : _to_str (lease_id ),
36223622 'x-ms-source-lease-id' : _to_str (source_lease_id ),
36233623 'x-ms-source-if-modified-since' : _datetime_to_utc_string (source_if_modified_since ),
@@ -3629,6 +3629,148 @@ def rename_directory(self, container_name, new_directory_path, source_directory_
36293629 _add_file_or_directory_properties_header (metadata , request )
36303630 return self ._perform_request (request , parser = _parse_continuation_token )
36313631
3632+ def get_path_access_control (self , container_name , path , user_principle_names = False ,
3633+ lease_id = None , if_modified_since = None , if_unmodified_since = None ,
3634+ if_match = None , if_none_match = None , timeout = None ):
3635+ """
3636+ Retrieve the access control properties of a path(directory or blob).
3637+
3638+ :param str container_name:
3639+ Name of existing container.
3640+ :param str path:
3641+ Path of the directory/blob.
3642+ :param user_principle_names:
3643+ Valid only when Hierarchical Namespace is enabled for the account.
3644+ If "true", the user identity values returned for owner, group, and acl will be transformed
3645+ from Azure Active Directory Object IDs to User Principal Names.
3646+ If "false", the values will be returned as Azure Active Directory Object IDs.
3647+ The default value is false. Note that group and application Object IDs are not translated
3648+ because they do not have unique friendly names.
3649+ :param str lease_id:
3650+ Required if the path has an active lease.
3651+ :param datetime if_modified_since:
3652+ A date and time value. Specify this header to perform the operation only if the resource
3653+ has been modified since the specified date and time.
3654+ :param datetime if_unmodified_since:
3655+ A date and time value. Specify this header to perform the operation only if the resource
3656+ has not been modified since the specified date and time.
3657+ :param datetime if_match:
3658+ An ETag value. Specify this header to perform the operation
3659+ only if the resource's ETag matches the value specified. The ETag must be specified in quotes.
3660+ :param datetime if_none_match:
3661+ An ETag value or the special wildcard ("*") value.
3662+ Specify this header to perform the operation only if the resource's ETag
3663+ does not match the value specified. The ETag must be specified in quotes.
3664+ :param int timeout:
3665+ The timeout parameter is expressed in seconds.
3666+ :return: ETag and last modified time of the new directory.
3667+ :rtype: :class:`~azure.storage.blob.models.ResourceProperties`
3668+ """
3669+ _validate_not_none ('path' , path )
3670+
3671+ request = HTTPRequest ()
3672+ # TODO remove endpoint swapping after service update
3673+ request .host_locations = self ._swap_blob_endpoints (self ._get_host_locations ())
3674+ request .method = 'HEAD'
3675+ request .path = _get_path (container_name , path )
3676+ request .query = {
3677+ 'action' : 'getAccessControl' ,
3678+ 'upn' : _to_str (user_principle_names ),
3679+ 'timeout' : _int_to_str (timeout ),
3680+ }
3681+ request .headers = {
3682+ 'x-ms-lease-id' : _to_str (lease_id ),
3683+ 'If-Modified-Since' : _datetime_to_utc_string (if_modified_since ),
3684+ 'If-Unmodified-Since' : _datetime_to_utc_string (if_unmodified_since ),
3685+ 'If-Match' : _to_str (if_match ),
3686+ 'If-None-Match' : _to_str (if_none_match ),
3687+ }
3688+ return self ._perform_request (request , parser = _parse_path_permission_and_acl )
3689+
3690+ def set_path_access_control (self , container_name , path , owner = None , group = None , permissions = None ,
3691+ acl = None , lease_id = None , if_modified_since = None , if_unmodified_since = None ,
3692+ if_match = None , if_none_match = None , timeout = None ):
3693+ """
3694+ Set the access control properties of a path(directory or blob).
3695+
3696+ :param str container_name:
3697+ Name of existing container.
3698+ :param str path:
3699+ Path of the directory/blob.
3700+ :param str owner:
3701+ Sets the owner of the file or directory.
3702+ :param str group:
3703+ Sets the owning group of the file or directory.
3704+ :param str permissions:
3705+ Invalid in conjunction with acl.
3706+ Sets POSIX access permissions for the file owner, the file owning group, and others.
3707+ Each class may be granted read, write, or execute permission.
3708+ The sticky bit is also supported. Both symbolic (rwxrw-rw-)
3709+ and 4-digit octal notation (e.g. 0766) are supported.
3710+ :param str acl:
3711+ Invalid in conjunction with permissions.
3712+ Sets POSIX access control rights on files and directories.
3713+ The value is a comma-separated list of access control entries that fully replaces the existing
3714+ access control list (ACL). Each access control entry (ACE) consists of a scope, a type,
3715+ a user or group identifier, and permissions in the format "[scope:][type]:[id]:[permissions]".
3716+ The scope must be "default" to indicate the ACE belongs to the default ACL for a directory;
3717+ otherwise scope is implicit and the ACE belongs to the access ACL.
3718+ There are four ACE types: "user" grants rights to the owner or a named user,
3719+ "group" grants rights to the owning group or a named group,
3720+ "mask" restricts rights granted to named users and the members of groups,
3721+ and "other" grants rights to all users not found in any of the other entries.
3722+ The user or group identifier is omitted for entries of type "mask" and "other".
3723+ The user or group identifier is also omitted for the owner and owning group.
3724+ The permission field is a 3-character sequence where the first character is 'r' to grant read access,
3725+ the second character is 'w' to grant write access, and the third character is 'x'
3726+ to grant execute permission. If access is not granted, the '-' character is used to denote
3727+ that the permission is denied. For example, the following ACL grants read, write, and execute rights to
3728+ the file owner and john.doe@contoso, the read right to the owning group,
3729+ and nothing to everyone else: "user::rwx,user:john.doe@contoso:rwx,group::r--,other::---,mask=rwx".
3730+ :param str lease_id:
3731+ Required if the path has an active lease.
3732+ :param datetime if_modified_since:
3733+ A date and time value. Specify this header to perform the operation only if the resource
3734+ has been modified since the specified date and time.
3735+ :param datetime if_unmodified_since:
3736+ A date and time value. Specify this header to perform the operation only if the resource
3737+ has not been modified since the specified date and time.
3738+ :param datetime if_match:
3739+ An ETag value. Specify this header to perform the operation
3740+ only if the resource's ETag matches the value specified. The ETag must be specified in quotes.
3741+ :param datetime if_none_match:
3742+ An ETag value or the special wildcard ("*") value.
3743+ Specify this header to perform the operation only if the resource's ETag
3744+ does not match the value specified. The ETag must be specified in quotes.
3745+ :param int timeout:
3746+ The timeout parameter is expressed in seconds.
3747+ :return: ETag and last modified time of the new directory.
3748+ :rtype: :class:`~azure.storage.blob.models.ResourceProperties`
3749+ """
3750+ _validate_not_none ('path' , path )
3751+
3752+ request = HTTPRequest ()
3753+ # TODO remove endpoint swapping after service update
3754+ request .host_locations = self ._swap_blob_endpoints (self ._get_host_locations ())
3755+ request .method = 'PATCH'
3756+ request .path = _get_path (container_name , path )
3757+ request .query = {
3758+ 'action' : 'setAccessControl' ,
3759+ 'timeout' : _int_to_str (timeout ),
3760+ }
3761+ request .headers = {
3762+ 'x-ms-owner' : _to_str (owner ),
3763+ 'x-ms-group' : _to_str (group ),
3764+ 'x-ms-permissions' : _to_str (permissions ),
3765+ 'x-ms-acl' : _to_str (acl ),
3766+ 'x-ms-lease-id' : _to_str (lease_id ),
3767+ 'If-Modified-Since' : _datetime_to_utc_string (if_modified_since ),
3768+ 'If-Unmodified-Since' : _datetime_to_utc_string (if_unmodified_since ),
3769+ 'If-Match' : _to_str (if_match ),
3770+ 'If-None-Match' : _to_str (if_none_match ),
3771+ }
3772+ return self ._perform_request (request , parser = _parse_base_properties )
3773+
36323774 # ----------------------------Helpers for directory manipulations---------------------------- #
36333775 @staticmethod
36343776 def _swap_blob_endpoints (host_locations ):
0 commit comments