1# ------------------------------------------------------------------------- 2# Copyright (c) Microsoft Corporation. All rights reserved. 3# Licensed under the MIT License. See License.txt in the project root for 4# license information. 5# -------------------------------------------------------------------------- 6 7from typing import ( # pylint: disable=unused-import 8 Union, Optional, Any, List, TYPE_CHECKING 9) 10 11from ._shared import sign_string 12from ._shared.constants import X_MS_VERSION 13from ._shared.models import Services 14from ._shared.shared_access_signature import SharedAccessSignature, _SharedAccessHelper, QueryStringConstants 15from ._shared.parser import _str 16 17if TYPE_CHECKING: 18 from datetime import datetime 19 from .import ( 20 ResourceTypes, 21 AccountSasPermissions, 22 ShareSasPermissions, 23 FileSasPermissions 24 ) 25 26class FileSharedAccessSignature(SharedAccessSignature): 27 ''' 28 Provides a factory for creating file and share access 29 signature tokens with a common account name and account key. Users can either 30 use the factory or can construct the appropriate service and use the 31 generate_*_shared_access_signature method directly. 32 ''' 33 34 def __init__(self, account_name, account_key): 35 ''' 36 :param str account_name: 37 The storage account name used to generate the shared access signatures. 38 :param str account_key: 39 The access key to generate the shares access signatures. 40 ''' 41 super(FileSharedAccessSignature, self).__init__(account_name, account_key, x_ms_version=X_MS_VERSION) 42 43 def generate_file(self, share_name, directory_name=None, file_name=None, 44 permission=None, expiry=None, start=None, policy_id=None, 45 ip=None, protocol=None, cache_control=None, 46 content_disposition=None, content_encoding=None, 47 content_language=None, content_type=None): 48 ''' 49 Generates a shared access signature for the file. 50 Use the returned signature with the sas_token parameter of FileService. 51 52 :param str share_name: 53 Name of share. 54 :param str directory_name: 55 Name of directory. SAS tokens cannot be created for directories, so 56 this parameter should only be present if file_name is provided. 57 :param str file_name: 58 Name of file. 59 :param ~azure.storage.fileshare.FileSasPermissions permission: 60 The permissions associated with the shared access signature. The 61 user is restricted to operations allowed by the permissions. 62 Permissions must be ordered read, create, write, delete, list. 63 Required unless an id is given referencing a stored access policy 64 which contains this field. This field must be omitted if it has been 65 specified in an associated stored access policy. 66 :param expiry: 67 The time at which the shared access signature becomes invalid. 68 Required unless an id is given referencing a stored access policy 69 which contains this field. This field must be omitted if it has 70 been specified in an associated stored access policy. Azure will always 71 convert values to UTC. If a date is passed in without timezone info, it 72 is assumed to be UTC. 73 :type expiry: datetime or str 74 :param start: 75 The time at which the shared access signature becomes valid. If 76 omitted, start time for this call is assumed to be the time when the 77 storage service receives the request. Azure will always convert values 78 to UTC. If a date is passed in without timezone info, it is assumed to 79 be UTC. 80 :type start: datetime or str 81 :param str policy_id: 82 A unique value up to 64 characters in length that correlates to a 83 stored access policy. To create a stored access policy, use 84 set_file_service_properties. 85 :param str ip: 86 Specifies an IP address or a range of IP addresses from which to accept requests. 87 If the IP address from which the request originates does not match the IP address 88 or address range specified on the SAS token, the request is not authenticated. 89 For example, specifying sip=168.1.5.65 or sip=168.1.5.60-168.1.5.70 on the SAS 90 restricts the request to those IP addresses. 91 :param str protocol: 92 Specifies the protocol permitted for a request made. The default value 93 is https,http. See :class:`~azure.storage.common.models.Protocol` for possible values. 94 :param str cache_control: 95 Response header value for Cache-Control when resource is accessed 96 using this shared access signature. 97 :param str content_disposition: 98 Response header value for Content-Disposition when resource is accessed 99 using this shared access signature. 100 :param str content_encoding: 101 Response header value for Content-Encoding when resource is accessed 102 using this shared access signature. 103 :param str content_language: 104 Response header value for Content-Language when resource is accessed 105 using this shared access signature. 106 :param str content_type: 107 Response header value for Content-Type when resource is accessed 108 using this shared access signature. 109 ''' 110 resource_path = share_name 111 if directory_name is not None: 112 resource_path += '/' + _str(directory_name) if directory_name is not None else None 113 resource_path += '/' + _str(file_name) if file_name is not None else None 114 115 sas = _FileSharedAccessHelper() 116 sas.add_base(permission, expiry, start, ip, protocol, self.x_ms_version) 117 sas.add_id(policy_id) 118 sas.add_resource('f') 119 sas.add_override_response_headers(cache_control, content_disposition, 120 content_encoding, content_language, 121 content_type) 122 sas.add_resource_signature(self.account_name, self.account_key, resource_path) 123 124 return sas.get_token() 125 126 def generate_share(self, share_name, permission=None, expiry=None, 127 start=None, policy_id=None, ip=None, protocol=None, 128 cache_control=None, content_disposition=None, 129 content_encoding=None, content_language=None, 130 content_type=None): 131 ''' 132 Generates a shared access signature for the share. 133 Use the returned signature with the sas_token parameter of FileService. 134 135 :param str share_name: 136 Name of share. 137 :param ShareSasPermissions permission: 138 The permissions associated with the shared access signature. The 139 user is restricted to operations allowed by the permissions. 140 Permissions must be ordered read, create, write, delete, list. 141 Required unless an id is given referencing a stored access policy 142 which contains this field. This field must be omitted if it has been 143 specified in an associated stored access policy. 144 :param expiry: 145 The time at which the shared access signature becomes invalid. 146 Required unless an id is given referencing a stored access policy 147 which contains this field. This field must be omitted if it has 148 been specified in an associated stored access policy. Azure will always 149 convert values to UTC. If a date is passed in without timezone info, it 150 is assumed to be UTC. 151 :type expiry: datetime or str 152 :param start: 153 The time at which the shared access signature becomes valid. If 154 omitted, start time for this call is assumed to be the time when the 155 storage service receives the request. Azure will always convert values 156 to UTC. If a date is passed in without timezone info, it is assumed to 157 be UTC. 158 :type start: datetime or str 159 :param str policy_id: 160 A unique value up to 64 characters in length that correlates to a 161 stored access policy. To create a stored access policy, use 162 set_file_service_properties. 163 :param str ip: 164 Specifies an IP address or a range of IP addresses from which to accept requests. 165 If the IP address from which the request originates does not match the IP address 166 or address range specified on the SAS token, the request is not authenticated. 167 For example, specifying sip=168.1.5.65 or sip=168.1.5.60-168.1.5.70 on the SAS 168 restricts the request to those IP addresses. 169 :param str protocol: 170 Specifies the protocol permitted for a request made. The default value 171 is https,http. See :class:`~azure.storage.common.models.Protocol` for possible values. 172 :param str cache_control: 173 Response header value for Cache-Control when resource is accessed 174 using this shared access signature. 175 :param str content_disposition: 176 Response header value for Content-Disposition when resource is accessed 177 using this shared access signature. 178 :param str content_encoding: 179 Response header value for Content-Encoding when resource is accessed 180 using this shared access signature. 181 :param str content_language: 182 Response header value for Content-Language when resource is accessed 183 using this shared access signature. 184 :param str content_type: 185 Response header value for Content-Type when resource is accessed 186 using this shared access signature. 187 ''' 188 sas = _FileSharedAccessHelper() 189 sas.add_base(permission, expiry, start, ip, protocol, self.x_ms_version) 190 sas.add_id(policy_id) 191 sas.add_resource('s') 192 sas.add_override_response_headers(cache_control, content_disposition, 193 content_encoding, content_language, 194 content_type) 195 sas.add_resource_signature(self.account_name, self.account_key, share_name) 196 197 return sas.get_token() 198 199 200class _FileSharedAccessHelper(_SharedAccessHelper): 201 202 def add_resource_signature(self, account_name, account_key, path): 203 def get_value_to_append(query): 204 return_value = self.query_dict.get(query) or '' 205 return return_value + '\n' 206 207 if path[0] != '/': 208 path = '/' + path 209 210 canonicalized_resource = '/file/' + account_name + path + '\n' 211 212 # Form the string to sign from shared_access_policy and canonicalized 213 # resource. The order of values is important. 214 string_to_sign = \ 215 (get_value_to_append(QueryStringConstants.SIGNED_PERMISSION) + 216 get_value_to_append(QueryStringConstants.SIGNED_START) + 217 get_value_to_append(QueryStringConstants.SIGNED_EXPIRY) + 218 canonicalized_resource + 219 get_value_to_append(QueryStringConstants.SIGNED_IDENTIFIER) + 220 get_value_to_append(QueryStringConstants.SIGNED_IP) + 221 get_value_to_append(QueryStringConstants.SIGNED_PROTOCOL) + 222 get_value_to_append(QueryStringConstants.SIGNED_VERSION) + 223 get_value_to_append(QueryStringConstants.SIGNED_CACHE_CONTROL) + 224 get_value_to_append(QueryStringConstants.SIGNED_CONTENT_DISPOSITION) + 225 get_value_to_append(QueryStringConstants.SIGNED_CONTENT_ENCODING) + 226 get_value_to_append(QueryStringConstants.SIGNED_CONTENT_LANGUAGE) + 227 get_value_to_append(QueryStringConstants.SIGNED_CONTENT_TYPE)) 228 229 # remove the trailing newline 230 if string_to_sign[-1] == '\n': 231 string_to_sign = string_to_sign[:-1] 232 233 self._add_query(QueryStringConstants.SIGNED_SIGNATURE, 234 sign_string(account_key, string_to_sign)) 235 236 237def generate_account_sas( 238 account_name, # type: str 239 account_key, # type: str 240 resource_types, # type: Union[ResourceTypes, str] 241 permission, # type: Union[AccountSasPermissions, str] 242 expiry, # type: Optional[Union[datetime, str]] 243 start=None, # type: Optional[Union[datetime, str]] 244 ip=None, # type: Optional[str] 245 **kwargs # type: Any 246 ): 247 # type: (...) -> str 248 """Generates a shared access signature for the file service. 249 250 Use the returned signature with the credential parameter of any ShareServiceClient, 251 ShareClient, ShareDirectoryClient, or ShareFileClient. 252 253 :param str account_name: 254 The storage account name used to generate the shared access signature. 255 :param str account_key: 256 The account key, also called shared key or access key, to generate the shared access signature. 257 :param ~azure.storage.fileshare.ResourceTypes resource_types: 258 Specifies the resource types that are accessible with the account SAS. 259 :param ~azure.storage.fileshare.AccountSasPermissions permission: 260 The permissions associated with the shared access signature. The 261 user is restricted to operations allowed by the permissions. 262 Required unless an id is given referencing a stored access policy 263 which contains this field. This field must be omitted if it has been 264 specified in an associated stored access policy. 265 :param expiry: 266 The time at which the shared access signature becomes invalid. 267 Required unless an id is given referencing a stored access policy 268 which contains this field. This field must be omitted if it has 269 been specified in an associated stored access policy. Azure will always 270 convert values to UTC. If a date is passed in without timezone info, it 271 is assumed to be UTC. 272 :type expiry: ~datetime.datetime or str 273 :param start: 274 The time at which the shared access signature becomes valid. If 275 omitted, start time for this call is assumed to be the time when the 276 storage service receives the request. Azure will always convert values 277 to UTC. If a date is passed in without timezone info, it is assumed to 278 be UTC. 279 :type start: ~datetime.datetime or str 280 :param str ip: 281 Specifies an IP address or a range of IP addresses from which to accept requests. 282 If the IP address from which the request originates does not match the IP address 283 or address range specified on the SAS token, the request is not authenticated. 284 For example, specifying sip=168.1.5.65 or sip=168.1.5.60-168.1.5.70 on the SAS 285 restricts the request to those IP addresses. 286 :keyword str protocol: 287 Specifies the protocol permitted for a request made. The default value is https. 288 :return: A Shared Access Signature (sas) token. 289 :rtype: str 290 291 .. admonition:: Example: 292 293 .. literalinclude:: ../samples/file_samples_authentication.py 294 :start-after: [START generate_sas_token] 295 :end-before: [END generate_sas_token] 296 :language: python 297 :dedent: 8 298 :caption: Generate a sas token. 299 """ 300 sas = SharedAccessSignature(account_name, account_key) 301 return sas.generate_account( 302 services=Services(fileshare=True), 303 resource_types=resource_types, 304 permission=permission, 305 expiry=expiry, 306 start=start, 307 ip=ip, 308 **kwargs 309 ) # type: ignore 310 311 312def generate_share_sas( 313 account_name, # type: str 314 share_name, # type: str 315 account_key, # type: str 316 permission=None, # type: Optional[Union[ShareSasPermissions, str]] 317 expiry=None, # type: Optional[Union[datetime, str]] 318 start=None, # type: Optional[Union[datetime, str]] 319 policy_id=None, # type: Optional[str] 320 ip=None, # type: Optional[str] 321 **kwargs # type: Any 322 ): # type: (...) -> str 323 """Generates a shared access signature for a share. 324 325 Use the returned signature with the credential parameter of any ShareServiceClient, 326 ShareClient, ShareDirectoryClient, or ShareFileClient. 327 328 :param str account_name: 329 The storage account name used to generate the shared access signature. 330 :param str share_name: 331 The name of the share. 332 :param str account_key: 333 The account key, also called shared key or access key, to generate the shared access signature. 334 :param ~azure.storage.fileshare.ShareSasPermissions permission: 335 The permissions associated with the shared access signature. The 336 user is restricted to operations allowed by the permissions. 337 Permissions must be ordered read, create, write, delete, list. 338 Required unless an id is given referencing a stored access policy 339 which contains this field. This field must be omitted if it has been 340 specified in an associated stored access policy. 341 :param expiry: 342 The time at which the shared access signature becomes invalid. 343 Required unless an id is given referencing a stored access policy 344 which contains this field. This field must be omitted if it has 345 been specified in an associated stored access policy. Azure will always 346 convert values to UTC. If a date is passed in without timezone info, it 347 is assumed to be UTC. 348 :type expiry: ~datetime.datetime or str 349 :param start: 350 The time at which the shared access signature becomes valid. If 351 omitted, start time for this call is assumed to be the time when the 352 storage service receives the request. Azure will always convert values 353 to UTC. If a date is passed in without timezone info, it is assumed to 354 be UTC. 355 :type start: ~datetime.datetime or str 356 :param str policy_id: 357 A unique value up to 64 characters in length that correlates to a 358 stored access policy. To create a stored access policy, use 359 :func:`~azure.storage.fileshare.ShareClient.set_share_access_policy`. 360 :param str ip: 361 Specifies an IP address or a range of IP addresses from which to accept requests. 362 If the IP address from which the request originates does not match the IP address 363 or address range specified on the SAS token, the request is not authenticated. 364 For example, specifying sip=168.1.5.65 or sip=168.1.5.60-168.1.5.70 on the SAS 365 restricts the request to those IP addresses. 366 :keyword str cache_control: 367 Response header value for Cache-Control when resource is accessed 368 using this shared access signature. 369 :keyword str content_disposition: 370 Response header value for Content-Disposition when resource is accessed 371 using this shared access signature. 372 :keyword str content_encoding: 373 Response header value for Content-Encoding when resource is accessed 374 using this shared access signature. 375 :keyword str content_language: 376 Response header value for Content-Language when resource is accessed 377 using this shared access signature. 378 :keyword str content_type: 379 Response header value for Content-Type when resource is accessed 380 using this shared access signature. 381 :keyword str protocol: 382 Specifies the protocol permitted for a request made. The default value is https. 383 :return: A Shared Access Signature (sas) token. 384 :rtype: str 385 """ 386 sas = FileSharedAccessSignature(account_name, account_key) 387 return sas.generate_share( 388 share_name=share_name, 389 permission=permission, 390 expiry=expiry, 391 start=start, 392 policy_id=policy_id, 393 ip=ip, 394 **kwargs 395 ) 396 397 398def generate_file_sas( 399 account_name, # type: str 400 share_name, # type: str 401 file_path, # type: List[str] 402 account_key, # type: str 403 permission=None, # type: Optional[Union[FileSasPermissions, str]] 404 expiry=None, # type: Optional[Union[datetime, str]] 405 start=None, # type: Optional[Union[datetime, str]] 406 policy_id=None, # type: Optional[str] 407 ip=None, # type: Optional[str] 408 **kwargs # type: Any 409 ): 410 # type: (...) -> str 411 """Generates a shared access signature for a file. 412 413 Use the returned signature with the credential parameter of any ShareServiceClient, 414 ShareClient, ShareDirectoryClient, or ShareFileClient. 415 416 :param str account_name: 417 The storage account name used to generate the shared access signature. 418 :param str share_name: 419 The name of the share. 420 :param file_path: 421 The file path represented as a list of path segments, including the file name. 422 :type file_path: List[str] 423 :param str account_key: 424 The account key, also called shared key or access key, to generate the shared access signature. 425 :param ~azure.storage.fileshare.FileSasPermissions permission: 426 The permissions associated with the shared access signature. The 427 user is restricted to operations allowed by the permissions. 428 Permissions must be ordered read, write, delete, list. 429 Required unless an id is given referencing a stored access policy 430 which contains this field. This field must be omitted if it has been 431 specified in an associated stored access policy. 432 :param expiry: 433 The time at which the shared access signature becomes invalid. 434 Required unless an id is given referencing a stored access policy 435 which contains this field. This field must be omitted if it has 436 been specified in an associated stored access policy. Azure will always 437 convert values to UTC. If a date is passed in without timezone info, it 438 is assumed to be UTC. 439 :type expiry: ~datetime.datetime or str 440 :param start: 441 The time at which the shared access signature becomes valid. If 442 omitted, start time for this call is assumed to be the time when the 443 storage service receives the request. Azure will always convert values 444 to UTC. If a date is passed in without timezone info, it is assumed to 445 be UTC. 446 :type start: ~datetime.datetime or str 447 :param str policy_id: 448 A unique value up to 64 characters in length that correlates to a 449 stored access policy. 450 :param str ip: 451 Specifies an IP address or a range of IP addresses from which to accept requests. 452 If the IP address from which the request originates does not match the IP address 453 or address range specified on the SAS token, the request is not authenticated. 454 For example, specifying sip=168.1.5.65 or sip=168.1.5.60-168.1.5.70 on the SAS 455 restricts the request to those IP addresses. 456 :keyword str cache_control: 457 Response header value for Cache-Control when resource is accessed 458 using this shared access signature. 459 :keyword str content_disposition: 460 Response header value for Content-Disposition when resource is accessed 461 using this shared access signature. 462 :keyword str content_encoding: 463 Response header value for Content-Encoding when resource is accessed 464 using this shared access signature. 465 :keyword str content_language: 466 Response header value for Content-Language when resource is accessed 467 using this shared access signature. 468 :keyword str content_type: 469 Response header value for Content-Type when resource is accessed 470 using this shared access signature. 471 :keyword str protocol: 472 Specifies the protocol permitted for a request made. The default value is https. 473 :return: A Shared Access Signature (sas) token. 474 :rtype: str 475 """ 476 sas = FileSharedAccessSignature(account_name, account_key) 477 if len(file_path) > 1: 478 dir_path = '/'.join(file_path[:-1]) 479 else: 480 dir_path = None # type: ignore 481 return sas.generate_file( # type: ignore 482 share_name=share_name, 483 directory_name=dir_path, 484 file_name=file_path[-1], 485 permission=permission, 486 expiry=expiry, 487 start=start, 488 policy_id=policy_id, 489 ip=ip, 490 **kwargs 491 ) 492