From 8f341f2e218bb3fef6bbcb9e3d0af2a097c326dd Mon Sep 17 00:00:00 2001
From: Kamil Sobol <61715331+kasobol-msft@users.noreply.github.com>
Date: Tue, 15 Jun 2021 14:48:16 -0700
Subject: [PATCH] [Storage] SAS version cleanup. (#22255)
* deprecate BlobSasServiceVersion. Make version not settable.
* More of that.
* deprecate old constatnt...
* fix test.
* rework constants again.
* ...
* let's run some live tests.
* fix live tests.
* fix datalake tests.
* PR feedback.
* use separate constant for deprecated part.
* remind us about this problem in files and queues.
* fix ci.
---
sdk/storage/azure-storage-blob/pom.xml | 39 +++++++
.../implementation/util/BlobSasImplUtil.java | 102 ++++++++++-------
.../blob/sas/BlobSasServiceVersion.java | 2 +
.../sas/BlobServiceSasSignatureValues.java | 31 +++---
.../blob/BlobServiceSasModelsTest.groovy | 12 --
.../azure/storage/blob/SasClientTests.groovy | 98 ++++++++--------
.../blob/specialized/HelperTest.groovy | 6 +-
.../implementation/AccountSasImplUtil.java | 15 +--
.../common/implementation/Constants.java | 8 ++
.../common/sas/AccountSasSignatureValues.java | 18 ++-
.../azure-storage-file-datalake/pom.xml | 39 +++++++
.../util/DataLakeSasImplUtil.java | 95 ++++++++++------
.../DataLakeServiceSasSignatureValues.java | 7 +-
.../storage/file/datalake/SASTest.groovy | 105 ++++++++++--------
sdk/storage/azure-storage-file-share/pom.xml | 39 +++++++
.../implementation/util/ShareSasImplUtil.java | 21 ++--
.../sas/ShareServiceSasSignatureValues.java | 21 ++--
.../file/share/FileSasClientTests.groovy | 19 ++++
...sRememberAboutStringToSignDeprecation.json | 54 +++++++++
sdk/storage/azure-storage-queue/pom.xml | 39 +++++++
.../implementation/util/QueueSasImplUtil.java | 21 ++--
.../sas/QueueServiceSasSignatureValues.java | 22 ++--
.../azure/storage/queue/QueueSASTests.groovy | 1 -
.../storage/queue/QueueSasClientTests.groovy | 20 +++-
...ueSASTestsAccountSASCreateDeleteQueue.json | 34 +++---
...sRememberAboutStringToSignDeprecation.json | 45 ++++++++
26 files changed, 631 insertions(+), 282 deletions(-)
create mode 100644 sdk/storage/azure-storage-file-share/src/test/resources/session-records/FileSasClientTestsRememberAboutStringToSignDeprecation.json
create mode 100644 sdk/storage/azure-storage-queue/src/test/resources/session-records/QueueSasClientTestsRememberAboutStringToSignDeprecation.json
diff --git a/sdk/storage/azure-storage-blob/pom.xml b/sdk/storage/azure-storage-blob/pom.xml
index 5e08396ea43ab..e84761c32cfa5 100644
--- a/sdk/storage/azure-storage-blob/pom.xml
+++ b/sdk/storage/azure-storage-blob/pom.xml
@@ -307,5 +307,44 @@
+
+ inject-sas-service-version
+
+ env.AZURE_LIVE_TEST_SERVICE_VERSION
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 3.0.0
+
+
+ regex-property
+
+ regex-property
+
+
+ AZURE_STORAGE_SAS_SERVICE_VERSION
+ ${env.AZURE_LIVE_TEST_SERVICE_VERSION}
+ V(\d+)_(\d+)_(\d+)
+ $1-$2-$3
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M3
+
+
+ ${AZURE_STORAGE_SAS_SERVICE_VERSION}
+
+
+
+
+
+
diff --git a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/implementation/util/BlobSasImplUtil.java b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/implementation/util/BlobSasImplUtil.java
index 50d9797dcfc0d..7376b8c70e288 100644
--- a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/implementation/util/BlobSasImplUtil.java
+++ b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/implementation/util/BlobSasImplUtil.java
@@ -3,14 +3,15 @@
package com.azure.storage.blob.implementation.util;
+import com.azure.core.util.Configuration;
import com.azure.core.util.Context;
import com.azure.core.util.CoreUtils;
import com.azure.core.util.logging.ClientLogger;
+import com.azure.storage.blob.BlobServiceVersion;
import com.azure.storage.blob.models.UserDelegationKey;
import com.azure.storage.blob.sas.BlobContainerSasPermission;
import com.azure.storage.blob.sas.BlobSasPermission;
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
-import com.azure.storage.blob.sas.BlobSasServiceVersion;
import com.azure.storage.common.StorageSharedKeyCredential;
import com.azure.storage.common.implementation.Constants;
import com.azure.storage.common.implementation.StorageImplUtils;
@@ -49,9 +50,10 @@ public class BlobSasImplUtil {
*/
private static final String SAS_CONTAINER_CONSTANT = "c";
- private final ClientLogger logger = new ClientLogger(BlobSasImplUtil.class);
+ private static final ClientLogger LOGGER = new ClientLogger(BlobSasImplUtil.class);
- private String version;
+ private static final String VERSION = Configuration.getGlobalConfiguration()
+ .get(Constants.PROPERTY_AZURE_STORAGE_SAS_SERVICE_VERSION, BlobServiceVersion.getLatest().getVersion());
private SasProtocol protocol;
@@ -112,10 +114,9 @@ public BlobSasImplUtil(BlobServiceSasSignatureValues sasValues, String container
String snapshotId, String versionId) {
Objects.requireNonNull(sasValues);
if (snapshotId != null && versionId != null) {
- throw logger.logExceptionAsError(
+ throw LOGGER.logExceptionAsError(
new IllegalArgumentException("'snapshot' and 'versionId' cannot be used at the same time."));
}
- this.version = null; /* Setting this to null forces the latest service version - see ensureState. */
this.protocol = sasValues.getProtocol();
this.startTime = sasValues.getStartTime();
this.expiryTime = sasValues.getExpiryTime();
@@ -150,7 +151,7 @@ public String generateSas(StorageSharedKeyCredential storageSharedKeyCredentials
// Signature is generated on the un-url-encoded values.
final String canonicalName = getCanonicalName(storageSharedKeyCredentials.getAccountName());
final String stringToSign = stringToSign(canonicalName);
- StorageImplUtils.logStringToSign(logger, stringToSign, context);
+ StorageImplUtils.logStringToSign(LOGGER, stringToSign, context);
final String signature = storageSharedKeyCredentials.computeHmac256(stringToSign);
return encode(null /* userDelegationKey */, signature);
@@ -173,7 +174,7 @@ public String generateUserDelegationSas(UserDelegationKey delegationKey, String
// Signature is generated on the un-url-encoded values.
final String canonicalName = getCanonicalName(accountName);
final String stringToSign = stringToSign(delegationKey, canonicalName);
- StorageImplUtils.logStringToSign(logger, stringToSign, context);
+ StorageImplUtils.logStringToSign(LOGGER, stringToSign, context);
String signature = StorageImplUtils.computeHMac256(delegationKey.getValue(), stringToSign);
return encode(delegationKey, signature);
@@ -192,7 +193,7 @@ private String encode(UserDelegationKey userDelegationKey, String signature) {
*/
StringBuilder sb = new StringBuilder();
- tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SERVICE_VERSION, this.version);
+ tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SERVICE_VERSION, VERSION);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_PROTOCOL, this.protocol);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_START_TIME, formatQueryParameterDate(this.startTime));
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_EXPIRY_TIME, formatQueryParameterDate(this.expiryTime));
@@ -246,13 +247,9 @@ private String encode(UserDelegationKey userDelegationKey, String signature) {
* https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/src/Sas/BlobSasBuilder.cs
*/
private void ensureState() {
- if (version == null) {
- version = BlobSasServiceVersion.getLatest().getVersion();
- }
-
if (identifier == null) {
if (expiryTime == null || permissions == null) {
- throw logger.logExceptionAsError(new IllegalStateException("If identifier is not set, expiry time "
+ throw LOGGER.logExceptionAsError(new IllegalStateException("If identifier is not set, expiry time "
+ "and permissions must be set"));
}
}
@@ -279,7 +276,7 @@ private void ensureState() {
break;
default:
// We won't reparse the permissions if we don't know the type.
- logger.info("Not re-parsing permissions. Resource type '{}' is unknown.", resource);
+ LOGGER.info("Not re-parsing permissions. Resource type '{}' is unknown.", resource);
break;
}
}
@@ -306,7 +303,7 @@ private String stringToSign(String canonicalName) {
this.identifier == null ? "" : this.identifier,
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : this.protocol.toString(),
- version,
+ VERSION,
resource,
versionSegment == null ? "" : versionSegment,
this.cacheControl == null ? "" : this.cacheControl,
@@ -319,30 +316,55 @@ private String stringToSign(String canonicalName) {
private String stringToSign(final UserDelegationKey key, String canonicalName) {
String versionSegment = this.snapshotId == null ? this.versionId : this.snapshotId;
- return String.join("\n",
- this.permissions == null ? "" : this.permissions,
- this.startTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.startTime),
- this.expiryTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.expiryTime),
- canonicalName,
- key.getSignedObjectId() == null ? "" : key.getSignedObjectId(),
- key.getSignedTenantId() == null ? "" : key.getSignedTenantId(),
- key.getSignedStart() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedStart()),
- key.getSignedExpiry() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedExpiry()),
- key.getSignedService() == null ? "" : key.getSignedService(),
- key.getSignedVersion() == null ? "" : key.getSignedVersion(),
- this.authorizedAadObjectId == null ? "" : this.authorizedAadObjectId,
- "", /* suoid - empty since this applies to HNS only accounts. */
- this.correlationId == null ? "" : this.correlationId,
- this.sasIpRange == null ? "" : this.sasIpRange.toString(),
- this.protocol == null ? "" : this.protocol.toString(),
- version,
- resource,
- versionSegment == null ? "" : versionSegment,
- this.cacheControl == null ? "" : this.cacheControl,
- this.contentDisposition == null ? "" : this.contentDisposition,
- this.contentEncoding == null ? "" : this.contentEncoding,
- this.contentLanguage == null ? "" : this.contentLanguage,
- this.contentType == null ? "" : this.contentType
- );
+ if (VERSION.compareTo(BlobServiceVersion.V2019_12_12.getVersion()) <= 0) {
+ return String.join("\n",
+ this.permissions == null ? "" : this.permissions,
+ this.startTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.startTime),
+ this.expiryTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.expiryTime),
+ canonicalName,
+ key.getSignedObjectId() == null ? "" : key.getSignedObjectId(),
+ key.getSignedTenantId() == null ? "" : key.getSignedTenantId(),
+ key.getSignedStart() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedStart()),
+ key.getSignedExpiry() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedExpiry()),
+ key.getSignedService() == null ? "" : key.getSignedService(),
+ key.getSignedVersion() == null ? "" : key.getSignedVersion(),
+ this.sasIpRange == null ? "" : this.sasIpRange.toString(),
+ this.protocol == null ? "" : this.protocol.toString(),
+ VERSION,
+ resource,
+ versionSegment == null ? "" : versionSegment,
+ this.cacheControl == null ? "" : this.cacheControl,
+ this.contentDisposition == null ? "" : this.contentDisposition,
+ this.contentEncoding == null ? "" : this.contentEncoding,
+ this.contentLanguage == null ? "" : this.contentLanguage,
+ this.contentType == null ? "" : this.contentType
+ );
+ } else {
+ return String.join("\n",
+ this.permissions == null ? "" : this.permissions,
+ this.startTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.startTime),
+ this.expiryTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.expiryTime),
+ canonicalName,
+ key.getSignedObjectId() == null ? "" : key.getSignedObjectId(),
+ key.getSignedTenantId() == null ? "" : key.getSignedTenantId(),
+ key.getSignedStart() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedStart()),
+ key.getSignedExpiry() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedExpiry()),
+ key.getSignedService() == null ? "" : key.getSignedService(),
+ key.getSignedVersion() == null ? "" : key.getSignedVersion(),
+ this.authorizedAadObjectId == null ? "" : this.authorizedAadObjectId,
+ "", /* suoid - empty since this applies to HNS only accounts. */
+ this.correlationId == null ? "" : this.correlationId,
+ this.sasIpRange == null ? "" : this.sasIpRange.toString(),
+ this.protocol == null ? "" : this.protocol.toString(),
+ VERSION,
+ resource,
+ versionSegment == null ? "" : versionSegment,
+ this.cacheControl == null ? "" : this.cacheControl,
+ this.contentDisposition == null ? "" : this.contentDisposition,
+ this.contentEncoding == null ? "" : this.contentEncoding,
+ this.contentLanguage == null ? "" : this.contentLanguage,
+ this.contentType == null ? "" : this.contentType
+ );
+ }
}
}
diff --git a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/sas/BlobSasServiceVersion.java b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/sas/BlobSasServiceVersion.java
index de955f985fed3..6dc5f59fc06d7 100644
--- a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/sas/BlobSasServiceVersion.java
+++ b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/sas/BlobSasServiceVersion.java
@@ -7,7 +7,9 @@
/**
* The versions of Azure Storage Blob Sas supported by this client library.
+ * @deprecated The version is set to the latest version of sas.
*/
+@Deprecated
public enum BlobSasServiceVersion implements ServiceVersion {
V2019_02_02("2019-02-02"),
V2019_07_07("2019-07-07"),
diff --git a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/sas/BlobServiceSasSignatureValues.java b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/sas/BlobServiceSasSignatureValues.java
index 7619e7aa27227..4cddfc4fce609 100644
--- a/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/sas/BlobServiceSasSignatureValues.java
+++ b/sdk/storage/azure-storage-blob/src/main/java/com/azure/storage/blob/sas/BlobServiceSasSignatureValues.java
@@ -3,8 +3,10 @@
package com.azure.storage.blob.sas;
+import com.azure.core.util.Configuration;
import com.azure.core.util.CoreUtils;
import com.azure.core.util.logging.ClientLogger;
+import com.azure.storage.blob.BlobServiceVersion;
import com.azure.storage.blob.models.UserDelegationKey;
import com.azure.storage.common.Utility;
import com.azure.storage.common.implementation.Constants;
@@ -43,9 +45,16 @@ public final class BlobServiceSasSignatureValues {
*/
private static final String SAS_CONTAINER_CONSTANT = "c";
- private final ClientLogger logger = new ClientLogger(BlobServiceSasSignatureValues.class);
+ private static final ClientLogger LOGGER = new ClientLogger(BlobServiceSasSignatureValues.class);
- private final String version = BlobSasServiceVersion.getLatest().getVersion();
+ private static final String VERSION = Configuration.getGlobalConfiguration()
+ .get(Constants.PROPERTY_AZURE_STORAGE_SAS_SERVICE_VERSION, BlobServiceVersion.getLatest().getVersion());
+
+ /**
+ * Pin down to highest version that worked with string to sign defined here.
+ */
+ private static final String VERSION_DEPRECATED_STRING_TO_SIGN = Configuration.getGlobalConfiguration()
+ .get(Constants.PROPERTY_AZURE_STORAGE_SAS_SERVICE_VERSION, BlobServiceVersion.V2019_12_12.getVersion());
private SasProtocol protocol;
@@ -171,7 +180,7 @@ public BlobServiceSasSignatureValues(String version, SasProtocol sasProtocol, Of
* targeted by the library.
*/
public String getVersion() {
- return version;
+ return VERSION;
}
/**
@@ -543,8 +552,6 @@ public BlobServiceSasSignatureValues setCorrelationId(String correlationId) {
*
*
Notes on SAS generation
*
- * - If {@link #setVersion(String) version} is not set,
- * the {@link BlobSasServiceVersion#getLatest() latest service version} is used.
* - If {@link #setIdentifier(String) identifier} is set, {@link #setExpiryTime(OffsetDateTime) expiryTime} and
* permissions should not be set. These values are inherited from the stored access policy.
* - Otherwise, {@link #setExpiryTime(OffsetDateTime) expiryTime} and {@link #getPermissions() permissions} must
@@ -582,7 +589,7 @@ public BlobServiceSasQueryParameters generateSasQueryParameters(
final String canonicalName = getCanonicalName(storageSharedKeyCredentials.getAccountName());
final String signature = storageSharedKeyCredentials.computeHmac256(stringToSign(canonicalName));
- return new BlobServiceSasQueryParameters(this.version, this.protocol, this.startTime, this.expiryTime,
+ return new BlobServiceSasQueryParameters(VERSION, this.protocol, this.startTime, this.expiryTime,
this.sasIpRange, this.identifier, this.resource, this.permissions, signature, this.cacheControl,
this.contentDisposition, this.contentEncoding, this.contentLanguage, this.contentType, null /* delegate */);
}
@@ -592,8 +599,6 @@ public BlobServiceSasQueryParameters generateSasQueryParameters(
*
*
Notes on SAS generation
*
- * - If {@link #setVersion(String) version} is not set,
- * the {@link BlobSasServiceVersion#getLatest() latest service version} is used.
* - If {@link #setIdentifier(String) identifier} is set, {@link #setExpiryTime(OffsetDateTime) expiryTime} and
* permissions should not be set. These values are inherited from the stored access policy.
* - Otherwise, {@link #setExpiryTime(OffsetDateTime) expiryTime} and {@link #getPermissions() permissions} must
@@ -636,7 +641,7 @@ public BlobServiceSasQueryParameters generateSasQueryParameters(UserDelegationKe
String signature = StorageImplUtils.computeHMac256(
delegationKey.getValue(), stringToSign(delegationKey, canonicalName));
- return new BlobServiceSasQueryParameters(this.version, this.protocol, this.startTime, this.expiryTime,
+ return new BlobServiceSasQueryParameters(VERSION, this.protocol, this.startTime, this.expiryTime,
this.sasIpRange, null /* identifier */, this.resource, this.permissions, signature,
this.cacheControl, this.contentDisposition, this.contentEncoding, this.contentLanguage, this.contentType,
delegationKey);
@@ -676,7 +681,7 @@ private void ensureState() {
break;
default:
// We won't reparse the permissions if we don't know the type.
- logger.info("Not re-parsing permissions. Resource type '{}' is unknown.", resource);
+ LOGGER.info("Not re-parsing permissions. Resource type '{}' is unknown.", resource);
break;
}
}
@@ -702,8 +707,7 @@ private String stringToSign(String canonicalName) {
this.identifier == null ? "" : this.identifier,
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : this.protocol.toString(),
- version, /* Pin down to version so old string to sign works. This is reflected in the declaration of
- version */
+ VERSION_DEPRECATED_STRING_TO_SIGN, /* Pin down to version so old string to sign works. */
resource,
this.snapshotId == null ? "" : this.snapshotId,
this.cacheControl == null ? "" : this.cacheControl,
@@ -728,8 +732,7 @@ private String stringToSign(final UserDelegationKey key, String canonicalName) {
key.getSignedVersion() == null ? "" : key.getSignedVersion(),
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : this.protocol.toString(),
- version, /* Pin down to version so old string to sign works. This is reflected in the declaration of
- version */
+ VERSION_DEPRECATED_STRING_TO_SIGN, /* Pin down to version so old string to sign works. */
resource,
this.snapshotId == null ? "" : this.snapshotId,
this.cacheControl == null ? "" : this.cacheControl,
diff --git a/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/BlobServiceSasModelsTest.groovy b/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/BlobServiceSasModelsTest.groovy
index aceeea173203f..3f81f73720ce8 100644
--- a/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/BlobServiceSasModelsTest.groovy
+++ b/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/BlobServiceSasModelsTest.groovy
@@ -217,18 +217,6 @@ class BlobServiceSasModelsTest extends Specification {
ex.getMessage().contains("accountName")
}
- def "ensure state version"() {
- when:
- BlobSasImplUtil implUtil = new BlobSasImplUtil(new BlobServiceSasSignatureValues("id"), "container")
- implUtil.version = null
- implUtil.ensureState()
-
- then:
- implUtil.version // Version is set
- implUtil.resource == "c" // Default resource is container
- !implUtil.permissions // Identifier was used so permissions is null
- }
-
def "ensure state illegal argument"() {
when:
BlobSasImplUtil implUtil = new BlobSasImplUtil(new BlobServiceSasSignatureValues(), null)
diff --git a/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/SasClientTests.groovy b/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/SasClientTests.groovy
index 576a59ab2ae2c..5c4df447e5382 100644
--- a/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/SasClientTests.groovy
+++ b/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/SasClientTests.groovy
@@ -14,7 +14,6 @@ import com.azure.storage.blob.models.BlobStorageException
import com.azure.storage.blob.models.UserDelegationKey
import com.azure.storage.blob.sas.BlobContainerSasPermission
import com.azure.storage.blob.sas.BlobSasPermission
-import com.azure.storage.blob.sas.BlobSasServiceVersion
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues
import com.azure.storage.blob.specialized.BlockBlobClient
import com.azure.storage.blob.specialized.SpecializedBlobClientBuilder
@@ -57,8 +56,11 @@ class SasClientTests extends APISpec {
.setDeletePermission(true)
.setAddPermission(true)
.setListPermission(true)
- .setMovePermission(true)
- .setExecutePermission(true)
+ if (Constants.SAS_SERVICE_VERSION >= "2019-12-12") {
+ permissions
+ .setMovePermission(true)
+ .setExecutePermission(true)
+ }
def sasValues = generateValues(permissions)
@@ -72,9 +74,9 @@ class SasClientTests extends APISpec {
def properties = client.getProperties()
then:
+ notThrown(BlobStorageException)
os.toString() == data.defaultText
validateSasProperties(properties)
- notThrown(BlobStorageException)
}
def "container sas identifier and permissions"() {
@@ -94,8 +96,11 @@ class SasClientTests extends APISpec {
.setDeletePermission(true)
.setAddPermission(true)
.setListPermission(true)
- .setMovePermission(true)
- .setExecutePermission(true)
+ if (Constants.SAS_SERVICE_VERSION >= "2019-12-12") {
+ permissions
+ .setMovePermission(true)
+ .setExecutePermission(true)
+ }
def expiryTime = namer.getUtcNow().plusDays(1)
when:
@@ -125,8 +130,11 @@ class SasClientTests extends APISpec {
.setDeletePermission(true)
.setAddPermission(true)
.setListPermission(true)
- .setMovePermission(true)
- .setExecutePermission(true)
+ if (Constants.SAS_SERVICE_VERSION >= "2019-12-12") {
+ permissions
+ .setMovePermission(true)
+ .setExecutePermission(true)
+ }
def sasValues = generateValues(permissions)
@@ -140,9 +148,9 @@ class SasClientTests extends APISpec {
def properties = client.getProperties()
then:
+ notThrown(BlobStorageException)
os.toString() == data.defaultText
validateSasProperties(properties)
- notThrown(BlobStorageException)
}
def "blob sas snapshot"() {
@@ -413,6 +421,7 @@ class SasClientTests extends APISpec {
notThrown(BlobStorageException)
}
+ @RequiredServiceVersion(clazz = BlobServiceVersion.class, min = "V2020_02_10")
def "container user delegation correlation id error"() {
setup:
def permissions = new BlobContainerSasPermission()
@@ -896,19 +905,20 @@ class SasClientTests extends APISpec {
*/
where:
startTime | identifier | ipRange | protocol | snapId | cacheControl | disposition | encoding | language | type | versionId || expectedStringToSign
- OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC) | null | null | null | null | null | null | null | null | null | null || "r\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | "id" | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\nid\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | null | new SasIpRange() | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\nip\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | null | null | SasProtocol.HTTPS_ONLY | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n" + SasProtocol.HTTPS_ONLY + "\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | null | null | null | "snapId" | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nbs\nsnapId\n\n\n\n\n"
- null | null | null | null | null | "control" | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\ncontrol\n\n\n\n"
- null | null | null | null | null | null | "disposition" | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\ndisposition\n\n\n"
- null | null | null | null | null | null | null | "encoding" | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\nencoding\n\n"
- null | null | null | null | null | null | null | null | "language" | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\nlanguage\n"
- null | null | null | null | null | null | null | null | null | "type" | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\ntype"
- null | null | null | null | null | null | null | null | null | null | "versionId" || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nbv\nversionId\n\n\n\n\n"
+ OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC) | null | null | null | null | null | null | null | null | null | null || "r\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | "id" | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\nid\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | new SasIpRange() | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\nip\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | SasProtocol.HTTPS_ONLY | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n" + SasProtocol.HTTPS_ONLY + "\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | "snapId" | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nbs\nsnapId\n\n\n\n\n"
+ null | null | null | null | null | "control" | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\ncontrol\n\n\n\n"
+ null | null | null | null | null | null | "disposition" | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\ndisposition\n\n\n"
+ null | null | null | null | null | null | null | "encoding" | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\nencoding\n\n"
+ null | null | null | null | null | null | null | null | "language" | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\nlanguage\n"
+ null | null | null | null | null | null | null | null | null | "type" | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\ntype"
+ null | null | null | null | null | null | null | null | null | null | "versionId" || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nbv\nversionId\n\n\n\n\n"
}
+ @RequiredServiceVersion(clazz = BlobServiceVersion.class, min = "V2020_02_10")
@Unroll
def "blob sas impl util string to sign user delegation key"() {
when:
@@ -956,24 +966,24 @@ class SasClientTests extends APISpec {
*/
where:
startTime | keyOid | keyTid | keyStart | keyExpiry | keyService | keyVersion | keyValue | ipRange | protocol | snapId | cacheControl | disposition | encoding | language | type | versionId | saoid | cid || expectedStringToSign
- OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC) | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | "11111111-1111-1111-1111-111111111111" | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n11111111-1111-1111-1111-111111111111\n\n\n\n\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | null | "22222222-2222-2222-2222-222222222222" | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n22222222-2222-2222-2222-222222222222\n\n\n\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | null | null | OffsetDateTime.of(LocalDateTime.of(2018, 1, 1, 0, 0), ZoneOffset.UTC) | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n2018-01-01T00:00:00Z\n\n\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | null | null | null | OffsetDateTime.of(LocalDateTime.of(2018, 1, 1, 0, 0), ZoneOffset.UTC) | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n2018-01-01T00:00:00Z\n\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | "b" | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\nb\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | null | "2018-06-17" | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n2018-06-17\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | new SasIpRange() | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\nip\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | SasProtocol.HTTPS_ONLY | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n" + SasProtocol.HTTPS_ONLY + "\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | "snapId" | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nbs\nsnapId\n\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | "control" | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\ncontrol\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | "disposition" | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\ndisposition\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | "encoding" | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\nencoding\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | "language" | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\nlanguage\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | "type" | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\ntype"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | "versionId" | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nbv\nversionId\n\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | "saoid" | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\nsaoid\n\n\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | "cid" || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\ncid\n\n\n" + Constants.HeaderConstants.TARGET_STORAGE_VERSION + "\nb\n\n\n\n\n\n"
+ OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC) | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | "11111111-1111-1111-1111-111111111111" | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n11111111-1111-1111-1111-111111111111\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | "22222222-2222-2222-2222-222222222222" | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n22222222-2222-2222-2222-222222222222\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | OffsetDateTime.of(LocalDateTime.of(2018, 1, 1, 0, 0), ZoneOffset.UTC) | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n2018-01-01T00:00:00Z\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | OffsetDateTime.of(LocalDateTime.of(2018, 1, 1, 0, 0), ZoneOffset.UTC) | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n2018-01-01T00:00:00Z\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | "b" | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\nb\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | null | "2018-06-17" | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n2018-06-17\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | new SasIpRange() | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\nip\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | SasProtocol.HTTPS_ONLY | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n" + SasProtocol.HTTPS_ONLY + "\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | "snapId" | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nbs\nsnapId\n\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | "control" | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\ncontrol\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | "disposition" | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\ndisposition\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | "encoding" | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\nencoding\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | "language" | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\nlanguage\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | "type" | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\ntype"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | "versionId" | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nbv\nversionId\n\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | "saoid" | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\nsaoid\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null | "cid" || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/containerName/blobName\n\n\n\n\n\n\n\n\ncid\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
}
@Unroll
@@ -998,9 +1008,9 @@ class SasClientTests extends APISpec {
where:
containerName | blobName | snapId | expiryTime || expectedResource | expectedStringToSign
- "c" | "b" | "id" | OffsetDateTime.now() || "bs" | "\n\n%s\n" + "/blob/%s/c/b\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nbs\nid\n\n\n\n\n"
- "c" | "b" | null | OffsetDateTime.now() || "b" | "\n\n%s\n" + "/blob/%s/c/b\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- "c" | null | null | OffsetDateTime.now() || "c" | "\n\n%s\n" + "/blob/%s/c\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nc\n\n\n\n\n\n"
+ "c" | "b" | "id" | OffsetDateTime.now() || "bs" | "\n\n%s\n" + "/blob/%s/c/b\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nbs\nid\n\n\n\n\n"
+ "c" | "b" | null | OffsetDateTime.now() || "b" | "\n\n%s\n" + "/blob/%s/c/b\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ "c" | null | null | OffsetDateTime.now() || "c" | "\n\n%s\n" + "/blob/%s/c\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nc\n\n\n\n\n\n"
}
@@ -1032,9 +1042,9 @@ class SasClientTests extends APISpec {
where:
startTime | ipRange | protocol || expectedStringToSign
- OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC) | null | null || "%s" + "\nr\nb\no\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\n"
- null | new SasIpRange() | null || "%s" + "\nr\nb\no\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\nip\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\n"
- null | null | SasProtocol.HTTPS_ONLY || "%s" + "\nr\nb\no\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n\n" + SasProtocol.HTTPS_ONLY + "\n" + BlobSasServiceVersion.getLatest().getVersion() + "\n"
+ OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC) | null | null || "%s" + "\nr\nb\no\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n\n\n" + Constants.SAS_SERVICE_VERSION + "\n"
+ null | new SasIpRange() | null || "%s" + "\nr\nb\no\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\nip\n\n" + Constants.SAS_SERVICE_VERSION + "\n"
+ null | null | SasProtocol.HTTPS_ONLY || "%s" + "\nr\nb\no\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n\n" + SasProtocol.HTTPS_ONLY + "\n" + Constants.SAS_SERVICE_VERSION + "\n"
}
}
diff --git a/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/specialized/HelperTest.groovy b/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/specialized/HelperTest.groovy
index 95ef1f3d4cb19..9eeb6e51cfbf6 100644
--- a/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/specialized/HelperTest.groovy
+++ b/sdk/storage/azure-storage-blob/src/test/java/com/azure/storage/blob/specialized/HelperTest.groovy
@@ -13,9 +13,9 @@ import com.azure.storage.blob.implementation.util.BlobSasImplUtil
import com.azure.storage.blob.models.BlobRange
import com.azure.storage.blob.models.PageList
import com.azure.storage.blob.sas.BlobSasPermission
-import com.azure.storage.blob.sas.BlobSasServiceVersion
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues
import com.azure.storage.common.Utility
+import com.azure.storage.common.implementation.Constants
import com.azure.storage.common.implementation.SasImplUtils
import com.azure.storage.common.sas.CommonSasQueryParameters
import reactor.test.StepVerifier
@@ -68,7 +68,7 @@ class HelperTest extends APISpec {
def "URLParser"() {
when:
- def parts = BlobUrlParts.parse(new URL("http://host/container/" + originalBlobName + "?snapshot=snapshot&sv=" + BlobSasServiceVersion.getLatest().getVersion() + "&sr=c&sp=r&sig=Ee%2BSodSXamKSzivSdRTqYGh7AeMVEk3wEoRZ1yzkpSc%3D"))
+ def parts = BlobUrlParts.parse(new URL("http://host/container/" + originalBlobName + "?snapshot=snapshot&sv=" + Constants.SAS_SERVICE_VERSION + "&sr=c&sp=r&sig=Ee%2BSodSXamKSzivSdRTqYGh7AeMVEk3wEoRZ1yzkpSc%3D"))
then:
parts.getScheme() == "http"
@@ -77,7 +77,7 @@ class HelperTest extends APISpec {
parts.getBlobName() == finalBlobName
parts.getSnapshot() == "snapshot"
parts.getCommonSasQueryParameters().getPermissions() == "r"
- parts.getCommonSasQueryParameters().getVersion() == BlobSasServiceVersion.getLatest().getVersion()
+ parts.getCommonSasQueryParameters().getVersion() == Constants.SAS_SERVICE_VERSION
parts.getCommonSasQueryParameters().getResource() == "c"
parts.getCommonSasQueryParameters().getSignature() == Utility.urlDecode("Ee%2BSodSXamKSzivSdRTqYGh7AeMVEk3wEoRZ1yzkpSc%3D")
diff --git a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/AccountSasImplUtil.java b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/AccountSasImplUtil.java
index 8e1804ea8fb40..fdbd924613ece 100644
--- a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/AccountSasImplUtil.java
+++ b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/AccountSasImplUtil.java
@@ -4,7 +4,6 @@
package com.azure.storage.common.implementation;
import com.azure.core.util.Context;
-import com.azure.core.util.CoreUtils;
import com.azure.core.util.logging.ClientLogger;
import com.azure.storage.common.StorageSharedKeyCredential;
import com.azure.storage.common.sas.AccountSasPermission;
@@ -24,9 +23,9 @@
*/
public class AccountSasImplUtil {
- private final ClientLogger logger = new ClientLogger(AccountSasImplUtil.class);
+ private static final ClientLogger LOGGER = new ClientLogger(AccountSasImplUtil.class);
- private String version;
+ private static final String VERSION = Constants.SAS_SERVICE_VERSION;
private SasProtocol protocol;
@@ -48,7 +47,6 @@ public class AccountSasImplUtil {
* @param sasValues {@link AccountSasSignatureValues}
*/
public AccountSasImplUtil(AccountSasSignatureValues sasValues) {
- this.version = sasValues.getVersion();
this.protocol = sasValues.getProtocol();
this.startTime = sasValues.getStartTime();
this.expiryTime = sasValues.getExpiryTime();
@@ -72,11 +70,8 @@ public String generateSas(StorageSharedKeyCredential storageSharedKeyCredentials
StorageImplUtils.assertNotNull("expiryTime", this.expiryTime);
StorageImplUtils.assertNotNull("permissions", this.permissions);
- if (CoreUtils.isNullOrEmpty(version)) {
- version = Constants.HeaderConstants.TARGET_STORAGE_VERSION;
- }
String stringToSign = stringToSign(storageSharedKeyCredentials);
- StorageImplUtils.logStringToSign(logger, stringToSign, context);
+ StorageImplUtils.logStringToSign(LOGGER, stringToSign, context);
// Signature is generated on the un-url-encoded values.
String signature = storageSharedKeyCredentials.computeHmac256(stringToSign);
@@ -94,7 +89,7 @@ private String stringToSign(final StorageSharedKeyCredential storageSharedKeyCre
Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.expiryTime),
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : this.protocol.toString(),
- this.version,
+ VERSION,
"" // Account SAS requires an additional newline character
);
}
@@ -106,7 +101,7 @@ private String encode(String signature) {
*/
StringBuilder sb = new StringBuilder();
- tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SERVICE_VERSION, this.version);
+ tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SERVICE_VERSION, VERSION);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SERVICES, this.services);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_RESOURCES_TYPES, this.resourceTypes);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_PROTOCOL, this.protocol);
diff --git a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/Constants.java b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/Constants.java
index 51a427ee64bc3..f2044a6342e35 100644
--- a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/Constants.java
+++ b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/implementation/Constants.java
@@ -3,6 +3,7 @@
package com.azure.storage.common.implementation;
+import com.azure.core.util.Configuration;
import com.azure.storage.common.sas.SasProtocol;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
@@ -74,6 +75,11 @@ public final class Constants {
public static final String STORAGE_LOG_STRING_TO_SIGN = "Azure-Storage-Log-String-To-Sign";
+ public static final String PROPERTY_AZURE_STORAGE_SAS_SERVICE_VERSION = "AZURE_STORAGE_SAS_SERVICE_VERSION";
+
+ public static final String SAS_SERVICE_VERSION = Configuration.getGlobalConfiguration()
+ .get(PROPERTY_AZURE_STORAGE_SAS_SERVICE_VERSION, "2020-08-04");
+
private Constants() {
}
@@ -197,7 +203,9 @@ public static final class HeaderConstants {
/**
* The current storage version header value.
+ * @deprecated For SAS Service Version use {@link Constants#SAS_SERVICE_VERSION}.
*/
+ @Deprecated
public static final String TARGET_STORAGE_VERSION = "2020-08-04";
/**
diff --git a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/sas/AccountSasSignatureValues.java b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/sas/AccountSasSignatureValues.java
index 45ae5adcbbc60..029dbf8263002 100644
--- a/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/sas/AccountSasSignatureValues.java
+++ b/sdk/storage/azure-storage-common/src/main/java/com/azure/storage/common/sas/AccountSasSignatureValues.java
@@ -3,7 +3,6 @@
package com.azure.storage.common.sas;
-import com.azure.core.util.CoreUtils;
import com.azure.storage.common.StorageSharedKeyCredential;
import com.azure.storage.common.implementation.Constants;
import com.azure.storage.common.implementation.StorageImplUtils;
@@ -19,7 +18,7 @@
* @see Create an account SAS
*/
public final class AccountSasSignatureValues {
- private String version;
+ private static final String VERSION = Constants.SAS_SERVICE_VERSION;
private SasProtocol protocol;
@@ -70,7 +69,7 @@ public AccountSasSignatureValues(OffsetDateTime expiryTime, AccountSasPermission
* library will be used.
*/
public String getVersion() {
- return version;
+ return VERSION;
}
/**
@@ -79,9 +78,12 @@ public String getVersion() {
*
* @param version Target version to set
* @return the updated AccountSasSignatureValues object.
+ * @deprecated The version is set to the latest version of sas. Users should stop calling this API as it is now
+ * treated as a no-op.
*/
+ @Deprecated
public AccountSasSignatureValues setVersion(String version) {
- this.version = version;
+ // no-op
return this;
}
@@ -272,14 +274,10 @@ public AccountSasQueryParameters generateSasQueryParameters(
StorageImplUtils.assertNotNull("expiryTime", this.expiryTime);
StorageImplUtils.assertNotNull("permissions", this.permissions);
- if (CoreUtils.isNullOrEmpty(version)) {
- version = Constants.HeaderConstants.TARGET_STORAGE_VERSION;
- }
-
// Signature is generated on the un-url-encoded values.
String signature = storageSharedKeyCredentials.computeHmac256(stringToSign(storageSharedKeyCredentials));
- return new AccountSasQueryParameters(this.version, this.services, resourceTypes,
+ return new AccountSasQueryParameters(VERSION, this.services, resourceTypes,
this.protocol, this.startTime, this.expiryTime, this.sasIpRange, this.permissions, signature);
}
@@ -293,7 +291,7 @@ private String stringToSign(final StorageSharedKeyCredential storageSharedKeyCre
Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.expiryTime),
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : this.protocol.toString(),
- this.version,
+ VERSION,
"" // Account SAS requires an additional newline character
);
}
diff --git a/sdk/storage/azure-storage-file-datalake/pom.xml b/sdk/storage/azure-storage-file-datalake/pom.xml
index 056b9c60ffeb6..dd1d44ee7d8dd 100644
--- a/sdk/storage/azure-storage-file-datalake/pom.xml
+++ b/sdk/storage/azure-storage-file-datalake/pom.xml
@@ -313,5 +313,44 @@
+
+ inject-sas-service-version
+
+ env.AZURE_LIVE_TEST_SERVICE_VERSION
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 3.0.0
+
+
+ regex-property
+
+ regex-property
+
+
+ AZURE_STORAGE_SAS_SERVICE_VERSION
+ ${env.AZURE_LIVE_TEST_SERVICE_VERSION}
+ V(\d+)_(\d+)_(\d+)
+ $1-$2-$3
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M3
+
+
+ ${AZURE_STORAGE_SAS_SERVICE_VERSION}
+
+
+
+
+
+
diff --git a/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/implementation/util/DataLakeSasImplUtil.java b/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/implementation/util/DataLakeSasImplUtil.java
index e60a844b0efa0..2ebe33aaa06d4 100644
--- a/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/implementation/util/DataLakeSasImplUtil.java
+++ b/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/implementation/util/DataLakeSasImplUtil.java
@@ -3,6 +3,7 @@
package com.azure.storage.file.datalake.implementation.util;
+import com.azure.core.util.Configuration;
import com.azure.core.util.Context;
import com.azure.core.util.CoreUtils;
import com.azure.core.util.logging.ClientLogger;
@@ -44,9 +45,10 @@ public class DataLakeSasImplUtil {
*/
private static final String SAS_CONTAINER_CONSTANT = "c";
- private final ClientLogger logger = new ClientLogger(DataLakeSasImplUtil.class);
+ private static final ClientLogger LOGGER = new ClientLogger(DataLakeSasImplUtil.class);
- private static String version = DataLakeServiceVersion.getLatest().getVersion();
+ private static final String VERSION = Configuration.getGlobalConfiguration()
+ .get(Constants.PROPERTY_AZURE_STORAGE_SAS_SERVICE_VERSION, DataLakeServiceVersion.getLatest().getVersion());
private SasProtocol protocol;
@@ -141,7 +143,7 @@ public String generateSas(StorageSharedKeyCredential storageSharedKeyCredentials
// Signature is generated on the un-url-encoded values.
final String canonicalName = getCanonicalName(storageSharedKeyCredentials.getAccountName());
final String stringToSign = stringToSign(canonicalName);
- StorageImplUtils.logStringToSign(logger, stringToSign, context);
+ StorageImplUtils.logStringToSign(LOGGER, stringToSign, context);
final String signature = storageSharedKeyCredentials.computeHmac256(stringToSign);
return encode(null /* userDelegationKey */, signature);
@@ -164,7 +166,7 @@ public String generateUserDelegationSas(UserDelegationKey delegationKey, String
// Signature is generated on the un-url-encoded values.
final String canonicalName = getCanonicalName(accountName);
final String stringToSign = stringToSign(delegationKey, canonicalName);
- StorageImplUtils.logStringToSign(logger, stringToSign, context);
+ StorageImplUtils.logStringToSign(LOGGER, stringToSign, context);
String signature = StorageImplUtils.computeHMac256(delegationKey.getValue(), stringToSign);
return encode(delegationKey, signature);
@@ -183,7 +185,7 @@ private String encode(UserDelegationKey userDelegationKey, String signature) {
*/
StringBuilder sb = new StringBuilder();
- tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SERVICE_VERSION, version);
+ tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SERVICE_VERSION, VERSION);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_PROTOCOL, this.protocol);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_START_TIME, formatQueryParameterDate(this.startTime));
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_EXPIRY_TIME, formatQueryParameterDate(this.expiryTime));
@@ -247,7 +249,7 @@ private String encode(UserDelegationKey userDelegationKey, String signature) {
private void ensureState() {
if (identifier == null) {
if (expiryTime == null || permissions == null) {
- throw logger.logExceptionAsError(new IllegalStateException("If identifier is not set, expiry time "
+ throw LOGGER.logExceptionAsError(new IllegalStateException("If identifier is not set, expiry time "
+ "and permissions must be set"));
}
}
@@ -274,13 +276,13 @@ private void ensureState() {
break;
default:
// We won't reparse the permissions if we don't know the type.
- logger.info("Not re-parsing permissions. Resource type '{}' is unknown.", resource);
+ LOGGER.info("Not re-parsing permissions. Resource type '{}' is unknown.", resource);
break;
}
}
if (this.authorizedAadObjectId != null && this.unauthorizedAadObjectId != null) {
- throw logger.logExceptionAsError(new IllegalStateException("agentObjectId and preauthorizedAgentObjectId "
+ throw LOGGER.logExceptionAsError(new IllegalStateException("agentObjectId and preauthorizedAgentObjectId "
+ "can not both be set."));
}
}
@@ -305,7 +307,7 @@ private String stringToSign(String canonicalName) {
this.identifier == null ? "" : this.identifier,
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : this.protocol.toString(),
- version,
+ VERSION,
resource,
"", /* Version segment. */
this.cacheControl == null ? "" : this.cacheControl,
@@ -317,30 +319,55 @@ private String stringToSign(String canonicalName) {
}
private String stringToSign(final UserDelegationKey key, String canonicalName) {
- return String.join("\n",
- this.permissions == null ? "" : this.permissions,
- this.startTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.startTime),
- this.expiryTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.expiryTime),
- canonicalName,
- key.getSignedObjectId() == null ? "" : key.getSignedObjectId(),
- key.getSignedTenantId() == null ? "" : key.getSignedTenantId(),
- key.getSignedStart() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedStart()),
- key.getSignedExpiry() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedExpiry()),
- key.getSignedService() == null ? "" : key.getSignedService(),
- key.getSignedVersion() == null ? "" : key.getSignedVersion(),
- this.authorizedAadObjectId == null ? "" : this.authorizedAadObjectId,
- this.unauthorizedAadObjectId == null ? "" : this.unauthorizedAadObjectId,
- this.correlationId == null ? "" : this.correlationId,
- this.sasIpRange == null ? "" : this.sasIpRange.toString(),
- this.protocol == null ? "" : this.protocol.toString(),
- version,
- resource,
- "", /* Version segment. */
- this.cacheControl == null ? "" : this.cacheControl,
- this.contentDisposition == null ? "" : this.contentDisposition,
- this.contentEncoding == null ? "" : this.contentEncoding,
- this.contentLanguage == null ? "" : this.contentLanguage,
- this.contentType == null ? "" : this.contentType
- );
+ if (VERSION.compareTo(DataLakeServiceVersion.V2019_12_12.getVersion()) <= 0) {
+ return String.join("\n",
+ this.permissions == null ? "" : this.permissions,
+ this.startTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.startTime),
+ this.expiryTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.expiryTime),
+ canonicalName,
+ key.getSignedObjectId() == null ? "" : key.getSignedObjectId(),
+ key.getSignedTenantId() == null ? "" : key.getSignedTenantId(),
+ key.getSignedStart() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedStart()),
+ key.getSignedExpiry() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedExpiry()),
+ key.getSignedService() == null ? "" : key.getSignedService(),
+ key.getSignedVersion() == null ? "" : key.getSignedVersion(),
+ this.sasIpRange == null ? "" : this.sasIpRange.toString(),
+ this.protocol == null ? "" : this.protocol.toString(),
+ VERSION,
+ resource,
+ "", /* Version segment. */
+ this.cacheControl == null ? "" : this.cacheControl,
+ this.contentDisposition == null ? "" : this.contentDisposition,
+ this.contentEncoding == null ? "" : this.contentEncoding,
+ this.contentLanguage == null ? "" : this.contentLanguage,
+ this.contentType == null ? "" : this.contentType
+ );
+ } else {
+ return String.join("\n",
+ this.permissions == null ? "" : this.permissions,
+ this.startTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.startTime),
+ this.expiryTime == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(this.expiryTime),
+ canonicalName,
+ key.getSignedObjectId() == null ? "" : key.getSignedObjectId(),
+ key.getSignedTenantId() == null ? "" : key.getSignedTenantId(),
+ key.getSignedStart() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedStart()),
+ key.getSignedExpiry() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedExpiry()),
+ key.getSignedService() == null ? "" : key.getSignedService(),
+ key.getSignedVersion() == null ? "" : key.getSignedVersion(),
+ this.authorizedAadObjectId == null ? "" : this.authorizedAadObjectId,
+ this.unauthorizedAadObjectId == null ? "" : this.unauthorizedAadObjectId,
+ this.correlationId == null ? "" : this.correlationId,
+ this.sasIpRange == null ? "" : this.sasIpRange.toString(),
+ this.protocol == null ? "" : this.protocol.toString(),
+ VERSION,
+ resource,
+ "", /* Version segment. */
+ this.cacheControl == null ? "" : this.cacheControl,
+ this.contentDisposition == null ? "" : this.contentDisposition,
+ this.contentEncoding == null ? "" : this.contentEncoding,
+ this.contentLanguage == null ? "" : this.contentLanguage,
+ this.contentType == null ? "" : this.contentType
+ );
+ }
}
}
diff --git a/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/sas/DataLakeServiceSasSignatureValues.java b/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/sas/DataLakeServiceSasSignatureValues.java
index c2e61f7525a07..f7cd4117985b9 100644
--- a/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/sas/DataLakeServiceSasSignatureValues.java
+++ b/sdk/storage/azure-storage-file-datalake/src/main/java/com/azure/storage/file/datalake/sas/DataLakeServiceSasSignatureValues.java
@@ -3,6 +3,8 @@
package com.azure.storage.file.datalake.sas;
+import com.azure.core.util.Configuration;
+import com.azure.storage.common.implementation.Constants;
import com.azure.storage.common.implementation.StorageImplUtils;
import com.azure.storage.common.sas.SasIpRange;
import com.azure.storage.common.sas.SasProtocol;
@@ -25,7 +27,8 @@
*/
public final class DataLakeServiceSasSignatureValues {
- private final String version = DataLakeServiceVersion.getLatest().getVersion();
+ private static final String VERSION = Configuration.getGlobalConfiguration()
+ .get(Constants.PROPERTY_AZURE_STORAGE_SAS_SERVICE_VERSION, DataLakeServiceVersion.getLatest().getVersion());
private SasProtocol protocol;
@@ -97,7 +100,7 @@ public DataLakeServiceSasSignatureValues(String identifier) {
* targeted by the library.
*/
public String getVersion() {
- return version;
+ return VERSION;
}
/**
diff --git a/sdk/storage/azure-storage-file-datalake/src/test/java/com/azure/storage/file/datalake/SASTest.groovy b/sdk/storage/azure-storage-file-datalake/src/test/java/com/azure/storage/file/datalake/SASTest.groovy
index 554fe87dd3d6a..8c7ba4d04dc04 100644
--- a/sdk/storage/azure-storage-file-datalake/src/test/java/com/azure/storage/file/datalake/SASTest.groovy
+++ b/sdk/storage/azure-storage-file-datalake/src/test/java/com/azure/storage/file/datalake/SASTest.groovy
@@ -4,9 +4,6 @@
package com.azure.storage.file.datalake
import com.azure.core.credential.AzureSasCredential
-import com.azure.core.http.policy.HttpPipelinePolicy
-import com.azure.core.test.TestMode
-import com.azure.storage.blob.sas.BlobSasServiceVersion
import com.azure.storage.common.implementation.Constants
import com.azure.storage.common.sas.AccountSasPermission
import com.azure.storage.common.sas.AccountSasResourceType
@@ -14,6 +11,7 @@ import com.azure.storage.common.sas.AccountSasService
import com.azure.storage.common.sas.AccountSasSignatureValues
import com.azure.storage.common.sas.SasIpRange
import com.azure.storage.common.sas.SasProtocol
+import com.azure.storage.common.test.shared.extensions.RequiredServiceVersion
import com.azure.storage.file.datalake.implementation.util.DataLakeSasImplUtil
import com.azure.storage.file.datalake.models.AccessControlType
import com.azure.storage.file.datalake.models.DataLakeAccessPolicy
@@ -84,10 +82,12 @@ class SASTest extends APISpec {
.setCreatePermission(true)
.setAddPermission(true)
.setListPermission(true)
- .setMovePermission(true)
- .setExecutePermission(true)
- .setManageOwnershipPermission(true)
- .setManageAccessControlPermission(true)
+ if (Constants.SAS_SERVICE_VERSION >= DataLakeServiceVersion.V2019_12_12.version) {
+ permissions.setMovePermission(true)
+ .setExecutePermission(true)
+ .setManageOwnershipPermission(true)
+ .setManageAccessControlPermission(true)
+ }
def sasValues = generateValues(permissions)
@@ -106,6 +106,7 @@ class SASTest extends APISpec {
notThrown(DataLakeStorageException)
}
+ @RequiredServiceVersion(clazz = DataLakeServiceVersion.class, min = "V2020_02_10")
def "directory sas permission"() {
setup:
def pathName = generatePathName()
@@ -143,6 +144,7 @@ class SASTest extends APISpec {
notThrown(DataLakeStorageException)
}
+ @RequiredServiceVersion(clazz = DataLakeServiceVersion.class, min = "V2020_02_10")
def "directory sas permission fail"() {
setup:
def pathName = generatePathName()
@@ -182,10 +184,12 @@ class SASTest extends APISpec {
.setCreatePermission(true)
.setAddPermission(true)
.setListPermission(true)
- .setMovePermission(true)
- .setExecutePermission(true)
- .setManageOwnershipPermission(true)
- .setManageAccessControlPermission(true)
+ if (Constants.SAS_SERVICE_VERSION >= DataLakeServiceVersion.V2020_02_10.version) {
+ permissions.setMovePermission(true)
+ .setExecutePermission(true)
+ .setManageOwnershipPermission(true)
+ .setManageAccessControlPermission(true)
+ }
def expiryTime = namer.getUtcNow().plusDays(1)
@@ -219,10 +223,12 @@ class SASTest extends APISpec {
.setCreatePermission(true)
.setAddPermission(true)
.setListPermission(true)
- .setMovePermission(true)
- .setExecutePermission(true)
- .setManageOwnershipPermission(true)
- .setManageAccessControlPermission(true)
+ if (Constants.SAS_SERVICE_VERSION >= DataLakeServiceVersion.V2019_12_12.version) {
+ permissions.setMovePermission(true)
+ .setExecutePermission(true)
+ .setManageOwnershipPermission(true)
+ .setManageAccessControlPermission(true)
+ }
def sasValues = generateValues(permissions)
@@ -241,6 +247,7 @@ class SASTest extends APISpec {
notThrown(DataLakeStorageException)
}
+ @RequiredServiceVersion(clazz = DataLakeServiceVersion.class, min = "V2020_02_10")
def "directory user delegation"() {
setup:
def pathName = generatePathName()
@@ -296,10 +303,12 @@ class SASTest extends APISpec {
.setCreatePermission(true)
.setAddPermission(true)
.setListPermission(true)
- .setMovePermission(true)
- .setExecutePermission(true)
- .setManageOwnershipPermission(true)
- .setManageAccessControlPermission(true)
+ if (Constants.SAS_SERVICE_VERSION >= DataLakeServiceVersion.V2020_02_10.version) {
+ permissions.setMovePermission(true)
+ .setExecutePermission(true)
+ .setManageOwnershipPermission(true)
+ .setManageAccessControlPermission(true)
+ }
def expiryTime = namer.getUtcNow().plusDays(1)
@@ -322,6 +331,7 @@ class SASTest extends APISpec {
notThrown(DataLakeStorageException)
}
+ @RequiredServiceVersion(clazz = DataLakeServiceVersion.class, min = "V2020_02_10")
def "file user delegation saoid"() {
setup:
def saoid = namer.getRandomUuid()
@@ -380,6 +390,7 @@ class SASTest extends APISpec {
accessControl.getOwner() == saoid
}
+ @RequiredServiceVersion(clazz = DataLakeServiceVersion.class, min = "V2020_02_10")
def "file user delegation suoid"() {
setup:
def suoid = namer.getRandomUuid()
@@ -489,6 +500,7 @@ class SASTest extends APISpec {
notThrown(DataLakeStorageException)
}
+ @RequiredServiceVersion(clazz = DataLakeServiceVersion.class, min = "V2020_02_10")
def "file system user delegation correlation id error"() {
setup:
def permissions = new FileSystemSasPermission()
@@ -708,17 +720,18 @@ class SASTest extends APISpec {
*/
where:
startTime | identifier | ipRange | protocol | cacheControl | disposition | encoding | language | type || expectedStringToSign
- OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC) | null | null | null | null | null | null | null | null || "r\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | "id" | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\nid\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | new SasIpRange() | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\nip\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | null | SasProtocol.HTTPS_ONLY | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n" + SasProtocol.HTTPS_ONLY + "\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | null | null | "control" | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\ncontrol\n\n\n\n"
- null | null | null | null | null | "disposition" | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\ndisposition\n\n\n"
- null | null | null | null | null | null | "encoding" | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\nencoding\n\n"
- null | null | null | null | null | null | null | "language" | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\nlanguage\n"
- null | null | null | null | null | null | null | null | "type" || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\ntype"
+ OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC) | null | null | null | null | null | null | null | null || "r\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | "id" | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\nid\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | new SasIpRange() | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\nip\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | SasProtocol.HTTPS_ONLY | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n" + SasProtocol.HTTPS_ONLY + "\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | "control" | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\ncontrol\n\n\n\n"
+ null | null | null | null | null | "disposition" | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\ndisposition\n\n\n"
+ null | null | null | null | null | null | "encoding" | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\nencoding\n\n"
+ null | null | null | null | null | null | null | "language" | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\nlanguage\n"
+ null | null | null | null | null | null | null | null | "type" || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\ntype"
}
+ @RequiredServiceVersion(clazz = DataLakeServiceVersion.class, min = "V2020_02_10")
@Unroll
def "sas impl util string to sign user delegation key"() {
when:
@@ -772,24 +785,24 @@ class SASTest extends APISpec {
*/
where:
startTime | keyOid | keyTid | keyStart | keyExpiry | keyService | keyVersion | keyValue | ipRange | protocol | cacheControl | disposition | encoding | language | type | saoid | suoid | cid || expectedStringToSign
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC) | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | "11111111-1111-1111-1111-111111111111" | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n11111111-1111-1111-1111-111111111111\n\n\n\n\n\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | "22222222-2222-2222-2222-222222222222" | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n22222222-2222-2222-2222-222222222222\n\n\n\n\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | null | OffsetDateTime.of(LocalDateTime.of(2018, 1, 1, 0, 0), ZoneOffset.UTC) | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n2018-01-01T00:00:00Z\n\n\n\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | null | null | OffsetDateTime.of(LocalDateTime.of(2018, 1, 1, 0, 0), ZoneOffset.UTC) | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n2018-01-01T00:00:00Z\n\n\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | "b" | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\nb\n\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | null | "2018-06-17" | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n2018-06-17\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | new SasIpRange() | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\nip\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | SasProtocol.HTTPS_ONLY | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n" + SasProtocol.HTTPS_ONLY + "\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | "control" | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\ncontrol\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | "disposition" | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\ndisposition\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | "encoding" | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\nencoding\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | "language" | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\nlanguage\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | "type" | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\ntype"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | "saoid" | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\nsaoid\n\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | "suoid" | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\nsuoid\n\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
- null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | "cid" || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\ncid\n\n\n" + BlobSasServiceVersion.getLatest().getVersion() + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC) | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | "11111111-1111-1111-1111-111111111111" | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n11111111-1111-1111-1111-111111111111\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | "22222222-2222-2222-2222-222222222222" | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n22222222-2222-2222-2222-222222222222\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | OffsetDateTime.of(LocalDateTime.of(2018, 1, 1, 0, 0), ZoneOffset.UTC) | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n2018-01-01T00:00:00Z\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | OffsetDateTime.of(LocalDateTime.of(2018, 1, 1, 0, 0), ZoneOffset.UTC) | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n2018-01-01T00:00:00Z\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | "b" | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\nb\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | null | "2018-06-17" | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n2018-06-17\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | new SasIpRange() | null | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\nip\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | SasProtocol.HTTPS_ONLY | null | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n" + SasProtocol.HTTPS_ONLY + "\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | "control" | null | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\ncontrol\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | "disposition" | null | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\ndisposition\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | "encoding" | null | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\nencoding\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | "language" | null | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\nlanguage\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | "type" | null | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\ntype"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | "saoid" | null | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\nsaoid\n\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | "suoid" | null || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\nsuoid\n\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
+ null | null | null | null | null | null | null | "3hd4LRwrARVGbeMRQRfTLIsGMkCPuZJnvxZDU7Gak8c=" | null | null | null | null | null | null | null | null | null | "cid" || "r\n\n" + Constants.ISO_8601_UTC_DATE_FORMATTER.format(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + "\n/blob/%s/fileSystemName/pathName\n\n\n\n\n\n\n\n\ncid\n\n\n" + Constants.SAS_SERVICE_VERSION + "\nb\n\n\n\n\n\n"
}
def "can use sas to authenticate"() {
diff --git a/sdk/storage/azure-storage-file-share/pom.xml b/sdk/storage/azure-storage-file-share/pom.xml
index adf240b6846d6..1b0c8c07d9201 100644
--- a/sdk/storage/azure-storage-file-share/pom.xml
+++ b/sdk/storage/azure-storage-file-share/pom.xml
@@ -250,5 +250,44 @@
+
+ inject-sas-service-version
+
+ env.AZURE_LIVE_TEST_SERVICE_VERSION
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 3.0.0
+
+
+ regex-property
+
+ regex-property
+
+
+ AZURE_STORAGE_SAS_SERVICE_VERSION
+ ${env.AZURE_LIVE_TEST_SERVICE_VERSION}
+ V(\d+)_(\d+)_(\d+)
+ $1-$2-$3
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M3
+
+
+ ${AZURE_STORAGE_SAS_SERVICE_VERSION}
+
+
+
+
+
+
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/util/ShareSasImplUtil.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/util/ShareSasImplUtil.java
index 5ef5a758d1946..7eb7371f104a6 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/util/ShareSasImplUtil.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/implementation/util/ShareSasImplUtil.java
@@ -3,6 +3,7 @@
package com.azure.storage.file.share.implementation.util;
+import com.azure.core.util.Configuration;
import com.azure.core.util.Context;
import com.azure.core.util.CoreUtils;
import com.azure.core.util.logging.ClientLogger;
@@ -38,9 +39,10 @@ public class ShareSasImplUtil {
*/
private static final String SAS_SHARE_CONSTANT = "s";
- private final ClientLogger logger = new ClientLogger(ShareSasImplUtil.class);
+ private static final ClientLogger LOGGER = new ClientLogger(ShareSasImplUtil.class);
- private String version;
+ private static final String VERSION = Configuration.getGlobalConfiguration()
+ .get(Constants.PROPERTY_AZURE_STORAGE_SAS_SERVICE_VERSION, ShareServiceVersion.getLatest().getVersion());
private SasProtocol protocol;
@@ -89,7 +91,6 @@ public ShareSasImplUtil(ShareServiceSasSignatureValues sasValues, String shareNa
*/
public ShareSasImplUtil(ShareServiceSasSignatureValues sasValues, String shareName, String filePath) {
Objects.requireNonNull(sasValues);
- this.version = sasValues.getVersion();
this.protocol = sasValues.getProtocol();
this.startTime = sasValues.getStartTime();
this.expiryTime = sasValues.getExpiryTime();
@@ -120,7 +121,7 @@ public String generateSas(StorageSharedKeyCredential storageSharedKeyCredentials
// Signature is generated on the un-url-encoded values.
final String canonicalName = getCanonicalName(storageSharedKeyCredentials.getAccountName());
final String stringToSign = stringToSign(canonicalName);
- StorageImplUtils.logStringToSign(logger, stringToSign, context);
+ StorageImplUtils.logStringToSign(LOGGER, stringToSign, context);
final String signature = storageSharedKeyCredentials.computeHmac256(stringToSign);
return encode(signature);
@@ -138,7 +139,7 @@ private String encode(String signature) {
*/
StringBuilder sb = new StringBuilder();
- tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SERVICE_VERSION, this.version);
+ tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SERVICE_VERSION, VERSION);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_PROTOCOL, this.protocol);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_START_TIME, formatQueryParameterDate(this.startTime));
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_EXPIRY_TIME, formatQueryParameterDate(this.expiryTime));
@@ -168,13 +169,9 @@ private String encode(String signature) {
* 4. Reparse permissions depending on what the resource is. If it is an unrecognised resource, do nothing.
*/
private void ensureState() {
- if (version == null) {
- version = ShareServiceVersion.getLatest().getVersion();
- }
-
if (identifier == null) {
if (expiryTime == null || permissions == null) {
- throw logger.logExceptionAsError(new IllegalStateException("If identifier is not set, expiry time "
+ throw LOGGER.logExceptionAsError(new IllegalStateException("If identifier is not set, expiry time "
+ "and permissions must be set"));
}
}
@@ -195,7 +192,7 @@ private void ensureState() {
break;
default:
// We won't reparse the permissions if we don't know the type.
- logger.info("Not re-parsing permissions. Resource type '{}' is unknown.", resource);
+ LOGGER.info("Not re-parsing permissions. Resource type '{}' is unknown.", resource);
break;
}
}
@@ -225,7 +222,7 @@ private String stringToSign(String canonicalName) {
this.identifier == null ? "" : this.identifier,
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : this.protocol.toString(),
- this.version == null ? "" : this.version,
+ VERSION == null ? "" : VERSION,
this.cacheControl == null ? "" : this.cacheControl,
this.contentDisposition == null ? "" : this.contentDisposition,
this.contentEncoding == null ? "" : this.contentEncoding,
diff --git a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/sas/ShareServiceSasSignatureValues.java b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/sas/ShareServiceSasSignatureValues.java
index 3a046f4b9fbfe..69634f9550033 100644
--- a/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/sas/ShareServiceSasSignatureValues.java
+++ b/sdk/storage/azure-storage-file-share/src/main/java/com/azure/storage/file/share/sas/ShareServiceSasSignatureValues.java
@@ -3,6 +3,7 @@
package com.azure.storage.file.share.sas;
+import com.azure.core.util.Configuration;
import com.azure.core.util.CoreUtils;
import com.azure.storage.common.StorageSharedKeyCredential;
import com.azure.storage.common.implementation.Constants;
@@ -34,7 +35,8 @@ public final class ShareServiceSasSignatureValues {
*/
private static final String SAS_SHARE_CONSTANT = "s";
- private String version;
+ private static final String VERSION = Configuration.getGlobalConfiguration()
+ .get(Constants.PROPERTY_AZURE_STORAGE_SAS_SERVICE_VERSION, ShareServiceVersion.getLatest().getVersion());
private SasProtocol protocol;
@@ -113,7 +115,7 @@ public ShareServiceSasSignatureValues(String identifier) {
* targeted by the library.
*/
public String getVersion() {
- return version;
+ return VERSION;
}
/**
@@ -122,9 +124,12 @@ public String getVersion() {
*
* @param version Version to target
* @return the updated FileServiceSasSignatureValues object
+ * @deprecated The version is set to the latest version of sas. Users should stop calling this API as it is now
+ * treated as a no-op.
*/
+ @Deprecated
public ShareServiceSasSignatureValues setVersion(String version) {
- this.version = version;
+ // no-op
return this;
}
@@ -406,8 +411,6 @@ public ShareServiceSasSignatureValues setContentType(String contentType) {
*
*
Notes on SAS generation
*
- * - If {@link #setVersion(String) version} is not set, the {@link ShareServiceVersion#getLatest() latest service
- * version} is used.
* - If {@link #setIdentifier(String) identifier} is set, {@link #setExpiryTime(OffsetDateTime) expiryTime} and
* permissions should not be set. These values are inherited from the stored access policy.
* - Otherwise, {@link #setExpiryTime(OffsetDateTime) expiryTime} and {@link #getPermissions() permissions} must
@@ -455,16 +458,12 @@ public ShareServiceSasQueryParameters generateSasQueryParameters(
}
}
- if (CoreUtils.isNullOrEmpty(version)) {
- version = ShareServiceVersion.getLatest().getVersion();
- }
-
// Signature is generated on the un-url-encoded values.
String canonicalName = getCanonicalName(storageSharedKeyCredentials.getAccountName(), shareName, filePath);
String stringToSign = stringToSign(canonicalName);
String signature = storageSharedKeyCredentials.computeHmac256(stringToSign);
- return new ShareServiceSasQueryParameters(this.version, this.protocol, this.startTime, this.expiryTime,
+ return new ShareServiceSasQueryParameters(VERSION, this.protocol, this.startTime, this.expiryTime,
this.sasIpRange, this.identifier, resource, this.permissions, signature, this.cacheControl,
this.contentDisposition, this.contentEncoding, this.contentLanguage, this.contentType);
}
@@ -495,7 +494,7 @@ private String stringToSign(String canonicalName) {
this.identifier == null ? "" : this.identifier,
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : protocol.toString(),
- this.version == null ? "" : this.version,
+ VERSION == null ? "" : VERSION,
this.cacheControl == null ? "" : this.cacheControl,
this.contentDisposition == null ? "" : this.contentDisposition,
this.contentEncoding == null ? "" : this.contentEncoding,
diff --git a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileSasClientTests.groovy b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileSasClientTests.groovy
index cf733c92e210d..bfccacb64561f 100644
--- a/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileSasClientTests.groovy
+++ b/sdk/storage/azure-storage-file-share/src/test/java/com/azure/storage/file/share/FileSasClientTests.groovy
@@ -1,5 +1,6 @@
package com.azure.storage.file.share
+import com.azure.storage.common.StorageSharedKeyCredential
import com.azure.storage.common.implementation.Constants
import com.azure.storage.common.sas.AccountSasPermission
import com.azure.storage.common.sas.AccountSasResourceType
@@ -181,4 +182,22 @@ class FileSasClientTests extends APISpec {
then:
notThrown(ShareStorageException)
}
+
+ /**
+ * If this test fails it means that non-deprecated string to sign has new components.
+ * In that case we should hardcode version used for deprecated string to sign like we did for blobs.
+ */
+ def "Remember about string to sign deprecation"() {
+ setup:
+ def client = shareBuilderHelper(shareName).credential(env.primaryAccount.credential).buildClient()
+ def values = new ShareServiceSasSignatureValues(namer.getUtcNow(), new ShareSasPermission())
+ values.setShareName(client.getShareName())
+
+ when:
+ def deprecatedStringToSign = values.generateSasQueryParameters(env.primaryAccount.credential).encode()
+ def stringToSign = client.generateSas(values)
+
+ then:
+ deprecatedStringToSign == stringToSign
+ }
}
diff --git a/sdk/storage/azure-storage-file-share/src/test/resources/session-records/FileSasClientTestsRememberAboutStringToSignDeprecation.json b/sdk/storage/azure-storage-file-share/src/test/resources/session-records/FileSasClientTestsRememberAboutStringToSignDeprecation.json
new file mode 100644
index 0000000000000..aefdd91544fe6
--- /dev/null
+++ b/sdk/storage/azure-storage-file-share/src/test/resources/session-records/FileSasClientTestsRememberAboutStringToSignDeprecation.json
@@ -0,0 +1,54 @@
+{
+ "networkCallRecords" : [ {
+ "Method" : "PUT",
+ "Uri" : "https://REDACTED.file.core.windows.net/2ac4d54b2ac4d54bd5326936bf9732869a0b4dbc8f?restype=share",
+ "Headers" : {
+ "x-ms-version" : "2020-08-04",
+ "User-Agent" : "azsdk-java-azure-storage-file-share/12.11.0-beta.1 (11; Windows 10; 10.0)",
+ "x-ms-client-request-id" : "fa831a33-75d2-4b15-a01c-f6762b04df09"
+ },
+ "Response" : {
+ "content-length" : "0",
+ "x-ms-version" : "2020-08-04",
+ "Server" : "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "eTag" : "0x8D9302D591C0DA0",
+ "Last-Modified" : "Tue, 15 Jun 2021 18:42:37 GMT",
+ "retry-after" : "0",
+ "StatusCode" : "201",
+ "x-ms-request-id" : "d59bf1b0-e01a-0051-5316-62573d000000",
+ "x-ms-client-request-id" : "fa831a33-75d2-4b15-a01c-f6762b04df09",
+ "Date" : "Tue, 15 Jun 2021 18:42:37 GMT"
+ },
+ "Exception" : null
+ }, {
+ "Method" : "PUT",
+ "Uri" : "https://REDACTED.file.core.windows.net/2ac4d54b2ac4d54bd5326936bf9732869a0b4dbc8f/filename",
+ "Headers" : {
+ "x-ms-version" : "2020-08-04",
+ "User-Agent" : "azsdk-java-azure-storage-file-share/12.11.0-beta.1 (11; Windows 10; 10.0)",
+ "x-ms-client-request-id" : "77d81ba0-3218-4fa7-9ead-ba5a331c876b"
+ },
+ "Response" : {
+ "content-length" : "0",
+ "x-ms-version" : "2020-08-04",
+ "x-ms-file-permission-key" : "17737392480967489306*6811422022089678740",
+ "x-ms-file-id" : "13835128424026341376",
+ "Server" : "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-file-creation-time" : "2021-06-15T18:42:37.8825302Z",
+ "Last-Modified" : "Tue, 15 Jun 2021 18:42:37 GMT",
+ "retry-after" : "0",
+ "StatusCode" : "201",
+ "x-ms-request-server-encrypted" : "true",
+ "Date" : "Tue, 15 Jun 2021 18:42:37 GMT",
+ "x-ms-file-attributes" : "Archive",
+ "x-ms-file-change-time" : "2021-06-15T18:42:37.8825302Z",
+ "x-ms-file-parent-id" : "0",
+ "eTag" : "0x8D9302D59427656",
+ "x-ms-request-id" : "d59bf1b3-e01a-0051-5416-62573d000000",
+ "x-ms-client-request-id" : "77d81ba0-3218-4fa7-9ead-ba5a331c876b",
+ "x-ms-file-last-write-time" : "2021-06-15T18:42:37.8825302Z"
+ },
+ "Exception" : null
+ } ],
+ "variables" : [ "2ac4d54b2ac4d54bd5326936bf9732869a0b4dbc8f", "2021-06-15T18:42:38.034011100Z" ]
+}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-queue/pom.xml b/sdk/storage/azure-storage-queue/pom.xml
index bff62297aac89..315567f3172ad 100644
--- a/sdk/storage/azure-storage-queue/pom.xml
+++ b/sdk/storage/azure-storage-queue/pom.xml
@@ -245,5 +245,44 @@
+
+ inject-sas-service-version
+
+ env.AZURE_LIVE_TEST_SERVICE_VERSION
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 3.0.0
+
+
+ regex-property
+
+ regex-property
+
+
+ AZURE_STORAGE_SAS_SERVICE_VERSION
+ ${env.AZURE_LIVE_TEST_SERVICE_VERSION}
+ V(\d+)_(\d+)_(\d+)
+ $1-$2-$3
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M3
+
+
+ ${AZURE_STORAGE_SAS_SERVICE_VERSION}
+
+
+
+
+
+
diff --git a/sdk/storage/azure-storage-queue/src/main/java/com/azure/storage/queue/implementation/util/QueueSasImplUtil.java b/sdk/storage/azure-storage-queue/src/main/java/com/azure/storage/queue/implementation/util/QueueSasImplUtil.java
index 275a4294d2cba..1cacfa9eec2a9 100644
--- a/sdk/storage/azure-storage-queue/src/main/java/com/azure/storage/queue/implementation/util/QueueSasImplUtil.java
+++ b/sdk/storage/azure-storage-queue/src/main/java/com/azure/storage/queue/implementation/util/QueueSasImplUtil.java
@@ -3,6 +3,7 @@
package com.azure.storage.queue.implementation.util;
+import com.azure.core.util.Configuration;
import com.azure.core.util.Context;
import com.azure.core.util.logging.ClientLogger;
import com.azure.storage.common.StorageSharedKeyCredential;
@@ -27,9 +28,10 @@
*/
public class QueueSasImplUtil {
- private final ClientLogger logger = new ClientLogger(QueueSasImplUtil.class);
+ private static final ClientLogger LOGGER = new ClientLogger(QueueSasImplUtil.class);
- private String version;
+ private static final String VERSION = Configuration.getGlobalConfiguration()
+ .get(Constants.PROPERTY_AZURE_STORAGE_SAS_SERVICE_VERSION, QueueServiceVersion.getLatest().getVersion());
private SasProtocol protocol;
@@ -53,7 +55,6 @@ public class QueueSasImplUtil {
*/
public QueueSasImplUtil(QueueServiceSasSignatureValues sasValues, String queueName) {
Objects.requireNonNull(sasValues);
- this.version = sasValues.getVersion();
this.protocol = sasValues.getProtocol();
this.startTime = sasValues.getStartTime();
this.expiryTime = sasValues.getExpiryTime();
@@ -78,7 +79,7 @@ public String generateSas(StorageSharedKeyCredential storageSharedKeyCredentials
// Signature is generated on the un-url-encoded values.
String canonicalName = getCanonicalName(storageSharedKeyCredentials.getAccountName());
String stringToSign = stringToSign(canonicalName);
- StorageImplUtils.logStringToSign(logger, stringToSign, context);
+ StorageImplUtils.logStringToSign(LOGGER, stringToSign, context);
String signature = storageSharedKeyCredentials.computeHmac256(stringToSign);
return encode(signature);
@@ -91,7 +92,7 @@ private String encode(String signature) {
*/
StringBuilder sb = new StringBuilder();
- tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SERVICE_VERSION, this.version);
+ tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_SERVICE_VERSION, VERSION);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_PROTOCOL, this.protocol);
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_START_TIME, formatQueryParameterDate(this.startTime));
tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_EXPIRY_TIME, formatQueryParameterDate(this.expiryTime));
@@ -111,13 +112,9 @@ private String encode(String signature) {
* 4. Reparse permissions depending on what the resource is. If it is an unrecognised resource, do nothing.
*/
private void ensureState() {
- if (version == null) {
- version = QueueServiceVersion.getLatest().getVersion();
- }
-
if (identifier == null) {
if (expiryTime == null || permissions == null) {
- throw logger.logExceptionAsError(new IllegalStateException("If identifier is not set, expiry time "
+ throw LOGGER.logExceptionAsError(new IllegalStateException("If identifier is not set, expiry time "
+ "and permissions must be set"));
}
}
@@ -127,7 +124,7 @@ private void ensureState() {
permissions = QueueSasPermission.parse(permissions).toString();
} else {
// We won't reparse the permissions if we don't know the type.
- logger.info("Not re-parsing permissions. Resource type is not queue.");
+ LOGGER.info("Not re-parsing permissions. Resource type is not queue.");
}
}
}
@@ -151,7 +148,7 @@ private String stringToSign(String canonicalName) {
this.identifier == null ? "" : this.identifier,
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : protocol.toString(),
- this.version == null ? "" : this.version
+ VERSION == null ? "" : VERSION
);
}
diff --git a/sdk/storage/azure-storage-queue/src/main/java/com/azure/storage/queue/sas/QueueServiceSasSignatureValues.java b/sdk/storage/azure-storage-queue/src/main/java/com/azure/storage/queue/sas/QueueServiceSasSignatureValues.java
index 6d9bfa599bb24..e1012a8d1ba4f 100644
--- a/sdk/storage/azure-storage-queue/src/main/java/com/azure/storage/queue/sas/QueueServiceSasSignatureValues.java
+++ b/sdk/storage/azure-storage-queue/src/main/java/com/azure/storage/queue/sas/QueueServiceSasSignatureValues.java
@@ -3,11 +3,11 @@
package com.azure.storage.queue.sas;
+import com.azure.core.util.Configuration;
import com.azure.storage.common.implementation.StorageImplUtils;
import com.azure.storage.common.sas.SasProtocol;
import com.azure.storage.common.implementation.Constants;
import com.azure.storage.common.sas.SasIpRange;
-import com.azure.core.util.CoreUtils;
import com.azure.storage.common.StorageSharedKeyCredential;
import com.azure.storage.queue.QueueServiceVersion;
@@ -24,7 +24,8 @@
* SAS
*/
public final class QueueServiceSasSignatureValues {
- private String version;
+ private static final String VERSION = Configuration.getGlobalConfiguration()
+ .get(Constants.PROPERTY_AZURE_STORAGE_SAS_SERVICE_VERSION, QueueServiceVersion.getLatest().getVersion());
private SasProtocol protocol;
@@ -77,7 +78,7 @@ public QueueServiceSasSignatureValues(String identifier) {
* targeted by the library.
*/
public String getVersion() {
- return version;
+ return VERSION;
}
/**
@@ -86,9 +87,12 @@ public String getVersion() {
*
* @param version Version to target
* @return the updated QueueServiceSasSignatureValues object
+ * @deprecated The version is set to the latest version of sas. Users should stop calling this API as it is now
+ * treated as a no-op.
*/
+ @Deprecated
public QueueServiceSasSignatureValues setVersion(String version) {
- this.version = version;
+ // no-op
return this;
}
@@ -251,8 +255,6 @@ public QueueServiceSasSignatureValues setIdentifier(String identifier) {
*
*
Notes on SAS generation
*
- * - If {@link #setVersion(String) version} is not set, the {@link QueueServiceVersion#getLatest() latest service
- * version} is used.
* - If {@link #setIdentifier(String) identifier} is set, {@link #setExpiryTime(OffsetDateTime) expiryTime} and
* permissions should not be set. These values are inherited from the stored access policy.
* - Otherwise, {@link #setExpiryTime(OffsetDateTime) expiryTime} and {@link #getPermissions() permissions} must
@@ -274,16 +276,12 @@ public QueueServiceSasQueryParameters generateSasQueryParameters(
StorageSharedKeyCredential storageSharedKeyCredentials) {
StorageImplUtils.assertNotNull("storageSharedKeyCredentials", storageSharedKeyCredentials);
- if (CoreUtils.isNullOrEmpty(version)) {
- version = QueueServiceVersion.getLatest().getVersion();
- }
-
// Signature is generated on the un-url-encoded values.
String canonicalName = getCanonicalName(storageSharedKeyCredentials.getAccountName(), queueName);
String stringToSign = stringToSign(canonicalName);
String signature = storageSharedKeyCredentials.computeHmac256(stringToSign);
- return new QueueServiceSasQueryParameters(this.version, this.protocol, this.startTime, this.expiryTime,
+ return new QueueServiceSasQueryParameters(VERSION, this.protocol, this.startTime, this.expiryTime,
this.sasIpRange, this.identifier, this.permissions, signature);
}
@@ -307,7 +305,7 @@ private String stringToSign(String canonicalName) {
this.identifier == null ? "" : this.identifier,
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : protocol.toString(),
- this.version == null ? "" : this.version
+ VERSION == null ? "" : VERSION
);
}
}
diff --git a/sdk/storage/azure-storage-queue/src/test/java/com/azure/storage/queue/QueueSASTests.groovy b/sdk/storage/azure-storage-queue/src/test/java/com/azure/storage/queue/QueueSASTests.groovy
index 6d00596add5f1..2539d27b91bdc 100644
--- a/sdk/storage/azure-storage-queue/src/test/java/com/azure/storage/queue/QueueSASTests.groovy
+++ b/sdk/storage/azure-storage-queue/src/test/java/com/azure/storage/queue/QueueSASTests.groovy
@@ -250,7 +250,6 @@ class QueueSASTests extends APISpec {
.setResourceTypes(resourceType.toString())
.setPermissions(permissions)
.setExpiryTime(expiryTime)
- .setVersion(QueueServiceVersion.V2019_02_02.version)
.generateSasQueryParameters(credential)
.encode()
diff --git a/sdk/storage/azure-storage-queue/src/test/java/com/azure/storage/queue/QueueSasClientTests.groovy b/sdk/storage/azure-storage-queue/src/test/java/com/azure/storage/queue/QueueSasClientTests.groovy
index 27782c2e731e4..17e2f41b59ea5 100644
--- a/sdk/storage/azure-storage-queue/src/test/java/com/azure/storage/queue/QueueSasClientTests.groovy
+++ b/sdk/storage/azure-storage-queue/src/test/java/com/azure/storage/queue/QueueSasClientTests.groovy
@@ -4,12 +4,10 @@ import com.azure.storage.common.sas.AccountSasPermission
import com.azure.storage.common.sas.AccountSasResourceType
import com.azure.storage.common.sas.AccountSasService
import com.azure.storage.common.sas.AccountSasSignatureValues
-import com.azure.storage.common.sas.SasIpRange
import com.azure.storage.common.sas.SasProtocol
import com.azure.storage.queue.models.QueueAccessPolicy
import com.azure.storage.queue.models.QueueSignedIdentifier
import com.azure.storage.queue.models.QueueStorageException
-import com.azure.storage.queue.models.SendMessageResult
import com.azure.storage.queue.sas.QueueSasPermission
import com.azure.storage.queue.sas.QueueServiceSasSignatureValues
@@ -196,4 +194,22 @@ class QueueSasClientTests extends APISpec {
then:
notThrown(QueueStorageException)
}
+
+ /**
+ * If this test fails it means that non-deprecated string to sign has new components.
+ * In that case we should hardcode version used for deprecated string to sign like we did for blobs.
+ */
+ def "Remember about string to sign deprecation"() {
+ setup:
+ def client = queueBuilderHelper().credential(env.primaryAccount.credential).buildClient()
+ def values = new QueueServiceSasSignatureValues(namer.getUtcNow(), new QueueSasPermission())
+ values.setQueueName(client.getQueueName())
+
+ when:
+ def deprecatedStringToSign = values.generateSasQueryParameters(env.primaryAccount.credential).encode()
+ def stringToSign = client.generateSas(values)
+
+ then:
+ deprecatedStringToSign == stringToSign
+ }
}
diff --git a/sdk/storage/azure-storage-queue/src/test/resources/session-records/QueueSASTestsAccountSASCreateDeleteQueue.json b/sdk/storage/azure-storage-queue/src/test/resources/session-records/QueueSASTestsAccountSASCreateDeleteQueue.json
index 9e8d76822eb48..285006c09eb1a 100644
--- a/sdk/storage/azure-storage-queue/src/test/resources/session-records/QueueSASTestsAccountSASCreateDeleteQueue.json
+++ b/sdk/storage/azure-storage-queue/src/test/resources/session-records/QueueSASTestsAccountSASCreateDeleteQueue.json
@@ -1,42 +1,42 @@
{
"networkCallRecords" : [ {
"Method" : "PUT",
- "Uri" : "https://REDACTED.queue.core.windows.net/cf320dddcf320ddd1565929340212e359164473cbb?sv=2019-02-02&ss=q&srt=sco&se=2021-05-05T17%3A18%3A32Z&sp=rdc&sig=REDACTED",
+ "Uri" : "https://REDACTED.queue.core.windows.net/cf320dddcf320ddd71971375275b773e1ce247a6b5?sv=2020-08-04&ss=q&srt=sco&se=2021-06-12T23%3A00%3A48Z&sp=rdc&sig=REDACTED",
"Headers" : {
- "x-ms-version" : "2020-06-12",
- "User-Agent" : "azsdk-java-azure-storage-queue/12.10.0-beta.1 (11.0.8; Windows 10; 10.0)",
- "x-ms-client-request-id" : "294652a0-533a-4b4c-a0a2-80f69e7b4218"
+ "x-ms-version" : "2020-08-04",
+ "User-Agent" : "azsdk-java-azure-storage-queue/12.11.0-beta.1 (11.0.8; Windows 10; 10.0)",
+ "x-ms-client-request-id" : "7d73cb73-40ea-44a8-9433-16064a1b5b80"
},
"Response" : {
"content-length" : "0",
- "x-ms-version" : "2020-06-12",
+ "x-ms-version" : "2020-08-04",
"Server" : "Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0",
"retry-after" : "0",
"StatusCode" : "201",
- "x-ms-request-id" : "b050af46-6003-00cb-3909-41f574000000",
- "x-ms-client-request-id" : "294652a0-533a-4b4c-a0a2-80f69e7b4218",
- "Date" : "Tue, 04 May 2021 17:18:35 GMT"
+ "x-ms-request-id" : "a3a1ae18-f003-003f-0715-5f0212000000",
+ "x-ms-client-request-id" : "7d73cb73-40ea-44a8-9433-16064a1b5b80",
+ "Date" : "Fri, 11 Jun 2021 23:00:49 GMT"
},
"Exception" : null
}, {
"Method" : "DELETE",
- "Uri" : "https://REDACTED.queue.core.windows.net/cf320dddcf320ddd1565929340212e359164473cbb?sv=2019-02-02&ss=q&srt=sco&se=2021-05-05T17%3A18%3A32Z&sp=rdc&sig=REDACTED",
+ "Uri" : "https://REDACTED.queue.core.windows.net/cf320dddcf320ddd71971375275b773e1ce247a6b5?sv=2020-08-04&ss=q&srt=sco&se=2021-06-12T23%3A00%3A48Z&sp=rdc&sig=REDACTED",
"Headers" : {
- "x-ms-version" : "2020-06-12",
- "User-Agent" : "azsdk-java-azure-storage-queue/12.10.0-beta.1 (11.0.8; Windows 10; 10.0)",
- "x-ms-client-request-id" : "7b7435fd-0a5f-4e0d-9a3f-838578d686aa"
+ "x-ms-version" : "2020-08-04",
+ "User-Agent" : "azsdk-java-azure-storage-queue/12.11.0-beta.1 (11.0.8; Windows 10; 10.0)",
+ "x-ms-client-request-id" : "ed7dbbd4-4433-4cea-9feb-e05081d524ae"
},
"Response" : {
"content-length" : "0",
- "x-ms-version" : "2020-06-12",
+ "x-ms-version" : "2020-08-04",
"Server" : "Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0",
"retry-after" : "0",
"StatusCode" : "204",
- "x-ms-request-id" : "34fa79ff-1003-0078-4209-4155d9000000",
- "x-ms-client-request-id" : "7b7435fd-0a5f-4e0d-9a3f-838578d686aa",
- "Date" : "Tue, 04 May 2021 17:18:37 GMT"
+ "x-ms-request-id" : "a3a1ae87-f003-003f-6c15-5f0212000000",
+ "x-ms-client-request-id" : "ed7dbbd4-4433-4cea-9feb-e05081d524ae",
+ "Date" : "Fri, 11 Jun 2021 23:00:50 GMT"
},
"Exception" : null
} ],
- "variables" : [ "cf320dddcf320ddd15643464768a435b47ca498883", "2021-05-04T17:18:32.540972200Z", "cf320dddcf320ddd1565929340212e359164473cbb" ]
+ "variables" : [ "cf320dddcf320ddd719373645103c68a347749a394", "2021-06-11T23:00:48.051306Z", "cf320dddcf320ddd71971375275b773e1ce247a6b5" ]
}
\ No newline at end of file
diff --git a/sdk/storage/azure-storage-queue/src/test/resources/session-records/QueueSasClientTestsRememberAboutStringToSignDeprecation.json b/sdk/storage/azure-storage-queue/src/test/resources/session-records/QueueSasClientTestsRememberAboutStringToSignDeprecation.json
new file mode 100644
index 0000000000000..c902d209098c7
--- /dev/null
+++ b/sdk/storage/azure-storage-queue/src/test/resources/session-records/QueueSasClientTestsRememberAboutStringToSignDeprecation.json
@@ -0,0 +1,45 @@
+{
+ "networkCallRecords" : [ {
+ "Method" : "PUT",
+ "Uri" : "https://REDACTED.queue.core.windows.net/7b20caae7b20caaefd9233257e2db5c327f14",
+ "Headers" : {
+ "x-ms-version" : "2020-08-04",
+ "User-Agent" : "azsdk-java-azure-storage-queue/12.11.0-beta.1 (11; Windows 10; 10.0)",
+ "x-ms-client-request-id" : "a746ea46-f524-4565-976a-90c9871baa3f"
+ },
+ "Response" : {
+ "content-length" : "0",
+ "x-ms-version" : "2020-08-04",
+ "Server" : "Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0",
+ "retry-after" : "0",
+ "StatusCode" : "201",
+ "x-ms-request-id" : "004650a2-1003-0055-7320-62da3a000000",
+ "x-ms-client-request-id" : "a746ea46-f524-4565-976a-90c9871baa3f",
+ "Date" : "Tue, 15 Jun 2021 19:57:28 GMT"
+ },
+ "Exception" : null
+ }, {
+ "Method" : "POST",
+ "Uri" : "https://REDACTED.queue.core.windows.net/7b20caae7b20caaefd9233257e2db5c327f14/messages",
+ "Headers" : {
+ "x-ms-version" : "2020-08-04",
+ "User-Agent" : "azsdk-java-azure-storage-queue/12.11.0-beta.1 (11; Windows 10; 10.0)",
+ "x-ms-client-request-id" : "5ad9daf0-1646-4d15-9a37-87adafe324da",
+ "Content-Type" : "application/xml"
+ },
+ "Response" : {
+ "Transfer-Encoding" : "chunked",
+ "x-ms-version" : "2020-08-04",
+ "Server" : "Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0",
+ "retry-after" : "0",
+ "StatusCode" : "201",
+ "x-ms-request-id" : "004650ff-1003-0055-4a20-62da3a000000",
+ "Body" : "0e3b8c38-612c-46b6-92f8-22a2009c76b0Tue, 15 Jun 2021 19:57:28 GMTTue, 22 Jun 2021 19:57:28 GMTAgAAAAMAAAAAAAAAk9+pqyBi1wE=Tue, 15 Jun 2021 19:57:28 GMT",
+ "x-ms-client-request-id" : "5ad9daf0-1646-4d15-9a37-87adafe324da",
+ "Date" : "Tue, 15 Jun 2021 19:57:28 GMT",
+ "Content-Type" : "application/xml"
+ },
+ "Exception" : null
+ } ],
+ "variables" : [ "7b20caae7b20caaefd9233257e2db5c327f14", "7b20caae7b20caaefd923837411191e6be874c8786", "2021-06-15T19:57:29.125555500Z" ]
+}
\ No newline at end of file