Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 13 additions & 4 deletions sdk/storage/storage-queue/review/storage-queue-browser.api.diff.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ For the complete API surface, see the corresponding -node.api.md file.
generateSasStringToSign(expiresOn?: Date, permissions?: AccountSASPermissions, resourceTypes?: string, options?: ServiceGenerateAccountSasUrlOptions): string;
getProperties(options?: ServiceGetPropertiesOptions): Promise<ServiceGetPropertiesResponse>;
getQueueClient(queueName: string): QueueClient;
@@ -611,15 +532,8 @@
@@ -612,15 +533,8 @@

// @public
export type ReceivedMessageItem = DequeuedMessageItem;
Expand All @@ -198,7 +198,7 @@ For the complete API surface, see the corresponding -node.api.md file.
export interface ResponseLike {
_response: HttpResponse;
}
@@ -654,31 +568,8 @@
@@ -655,31 +569,8 @@
start: string;
}

Expand Down Expand Up @@ -230,7 +230,7 @@ For the complete API surface, see the corresponding -node.api.md file.
httpClient?: RequestPolicy;
requestPolicyFactories?: RequestPolicyFactory[] | ((defaultRequestPolicyFactories: RequestPolicyFactory[]) => void | RequestPolicyFactory[]);
}
@@ -777,11 +668,8 @@
@@ -797,11 +688,8 @@

export { StorageBrowserPolicyFactory }

Expand All @@ -242,7 +242,7 @@ For the complete API surface, see the corresponding -node.api.md file.
audience?: string;
httpClient?: RequestPolicy;
keepAliveOptions?: KeepAliveOptions;
@@ -789,27 +677,10 @@
@@ -809,25 +697,10 @@
retryOptions?: StorageRetryOptions;
userAgentOptions?: UserAgentPolicyOptions;
}
Expand All @@ -264,6 +264,15 @@ For the complete API surface, see the corresponding -node.api.md file.
-
-export { StorageSharedKeyCredentialPolicy }
-
// @public
export interface UserDelegationKey {
signedExpiresOn: Date;
signedObjectId: string;
@@ -848,10 +721,8 @@
signedVersion: string;
value: string;
}

