Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for directory and delegation SAS #14531

Merged
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1ef2aae
Added code for directory and delegation SAS
gapra-msft Aug 25, 2020
db4e48f
Added code and tests for directory and delegation sas
gapra-msft Aug 25, 2020
1f6b636
Added code for delegation SAS
gapra-msft Aug 27, 2020
fe70587
recorded tests
gapra-msft Aug 27, 2020
d39b9c8
Added breadcrumbs
gapra-msft Aug 27, 2020
f85165b
Merge branch 'feature/storage/stg74' into storage/delegationSas
gapra-msft Aug 27, 2020
bd5dc6e
Added Changelog
gapra-msft Aug 27, 2020
5a744f8
Updated to pass Analyze step
gapra-msft Aug 27, 2020
599442d
Changed the permissions to include chagne
gapra-msft Aug 27, 2020
8c54c8b
Merge branch 'feature/storage/stg74' into storage/delegationSas
gapra-msft Aug 28, 2020
0a0e177
Merge branch 'feature/storage/stg74' into storage/delegationSas
gapra-msft Aug 28, 2020
80acb8a
Fixed line length
gapra-msft Aug 28, 2020
524b734
Changed to use one setter
gapra-msft Aug 28, 2020
d4db54a
removed unnecessary test
gapra-msft Aug 28, 2020
78448a9
Changed variable name
gapra-msft Aug 28, 2020
2ef2cee
Merge branch 'feature/storage/stg74' into storage/delegationSas
gapra-msft Sep 3, 2020
5b71fea
comment related stuff
gapra-msft Sep 3, 2020
35f2c9b
Addressed comments and changed change to manage
gapra-msft Sep 8, 2020
7b1a751
Modified public API to create 2 different setters
gapra-msft Sep 8, 2020
7e33e91
Fixed another test
gapra-msft Sep 8, 2020
971cf9a
rename of permission
gapra-msft Sep 9, 2020
8aed155
Changed public constants
gapra-msft Sep 9, 2020
fa4c50b
Analyze step
gapra-msft Sep 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public BlobSasImplUtil(BlobServiceSasSignatureValues sasValues, String container
throw logger.logExceptionAsError(
new IllegalArgumentException("'snapshot' and 'versionId' cannot be used at the same time."));
}
this.version = sasValues.getVersion();
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();
Expand Down Expand Up @@ -314,6 +314,9 @@ private String stringToSign(final UserDelegationKey key, String canonicalName) {
key.getSignedExpiry() == null ? "" : Constants.ISO_8601_UTC_DATE_FORMATTER.format(key.getSignedExpiry()),
key.getSignedService() == null ? "" : key.getSignedService(),
key.getSignedVersion() == null ? "" : key.getSignedVersion(),
"", /* saoid - empty since this applies to HNS only accounts. */
"", /* suoid - empty since this applies to HNS only accounts. */
"", /* cid - empty since this applies to HNS only accounts. */
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : this.protocol.toString(),
version,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,7 @@ public BlobServiceSasSignatureValues(String identifier) {
public BlobServiceSasSignatureValues(String version, SasProtocol sasProtocol, OffsetDateTime startTime,
OffsetDateTime expiryTime, String permission, SasIpRange sasIpRange, String identifier, String cacheControl,
String contentDisposition, String contentEncoding, String contentLanguage, String contentType) {
if (version != null) {
this.version = version;
}
this.version = null;
this.protocol = sasProtocol;
this.startTime = startTime;
this.expiryTime = expiryTime;
Expand Down Expand Up @@ -179,9 +177,11 @@ public String getVersion() {
*
* @param version Version to target
* @return the updated BlobServiceSASSignatureValues object
* @deprecated The version is set to the latest version of sas.
*/
@Deprecated
public BlobServiceSasSignatureValues setVersion(String version) {
this.version = version;
/* No-op.*/
return this;
}

Expand Down Expand Up @@ -656,7 +656,7 @@ private String stringToSign(String canonicalName) {
this.identifier == null ? "" : this.identifier,
this.sasIpRange == null ? "" : this.sasIpRange.toString(),
this.protocol == null ? "" : this.protocol.toString(),
version,
BlobSasServiceVersion.V2019_12_12.getVersion(), /* Pin down to version so old string to sign works. */
resource,
this.snapshotId == null ? "" : this.snapshotId,
this.cacheControl == null ? "" : this.cacheControl,
Expand All @@ -681,7 +681,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,
BlobSasServiceVersion.V2019_12_12.getVersion(), /* Pin down to version so old string to sign works. */
resource,
this.snapshotId == null ? "" : this.snapshotId,
this.cacheControl == null ? "" : this.cacheControl,
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,26 @@ public static final class UrlConstants {
*/
public static final String SAS_SIGNED_KEY_VERSION = "skv";

/**
* The SAS authorized object id parameter for user delegation SAS.
*/
public static final String SAS_AUTHORIZED_OBJECT_ID = "saoid";

/**
* The SAS unauthorized object id parameter for user delegation SAS.
*/
public static final String SAS_UNAUTHORIZED_OBJECT_ID = "suoid";

/**
* The SAS correlation id parameter for user delegation SAS.
*/
public static final String SAS_CORRELATION_ID = "scid";

/**
* The SAS directory depth parameter.
*/
public static final String SAS_DIRECTORY_DEPTH = "sdd";

/**
* The SAS queue constant.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.Map;
import java.util.function.Function;


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT - remove extra new line

/**
* Represents the components that make up an Azure Storage SAS' query parameters. This type is not constructed directly
* by the user; it is only generated by the URLParts type. NOTE: Instances of this class are immutable to ensure thread
Expand Down Expand Up @@ -62,6 +63,14 @@ public class CommonSasQueryParameters {

private final String contentType;

private final Integer directoryDepth;

private final String authorizedObjectId;

private final String unauthorizedObjectId;

private final String correlationId;

/**
* Creates a new {@link CommonSasQueryParameters} object.
*
Expand Down Expand Up @@ -114,6 +123,14 @@ public CommonSasQueryParameters(Map<String, String[]> queryParamsMap, boolean re
removeSasParametersFromMap);
this.contentType = getQueryParameter(queryParamsMap, Constants.UrlConstants.SAS_CONTENT_TYPE,
removeSasParametersFromMap);
this.authorizedObjectId = getQueryParameter(queryParamsMap, Constants.UrlConstants.SAS_AUTHORIZED_OBJECT_ID,
removeSasParametersFromMap);
this.unauthorizedObjectId = getQueryParameter(queryParamsMap, Constants.UrlConstants.SAS_UNAUTHORIZED_OBJECT_ID,
removeSasParametersFromMap);
this.correlationId = getQueryParameter(queryParamsMap, Constants.UrlConstants.SAS_CORRELATION_ID,
removeSasParametersFromMap);
this.directoryDepth = getQueryParameter(queryParamsMap, Constants.UrlConstants.SAS_DIRECTORY_DEPTH,
removeSasParametersFromMap, Integer::parseInt);
}

/**
Expand Down Expand Up @@ -196,6 +213,12 @@ public String encode() {
SasImplUtils.tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_CONTENT_ENCODING, this.contentEncoding);
SasImplUtils.tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_CONTENT_LANGUAGE, this.contentLanguage);
SasImplUtils.tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_CONTENT_TYPE, this.contentType);
SasImplUtils.tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_AUTHORIZED_OBJECT_ID,
this.authorizedObjectId);
SasImplUtils.tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_UNAUTHORIZED_OBJECT_ID,
this.unauthorizedObjectId);
SasImplUtils.tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_CORRELATION_ID, this.correlationId);
SasImplUtils.tryAppendQueryParameter(sb, Constants.UrlConstants.SAS_DIRECTORY_DEPTH, this.directoryDepth);

return sb.toString();
}
Expand Down Expand Up @@ -356,4 +379,34 @@ public String getPermissions() {
public String getSignature() {
return signature;
}

/**
* @return The directory depth of the resource this SAS token authorizes.
*/
public Integer getDirectoryDepth() {
return directoryDepth;
}

/**
* @return the AAD object id value for the SAS.
*/
public String getObjectId() {
return unauthorizedObjectId != null ? unauthorizedObjectId : authorizedObjectId;
}

/**
* @return Whether or not the service will perform an additional POSIX ACL check to determine
* if the user is authorized.
*/
public boolean isPosixCheckPerformed() {
return unauthorizedObjectId != null;
}

/**
* @return The correlation id to correlate the storage audit logs with the audit logs used by the principal
* generating and distributing the SAS.
*/
public String getCorrelationId() {
return correlationId;
}
}
1 change: 1 addition & 0 deletions sdk/storage/azure-storage-file-datalake/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Added support for the 2019-02-10 service version.
- Added support to schedule file expiration.
- Added support to specify Arrow Output Serialization when querying a file.
- Added support to generate directory SAS and added support to specify additional user ids and correlation ids for user delegation SAS.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT - double space after "..correlation ids for"

- Added support to upload data to a file from an InputStream.
- Added support to specify permissions and umask when uploading a file.
- Fixed a bug where an empty string would be sent with the x-ms-properties header when metadata was null or empty.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
import com.azure.storage.common.StorageSharedKeyCredential;
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.implementation.StorageImplUtils;
import com.azure.storage.file.datalake.implementation.DataLakeStorageClientBuilder;
import com.azure.storage.file.datalake.implementation.DataLakeStorageClientImpl;
import com.azure.storage.file.datalake.implementation.models.FileSystemsListPathsResponse;
import com.azure.storage.file.datalake.implementation.models.Path;
import com.azure.storage.file.datalake.implementation.util.DataLakeImplUtils;
import com.azure.storage.file.datalake.implementation.util.DataLakeSasImplUtil;
import com.azure.storage.file.datalake.models.DataLakeRequestConditions;
import com.azure.storage.file.datalake.models.DataLakeSignedIdentifier;
import com.azure.storage.file.datalake.models.FileSystemAccessPolicies;
Expand Down Expand Up @@ -798,9 +800,8 @@ BlobContainerAsyncClient getBlobContainerAsyncClient() {
*/
public String generateUserDelegationSas(DataLakeServiceSasSignatureValues dataLakeServiceSasSignatureValues,
UserDelegationKey userDelegationKey) {
return blobContainerAsyncClient.generateUserDelegationSas(
Transforms.toBlobSasValues(dataLakeServiceSasSignatureValues),
Transforms.toBlobUserDelegationKey(userDelegationKey));
return new DataLakeSasImplUtil(dataLakeServiceSasSignatureValues, getFileSystemName())
.generateUserDelegationSas(userDelegationKey, getAccountName());
}

/**
Expand All @@ -817,6 +818,7 @@ public String generateUserDelegationSas(DataLakeServiceSasSignatureValues dataLa
* @return A {@code String} representing all SAS query parameters.
*/
public String generateSas(DataLakeServiceSasSignatureValues dataLakeServiceSasSignatureValues) {
return blobContainerAsyncClient.generateSas(Transforms.toBlobSasValues(dataLakeServiceSasSignatureValues));
return new DataLakeSasImplUtil(dataLakeServiceSasSignatureValues, getFileSystemName())
.generateSas(SasImplUtils.extractSharedKeyCredential(getHttpPipeline()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.azure.storage.common.StorageSharedKeyCredential;
import com.azure.storage.common.Utility;
import com.azure.storage.common.implementation.Constants;
import com.azure.storage.common.implementation.SasImplUtils;
import com.azure.storage.file.datalake.implementation.DataLakeStorageClientBuilder;
import com.azure.storage.file.datalake.implementation.DataLakeStorageClientImpl;
import com.azure.storage.file.datalake.implementation.models.LeaseAccessConditions;
Expand All @@ -26,6 +27,7 @@
import com.azure.storage.file.datalake.implementation.models.PathResourceType;
import com.azure.storage.file.datalake.implementation.models.SourceModifiedAccessConditions;
import com.azure.storage.file.datalake.implementation.util.DataLakeImplUtils;
import com.azure.storage.file.datalake.implementation.util.DataLakeSasImplUtil;
import com.azure.storage.file.datalake.implementation.util.TransformUtils;
import com.azure.storage.file.datalake.models.DataLakeRequestConditions;
import com.azure.storage.file.datalake.models.PathAccessControl;
Expand Down Expand Up @@ -815,9 +817,9 @@ BlockBlobAsyncClient getBlockBlobAsyncClient() {
*/
public String generateUserDelegationSas(DataLakeServiceSasSignatureValues dataLakeServiceSasSignatureValues,
UserDelegationKey userDelegationKey) {
return blockBlobAsyncClient.generateUserDelegationSas(
Transforms.toBlobSasValues(dataLakeServiceSasSignatureValues),
Transforms.toBlobUserDelegationKey(userDelegationKey));
return new DataLakeSasImplUtil(dataLakeServiceSasSignatureValues, getFileSystemName(), getObjectPath(),
PathResourceType.DIRECTORY.equals(this.pathResourceType))
.generateUserDelegationSas(userDelegationKey, getAccountName());
}

/**
Expand All @@ -834,6 +836,8 @@ public String generateUserDelegationSas(DataLakeServiceSasSignatureValues dataLa
* @return A {@code String} representing all SAS query parameters.
*/
public String generateSas(DataLakeServiceSasSignatureValues dataLakeServiceSasSignatureValues) {
return blockBlobAsyncClient.generateSas(Transforms.toBlobSasValues(dataLakeServiceSasSignatureValues));
return new DataLakeSasImplUtil(dataLakeServiceSasSignatureValues, getFileSystemName(), getObjectPath(),
PathResourceType.DIRECTORY.equals(this.pathResourceType))
.generateSas(SasImplUtils.extractSharedKeyCredential(getHttpPipeline()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
import com.azure.storage.blob.models.BlobRequestConditions;
import com.azure.storage.blob.models.BlobSignedIdentifier;
import com.azure.storage.blob.models.ListBlobContainersOptions;
import com.azure.storage.blob.sas.BlobContainerSasPermission;
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
import com.azure.storage.common.ParallelTransferOptions;
import com.azure.storage.common.ProgressReceiver;
import com.azure.storage.file.datalake.implementation.models.Path;
Expand Down Expand Up @@ -71,7 +69,6 @@
import com.azure.storage.file.datalake.models.PathProperties;
import com.azure.storage.file.datalake.models.PublicAccessType;
import com.azure.storage.file.datalake.models.UserDelegationKey;
import com.azure.storage.file.datalake.sas.DataLakeServiceSasSignatureValues;

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
Expand Down Expand Up @@ -190,21 +187,6 @@ static UserDelegationKey toDataLakeUserDelegationKey(com.azure.storage.blob.mode
.setValue(blobUserDelegationKey.getValue());
}

static com.azure.storage.blob.models.UserDelegationKey toBlobUserDelegationKey(UserDelegationKey
dataLakeUserDelegationKey) {
if (dataLakeUserDelegationKey == null) {
return null;
}
return new com.azure.storage.blob.models.UserDelegationKey()
.setSignedExpiry(dataLakeUserDelegationKey.getSignedExpiry())
.setSignedObjectId(dataLakeUserDelegationKey.getSignedObjectId())
.setSignedTenantId(dataLakeUserDelegationKey.getSignedTenantId())
.setSignedService(dataLakeUserDelegationKey.getSignedService())
.setSignedStart(dataLakeUserDelegationKey.getSignedStart())
.setSignedVersion(dataLakeUserDelegationKey.getSignedVersion())
.setValue(dataLakeUserDelegationKey.getValue());
}

static BlobHttpHeaders toBlobHttpHeaders(PathHttpHeaders pathHTTPHeaders) {
if (pathHTTPHeaders == null) {
return null;
Expand Down Expand Up @@ -425,40 +407,6 @@ private static DataLakeAccessPolicy toDataLakeAccessPolicy(BlobAccessPolicy acce
.setPermissions(accessPolicy.getPermissions());
}

static BlobServiceSasSignatureValues toBlobSasValues(DataLakeServiceSasSignatureValues
dataLakeServiceSasSignatureValues) {
if (dataLakeServiceSasSignatureValues == null) {
return null;
}
BlobServiceSasSignatureValues blobServiceSasSignatureValues;
if (dataLakeServiceSasSignatureValues.getIdentifier() != null) {
blobServiceSasSignatureValues =
new BlobServiceSasSignatureValues(dataLakeServiceSasSignatureValues.getIdentifier());
} else {
// It's ok to use blob container sas permission since its a super set of blob sas permission
blobServiceSasSignatureValues =
new BlobServiceSasSignatureValues(dataLakeServiceSasSignatureValues.getExpiryTime(),
BlobContainerSasPermission.parse(dataLakeServiceSasSignatureValues.getPermissions()));
}
blobServiceSasSignatureValues.setVersion(dataLakeServiceSasSignatureValues.getVersion())
.setProtocol(dataLakeServiceSasSignatureValues.getProtocol())
.setStartTime(dataLakeServiceSasSignatureValues.getStartTime())
.setExpiryTime(dataLakeServiceSasSignatureValues.getExpiryTime())
.setSasIpRange(dataLakeServiceSasSignatureValues.getSasIpRange())
.setIdentifier(dataLakeServiceSasSignatureValues.getIdentifier())
.setCacheControl(dataLakeServiceSasSignatureValues.getCacheControl())
.setContentDisposition(dataLakeServiceSasSignatureValues.getContentDisposition())
.setContentEncoding(dataLakeServiceSasSignatureValues.getContentEncoding())
.setContentLanguage(dataLakeServiceSasSignatureValues.getContentLanguage())
.setContentType(dataLakeServiceSasSignatureValues.getContentType());
if (dataLakeServiceSasSignatureValues.getPermissions() != null) {
// It's ok to use blob container sas permission since its a super set of blob sas permission
blobServiceSasSignatureValues.setPermissions(BlobContainerSasPermission.parse(
dataLakeServiceSasSignatureValues.getPermissions()));
}
return blobServiceSasSignatureValues;
}

static com.azure.storage.blob.models.ParallelTransferOptions toBlobParallelTransferOptions(
ParallelTransferOptions pto) {
if (pto == null) {
Expand Down
Loading