diff --git a/sdk/storage/storage-file-datalake/CHANGELOG.md b/sdk/storage/storage-file-datalake/CHANGELOG.md index 103747a56bdf..c03076733734 100644 --- a/sdk/storage/storage-file-datalake/CHANGELOG.md +++ b/sdk/storage/storage-file-datalake/CHANGELOG.md @@ -2,6 +2,7 @@ ## 12.3.1 (Unreleased) +- Fixed a bug where `generateDataLakeSASQueryParameters()` won't correctly set the resource type if `DataLakeSASSignatureValues.permissions` is not specified. Fixed issue [13223](https://github.com/Azure/azure-sdk-for-js/issues/13223). - Fixed a compile failure due to "Can't resolve 'crypto'" in Angular. [Issue #13267](https://github.com/Azure/azure-sdk-for-js/issues/13267). - The `"Unclosed root tag"` XML parser error is now retriable. [PR #13076](https://github.com/Azure/azure-sdk-for-js/pull/13076). diff --git a/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_should_work_for_directory_with_access_policy.js b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_should_work_for_directory_with_access_policy.js new file mode 100644 index 000000000000..805e65764e7e --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/sas_generation_nodejs_only_for_directory_sas/recording_generatedatalakesasqueryparameters_should_work_for_directory_with_access_policy.js @@ -0,0 +1,167 @@ +let nock = require('nock'); + +module.exports.hash = "7542f6e3b6da8bb981da0db36214ab67"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem161068978171001194","directory":"directory161068978289702419","file":"file161068978420308044"},"newDate":{"now":"2021-01-15T05:49:45.398Z","tmr":"2021-01-15T05:49:45.398Z"}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem161068978171001194') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 15 Jan 2021 05:49:42 GMT', + 'ETag', + '"0x8D8B9195B1DB5BD"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '54e0c4dc-c01e-00b8-5702-eba76d000000', + 'x-ms-client-request-id', + 'bab112db-77c3-49ff-8b58-199f8ca5f6d0', + 'x-ms-version', + '2020-04-08', + 'Date', + 'Fri, 15 Jan 2021 05:49:42 GMT', + 'Connection', + 'close' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem161068978171001194/directory161068978289702419') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Fri, 15 Jan 2021 05:49:44 GMT', + 'ETag', + '"0x8D8B9195BE5E20E"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '0242bfe2-c01f-0012-5002-eb7182000000', + 'x-ms-version', + '2020-04-08', + 'x-ms-client-request-id', + '772bcae8-8675-4fca-afb9-4a910e3c6906', + 'Date', + 'Fri, 15 Jan 2021 05:49:43 GMT', + 'Connection', + 'close', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem161068978171001194/directory161068978289702419/file161068978420308044') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Fri, 15 Jan 2021 05:49:45 GMT', + 'ETag', + '"0x8D8B9195C9D1410"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '998333ca-401f-0003-1502-eb4699000000', + 'x-ms-version', + '2020-04-08', + 'x-ms-client-request-id', + '2cfb3beb-48d4-4c6f-ae83-ce45780a94f0', + 'Date', + 'Fri, 15 Jan 2021 05:49:44 GMT', + 'Connection', + 'close', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem161068978171001194', "unique-id2021-01-15T05:39:45.3980000Z2021-01-25T05:49:45.3980000Zracwd") + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 15 Jan 2021 05:49:46 GMT', + 'ETag', + '"0x8D8B9195D50B2CA"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'cc1c8884-401e-00a9-4502-eb9076000000', + 'x-ms-client-request-id', + '4296c8f7-f6f1-4c36-a769-51f419af6b94', + 'x-ms-version', + '2020-04-08', + 'Date', + 'Fri, 15 Jan 2021 05:49:46 GMT', + 'Connection', + 'close' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem161068978171001194/directory161068978289702419/file161068978420308044') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Content-Type', + 'application/octet-stream', + 'Last-Modified', + 'Fri, 15 Jan 2021 05:49:45 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D8B9195C9D1410"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'a3cef8fe-401e-008b-4b02-ebfe40000000', + 'x-ms-client-request-id', + 'dc4eaee1-3cbd-4a6d-ba85-efecd78243c0', + 'x-ms-version', + '2020-04-08', + 'x-ms-creation-time', + 'Fri, 15 Jan 2021 05:49:45 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-server-encrypted', + 'true', + 'x-ms-access-tier', + 'Hot', + 'x-ms-access-tier-inferred', + 'true', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-creation-time,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,x-ms-server-encrypted,x-ms-access-tier,x-ms-access-tier-inferred,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Fri, 15 Jan 2021 05:49:46 GMT', + 'Connection', + 'close' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem161068978171001194') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'df82fc23-601e-0014-0402-eb86fa000000', + 'x-ms-client-request-id', + '7b31202d-bf55-4eb5-94bb-8d9295d7223d', + 'x-ms-version', + '2020-04-08', + 'Date', + 'Fri, 15 Jan 2021 05:49:48 GMT', + 'Connection', + 'close' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatedatalakesasqueryparameters_should_work_for_file_with_access_policy.js b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatedatalakesasqueryparameters_should_work_for_file_with_access_policy.js index e3d48bf9ef9c..e1aae8910e76 100644 --- a/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatedatalakesasqueryparameters_should_work_for_file_with_access_policy.js +++ b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatedatalakesasqueryparameters_should_work_for_file_with_access_policy.js @@ -1,90 +1,105 @@ let nock = require('nock'); -module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem157534997919101488","file":"file157534998034506784"},"newDate":{"now":"2019-12-03T05:12:59.191Z","tmr":"2019-12-03T05:12:59.191Z"}} +module.exports.hash = "5a49665901d4c84e2f3503371afe0a81"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem161068977513004637","file":"file161068977659501721"},"newDate":{"now":"2021-01-15T05:49:35.129Z","tmr":"2021-01-15T05:49:35.130Z"}} nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/filesystem157534997919101488') + .put('/filesystem161068977513004637') .query(true) - .reply(201, "", [ 'Content-Length', + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Tue, 03 Dec 2019 05:07:01 GMT', + 'Fri, 15 Jan 2021 05:49:36 GMT', 'ETag', - '"0x8D777AEA1CD1048"', + '"0x8D8B91957582CB3"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '71849569-d01e-0085-3197-a9124b000000', + '283f6fb7-801e-001e-1f02-eb9f73000000', 'x-ms-client-request-id', - 'ac05d325-48f0-417f-8a45-7bd8a2ece9b7', + '2b960111-1a66-46b5-b993-f261fb0bdc3f', 'x-ms-version', - '2019-02-02', + '2020-04-08', 'Date', - 'Tue, 03 Dec 2019 05:07:00 GMT' ]); + 'Fri, 15 Jan 2021 05:49:36 GMT', + 'Connection', + 'close' +]); nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) - .put('/filesystem157534997919101488/file157534998034506784') + .put('/filesystem161068977513004637/file161068977659501721') .query(true) - .reply(201, "", [ 'Last-Modified', - 'Tue, 03 Dec 2019 05:07:03 GMT', + .reply(201, "", [ + 'Last-Modified', + 'Fri, 15 Jan 2021 05:49:37 GMT', 'ETag', - '"0x8D777AEA27EB057"', + '"0x8D8B919583E1CBA"', 'Server', 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'c5a4cba4-b01f-003f-6e97-a9f242000000', + '50c4e27e-301f-0007-5602-ebb31b000000', 'x-ms-version', - '2019-02-02', + '2020-04-08', 'x-ms-client-request-id', - 'a782b7a9-406d-4c3e-9ef9-308c107d5a30', + '4d4f3ce9-66e9-4951-b3d7-160e94199439', 'Date', - 'Tue, 03 Dec 2019 05:07:02 GMT', + 'Fri, 15 Jan 2021 05:49:37 GMT', + 'Connection', + 'close', 'Content-Length', - '0' ]); + '0' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .put('/filesystem157534997919101488', "unique-id2019-12-03T05:02:59.1910000Z2019-12-13T05:12:59.1910000Zracwdl") + .put('/filesystem161068977513004637', "unique-id2021-01-15T05:39:35.1290000Z2021-01-25T05:49:35.1300000Zracwd") .query(true) - .reply(200, "", [ 'Content-Length', + .reply(200, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Tue, 03 Dec 2019 05:07:03 GMT', + 'Fri, 15 Jan 2021 05:49:39 GMT', 'ETag', - '"0x8D777AEA2AA52DF"', + '"0x8D8B91958F93DF0"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '71849743-d01e-0085-5a97-a9124b000000', + 'a64cf8db-901e-0023-7002-eb2a55000000', 'x-ms-client-request-id', - '1a4503cf-6880-4643-9045-0a8ac204c295', + '8228734b-7747-4a9b-aad4-b63a6c571fff', 'x-ms-version', - '2019-02-02', + '2020-04-08', 'Date', - 'Tue, 03 Dec 2019 05:07:02 GMT' ]); + 'Fri, 15 Jan 2021 05:49:39 GMT', + 'Connection', + 'close' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .head('/filesystem157534997919101488/file157534998034506784') + .head('/filesystem161068977513004637/file161068977659501721') .query(true) - .reply(200, "", [ 'Content-Length', + .reply(200, "", [ + 'Content-Length', '0', 'Content-Type', 'application/octet-stream', 'Last-Modified', - 'Tue, 03 Dec 2019 05:07:03 GMT', + 'Fri, 15 Jan 2021 05:49:37 GMT', 'Accept-Ranges', 'bytes', 'ETag', - '"0x8D777AEA27EB057"', + '"0x8D8B919583E1CBA"', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'e19b3393-401e-00a2-4697-a98802000000', + '4482131d-501e-00b6-4b02-eb4b66000000', 'x-ms-client-request-id', - 'bb6b88b6-9f41-400f-b975-5bc3c47c03a8', + '69013d0c-f3f9-4f4e-9284-4eec2aee8925', 'x-ms-version', - '2019-02-02', + '2020-04-08', 'x-ms-creation-time', - 'Tue, 03 Dec 2019 05:07:03 GMT', + 'Fri, 15 Jan 2021 05:49:37 GMT', 'x-ms-lease-status', 'unlocked', 'x-ms-lease-state', @@ -102,20 +117,27 @@ nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParam 'Access-Control-Allow-Origin', '*', 'Date', - 'Tue, 03 Dec 2019 05:07:04 GMT' ]); + 'Fri, 15 Jan 2021 05:49:40 GMT', + 'Connection', + 'close' +]); nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) - .delete('/filesystem157534997919101488') + .delete('/filesystem161068977513004637') .query(true) - .reply(202, "", [ 'Content-Length', + .reply(202, "", [ + 'Content-Length', '0', 'Server', 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '71849999-d01e-0085-7a97-a9124b000000', + '93c90ced-901e-004e-2502-eb807b000000', 'x-ms-client-request-id', - '45848b57-e507-4097-a490-3a6f59b31e99', + 'a9250a72-3fb9-4fe5-937b-dcb6aea0130a', 'x-ms-version', - '2019-02-02', + '2020-04-08', 'Date', - 'Tue, 03 Dec 2019 05:07:03 GMT' ]); + 'Fri, 15 Jan 2021 05:49:41 GMT', + 'Connection', + 'close' +]); diff --git a/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatedatalakesasqueryparameters_should_work_for_filesystem_with_access_policy.js b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatedatalakesasqueryparameters_should_work_for_filesystem_with_access_policy.js new file mode 100644 index 000000000000..011b695ee32b --- /dev/null +++ b/sdk/storage/storage-file-datalake/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatedatalakesasqueryparameters_should_work_for_filesystem_with_access_policy.js @@ -0,0 +1,143 @@ +let nock = require('nock'); + +module.exports.hash = "6bb2814c3664616597c8f4ca9cfeea39"; + +module.exports.testInfo = {"uniqueName":{"filesystem":"filesystem161069077938008645","file":"file161069078083902614"},"newDate":{"now":"2021-01-15T06:06:19.379Z","tmr":"2021-01-15T06:06:19.380Z"}} + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem161069077938008645') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 15 Jan 2021 06:06:20 GMT', + 'ETag', + '"0x8D8B91BADEA5D17"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'c12265c9-301e-000c-0304-ebab6f000000', + 'x-ms-client-request-id', + '5270b401-37b1-4c38-ab05-657df28f2dfa', + 'x-ms-version', + '2020-04-08', + 'Date', + 'Fri, 15 Jan 2021 06:06:19 GMT', + 'Connection', + 'close' +]); + +nock('https://fakestorageaccount.dfs.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem161069077938008645/file161069078083902614') + .query(true) + .reply(201, "", [ + 'Last-Modified', + 'Fri, 15 Jan 2021 06:06:21 GMT', + 'ETag', + '"0x8D8B91BAEBCB74B"', + 'Server', + 'Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'd60bd40d-001f-0004-7b04-ebb01c000000', + 'x-ms-version', + '2020-04-08', + 'x-ms-client-request-id', + '99e21036-e5b1-4289-872c-6da758358024', + 'Date', + 'Fri, 15 Jan 2021 06:06:21 GMT', + 'Connection', + 'close', + 'Content-Length', + '0' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .put('/filesystem161069077938008645', "unique-id2021-01-15T05:56:19.3790000Z2021-01-25T06:06:19.3800000Zracwdl") + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 15 Jan 2021 06:06:23 GMT', + 'ETag', + '"0x8D8B91BAF74AE15"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '9ce3e19f-401e-0021-3304-eb28af000000', + 'x-ms-client-request-id', + '6c3b0d54-5e7a-405b-9f94-866866faea77', + 'x-ms-version', + '2020-04-08', + 'Date', + 'Fri, 15 Jan 2021 06:06:22 GMT', + 'Connection', + 'close' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .head('/filesystem161069077938008645/file161069078083902614') + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Content-Type', + 'application/octet-stream', + 'Last-Modified', + 'Fri, 15 Jan 2021 06:06:21 GMT', + 'Accept-Ranges', + 'bytes', + 'ETag', + '"0x8D8B91BAEBCB74B"', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + 'd4245393-a01e-0064-2d04-ebf53e000000', + 'x-ms-client-request-id', + '12b07880-d54b-40a3-9996-83a19abf7f95', + 'x-ms-version', + '2020-04-08', + 'x-ms-creation-time', + 'Fri, 15 Jan 2021 06:06:21 GMT', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-blob-type', + 'BlockBlob', + 'x-ms-server-encrypted', + 'true', + 'x-ms-access-tier', + 'Hot', + 'x-ms-access-tier-inferred', + 'true', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-creation-time,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,x-ms-server-encrypted,x-ms-access-tier,x-ms-access-tier-inferred,Accept-Ranges,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Fri, 15 Jan 2021 06:06:53 GMT', + 'Connection', + 'close' +]); + +nock('https://fakestorageaccount.blob.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/filesystem161069077938008645') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '7dcf6fe9-f01e-0055-5b04-ebaee9000000', + 'x-ms-client-request-id', + 'bf9ea6d9-c8eb-4c0d-a3e2-9c7ee343e99b', + 'x-ms-version', + '2020-04-08', + 'Date', + 'Fri, 15 Jan 2021 06:06:55 GMT', + 'Connection', + 'close' +]); diff --git a/sdk/storage/storage-file-datalake/src/sas/DataLakeSASSignatureValues.ts b/sdk/storage/storage-file-datalake/src/sas/DataLakeSASSignatureValues.ts index 9e2aeb8ee522..78d491842c78 100644 --- a/sdk/storage/storage-file-datalake/src/sas/DataLakeSASSignatureValues.ts +++ b/sdk/storage/storage-file-datalake/src/sas/DataLakeSASSignatureValues.ts @@ -394,20 +394,24 @@ function generateBlobSASQueryParameters20150405( const version = dataLakeSASSignatureValues.version ? dataLakeSASSignatureValues.version : SERVICE_VERSION; - let resource: string = "c"; - let verifiedPermissions: string | undefined; + dataLakeSASSignatureValues = SASSignatureValuesSanityCheckAndAutofill( dataLakeSASSignatureValues, version ); + let resource: string = "c"; + if (dataLakeSASSignatureValues.pathName) { + resource = "b"; + } + // Calling parse and toString guarantees the proper ordering and throws on invalid characters. + let verifiedPermissions: string | undefined; if (dataLakeSASSignatureValues.permissions) { if (dataLakeSASSignatureValues.pathName) { verifiedPermissions = DataLakeSASPermissions.parse( dataLakeSASSignatureValues.permissions.toString() ).toString(); - resource = "b"; } else { verifiedPermissions = FileSystemSASPermissions.parse( dataLakeSASSignatureValues.permissions.toString() @@ -497,30 +501,36 @@ function generateBlobSASQueryParameters20181109( const version = dataLakeSASSignatureValues.version ? dataLakeSASSignatureValues.version : SERVICE_VERSION; - let resource: string = "c"; - let verifiedPermissions: string | undefined; dataLakeSASSignatureValues = SASSignatureValuesSanityCheckAndAutofill( dataLakeSASSignatureValues, version ); + let resource: string = "c"; + if (dataLakeSASSignatureValues.pathName) { + if (dataLakeSASSignatureValues.isDirectory) { + resource = "d"; + } else { + resource = "b"; + if (dataLakeSASSignatureValues.snapshotTime) { + resource = "bs"; + } + } + } + // Calling parse and toString guarantees the proper ordering and throws on invalid characters. + let verifiedPermissions: string | undefined; if (dataLakeSASSignatureValues.permissions) { if (dataLakeSASSignatureValues.pathName) { if (dataLakeSASSignatureValues.isDirectory) { verifiedPermissions = DirectorySASPermissions.parse( dataLakeSASSignatureValues.permissions.toString() ).toString(); - resource = "d"; } else { verifiedPermissions = DataLakeSASPermissions.parse( dataLakeSASSignatureValues.permissions.toString() ).toString(); - resource = "b"; - if (dataLakeSASSignatureValues.snapshotTime) { - resource = "bs"; - } } } else { verifiedPermissions = FileSystemSASPermissions.parse( @@ -610,29 +620,35 @@ function generateBlobSASQueryParametersUDK20181109( const version = dataLakeSASSignatureValues.version ? dataLakeSASSignatureValues.version : SERVICE_VERSION; - let resource: string = "c"; - let verifiedPermissions: string | undefined; dataLakeSASSignatureValues = SASSignatureValuesSanityCheckAndAutofill( dataLakeSASSignatureValues, version ); + let resource: string = "c"; + if (dataLakeSASSignatureValues.pathName) { + if (dataLakeSASSignatureValues.isDirectory) { + resource = "d"; + } else { + resource = "b"; + if (dataLakeSASSignatureValues.snapshotTime) { + resource = "bs"; + } + } + } + // Calling parse and toString guarantees the proper ordering and throws on invalid characters. + let verifiedPermissions: string | undefined; if (dataLakeSASSignatureValues.permissions) { if (dataLakeSASSignatureValues.pathName) { if (dataLakeSASSignatureValues.isDirectory) { verifiedPermissions = DirectorySASPermissions.parse( dataLakeSASSignatureValues.permissions.toString() ).toString(); - resource = "d"; } else { verifiedPermissions = DataLakeSASPermissions.parse( dataLakeSASSignatureValues.permissions.toString() ).toString(); - resource = "b"; - if (dataLakeSASSignatureValues.snapshotTime) { - resource = "bs"; - } } } else { verifiedPermissions = FileSystemSASPermissions.parse( @@ -732,29 +748,35 @@ function generateBlobSASQueryParametersUDK20200210( const version = dataLakeSASSignatureValues.version ? dataLakeSASSignatureValues.version : SERVICE_VERSION; - let resource: string = "c"; - let verifiedPermissions: string | undefined; dataLakeSASSignatureValues = SASSignatureValuesSanityCheckAndAutofill( dataLakeSASSignatureValues, version ); + let resource: string = "c"; + if (dataLakeSASSignatureValues.pathName) { + if (dataLakeSASSignatureValues.isDirectory) { + resource = "d"; + } else { + resource = "b"; + if (dataLakeSASSignatureValues.snapshotTime) { + resource = "bs"; + } + } + } + // Calling parse and toString guarantees the proper ordering and throws on invalid characters. + let verifiedPermissions: string | undefined; if (dataLakeSASSignatureValues.permissions) { if (dataLakeSASSignatureValues.pathName) { if (dataLakeSASSignatureValues.isDirectory) { verifiedPermissions = DirectorySASPermissions.parse( dataLakeSASSignatureValues.permissions.toString() ).toString(); - resource = "d"; } else { verifiedPermissions = DataLakeSASPermissions.parse( dataLakeSASSignatureValues.permissions.toString() ).toString(); - resource = "b"; - if (dataLakeSASSignatureValues.snapshotTime) { - resource = "bs"; - } } } else { verifiedPermissions = FileSystemSASPermissions.parse( diff --git a/sdk/storage/storage-file-datalake/test/node/sas.spec.ts b/sdk/storage/storage-file-datalake/test/node/sas.spec.ts index 4b481bb2f56d..983aefa25e58 100644 --- a/sdk/storage/storage-file-datalake/test/node/sas.spec.ts +++ b/sdk/storage/storage-file-datalake/test/node/sas.spec.ts @@ -23,6 +23,7 @@ import { import { DataLakeFileClient } from "../../src/"; import { DirectorySASPermissions } from "../../src/sas/DirectorySASPermissions"; import { SASProtocol } from "../../src/sas/SASQueryParameters"; +import { delay } from "../../src/utils/utils.common"; import { getDataLakeServiceClient, getDataLakeServiceClientWithDefaultCredential, @@ -395,7 +396,7 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { await fileSystemClient.delete(); }); - it("generateDataLakeSASQueryParameters should work for file with access policy", async () => { + it("generateDataLakeSASQueryParameters should work for fileSystem with access policy", async () => { const now = recorder.newDate("now"); now.setMinutes(now.getMinutes() - 10); // Skip clock skew with server @@ -426,9 +427,77 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { } ]); + /* + * When you establish a stored access policy on a container, it may take up to 30 seconds to take effect. + * During this interval, a shared access signature that is associated with the stored access policy will + * fail with status code 403 (Forbidden), until the access policy becomes active. + * More details: https://docs.microsoft.com/en-us/rest/api/storageservices/set-container-acl + * Note: delay in recorder module only take effect in live and recording mode. + */ + await delay(30 * 1000); + + const fileSAS = generateDataLakeSASQueryParameters( + { + fileSystemName, + identifier: id + }, + sharedKeyCredential as StorageSharedKeyCredential + ); + + const sasClient = `${fileClient.url}?${fileSAS}`; + const fileClientWithSAS = new DataLakeFileClient( + sasClient, + newPipeline(new AnonymousCredential()) + ); + + await fileClientWithSAS.getProperties(); + await fileSystemClient.delete(); + }); + + it("generateDataLakeSASQueryParameters should work for file with access policy", async () => { + const now = recorder.newDate("now"); + now.setMinutes(now.getMinutes() - 10); // Skip clock skew with server + + const tmr = recorder.newDate("tmr"); + tmr.setDate(tmr.getDate() + 10); + + // By default, credential is always the last element of pipeline factories + const factories = (serviceClient as any).pipeline.factories; + const sharedKeyCredential = factories[factories.length - 1]; + + const fileSystemName = recorder.getUniqueName("filesystem"); + const fileSystemClient = serviceClient.getFileSystemClient(fileSystemName); + await fileSystemClient.create(); + + const fileName = recorder.getUniqueName("file"); + const fileClient = fileSystemClient.getFileClient(fileName); + await fileClient.create(); + + const id = "unique-id"; + await fileSystemClient.setAccessPolicy(undefined, [ + { + accessPolicy: { + expiresOn: tmr, + permissions: DataLakeSASPermissions.parse("racwd").toString(), + startsOn: now + }, + id + } + ]); + + /* + * When you establish a stored access policy on a container, it may take up to 30 seconds to take effect. + * During this interval, a shared access signature that is associated with the stored access policy will + * fail with status code 403 (Forbidden), until the access policy becomes active. + * More details: https://docs.microsoft.com/en-us/rest/api/storageservices/set-container-acl + * Note: delay in recorder module only take effect in live and recording mode. + */ + await delay(30 * 1000); + const fileSAS = generateDataLakeSASQueryParameters( { fileSystemName, + pathName: fileName, identifier: id }, sharedKeyCredential as StorageSharedKeyCredential @@ -1104,6 +1173,44 @@ describe("SAS generation Node.js only for directory SAS", () => { } assert.ok(exceptionCaught); }); + + it("generateDataLakeSASQueryParameters should work for directory with access policy", async () => { + const id = "unique-id"; + await fileSystemClient.setAccessPolicy(undefined, [ + { + accessPolicy: { + expiresOn: tmr, + permissions: DataLakeSASPermissions.parse("racwd").toString(), + startsOn: now + }, + id + } + ]); + + /* + * When you establish a stored access policy on a container, it may take up to 30 seconds to take effect. + * During this interval, a shared access signature that is associated with the stored access policy will + * fail with status code 403 (Forbidden), until the access policy becomes active. + * More details: https://docs.microsoft.com/en-us/rest/api/storageservices/set-container-acl + * Note: delay in recorder module only take effect in live and recording mode. + */ + await delay(30 * 1000); + + const directorySAS = generateDataLakeSASQueryParameters( + { + fileSystemName: fileSystemClient.name, + pathName: directoryClient.name, + isDirectory: true, + identifier: id + }, + sharedKeyCredential as StorageSharedKeyCredential + ); + + const sasClient = `${fileClient.url}?${directorySAS}`; + const fileClientWithSAS = new DataLakeFileClient(sasClient); + + await fileClientWithSAS.getProperties(); + }); }); describe("SAS generation Node.js only for delegation SAS", () => { @@ -1116,6 +1223,7 @@ describe("SAS generation Node.js only for delegation SAS", () => { let now: Date; let tmr: Date; let accountName: string; + let fileSystemName: string; const permissions: PathPermissions = { extendedAcls: false, @@ -1153,7 +1261,7 @@ describe("SAS generation Node.js only for delegation SAS", () => { tmr.setDate(tmr.getDate() + 5); userDelegationKey = await oauthServiceClient.getUserDelegationKey(now, tmr); - const fileSystemName = recorder.getUniqueName("filesystem"); + fileSystemName = recorder.getUniqueName("filesystem"); fileSystemClient = oauthServiceClient.getFileSystemClient(fileSystemName); await fileSystemClient.create(); diff --git a/sdk/storage/storage-file-share/CHANGELOG.md b/sdk/storage/storage-file-share/CHANGELOG.md index 4d140994758d..4ecfa1373af4 100644 --- a/sdk/storage/storage-file-share/CHANGELOG.md +++ b/sdk/storage/storage-file-share/CHANGELOG.md @@ -2,6 +2,7 @@ ## 12.4.1 (Unreleased) +- Fixed a bug where `generateFileSASQueryParameters()` won't correctly set the resource type if `FileSASSignatureValues.permissions` is not specified. Fixed issue [13223](https://github.com/Azure/azure-sdk-for-js/issues/13223). - The `"Unclosed root tag"` XML parser error is now retriable. [PR #13076](https://github.com/Azure/azure-sdk-for-js/pull/13076). ## 12.4.0 (2021-01-12) diff --git a/sdk/storage/storage-file-share/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatefilesasqueryparameters_should_work_for_file_with_access_policy.js b/sdk/storage/storage-file-share/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatefilesasqueryparameters_should_work_for_file_with_access_policy.js index b26070146b13..ec81f6fb9a2e 100644 --- a/sdk/storage/storage-file-share/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatefilesasqueryparameters_should_work_for_file_with_access_policy.js +++ b/sdk/storage/storage-file-share/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatefilesasqueryparameters_should_work_for_file_with_access_policy.js @@ -1,53 +1,57 @@ let nock = require('nock'); -module.exports.testInfo = {"now":"2019-09-11T02:22:21.301Z","share":"share156816854130109051","dir":"dir156816854179102705","file":"file156816854220004597"} +module.exports.hash = "4456afa7cdbd9d330289a94a4c3895b9"; + +module.exports.testInfo = {"uniqueName":{"share":"share161069088802504463","dir":"dir161069088832403501","file":"file161069088862702767"},"newDate":{"now":"2021-01-15T06:08:08.025Z","tmr":"2021-01-15T06:08:08.025Z"}} nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share156816854130109051') + .put('/share161069088802504463') .query(true) - .reply(201, "", [ 'Content-Length', + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:22:21 GMT', + 'Fri, 15 Jan 2021 06:08:08 GMT', 'ETag', - '"0x8D7365EE079B688"', + '"0x8D8B91BEE013880"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '333d7cd4-501a-0003-5d47-6865fb000000', + '59080b0b-501a-0063-7004-ebc806000000', 'x-ms-client-request-id', - '213481ed-60e1-42d4-810f-19505a736c35', + '846fcb0d-e977-43bb-8f68-059da54cd553', 'x-ms-version', - '2019-02-02', + '2020-04-08', 'Date', - 'Wed, 11 Sep 2019 02:22:20 GMT' ]); - + 'Fri, 15 Jan 2021 06:08:07 GMT' +]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share156816854130109051/dir156816854179102705') + .put('/share161069088802504463/dir161069088832403501') .query(true) - .reply(201, "", [ 'Content-Length', + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:22:22 GMT', + 'Fri, 15 Jan 2021 06:08:08 GMT', 'ETag', - '"0x8D7365EE0B96BF1"', + '"0x8D8B91BEE2FF006"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'ddf4b3ea-701a-003d-5347-68d3da000000', + '59080b2a-501a-0063-0d04-ebc806000000', 'x-ms-client-request-id', - '039fb7d9-9b18-4ddd-b848-e40ec7d03f1e', + 'b7e2ea6f-c9e1-4071-8012-54aebdbf6041', 'x-ms-version', - '2019-02-02', + '2020-04-08', 'x-ms-file-change-time', - '2019-09-11T02:22:22.1288433Z', + '2021-01-15T06:08:08.4299782Z', 'x-ms-file-last-write-time', - '2019-09-11T02:22:22.1288433Z', + '2021-01-15T06:08:08.4299782Z', 'x-ms-file-creation-time', - '2019-09-11T02:22:22.1288433Z', + '2021-01-15T06:08:08.4299782Z', 'x-ms-file-permission-key', - '15292852142319295125*13609941760923454748', + '18253506462963126402*10775527834424002315', 'x-ms-file-attributes', 'Directory', 'x-ms-file-id', @@ -57,102 +61,132 @@ nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParam 'x-ms-request-server-encrypted', 'true', 'Date', - 'Wed, 11 Sep 2019 02:22:21 GMT' ]); - + 'Fri, 15 Jan 2021 06:08:07 GMT' +]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share156816854130109051/dir156816854179102705/file156816854220004597') - .reply(201, "", [ 'Content-Length', + .put('/share161069088802504463/dir161069088832403501/file161069088862702767') + .reply(201, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:22:22 GMT', + 'Fri, 15 Jan 2021 06:08:08 GMT', 'ETag', - '"0x8D7365EE0F82E0F"', + '"0x8D8B91BEE5DBEFC"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'f431eb2e-201a-006a-1247-683a57000000', + '59080b3f-501a-0063-2104-ebc806000000', 'x-ms-client-request-id', - '8c90a54f-fab8-4825-8e1f-385b06b8651b', + 'a0b58298-8fd1-4d7a-81de-3b63d16dd935', 'x-ms-version', - '2019-02-02', + '2020-04-08', 'x-ms-file-change-time', - '2019-09-11T02:22:22.5401359Z', + '2021-01-15T06:08:08.7301884Z', 'x-ms-file-last-write-time', - '2019-09-11T02:22:22.5401359Z', + '2021-01-15T06:08:08.7301884Z', 'x-ms-file-creation-time', - '2019-09-11T02:22:22.5401359Z', + '2021-01-15T06:08:08.7301884Z', 'x-ms-file-permission-key', - '1459396823544571282*13609941760923454748', + '4407534441384161157*10775527834424002315', 'x-ms-file-attributes', 'Archive', 'x-ms-file-id', - '13835093239654252544', + '11529285414812647424', 'x-ms-file-parent-id', '13835128424026341376', 'x-ms-request-server-encrypted', 'true', 'Date', - 'Wed, 11 Sep 2019 02:22:22 GMT' ]); - + 'Fri, 15 Jan 2021 06:08:08 GMT' +]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .put('/share156816854130109051', "unique-id2019-09-11T02:17:21.3010000Z2019-09-12T02:22:21.3010000Zrcwdl") + .put('/share161069088802504463', "unique-id2021-01-15T06:03:08.0250000Z2021-01-16T06:08:08.0250000Zrcwd") .query(true) - .reply(200, "", [ 'Content-Length', + .reply(200, "", [ + 'Content-Length', '0', 'Last-Modified', - 'Wed, 11 Sep 2019 02:22:23 GMT', + 'Fri, 15 Jan 2021 06:08:09 GMT', 'ETag', - '"0x8D7365EE142856D"', + '"0x8D8B91BEE8A8325"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'bee1e17d-201a-0061-6947-682223000000', + '59080b59-501a-0063-3a04-ebc806000000', 'x-ms-client-request-id', - '7993fe52-65d7-45a7-9ad6-1999dcf05f16', + 'ab8928e9-ac60-43d4-8a66-3b7e3a40d1f5', 'x-ms-version', - '2019-02-02', + '2020-04-08', 'Date', - 'Wed, 11 Sep 2019 02:22:22 GMT' ]); - + 'Fri, 15 Jan 2021 06:08:08 GMT' +]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .get('/share156816854130109051/') + .head('/share161069088802504463/dir161069088832403501/file161069088862702767') .query(true) - .reply(200, "dir156816854179102705", [ 'Transfer-Encoding', - 'chunked', + .reply(200, "", [ + 'Content-Length', + '1024', 'Content-Type', - 'application/xml', + 'content-type-original', + 'Last-Modified', + 'Fri, 15 Jan 2021 06:08:08 GMT', + 'ETag', + '"0x8D8B91BEE5DBEFC"', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - '7fbe3d99-301a-003a-0647-68255f000000', + '5908123b-501a-0063-6704-ebc806000000', 'x-ms-client-request-id', - '0610ec07-67aa-4825-86ac-cc1779fd38d8', + '5716d565-4204-47f6-96ba-c9ad60eabddc', 'x-ms-version', - '2019-02-02', + '2020-04-08', + 'x-ms-type', + 'File', + 'x-ms-server-encrypted', + 'true', + 'x-ms-lease-status', + 'unlocked', + 'x-ms-lease-state', + 'available', + 'x-ms-file-change-time', + '2021-01-15T06:08:08.7301884Z', + 'x-ms-file-last-write-time', + '2021-01-15T06:08:08.7301884Z', + 'x-ms-file-creation-time', + '2021-01-15T06:08:08.7301884Z', + 'x-ms-file-permission-key', + '4407534441384161157*10775527834424002315', + 'x-ms-file-attributes', + 'Archive', + 'x-ms-file-id', + '11529285414812647424', + 'x-ms-file-parent-id', + '13835128424026341376', 'Access-Control-Expose-Headers', - 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Content-Length,Date,Transfer-Encoding', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-type,x-ms-server-encrypted,x-ms-lease-status,x-ms-lease-state,x-ms-file-change-time,x-ms-file-last-write-time,x-ms-file-creation-time,x-ms-file-permission-key,x-ms-file-attributes,x-ms-file-id,x-ms-file-parent-id,Content-Length,Date,Transfer-Encoding', 'Access-Control-Allow-Origin', '*', 'Date', - 'Wed, 11 Sep 2019 02:22:23 GMT' ]); - + 'Fri, 15 Jan 2021 06:08:38 GMT' +]); nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) - .delete('/share156816854130109051') + .delete('/share161069088802504463') .query(true) - .reply(202, "", [ 'Content-Length', + .reply(202, "", [ + 'Content-Length', '0', 'Server', 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', 'x-ms-request-id', - 'bee1e17e-201a-0061-6a47-682223000000', + '59081252-501a-0063-7b04-ebc806000000', 'x-ms-client-request-id', - '354bbd2c-4832-42da-be21-0bfeab5aabe3', + '4c29c515-82c5-48fb-a130-ae1ea58ff5fd', 'x-ms-version', - '2019-02-02', + '2020-04-08', 'Date', - 'Wed, 11 Sep 2019 02:22:23 GMT' ]); - + 'Fri, 15 Jan 2021 06:08:39 GMT' +]); diff --git a/sdk/storage/storage-file-share/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatefilesasqueryparameters_should_work_for_share_with_access_policy.js b/sdk/storage/storage-file-share/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatefilesasqueryparameters_should_work_for_share_with_access_policy.js new file mode 100644 index 000000000000..ce31050d20fa --- /dev/null +++ b/sdk/storage/storage-file-share/recordings/node/shared_access_signature_sas_generation_nodejs_only/recording_generatefilesasqueryparameters_should_work_for_share_with_access_policy.js @@ -0,0 +1,166 @@ +let nock = require('nock'); + +module.exports.hash = "5f413948b50993a7cb3655d78f239619"; + +module.exports.testInfo = {"uniqueName":{"share":"share161069085477203632","dir":"dir161069085633007045","file":"file161069085664605354"},"newDate":{"now":"2021-01-15T06:07:34.769Z","tmr":"2021-01-15T06:07:34.772Z"}} + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share161069085477203632') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 15 Jan 2021 06:07:36 GMT', + 'ETag', + '"0x8D8B91BDAEB933A"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '590805c2-501a-0063-5804-ebc806000000', + 'x-ms-client-request-id', + 'b1d38584-fd18-4511-a74a-ddde1cfcfb02', + 'x-ms-version', + '2020-04-08', + 'Date', + 'Fri, 15 Jan 2021 06:07:35 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share161069085477203632/dir161069085633007045') + .query(true) + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 15 Jan 2021 06:07:36 GMT', + 'ETag', + '"0x8D8B91BDB1F81B0"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '590805cf-501a-0063-6004-ebc806000000', + 'x-ms-client-request-id', + 'fbc4decc-450d-482c-bc33-cbb5d834976b', + 'x-ms-version', + '2020-04-08', + 'x-ms-file-change-time', + '2021-01-15T06:07:36.4455856Z', + 'x-ms-file-last-write-time', + '2021-01-15T06:07:36.4455856Z', + 'x-ms-file-creation-time', + '2021-01-15T06:07:36.4455856Z', + 'x-ms-file-permission-key', + '18253506462963126402*10775527834424002315', + 'x-ms-file-attributes', + 'Directory', + 'x-ms-file-id', + '13835128424026341376', + 'x-ms-file-parent-id', + '0', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Fri, 15 Jan 2021 06:07:36 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share161069085477203632/dir161069085633007045/file161069085664605354') + .reply(201, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 15 Jan 2021 06:07:36 GMT', + 'ETag', + '"0x8D8B91BDB4D50AA"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '590805d7-501a-0063-6604-ebc806000000', + 'x-ms-client-request-id', + '4b4a2e3c-9f08-45d1-b4b5-9ef917ffa219', + 'x-ms-version', + '2020-04-08', + 'x-ms-file-change-time', + '2021-01-15T06:07:36.7457962Z', + 'x-ms-file-last-write-time', + '2021-01-15T06:07:36.7457962Z', + 'x-ms-file-creation-time', + '2021-01-15T06:07:36.7457962Z', + 'x-ms-file-permission-key', + '4407534441384161157*10775527834424002315', + 'x-ms-file-attributes', + 'Archive', + 'x-ms-file-id', + '11529285414812647424', + 'x-ms-file-parent-id', + '13835128424026341376', + 'x-ms-request-server-encrypted', + 'true', + 'Date', + 'Fri, 15 Jan 2021 06:07:36 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .put('/share161069085477203632', "unique-id2021-01-15T06:02:34.7690000Z2021-01-16T06:07:34.7720000Zrcwdl") + .query(true) + .reply(200, "", [ + 'Content-Length', + '0', + 'Last-Modified', + 'Fri, 15 Jan 2021 06:07:37 GMT', + 'ETag', + '"0x8D8B91BDB89C1FA"', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '590805de-501a-0063-6d04-ebc806000000', + 'x-ms-client-request-id', + 'd4bcd15f-f3d2-4b8b-8257-e6057bc08a98', + 'x-ms-version', + '2020-04-08', + 'Date', + 'Fri, 15 Jan 2021 06:07:36 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .get('/share161069085477203632/') + .query(true) + .reply(200, "dir161069085633007045", [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/xml', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '59080ad1-501a-0063-3804-ebc806000000', + 'x-ms-client-request-id', + '97ed3315-31b3-4ee2-bf26-c8a4635488e2', + 'x-ms-version', + '2020-04-08', + 'Access-Control-Expose-Headers', + 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Content-Length,Date,Transfer-Encoding', + 'Access-Control-Allow-Origin', + '*', + 'Date', + 'Fri, 15 Jan 2021 06:08:07 GMT' +]); + +nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true}) + .delete('/share161069085477203632') + .query(true) + .reply(202, "", [ + 'Content-Length', + '0', + 'Server', + 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0', + 'x-ms-request-id', + '59080aef-501a-0063-5404-ebc806000000', + 'x-ms-client-request-id', + '2a3a571d-97b1-405d-8441-79b7f8edb9b1', + 'x-ms-version', + '2020-04-08', + 'Date', + 'Fri, 15 Jan 2021 06:08:07 GMT' +]); diff --git a/sdk/storage/storage-file-share/src/FileSASSignatureValues.ts b/sdk/storage/storage-file-share/src/FileSASSignatureValues.ts index fb32af28b551..990a5c46f719 100644 --- a/sdk/storage/storage-file-share/src/FileSASSignatureValues.ts +++ b/sdk/storage/storage-file-share/src/FileSASSignatureValues.ts @@ -169,15 +169,17 @@ export function generateFileSASQueryParameters( const version = fileSASSignatureValues.version ? fileSASSignatureValues.version : SERVICE_VERSION; let resource: string = "s"; - let verifiedPermissions: string | undefined; + if (fileSASSignatureValues.filePath) { + resource = "f"; + } + let verifiedPermissions: string | undefined; // Calling parse and toString guarantees the proper ordering and throws on invalid characters. if (fileSASSignatureValues.permissions) { if (fileSASSignatureValues.filePath) { verifiedPermissions = FileSASPermissions.parse( fileSASSignatureValues.permissions.toString() ).toString(); - resource = "f"; } else { verifiedPermissions = ShareSASPermissions.parse( fileSASSignatureValues.permissions.toString() diff --git a/sdk/storage/storage-file-share/test/node/sas.spec.ts b/sdk/storage/storage-file-share/test/node/sas.spec.ts index 5f1814453187..30513d55e8c2 100644 --- a/sdk/storage/storage-file-share/test/node/sas.spec.ts +++ b/sdk/storage/storage-file-share/test/node/sas.spec.ts @@ -267,11 +267,11 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { await shareClient.delete(); }); - it("generateFileSASQueryParameters should work for file with access policy", async () => { + it("generateFileSASQueryParameters should work for share with access policy", async () => { const now = recorder.newDate("now"); now.setMinutes(now.getMinutes() - 5); // Skip clock skew with server - const tmr = recorder.newDate("now"); + const tmr = recorder.newDate("tmr"); tmr.setDate(tmr.getDate() + 1); // By default, credential is always the last element of pipeline factories @@ -336,6 +336,66 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { await shareClient.delete(); }); + it("generateFileSASQueryParameters should work for file with access policy", async () => { + const now = recorder.newDate("now"); + now.setMinutes(now.getMinutes() - 5); // Skip clock skew with server + const tmr = recorder.newDate("tmr"); + tmr.setDate(tmr.getDate() + 1); + const sharedKeyCredential = serviceClient["credential"]; + + const shareName = recorder.getUniqueName("share"); + const shareClient = serviceClient.getShareClient(shareName); + await shareClient.create(); + + const dirName = recorder.getUniqueName("dir"); + const dirClient = shareClient.getDirectoryClient(dirName); + await dirClient.create(); + + const fileName = recorder.getUniqueName("file"); + const fileClient = dirClient.getFileClient(fileName); + await fileClient.create(1024, { + fileHttpHeaders: { + fileContentType: "content-type-original" + } + }); + + const id = "unique-id"; + await shareClient.setAccessPolicy([ + { + accessPolicy: { + expiresOn: tmr, + permissions: FileSASPermissions.parse("rcwd").toString(), + startsOn: now + }, + id + } + ]); + + /* + * When you establish a stored access policy on a share, it may take up to 30 seconds to take effect. + * During this interval, a shared access signature that is associated with the stored access policy will + * fail with status code 403 (Forbidden), until the access policy becomes active. + * More details: https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-acl + * Note: delay in recorder module only take effect in live and recording mode. + */ + await delay(30 * 1000); + + const fileSAS = generateFileSASQueryParameters( + { + identifier: id, + shareName, + filePath: fileClient.path + }, + sharedKeyCredential as StorageSharedKeyCredential + ); + + const sasURL = `${fileClient.url}?${fileSAS}`; + const fileClientWithSAS = new ShareFileClient(sasURL, newPipeline(new AnonymousCredential())); + await fileClientWithSAS.getProperties(); + + await shareClient.delete(); + }); + it("ShareServiceClient.generateAccountSasUrl should work", async () => { const now = recorder.newDate("now"); now.setMinutes(now.getMinutes() - 5); // Skip clock skew with server