UNPKG

7.43 kBJavaScriptView Raw
1import { __extends } from "tslib";
2import * as utils from "../util/utils";
3import { BaseRequestPolicy, } from "./requestPolicy";
4export function rpRegistrationPolicy(retryTimeout) {
5 if (retryTimeout === void 0) { retryTimeout = 30; }
6 return {
7 create: function (nextPolicy, options) {
8 return new RPRegistrationPolicy(nextPolicy, options, retryTimeout);
9 },
10 };
11}
12var RPRegistrationPolicy = /** @class */ (function (_super) {
13 __extends(RPRegistrationPolicy, _super);
14 function RPRegistrationPolicy(nextPolicy, options, _retryTimeout) {
15 if (_retryTimeout === void 0) { _retryTimeout = 30; }
16 var _this = _super.call(this, nextPolicy, options) || this;
17 _this._retryTimeout = _retryTimeout;
18 return _this;
19 }
20 RPRegistrationPolicy.prototype.sendRequest = function (request) {
21 var _this = this;
22 return this._nextPolicy
23 .sendRequest(request.clone())
24 .then(function (response) { return registerIfNeeded(_this, request, response); });
25 };
26 return RPRegistrationPolicy;
27}(BaseRequestPolicy));
28export { RPRegistrationPolicy };
29function registerIfNeeded(policy, request, response) {
30 if (response.status === 409) {
31 var rpName = checkRPNotRegisteredError(response.bodyAsText);
32 if (rpName) {
33 var urlPrefix = extractSubscriptionUrl(request.url);
34 return (registerRP(policy, urlPrefix, rpName, request)
35 // Autoregistration of ${provider} failed for some reason. We will not return this error
36 // instead will return the initial response with 409 status code back to the user.
37 // do nothing here as we are returning the original response at the end of this method.
38 .catch(function () { return false; })
39 .then(function (registrationStatus) {
40 if (registrationStatus) {
41 // Retry the original request. We have to change the x-ms-client-request-id
42 // otherwise Azure endpoint will return the initial 409 (cached) response.
43 request.headers.set("x-ms-client-request-id", utils.generateUuid());
44 return policy._nextPolicy.sendRequest(request.clone());
45 }
46 return response;
47 }));
48 }
49 }
50 return Promise.resolve(response);
51}
52/**
53 * Reuses the headers of the original request and url (if specified).
54 * @param {WebResourceLike} originalRequest The original request
55 * @param {boolean} reuseUrlToo Should the url from the original request be reused as well. Default false.
56 * @returns {object} A new request object with desired headers.
57 */
58function getRequestEssentials(originalRequest, reuseUrlToo) {
59 if (reuseUrlToo === void 0) { reuseUrlToo = false; }
60 var reqOptions = originalRequest.clone();
61 if (reuseUrlToo) {
62 reqOptions.url = originalRequest.url;
63 }
64 // We have to change the x-ms-client-request-id otherwise Azure endpoint
65 // will return the initial 409 (cached) response.
66 reqOptions.headers.set("x-ms-client-request-id", utils.generateUuid());
67 // Set content-type to application/json
68 reqOptions.headers.set("Content-Type", "application/json; charset=utf-8");
69 return reqOptions;
70}
71/**
72 * Validates the error code and message associated with 409 response status code. If it matches to that of
73 * RP not registered then it returns the name of the RP else returns undefined.
74 * @param {string} body The response body received after making the original request.
75 * @returns {string} The name of the RP if condition is satisfied else undefined.
76 */
77function checkRPNotRegisteredError(body) {
78 var result, responseBody;
79 if (body) {
80 try {
81 responseBody = JSON.parse(body);
82 }
83 catch (err) {
84 // do nothing;
85 }
86 if (responseBody &&
87 responseBody.error &&
88 responseBody.error.message &&
89 responseBody.error.code &&
90 responseBody.error.code === "MissingSubscriptionRegistration") {
91 var matchRes = responseBody.error.message.match(/.*'(.*)'/i);
92 if (matchRes) {
93 result = matchRes.pop();
94 }
95 }
96 }
97 return result;
98}
99/**
100 * Extracts the first part of the URL, just after subscription:
101 * https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/
102 * @param {string} url The original request url
103 * @returns {string} The url prefix as explained above.
104 */
105function extractSubscriptionUrl(url) {
106 var result;
107 var matchRes = url.match(/.*\/subscriptions\/[a-f0-9-]+\//gi);
108 if (matchRes && matchRes[0]) {
109 result = matchRes[0];
110 }
111 else {
112 throw new Error("Unable to extract subscriptionId from the given url - " + url + ".");
113 }
114 return result;
115}
116/**
117 * Registers the given provider.
118 * @param {RPRegistrationPolicy} policy The RPRegistrationPolicy this function is being called against.
119 * @param {string} urlPrefix https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/
120 * @param {string} provider The provider name to be registered.
121 * @param {WebResourceLike} originalRequest The original request sent by the user that returned a 409 response
122 * with a message that the provider is not registered.
123 * @param {registrationCallback} callback The callback that handles the RP registration
124 */
125function registerRP(policy, urlPrefix, provider, originalRequest) {
126 var postUrl = urlPrefix + "providers/" + provider + "/register?api-version=2016-02-01";
127 var getUrl = urlPrefix + "providers/" + provider + "?api-version=2016-02-01";
128 var reqOptions = getRequestEssentials(originalRequest);
129 reqOptions.method = "POST";
130 reqOptions.url = postUrl;
131 return policy._nextPolicy.sendRequest(reqOptions).then(function (response) {
132 if (response.status !== 200) {
133 throw new Error("Autoregistration of " + provider + " failed. Please try registering manually.");
134 }
135 return getRegistrationStatus(policy, getUrl, originalRequest);
136 });
137}
138/**
139 * Polls the registration status of the provider that was registered. Polling happens at an interval of 30 seconds.
140 * Polling will happen till the registrationState property of the response body is "Registered".
141 * @param {RPRegistrationPolicy} policy The RPRegistrationPolicy this function is being called against.
142 * @param {string} url The request url for polling
143 * @param {WebResourceLike} originalRequest The original request sent by the user that returned a 409 response
144 * with a message that the provider is not registered.
145 * @returns {Promise<boolean>} True if RP Registration is successful.
146 */
147function getRegistrationStatus(policy, url, originalRequest) {
148 var reqOptions = getRequestEssentials(originalRequest);
149 reqOptions.url = url;
150 reqOptions.method = "GET";
151 return policy._nextPolicy.sendRequest(reqOptions).then(function (res) {
152 var obj = res.parsedBody;
153 if (res.parsedBody && obj.registrationState && obj.registrationState === "Registered") {
154 return true;
155 }
156 else {
157 return utils
158 .delay(policy._retryTimeout * 1000)
159 .then(function () { return getRegistrationStatus(policy, url, originalRequest); });
160 }
161 });
162}
163//# sourceMappingURL=rpRegistrationPolicy.js.map
\No newline at end of file