UNPKG

5.71 kBJavaScriptView Raw
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT license.
3import { Constants, CosmosKeyType, SasTokenPermissionKind } from "../common";
4import { encodeUTF8 } from "./encode";
5import { hmac } from "./hmac";
6/**
7 * Experimental internal only
8 * Generates the payload representing the permission configuration for the sas token.
9 */
10export async function createAuthorizationSasToken(masterKey, sasTokenProperties) {
11 let resourcePrefixPath = "";
12 if (typeof sasTokenProperties.databaseName === "string" &&
13 sasTokenProperties.databaseName !== "") {
14 resourcePrefixPath += `/${Constants.Path.DatabasesPathSegment}/${sasTokenProperties.databaseName}`;
15 }
16 if (typeof sasTokenProperties.containerName === "string" &&
17 sasTokenProperties.containerName !== "") {
18 if (sasTokenProperties.databaseName === "") {
19 throw new Error(`illegalArgumentException : ${sasTokenProperties.databaseName} \
20 is an invalid database name`);
21 }
22 resourcePrefixPath += `/${Constants.Path.CollectionsPathSegment}/${sasTokenProperties.containerName}`;
23 }
24 if (typeof sasTokenProperties.resourceName === "string" &&
25 sasTokenProperties.resourceName !== "") {
26 if (sasTokenProperties.containerName === "") {
27 throw new Error(`illegalArgumentException : ${sasTokenProperties.containerName} \
28 is an invalid container name`);
29 }
30 switch (sasTokenProperties.resourceKind) {
31 case "ITEM":
32 resourcePrefixPath += `${Constants.Path.Root}${Constants.Path.DocumentsPathSegment}`;
33 break;
34 case "STORED_PROCEDURE":
35 resourcePrefixPath += `${Constants.Path.Root}${Constants.Path.StoredProceduresPathSegment}`;
36 break;
37 case "USER_DEFINED_FUNCTION":
38 resourcePrefixPath += `${Constants.Path.Root}${Constants.Path.UserDefinedFunctionsPathSegment}`;
39 break;
40 case "TRIGGER":
41 resourcePrefixPath += `${Constants.Path.Root}${Constants.Path.TriggersPathSegment}`;
42 break;
43 default:
44 throw new Error(`illegalArgumentException : ${sasTokenProperties.resourceKind} \
45 is an invalid resource kind`);
46 break;
47 }
48 resourcePrefixPath += `${Constants.Path.Root}${sasTokenProperties.resourceName}${Constants.Path.Root}`;
49 }
50 sasTokenProperties.resourcePath = resourcePrefixPath.toString();
51 let partitionRanges = "";
52 if (sasTokenProperties.partitionKeyValueRanges !== undefined &&
53 sasTokenProperties.partitionKeyValueRanges.length > 0) {
54 if (typeof sasTokenProperties.resourceKind !== "string" &&
55 sasTokenProperties.resourceKind !== "ITEM") {
56 throw new Error(`illegalArgumentException : ${sasTokenProperties.resourceKind} \
57 is an invalid partition key value range`);
58 }
59 sasTokenProperties.partitionKeyValueRanges.forEach((range) => {
60 partitionRanges += `${encodeUTF8(range)},`;
61 });
62 }
63 if (sasTokenProperties.controlPlaneReaderScope === 0) {
64 sasTokenProperties.controlPlaneReaderScope += SasTokenPermissionKind.ContainerReadAny;
65 sasTokenProperties.controlPlaneWriterScope += SasTokenPermissionKind.ContainerReadAny;
66 }
67 if (sasTokenProperties.dataPlaneReaderScope === 0 &&
68 sasTokenProperties.dataPlaneWriterScope === 0) {
69 sasTokenProperties.dataPlaneReaderScope = SasTokenPermissionKind.ContainerFullAccess;
70 sasTokenProperties.dataPlaneWriterScope = SasTokenPermissionKind.ContainerFullAccess;
71 }
72 if (typeof sasTokenProperties.keyType !== "number" ||
73 typeof sasTokenProperties.keyType === undefined) {
74 switch (sasTokenProperties.keyType) {
75 case CosmosKeyType.PrimaryMaster:
76 sasTokenProperties.keyType = 1;
77 break;
78 case CosmosKeyType.SecondaryMaster:
79 sasTokenProperties.keyType = 2;
80 break;
81 case CosmosKeyType.PrimaryReadOnly:
82 sasTokenProperties.keyType = 3;
83 break;
84 case CosmosKeyType.SecondaryReadOnly:
85 sasTokenProperties.keyType = 4;
86 break;
87 default:
88 throw new Error(`illegalArgumentException : ${sasTokenProperties.keyType} \
89 is an invalid key type`);
90 break;
91 }
92 }
93 const payload = sasTokenProperties.user +
94 "\n" +
95 sasTokenProperties.userTag +
96 "\n" +
97 sasTokenProperties.resourcePath +
98 "\n" +
99 partitionRanges +
100 "\n" +
101 utcsecondsSinceEpoch(sasTokenProperties.startTime).toString(16) +
102 "\n" +
103 utcsecondsSinceEpoch(sasTokenProperties.expiryTime).toString(16) +
104 "\n" +
105 sasTokenProperties.keyType +
106 "\n" +
107 sasTokenProperties.controlPlaneReaderScope.toString(16) +
108 "\n" +
109 sasTokenProperties.controlPlaneWriterScope.toString(16) +
110 "\n" +
111 sasTokenProperties.dataPlaneReaderScope.toString(16) +
112 "\n" +
113 sasTokenProperties.dataPlaneWriterScope.toString(16) +
114 "\n";
115 const signedPayload = await hmac(masterKey, Buffer.from(payload).toString("base64"));
116 return "type=sas&ver=1.0&sig=" + signedPayload + ";" + Buffer.from(payload).toString("base64");
117}
118/**
119 * @hidden
120 */
121// TODO: utcMilllisecondsSinceEpoch
122export function utcsecondsSinceEpoch(date) {
123 return Math.round(date.getTime() / 1000);
124}
125//# sourceMappingURL=SasToken.js.map
\No newline at end of file