-export { WebResource }
-
// @public
Expand Down
42 changes: 42 additions & 0 deletions sdk/storage/storage-queue/review/storage-queue-node.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ export class QueueServiceClient extends StorageClient {
getProperties(options?: ServiceGetPropertiesOptions): Promise<ServiceGetPropertiesResponse>;
getQueueClient(queueName: string): QueueClient;
getStatistics(options?: ServiceGetStatisticsOptions): Promise<ServiceGetStatisticsResponse>;
getUserDelegationKey(startsOn: Date, expiresOn: Date, options?: ServiceGetUserDelegationKeyOptions): Promise<ServiceGetUserDelegationKeyResponse>;
listQueues(options?: ServiceListQueuesOptions): PagedAsyncIterableIterator<QueueItem, ServiceListQueuesSegmentResponse>;
setProperties(properties: QueueServiceProperties, options?: ServiceGetPropertiesOptions): Promise<ServiceSetPropertiesResponse>;
}
Expand Down Expand Up @@ -724,6 +725,25 @@ export interface ServiceGetStatisticsOptions extends CommonOptions {
// @public
export type ServiceGetStatisticsResponse = WithResponse<ServiceGetStatisticsHeaders & QueueServiceStatistics, ServiceGetStatisticsHeaders, QueueServiceStatistics>;

// @public
export interface ServiceGetUserDelegationKeyHeaders {
clientRequestId?: string;
date?: Date;
requestId?: string;
version?: string;
}

// @public
export interface ServiceGetUserDelegationKeyOptions extends CommonOptions {
abortSignal?: AbortSignalLike;
}

// @public
export type ServiceGetUserDelegationKeyResponse = WithResponse<UserDelegationKey & ServiceGetUserDelegationKeyHeaders, ServiceGetUserDelegationKeyHeaders, UserDelegationKeyModel>;

// @public
export type ServiceGetUserDelegationKeyResponseModel = ServiceGetUserDelegationKeyHeaders & UserDelegationKeyModel;

// @public
export interface ServiceListQueuesOptions extends CommonOptions {
abortSignal?: AbortSignalLike;
Expand Down Expand Up @@ -807,6 +827,28 @@ export { StorageSharedKeyCredential }

export { StorageSharedKeyCredentialPolicy }

// @public
export interface UserDelegationKey {
signedExpiresOn: Date;
signedObjectId: string;
signedService: string;
signedStartsOn: Date;
signedTenantId: string;
signedVersion: string;
value: string;
}

// @public
export interface UserDelegationKeyModel {
signedExpiry: Date;
signedOid: string;
signedService: string;
signedStart: Date;
signedTid: string;
signedVersion: string;
value: string;
}

export { WebResource }

// @public
Expand Down
55 changes: 55 additions & 0 deletions sdk/storage/storage-queue/src/QueueClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import type {
MessagesClearHeaders,
MessageIdDeleteHeaders,
MessageIdUpdateHeaders,
UserDelegationKey,
} from "./generatedModels.js";
import type { AbortSignalLike } from "@azure/abort-controller";
import type { Messages, MessageId, Queue } from "./generated/src/operationsInterfaces/index.js";
Expand Down Expand Up @@ -1262,4 +1263,58 @@ export class QueueClient extends StorageClient {
this.credential,
).stringToSign;
}

/**
*
* Generates a Service Shared Access Signature (SAS) URI based on the client properties
* and parameters passed in. The SAS is signed by the user delegation key credential input.
*
* @see https://learn.microsoft.com/rest/api/storageservices/constructing-a-service-sas
*
* @param options - Optional parameters.
* @param userDelegationKey - user delegation key used to sign the SAS URI
* @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token.
*/
public generateUserDelegationSasUrl(
options: QueueGenerateSasUrlOptions,
userDelegationKey: UserDelegationKey,
): string {

const sas = generateQueueSASQueryParameters(
{
shareName: this.name,
...options,
},
userDelegationKey,
this.accountName
).toString();

return appendToURLQuery(this.url, sas);
}

/**
*
* Generates a Service Shared Access Signature (SAS) URI based on the client properties
* and parameters passed in. The SAS is signed by the user delegation key credential input.
*
* @see https://learn.microsoft.com/rest/api/storageservices/constructing-a-service-sas
*
* @param options - Optional parameters.
* @param userDelegationKey - user delegation key used to sign the SAS URI
* @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token.
*/
public generateUserDelegationStringToSign(
options: ShareGenerateSasUrlOptions,
userDelegationKey: UserDelegationKey,
): string {

return generateFileSASQueryParametersInternal(
{
shareName: this.name,
...options,
},
userDelegationKey,
this.accountName
).stringToSign;
}
}
34 changes: 32 additions & 2 deletions sdk/storage/storage-queue/src/QueueSASSignatureValues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
// Licensed under the MIT License.

import { QueueSASPermissions } from "./QueueSASPermissions.js";
import type { StorageSharedKeyCredential } from "@azure/storage-common";
import { StorageSharedKeyCredential } from "@azure/storage-common";
import type { SasIPRange } from "./SasIPRange.js";
import { ipRangeToString } from "./SasIPRange.js";
import type { SASProtocol } from "./SASQueryParameters.js";
import { SASQueryParameters } from "./SASQueryParameters.js";
import { SERVICE_VERSION } from "./utils/constants.js";
import { truncatedISO8061Date } from "./utils/utils.common.js";
import { UserDelegationKey } from "./generatedModels.js";

/**
* ONLY AVAILABLE IN NODE.JS RUNTIME.
Expand Down Expand Up @@ -77,18 +78,47 @@ export interface QueueSASSignatureValues {
* @param queueSASSignatureValues -
* @param sharedKeyCredential -
*/
export function generateQueueSASQueryParameters(
queueSASSignatureValues: QueueSASSignatureValues,
userDelegationKey: UserDelegationKey,
accountName: string,
): SASQueryParameters;

export function generateQueueSASQueryParameters(
queueSASSignatureValues: QueueSASSignatureValues,
sharedKeyCredential: StorageSharedKeyCredential,
): SASQueryParameters;

export function generateQueueSASQueryParameters(
queueSASSignatureValues: QueueSASSignatureValues,
sharedKeyCredentialOrUserDelegationKey: StorageSharedKeyCredential | UserDelegationKey,
accountName?: string,
): SASQueryParameters {
return generateQueueSASQueryParametersInternal(queueSASSignatureValues, sharedKeyCredential)
.sasQueryParameters;
}

