@microsoft/vscode-azext-azureauth 1.0.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/src/AzureAuthentication.d.ts +14 -14
- package/out/src/AzureAuthentication.js +6 -6
- package/out/src/AzureSubscription.d.ts +44 -44
- package/out/src/AzureSubscription.js +6 -6
- package/out/src/AzureSubscriptionProvider.d.ts +48 -48
- package/out/src/AzureSubscriptionProvider.js +6 -6
- package/out/src/NotSignedInError.d.ts +15 -15
- package/out/src/NotSignedInError.js +29 -29
- package/out/src/VSCodeAzureSubscriptionProvider.d.ts +112 -112
- package/out/src/VSCodeAzureSubscriptionProvider.js +321 -320
- package/out/src/index.d.ts +6 -6
- package/out/src/index.js +26 -26
- package/out/src/utils/configuredAzureEnv.d.ts +24 -24
- package/out/src/utils/configuredAzureEnv.js +94 -89
- package/package.json +1 -1
|
@@ -1,321 +1,322 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*---------------------------------------------------------------------------------------------
|
|
3
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
-
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
-
*--------------------------------------------------------------------------------------------*/
|
|
6
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
7
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
8
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
9
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
10
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
11
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
12
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
|
-
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
16
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
17
|
-
var m = o[Symbol.asyncIterator], i;
|
|
18
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
19
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
20
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
21
|
-
};
|
|
22
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.VSCodeAzureSubscriptionProvider = void 0;
|
|
24
|
-
const vscode = require("vscode");
|
|
25
|
-
const NotSignedInError_1 = require("./NotSignedInError");
|
|
26
|
-
const configuredAzureEnv_1 = require("./utils/configuredAzureEnv");
|
|
27
|
-
const EventDebounce = 5 * 1000; // 5 seconds
|
|
28
|
-
/**
|
|
29
|
-
* A class for obtaining Azure subscription information using VSCode's built-in authentication
|
|
30
|
-
* provider.
|
|
31
|
-
*/
|
|
32
|
-
class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
|
|
33
|
-
constructor() {
|
|
34
|
-
const disposable = vscode.authentication.onDidChangeSessions((e) => __awaiter(this, void 0, void 0, function* () {
|
|
35
|
-
// Ignore any sign in that isn't for the configured auth provider
|
|
36
|
-
if (e.provider.id !== (0, configuredAzureEnv_1.getConfiguredAuthProviderId)()) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (yield this.isSignedIn()) {
|
|
40
|
-
if (!this.suppressSignInEvents && Date.now() > this.lastSignInEventFired + EventDebounce) {
|
|
41
|
-
this.lastSignInEventFired = Date.now();
|
|
42
|
-
this.onDidSignInEmitter.fire();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
else if (Date.now() > this.lastSignOutEventFired + EventDebounce) {
|
|
46
|
-
this.lastSignOutEventFired = Date.now();
|
|
47
|
-
this.onDidSignOutEmitter.fire();
|
|
48
|
-
}
|
|
49
|
-
}));
|
|
50
|
-
super(() => {
|
|
51
|
-
this.onDidSignInEmitter.dispose();
|
|
52
|
-
this.onDidSignOutEmitter.dispose();
|
|
53
|
-
disposable.dispose();
|
|
54
|
-
});
|
|
55
|
-
this.onDidSignInEmitter = new vscode.EventEmitter();
|
|
56
|
-
this.lastSignInEventFired = 0;
|
|
57
|
-
this.suppressSignInEvents = false;
|
|
58
|
-
this.onDidSignOutEmitter = new vscode.EventEmitter();
|
|
59
|
-
this.lastSignOutEventFired = 0;
|
|
60
|
-
/**
|
|
61
|
-
* An event that is fired when the user signs in. Debounced to fire at most once every 5 seconds.
|
|
62
|
-
*/
|
|
63
|
-
this.onDidSignIn = this.onDidSignInEmitter.event;
|
|
64
|
-
/**
|
|
65
|
-
* An event that is fired when the user signs out. Debounced to fire at most once every 5 seconds.
|
|
66
|
-
*/
|
|
67
|
-
this.onDidSignOut = this.onDidSignOutEmitter.event;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Gets a list of Azure subscriptions available to the user.
|
|
71
|
-
*
|
|
72
|
-
* @param filter - Whether to filter the list returned, according to the list returned
|
|
73
|
-
* by `getTenantFilters()` and `getSubscriptionFilters()`. Optional, default true.
|
|
74
|
-
*
|
|
75
|
-
* @returns A list of Azure subscriptions.
|
|
76
|
-
*
|
|
77
|
-
* @throws A {@link NotSignedInError} If the user is not signed in to Azure.
|
|
78
|
-
* Use {@link isSignedIn} and/or {@link signIn} before this method to ensure
|
|
79
|
-
* the user is signed in.
|
|
80
|
-
*/
|
|
81
|
-
getSubscriptions(filter = true) {
|
|
82
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
-
const tenantIds = yield this.getTenantFilters();
|
|
84
|
-
const
|
|
85
|
-
const subscriptionIds = yield this.getSubscriptionFilters();
|
|
86
|
-
const
|
|
87
|
-
const results = [];
|
|
88
|
-
try {
|
|
89
|
-
this.suppressSignInEvents = true;
|
|
90
|
-
// Get the list of tenants
|
|
91
|
-
for (const tenant of yield this.getTenants()) {
|
|
92
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
93
|
-
const tenantId = tenant.tenantId;
|
|
94
|
-
// If filtering is enabled, and the current tenant is not in that list, then skip it
|
|
95
|
-
if (
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
// For each tenant, get the list of subscriptions
|
|
99
|
-
for (const subscription of yield this.getSubscriptionsForTenant(tenantId)) {
|
|
100
|
-
// If filtering is enabled, and the current subscription is not in that list, then skip it
|
|
101
|
-
if (
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
results.push(subscription);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
finally {
|
|
109
|
-
this.suppressSignInEvents = false;
|
|
110
|
-
}
|
|
111
|
-
return results;
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Checks to see if a user is signed in.
|
|
116
|
-
*
|
|
117
|
-
* @returns True if the user is signed in, false otherwise.
|
|
118
|
-
*/
|
|
119
|
-
isSignedIn() {
|
|
120
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
121
|
-
const session = yield vscode.authentication.getSession((0, configuredAzureEnv_1.getConfiguredAuthProviderId)(), this.getDefaultScopes(), { createIfNone: false, silent: true });
|
|
122
|
-
return !!session;
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Asks the user to sign in or pick an account to use.
|
|
127
|
-
*
|
|
128
|
-
* @returns True if the user is signed in, false otherwise.
|
|
129
|
-
*/
|
|
130
|
-
signIn() {
|
|
131
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
132
|
-
const session = yield vscode.authentication.getSession((0, configuredAzureEnv_1.getConfiguredAuthProviderId)(), this.getDefaultScopes(), { createIfNone: true, clearSessionPreference: true });
|
|
133
|
-
return !!session;
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Signs the user out
|
|
138
|
-
*
|
|
139
|
-
* @deprecated Not currently supported by VS Code auth providers
|
|
140
|
-
*/
|
|
141
|
-
signOut() {
|
|
142
|
-
throw new Error(vscode.l10n.t('Signing out programmatically is not supported. You must sign out by selecting the account in the Accounts menu and choosing Sign Out.'));
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Gets the tenant filters that are configured in `azureResourceGroups.selectedSubscriptions`. To
|
|
146
|
-
* override the settings with a custom filter, implement a child class with `getSubscriptionFilters()`
|
|
147
|
-
* and/or `getTenantFilters()` overridden.
|
|
148
|
-
*
|
|
149
|
-
* If no values are returned by `getTenantFilters()`, then all tenants will be scanned for subscriptions.
|
|
150
|
-
*
|
|
151
|
-
* @returns A list of tenant IDs that are configured in `azureResourceGroups.selectedSubscriptions`.
|
|
152
|
-
*/
|
|
153
|
-
getTenantFilters() {
|
|
154
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
155
|
-
const config = vscode.workspace.getConfiguration('azureResourceGroups');
|
|
156
|
-
const fullSubscriptionIds = config.get('selectedSubscriptions', []);
|
|
157
|
-
return fullSubscriptionIds.map(id => id.split('/')[0]);
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Gets the subscription filters that are configured in `azureResourceGroups.selectedSubscriptions`. To
|
|
162
|
-
* override the settings with a custom filter, implement a child class with `getSubscriptionFilters()`
|
|
163
|
-
* and/or `getTenantFilters()` overridden.
|
|
164
|
-
*
|
|
165
|
-
* If no values are returned by `getSubscriptionFilters()`, then all subscriptions will be returned.
|
|
166
|
-
*
|
|
167
|
-
* @returns A list of subscription IDs that are configured in `azureResourceGroups.selectedSubscriptions`.
|
|
168
|
-
*/
|
|
169
|
-
getSubscriptionFilters() {
|
|
170
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
171
|
-
const config = vscode.workspace.getConfiguration('azureResourceGroups');
|
|
172
|
-
const fullSubscriptionIds = config.get('selectedSubscriptions', []);
|
|
173
|
-
return fullSubscriptionIds.map(id => id.split('/')[1]);
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Gets the tenants available to a user.
|
|
178
|
-
*
|
|
179
|
-
* @returns The list of tenants visible to the user.
|
|
180
|
-
*/
|
|
181
|
-
getTenants() {
|
|
182
|
-
var _a, e_1, _b, _c;
|
|
183
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
184
|
-
const { client } = yield this.getSubscriptionClient();
|
|
185
|
-
const tenants = [];
|
|
186
|
-
try {
|
|
187
|
-
for (var _d = true, _e = __asyncValues(client.tenants.list()), _f; _f = yield _e.next(), _a = _f.done, !_a;) {
|
|
188
|
-
_c = _f.value;
|
|
189
|
-
_d = false;
|
|
190
|
-
try {
|
|
191
|
-
const tenant = _c;
|
|
192
|
-
tenants.push(tenant);
|
|
193
|
-
}
|
|
194
|
-
finally {
|
|
195
|
-
_d = true;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
200
|
-
finally {
|
|
201
|
-
try {
|
|
202
|
-
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
|
203
|
-
}
|
|
204
|
-
finally { if (e_1) throw e_1.error; }
|
|
205
|
-
}
|
|
206
|
-
return tenants;
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Gets the subscriptions for a given tenant.
|
|
211
|
-
*
|
|
212
|
-
* @param tenantId The tenant ID to get subscriptions for.
|
|
213
|
-
*
|
|
214
|
-
* @returns The list of subscriptions for the tenant.
|
|
215
|
-
*/
|
|
216
|
-
getSubscriptionsForTenant(tenantId) {
|
|
217
|
-
var _a, e_2, _b, _c;
|
|
218
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
219
|
-
const { client, credential, authentication } = yield this.getSubscriptionClient(tenantId);
|
|
220
|
-
const environment = (0, configuredAzureEnv_1.getConfiguredAzureEnv)();
|
|
221
|
-
const subscriptions = [];
|
|
222
|
-
try {
|
|
223
|
-
for (var _d = true, _e = __asyncValues(client.subscriptions.list()), _f; _f = yield _e.next(), _a = _f.done, !_a;) {
|
|
224
|
-
_c = _f.value;
|
|
225
|
-
_d = false;
|
|
226
|
-
try {
|
|
227
|
-
const subscription = _c;
|
|
228
|
-
subscriptions.push({
|
|
229
|
-
authentication: authentication,
|
|
230
|
-
environment: environment,
|
|
231
|
-
credential: credential,
|
|
232
|
-
isCustomCloud: environment.isCustomCloud,
|
|
233
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
234
|
-
name: subscription.displayName,
|
|
235
|
-
subscriptionId: subscription.subscriptionId,
|
|
236
|
-
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
|
237
|
-
tenantId: tenantId,
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
finally {
|
|
241
|
-
_d = true;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
246
|
-
finally {
|
|
247
|
-
try {
|
|
248
|
-
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
|
249
|
-
}
|
|
250
|
-
finally { if (e_2) throw e_2.error; }
|
|
251
|
-
}
|
|
252
|
-
return subscriptions;
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Gets a fully-configured subscription client for a given tenant ID
|
|
257
|
-
*
|
|
258
|
-
* @param tenantId (Optional) The tenant ID to get a client for
|
|
259
|
-
*
|
|
260
|
-
* @returns A client, the credential used by the client, and the authentication function
|
|
261
|
-
*/
|
|
262
|
-
getSubscriptionClient(tenantId) {
|
|
263
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
264
|
-
const armSubs = yield Promise.resolve().then(() => require('@azure/arm-subscriptions'));
|
|
265
|
-
// This gets filled in when the client calls `getToken`, and then it can be returned in the `authentication` property of `AzureSubscription`
|
|
266
|
-
let session;
|
|
267
|
-
const credential = {
|
|
268
|
-
getToken: (scopes) => __awaiter(this, void 0, void 0, function* () {
|
|
269
|
-
// TODO: change to `getSessions` when that API is available: https://github.com/microsoft/vscode/issues/152399
|
|
270
|
-
session = yield vscode.authentication.getSession((0, configuredAzureEnv_1.getConfiguredAuthProviderId)(), this.getScopes(scopes, tenantId), { createIfNone: false, silent: true });
|
|
271
|
-
if (!session) {
|
|
272
|
-
throw new NotSignedInError_1.NotSignedInError();
|
|
273
|
-
}
|
|
274
|
-
return {
|
|
275
|
-
token: session.accessToken,
|
|
276
|
-
expiresOnTimestamp: 0
|
|
277
|
-
};
|
|
278
|
-
})
|
|
279
|
-
};
|
|
280
|
-
return {
|
|
281
|
-
client: new armSubs.SubscriptionClient(credential),
|
|
282
|
-
credential: credential,
|
|
283
|
-
authentication: {
|
|
284
|
-
getSession: () => session // Rewrapped to make TS not confused about the weird initialization pattern
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Gets a normalized list of scopes
|
|
291
|
-
*
|
|
292
|
-
* @param scopes An input scope string, list, or undefined
|
|
293
|
-
* @param tenantId (Optional) The tenant ID, will be added to the scopes
|
|
294
|
-
*
|
|
295
|
-
* @returns A list of scopes, with the default scope and (optionally) the tenant scope added
|
|
296
|
-
*/
|
|
297
|
-
getScopes(scopes, tenantId) {
|
|
298
|
-
const scopeSet = new Set(this.getDefaultScopes());
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}
|
|
320
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
7
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
8
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
9
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
10
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
11
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
12
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
16
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
17
|
+
var m = o[Symbol.asyncIterator], i;
|
|
18
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
19
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
20
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.VSCodeAzureSubscriptionProvider = void 0;
|
|
24
|
+
const vscode = require("vscode");
|
|
25
|
+
const NotSignedInError_1 = require("./NotSignedInError");
|
|
26
|
+
const configuredAzureEnv_1 = require("./utils/configuredAzureEnv");
|
|
27
|
+
const EventDebounce = 5 * 1000; // 5 seconds
|
|
28
|
+
/**
|
|
29
|
+
* A class for obtaining Azure subscription information using VSCode's built-in authentication
|
|
30
|
+
* provider.
|
|
31
|
+
*/
|
|
32
|
+
class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
|
|
33
|
+
constructor() {
|
|
34
|
+
const disposable = vscode.authentication.onDidChangeSessions((e) => __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
// Ignore any sign in that isn't for the configured auth provider
|
|
36
|
+
if (e.provider.id !== (0, configuredAzureEnv_1.getConfiguredAuthProviderId)()) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (yield this.isSignedIn()) {
|
|
40
|
+
if (!this.suppressSignInEvents && Date.now() > this.lastSignInEventFired + EventDebounce) {
|
|
41
|
+
this.lastSignInEventFired = Date.now();
|
|
42
|
+
this.onDidSignInEmitter.fire();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else if (Date.now() > this.lastSignOutEventFired + EventDebounce) {
|
|
46
|
+
this.lastSignOutEventFired = Date.now();
|
|
47
|
+
this.onDidSignOutEmitter.fire();
|
|
48
|
+
}
|
|
49
|
+
}));
|
|
50
|
+
super(() => {
|
|
51
|
+
this.onDidSignInEmitter.dispose();
|
|
52
|
+
this.onDidSignOutEmitter.dispose();
|
|
53
|
+
disposable.dispose();
|
|
54
|
+
});
|
|
55
|
+
this.onDidSignInEmitter = new vscode.EventEmitter();
|
|
56
|
+
this.lastSignInEventFired = 0;
|
|
57
|
+
this.suppressSignInEvents = false;
|
|
58
|
+
this.onDidSignOutEmitter = new vscode.EventEmitter();
|
|
59
|
+
this.lastSignOutEventFired = 0;
|
|
60
|
+
/**
|
|
61
|
+
* An event that is fired when the user signs in. Debounced to fire at most once every 5 seconds.
|
|
62
|
+
*/
|
|
63
|
+
this.onDidSignIn = this.onDidSignInEmitter.event;
|
|
64
|
+
/**
|
|
65
|
+
* An event that is fired when the user signs out. Debounced to fire at most once every 5 seconds.
|
|
66
|
+
*/
|
|
67
|
+
this.onDidSignOut = this.onDidSignOutEmitter.event;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Gets a list of Azure subscriptions available to the user.
|
|
71
|
+
*
|
|
72
|
+
* @param filter - Whether to filter the list returned, according to the list returned
|
|
73
|
+
* by `getTenantFilters()` and `getSubscriptionFilters()`. Optional, default true.
|
|
74
|
+
*
|
|
75
|
+
* @returns A list of Azure subscriptions.
|
|
76
|
+
*
|
|
77
|
+
* @throws A {@link NotSignedInError} If the user is not signed in to Azure.
|
|
78
|
+
* Use {@link isSignedIn} and/or {@link signIn} before this method to ensure
|
|
79
|
+
* the user is signed in.
|
|
80
|
+
*/
|
|
81
|
+
getSubscriptions(filter = true) {
|
|
82
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
+
const tenantIds = yield this.getTenantFilters();
|
|
84
|
+
const shouldFilterTenants = filter && !!tenantIds.length; // If the list is empty it is treated as "no filter"
|
|
85
|
+
const subscriptionIds = yield this.getSubscriptionFilters();
|
|
86
|
+
const shouldFilterSubscriptions = filter && !!subscriptionIds.length; // If the list is empty it is treated as "no filter"
|
|
87
|
+
const results = [];
|
|
88
|
+
try {
|
|
89
|
+
this.suppressSignInEvents = true;
|
|
90
|
+
// Get the list of tenants
|
|
91
|
+
for (const tenant of yield this.getTenants()) {
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
93
|
+
const tenantId = tenant.tenantId;
|
|
94
|
+
// If filtering is enabled, and the current tenant is not in that list, then skip it
|
|
95
|
+
if (shouldFilterTenants && !tenantIds.includes(tenantId)) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
// For each tenant, get the list of subscriptions
|
|
99
|
+
for (const subscription of yield this.getSubscriptionsForTenant(tenantId)) {
|
|
100
|
+
// If filtering is enabled, and the current subscription is not in that list, then skip it
|
|
101
|
+
if (shouldFilterSubscriptions && !subscriptionIds.includes(subscription.subscriptionId)) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
results.push(subscription);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
this.suppressSignInEvents = false;
|
|
110
|
+
}
|
|
111
|
+
return results.sort((a, b) => a.name.localeCompare(b.name));
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Checks to see if a user is signed in.
|
|
116
|
+
*
|
|
117
|
+
* @returns True if the user is signed in, false otherwise.
|
|
118
|
+
*/
|
|
119
|
+
isSignedIn() {
|
|
120
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
121
|
+
const session = yield vscode.authentication.getSession((0, configuredAzureEnv_1.getConfiguredAuthProviderId)(), this.getDefaultScopes(), { createIfNone: false, silent: true });
|
|
122
|
+
return !!session;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Asks the user to sign in or pick an account to use.
|
|
127
|
+
*
|
|
128
|
+
* @returns True if the user is signed in, false otherwise.
|
|
129
|
+
*/
|
|
130
|
+
signIn() {
|
|
131
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
132
|
+
const session = yield vscode.authentication.getSession((0, configuredAzureEnv_1.getConfiguredAuthProviderId)(), this.getDefaultScopes(), { createIfNone: true, clearSessionPreference: true });
|
|
133
|
+
return !!session;
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Signs the user out
|
|
138
|
+
*
|
|
139
|
+
* @deprecated Not currently supported by VS Code auth providers
|
|
140
|
+
*/
|
|
141
|
+
signOut() {
|
|
142
|
+
throw new Error(vscode.l10n.t('Signing out programmatically is not supported. You must sign out by selecting the account in the Accounts menu and choosing Sign Out.'));
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Gets the tenant filters that are configured in `azureResourceGroups.selectedSubscriptions`. To
|
|
146
|
+
* override the settings with a custom filter, implement a child class with `getSubscriptionFilters()`
|
|
147
|
+
* and/or `getTenantFilters()` overridden.
|
|
148
|
+
*
|
|
149
|
+
* If no values are returned by `getTenantFilters()`, then all tenants will be scanned for subscriptions.
|
|
150
|
+
*
|
|
151
|
+
* @returns A list of tenant IDs that are configured in `azureResourceGroups.selectedSubscriptions`.
|
|
152
|
+
*/
|
|
153
|
+
getTenantFilters() {
|
|
154
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
155
|
+
const config = vscode.workspace.getConfiguration('azureResourceGroups');
|
|
156
|
+
const fullSubscriptionIds = config.get('selectedSubscriptions', []);
|
|
157
|
+
return fullSubscriptionIds.map(id => id.split('/')[0]);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Gets the subscription filters that are configured in `azureResourceGroups.selectedSubscriptions`. To
|
|
162
|
+
* override the settings with a custom filter, implement a child class with `getSubscriptionFilters()`
|
|
163
|
+
* and/or `getTenantFilters()` overridden.
|
|
164
|
+
*
|
|
165
|
+
* If no values are returned by `getSubscriptionFilters()`, then all subscriptions will be returned.
|
|
166
|
+
*
|
|
167
|
+
* @returns A list of subscription IDs that are configured in `azureResourceGroups.selectedSubscriptions`.
|
|
168
|
+
*/
|
|
169
|
+
getSubscriptionFilters() {
|
|
170
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
171
|
+
const config = vscode.workspace.getConfiguration('azureResourceGroups');
|
|
172
|
+
const fullSubscriptionIds = config.get('selectedSubscriptions', []);
|
|
173
|
+
return fullSubscriptionIds.map(id => id.split('/')[1]);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Gets the tenants available to a user.
|
|
178
|
+
*
|
|
179
|
+
* @returns The list of tenants visible to the user.
|
|
180
|
+
*/
|
|
181
|
+
getTenants() {
|
|
182
|
+
var _a, e_1, _b, _c;
|
|
183
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
184
|
+
const { client } = yield this.getSubscriptionClient();
|
|
185
|
+
const tenants = [];
|
|
186
|
+
try {
|
|
187
|
+
for (var _d = true, _e = __asyncValues(client.tenants.list()), _f; _f = yield _e.next(), _a = _f.done, !_a;) {
|
|
188
|
+
_c = _f.value;
|
|
189
|
+
_d = false;
|
|
190
|
+
try {
|
|
191
|
+
const tenant = _c;
|
|
192
|
+
tenants.push(tenant);
|
|
193
|
+
}
|
|
194
|
+
finally {
|
|
195
|
+
_d = true;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
200
|
+
finally {
|
|
201
|
+
try {
|
|
202
|
+
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
|
203
|
+
}
|
|
204
|
+
finally { if (e_1) throw e_1.error; }
|
|
205
|
+
}
|
|
206
|
+
return tenants;
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Gets the subscriptions for a given tenant.
|
|
211
|
+
*
|
|
212
|
+
* @param tenantId The tenant ID to get subscriptions for.
|
|
213
|
+
*
|
|
214
|
+
* @returns The list of subscriptions for the tenant.
|
|
215
|
+
*/
|
|
216
|
+
getSubscriptionsForTenant(tenantId) {
|
|
217
|
+
var _a, e_2, _b, _c;
|
|
218
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
219
|
+
const { client, credential, authentication } = yield this.getSubscriptionClient(tenantId);
|
|
220
|
+
const environment = (0, configuredAzureEnv_1.getConfiguredAzureEnv)();
|
|
221
|
+
const subscriptions = [];
|
|
222
|
+
try {
|
|
223
|
+
for (var _d = true, _e = __asyncValues(client.subscriptions.list()), _f; _f = yield _e.next(), _a = _f.done, !_a;) {
|
|
224
|
+
_c = _f.value;
|
|
225
|
+
_d = false;
|
|
226
|
+
try {
|
|
227
|
+
const subscription = _c;
|
|
228
|
+
subscriptions.push({
|
|
229
|
+
authentication: authentication,
|
|
230
|
+
environment: environment,
|
|
231
|
+
credential: credential,
|
|
232
|
+
isCustomCloud: environment.isCustomCloud,
|
|
233
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
234
|
+
name: subscription.displayName,
|
|
235
|
+
subscriptionId: subscription.subscriptionId,
|
|
236
|
+
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
|
237
|
+
tenantId: tenantId,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
finally {
|
|
241
|
+
_d = true;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
246
|
+
finally {
|
|
247
|
+
try {
|
|
248
|
+
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
|
249
|
+
}
|
|
250
|
+
finally { if (e_2) throw e_2.error; }
|
|
251
|
+
}
|
|
252
|
+
return subscriptions;
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Gets a fully-configured subscription client for a given tenant ID
|
|
257
|
+
*
|
|
258
|
+
* @param tenantId (Optional) The tenant ID to get a client for
|
|
259
|
+
*
|
|
260
|
+
* @returns A client, the credential used by the client, and the authentication function
|
|
261
|
+
*/
|
|
262
|
+
getSubscriptionClient(tenantId) {
|
|
263
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
264
|
+
const armSubs = yield Promise.resolve().then(() => require('@azure/arm-subscriptions'));
|
|
265
|
+
// This gets filled in when the client calls `getToken`, and then it can be returned in the `authentication` property of `AzureSubscription`
|
|
266
|
+
let session;
|
|
267
|
+
const credential = {
|
|
268
|
+
getToken: (scopes) => __awaiter(this, void 0, void 0, function* () {
|
|
269
|
+
// TODO: if possible, change to `getSessions` when that API is available: https://github.com/microsoft/vscode/issues/152399
|
|
270
|
+
session = yield vscode.authentication.getSession((0, configuredAzureEnv_1.getConfiguredAuthProviderId)(), this.getScopes(scopes, tenantId), { createIfNone: false, silent: true });
|
|
271
|
+
if (!session) {
|
|
272
|
+
throw new NotSignedInError_1.NotSignedInError();
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
token: session.accessToken,
|
|
276
|
+
expiresOnTimestamp: 0
|
|
277
|
+
};
|
|
278
|
+
})
|
|
279
|
+
};
|
|
280
|
+
return {
|
|
281
|
+
client: new armSubs.SubscriptionClient(credential),
|
|
282
|
+
credential: credential,
|
|
283
|
+
authentication: {
|
|
284
|
+
getSession: () => session // Rewrapped to make TS not confused about the weird initialization pattern
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Gets a normalized list of scopes
|
|
291
|
+
*
|
|
292
|
+
* @param scopes An input scope string, list, or undefined
|
|
293
|
+
* @param tenantId (Optional) The tenant ID, will be added to the scopes
|
|
294
|
+
*
|
|
295
|
+
* @returns A list of scopes, with the default scope and (optionally) the tenant scope added
|
|
296
|
+
*/
|
|
297
|
+
getScopes(scopes, tenantId) {
|
|
298
|
+
const scopeSet = new Set(this.getDefaultScopes());
|
|
299
|
+
// If `.default` is passed in, it will be ignored, in favor of the correct default added by `getDefaultScopes`
|
|
300
|
+
if (typeof scopes === 'string' && scopes !== '.default') {
|
|
301
|
+
scopeSet.add(scopes);
|
|
302
|
+
}
|
|
303
|
+
else if (Array.isArray(scopes)) {
|
|
304
|
+
scopes.filter(scope => scope !== '.default').forEach(scope => scopeSet.add(scope));
|
|
305
|
+
}
|
|
306
|
+
if (tenantId) {
|
|
307
|
+
scopeSet.add(`VSCODE_TENANT:${tenantId}`);
|
|
308
|
+
}
|
|
309
|
+
return Array.from(scopeSet);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Gets the default Azure scopes required for resource management,
|
|
313
|
+
* depending on the configured endpoint
|
|
314
|
+
*
|
|
315
|
+
* @returns The default Azure scopes required
|
|
316
|
+
*/
|
|
317
|
+
getDefaultScopes() {
|
|
318
|
+
return [`${(0, configuredAzureEnv_1.getConfiguredAzureEnv)().resourceManagerEndpointUrl}.default`];
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
exports.VSCodeAzureSubscriptionProvider = VSCodeAzureSubscriptionProvider;
|
|
321
322
|
//# sourceMappingURL=VSCodeAzureSubscriptionProvider.js.map
|