export function generateQueueSASQueryParametersInternal(
queueSASSignatureValues: QueueSASSignatureValues,
sharedKeyCredential: StorageSharedKeyCredential,
sharedKeyCredentialOrUserDelegationKey: StorageSharedKeyCredential | UserDelegationKey,
accountName?: string,
): { sasQueryParameters: SASQueryParameters; stringToSign: string } {

const version = queueSASSignatureValues.version ? queueSASSignatureValues.version : SERVICE_VERSION;

const sharedKeyCredential =
sharedKeyCredentialOrUserDelegationKey instanceof StorageSharedKeyCredential
? sharedKeyCredentialOrUserDelegationKey
: undefined;
let userDelegationKeyCredential: UserDelegationKeyCredential | undefined;

if (sharedKeyCredential === undefined && accountName !== undefined) {
userDelegationKeyCredential = new UserDelegationKeyCredential(
accountName,
sharedKeyCredentialOrUserDelegationKey as UserDelegationKey,
);
}

if (
!queueSASSignatureValues.identifier &&
!(queueSASSignatureValues.permissions && queueSASSignatureValues.expiresOn)
Expand Down
78 changes: 78 additions & 0 deletions sdk/storage/storage-queue/src/QueueServiceClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import type {
ServiceSetPropertiesHeaders,
ServiceGetStatisticsHeaders,
QueueServiceStatistics,
ServiceGetUserDelegationKeyResponse,
ServiceGetUserDelegationKeyResponseModel,
ServiceGetUserDelegationKeyHeaders,
UserDelegationKeyModel,
} from "./generatedModels.js";
import type { AbortSignalLike } from "@azure/abort-controller";
import type { Service } from "./generated/src/operationsInterfaces/index.js";
Expand All @@ -32,6 +36,7 @@ import {
appendToURLQuery,
extractConnectionStringParts,
assertResponse,
truncatedISO8061Date,
} from "./utils/utils.common.js";
import { StorageSharedKeyCredential } from "@azure/storage-common";
import { AnonymousCredential } from "@azure/storage-common";
Expand Down Expand Up @@ -164,6 +169,17 @@ export interface ServiceGenerateAccountSasUrlOptions {
ipRange?: SasIPRange;
}

/**
* Options to configure the Service - Get User Delegation Key.
*/
export interface ServiceGetUserDelegationKeyOptions extends CommonOptions {
/**
* An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
* For example, use the &commat;azure/abort-controller to create an `AbortSignal`.
*/
abortSignal?: AbortSignalLike;
}

/**
* A QueueServiceClient represents a URL to the Azure Storage Queue service allowing you
* to manipulate queues.
Expand Down Expand Up @@ -773,5 +789,67 @@ export class QueueServiceClient extends StorageClient {
},
this.credential,
).stringToSign;
}

/**
* ONLY AVAILABLE WHEN USING BEARER TOKEN AUTHENTICATION (TokenCredential).
*
* Retrieves a user delegation key for the Blob service. This is only a valid operation when using
* bearer token authentication.
*
* @see https://learn.microsoft.com/rest/api/storageservices/get-user-delegation-key
*
* @param startsOn - The start time for the user delegation SAS. Must be within 7 days of the current time
* @param expiresOn - The end time for the user delegation SAS. Must be within 7 days of the current time
*/
public async getUserDelegationKey(
startsOn: Date,
expiresOn: Date,
options: ServiceGetUserDelegationKeyOptions = {},
): Promise<ServiceGetUserDelegationKeyResponse> {
return tracingClient.withSpan(
"ShareServiceClient-getUserDelegationKey",
options,
async (updatedOptions) => {
const response = assertResponse<
ServiceGetUserDelegationKeyResponseModel,
ServiceGetUserDelegationKeyHeaders,
UserDelegationKeyModel
>(
await this.serviceContext.getUserDelegationKey(
{
start: truncatedISO8061Date(startsOn, false),
expiry: truncatedISO8061Date(expiresOn, false),
},
{
abortSignal: options.abortSignal,
tracingOptions: updatedOptions.tracingOptions,
},
),
);

const userDelegationKey = {
signedObjectId: response.signedOid,
signedTenantId: response.signedOid,
signedStartsOn: new Date(response.signedStart),
signedExpiresOn: new Date(response.signedExpiry),
signedService: response.signedService,
signedVersion: response.signedVersion,
value: response.value,
};

const res: ServiceGetUserDelegationKeyResponse = {
_response: response._response,
requestId: response.requestId,
clientRequestId: response.clientRequestId,
version: response.version,
date: response.date,
//errorCode: response.errorCode,
...userDelegationKey,
};

return res;
},
);
}
}
Loading