@microsoft/vscode-azext-azureauth 1.1.2 → 1.2.1

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Build Status](https://dev.azure.com/ms-azuretools/AzCode/_apis/build/status/vscode-azuretools)](https://dev.azure.com/ms-azuretools/AzCode/_build/latest?definitionId=17)
4
4
 
5
- This package provides a simple way to authenticate to Azure and receive Azure subscription information.
5
+ This package provides a simple way to authenticate to Azure and receive Azure subscription information. It uses the [built-in Microsoft Authentication extension](https://github.com/microsoft/vscode/tree/main/extensions/microsoft-authentication) and does not rely on the [Azure Account extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account) in any way.
6
6
 
7
7
  ## Azure Subscription Provider
8
8
 
@@ -13,6 +13,14 @@ The `AzureSubscriptionProvider` interface describes the functions of this packag
13
13
  * An interface for obtaining Azure subscription information
14
14
  */
15
15
  export interface AzureSubscriptionProvider {
16
+ /**
17
+ * Gets a list of tenants available to the user.
18
+ * Use {@link isSignedIn} to check if the user is signed in to a particular tenant.
19
+ *
20
+ * @returns A list of tenants.
21
+ */
22
+ getTenants(): Promise<TenantIdDescription[]>;
23
+
16
24
  /**
17
25
  * Gets a list of Azure subscriptions available to the user.
18
26
  *
@@ -30,16 +38,20 @@ export interface AzureSubscriptionProvider {
30
38
  /**
31
39
  * Checks to see if a user is signed in.
32
40
  *
41
+ * @param tenantId (Optional) Provide to check if a user is signed in to a specific tenant.
42
+ *
33
43
  * @returns True if the user is signed in, false otherwise.
34
44
  */
35
- isSignedIn(): Promise<boolean>;
45
+ isSignedIn(tenantId?: string): Promise<boolean>;
36
46
 
37
47
  /**
38
48
  * Asks the user to sign in or pick an account to use.
39
49
  *
50
+ * @param tenantId (Optional) Provide to sign in to a specific tenant.
51
+ *
40
52
  * @returns True if the user is signed in, false otherwise.
41
53
  */
42
- signIn(): Promise<boolean>;
54
+ signIn(tenantId?: string): Promise<boolean>;
43
55
 
44
56
  /**
45
57
  * An event that is fired when the user signs in. Debounced to fire at most once every 5 seconds.
@@ -88,6 +100,12 @@ export declare function getConfiguredAzureEnv(): azureEnv.Environment & {
88
100
  export declare function setConfiguredAzureEnv(cloud: string | azureEnv.EnvironmentParameters, target?: vscode.ConfigurationTarget): Promise<void>;
89
101
  ```
90
102
 
103
+ ## Logs
104
+
105
+ View the Microsoft Authentication extension logs by running the `Developer: Show Logs...` command from the VS Code command palette.
106
+
107
+ Change the log level by running the `Developer: Set Log Level...` command from the VS Code command palette. Select `Microsoft Authentication` from the list of loggers and then select the desired log level.
108
+
91
109
  ## License
92
110
 
93
111
  [MIT](LICENSE.md)
@@ -1,9 +1,17 @@
1
1
  import type * as vscode from 'vscode';
2
2
  import type { AzureSubscription } from './AzureSubscription';
3
+ import { TenantIdDescription } from '@azure/arm-subscriptions';
3
4
  /**
4
5
  * An interface for obtaining Azure subscription information
5
6
  */
6
7
  export interface AzureSubscriptionProvider {
8
+ /**
9
+ * Gets a list of tenants available to the user.
10
+ * Use {@link isSignedIn} to check if the user is signed in to a particular tenant.
11
+ *
12
+ * @returns A list of tenants.
13
+ */
14
+ getTenants(): Promise<TenantIdDescription[]>;
7
15
  /**
8
16
  * Gets a list of Azure subscriptions available to the user.
9
17
  *
@@ -20,15 +28,19 @@ export interface AzureSubscriptionProvider {
20
28
  /**
21
29
  * Checks to see if a user is signed in.
22
30
  *
31
+ * @param tenantId (Optional) Provide to check if a user is signed in to a specific tenant.
32
+ *
23
33
  * @returns True if the user is signed in, false otherwise.
24
34
  */
25
- isSignedIn(): Promise<boolean>;
35
+ isSignedIn(tenantId?: string): Promise<boolean>;
26
36
  /**
27
37
  * Asks the user to sign in or pick an account to use.
28
38
  *
39
+ * @param tenantId (Optional) Provide to sign in to a specific tenant.
40
+ *
29
41
  * @returns True if the user is signed in, false otherwise.
30
42
  */
31
- signIn(): Promise<boolean>;
43
+ signIn(tenantId?: string): Promise<boolean>;
32
44
  /**
33
45
  * An event that is fired when the user signs in. Debounced to fire at most once every 5 seconds.
34
46
  */
@@ -1,3 +1,4 @@
1
+ import type { TenantIdDescription } from '@azure/arm-subscriptions';
1
2
  import * as vscode from 'vscode';
2
3
  import type { AzureSubscription, SubscriptionId, TenantId } from './AzureSubscription';
3
4
  import type { AzureSubscriptionProvider } from './AzureSubscriptionProvider';
@@ -12,6 +13,13 @@ export declare class VSCodeAzureSubscriptionProvider extends vscode.Disposable i
12
13
  private readonly onDidSignOutEmitter;
13
14
  private lastSignOutEventFired;
14
15
  constructor();
16
+ /**
17
+ * Gets a list of tenants available to the user.
18
+ * Use {@link isSignedIn} to check if the user is signed in to a particular tenant.
19
+ *
20
+ * @returns A list of tenants.
21
+ */
22
+ getTenants(): Promise<TenantIdDescription[]>;
15
23
  /**
16
24
  * Gets a list of Azure subscriptions available to the user.
17
25
  *
@@ -28,15 +36,19 @@ export declare class VSCodeAzureSubscriptionProvider extends vscode.Disposable i
28
36
  /**
29
37
  * Checks to see if a user is signed in.
30
38
  *
39
+ * @param tenantId (Optional) Provide to check if a user is signed in to a specific tenant.
40
+ *
31
41
  * @returns True if the user is signed in, false otherwise.
32
42
  */
33
- isSignedIn(): Promise<boolean>;
43
+ isSignedIn(tenantId?: string): Promise<boolean>;
34
44
  /**
35
45
  * Asks the user to sign in or pick an account to use.
36
46
  *
47
+ * @param tenantId (Optional) Provide to sign in to a specific tenant.
48
+ *
37
49
  * @returns True if the user is signed in, false otherwise.
38
50
  */
39
- signIn(): Promise<boolean>;
51
+ signIn(tenantId?: string): Promise<boolean>;
40
52
  /**
41
53
  * An event that is fired when the user signs in. Debounced to fire at most once every 5 seconds.
42
54
  */
@@ -71,12 +83,6 @@ export declare class VSCodeAzureSubscriptionProvider extends vscode.Disposable i
71
83
  * @returns A list of subscription IDs that are configured in `azureResourceGroups.selectedSubscriptions`.
72
84
  */
73
85
  protected getSubscriptionFilters(): Promise<SubscriptionId[]>;
74
- /**
75
- * Gets the tenants available to a user.
76
- *
77
- * @returns The list of tenants visible to the user.
78
- */
79
- private getTenants;
80
86
  /**
81
87
  * Gets the subscriptions for a given tenant.
82
88
  *
@@ -93,13 +99,16 @@ export declare class VSCodeAzureSubscriptionProvider extends vscode.Disposable i
93
99
  * @returns A client, the credential used by the client, and the authentication function
94
100
  */
95
101
  private getSubscriptionClient;
102
+ private getToken;
96
103
  /**
97
- * Gets a normalized list of scopes
104
+ * Gets a normalized list of scopes. If no scopes are provided, the return value of {@link getDefaultScope} is used.
105
+ *
106
+ * Only supports top-level resource scopes (e.g. http://management.azure.com, http://storage.azure.com) or .default scopes.
107
+ *
108
+ * All resources/scopes will be normalized to the `.default` scope for each resource.
98
109
  *
99
110
  * @param scopes An input scope string, list, or undefined
100
111
  * @param tenantId (Optional) The tenant ID, will be added to the scopes
101
- *
102
- * @returns A list of scopes, with the default scope and (optionally) the tenant scope added
103
112
  */
104
113
  private getScopes;
105
114
  /**
@@ -108,5 +117,5 @@ export declare class VSCodeAzureSubscriptionProvider extends vscode.Disposable i
108
117
  *
109
118
  * @returns The default Azure scopes required
110
119
  */
111
- private getDefaultScopes;
120
+ private getDefaultScope;
112
121
  }
@@ -21,6 +21,7 @@ var __asyncValues = (this && this.__asyncValues) || function (o) {
21
21
  };
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
23
  exports.VSCodeAzureSubscriptionProvider = void 0;
24
+ const cross_fetch_1 = require("cross-fetch");
24
25
  const vscode = require("vscode");
25
26
  const NotSignedInError_1 = require("./NotSignedInError");
26
27
  const configuredAzureEnv_1 = require("./utils/configuredAzureEnv");
@@ -66,6 +67,22 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
66
67
  */
67
68
  this.onDidSignOut = this.onDidSignOutEmitter.event;
68
69
  }
70
+ /**
71
+ * Gets a list of tenants available to the user.
72
+ * Use {@link isSignedIn} to check if the user is signed in to a particular tenant.
73
+ *
74
+ * @returns A list of tenants.
75
+ */
76
+ getTenants() {
77
+ return __awaiter(this, void 0, void 0, function* () {
78
+ const listTenantsResponse = yield (0, cross_fetch_1.default)('https://management.azure.com/tenants?api-version=2022-12-01', {
79
+ headers: {
80
+ Authorization: `Bearer ${yield this.getToken()}`,
81
+ }
82
+ });
83
+ return (yield listTenantsResponse.json()).value;
84
+ });
85
+ }
69
86
  /**
70
87
  * Gets a list of Azure subscriptions available to the user.
71
88
  *
@@ -95,6 +112,10 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
95
112
  if (shouldFilterTenants && !tenantIds.includes(tenantId)) {
96
113
  continue;
97
114
  }
115
+ // If the user is not signed in to this tenant, then skip it
116
+ if (!(yield this.isSignedIn(tenantId))) {
117
+ continue;
118
+ }
98
119
  // For each tenant, get the list of subscriptions
99
120
  for (const subscription of yield this.getSubscriptionsForTenant(tenantId)) {
100
121
  // If filtering is enabled, and the current subscription is not in that list, then skip it
@@ -114,22 +135,26 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
114
135
  /**
115
136
  * Checks to see if a user is signed in.
116
137
  *
138
+ * @param tenantId (Optional) Provide to check if a user is signed in to a specific tenant.
139
+ *
117
140
  * @returns True if the user is signed in, false otherwise.
118
141
  */
119
- isSignedIn() {
142
+ isSignedIn(tenantId) {
120
143
  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 });
144
+ const session = yield vscode.authentication.getSession((0, configuredAzureEnv_1.getConfiguredAuthProviderId)(), this.getScopes([], tenantId), { createIfNone: false, silent: true });
122
145
  return !!session;
123
146
  });
124
147
  }
125
148
  /**
126
149
  * Asks the user to sign in or pick an account to use.
127
150
  *
151
+ * @param tenantId (Optional) Provide to sign in to a specific tenant.
152
+ *
128
153
  * @returns True if the user is signed in, false otherwise.
129
154
  */
130
- signIn() {
155
+ signIn(tenantId) {
131
156
  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 });
157
+ const session = yield vscode.authentication.getSession((0, configuredAzureEnv_1.getConfiguredAuthProviderId)(), this.getScopes([], tenantId), { createIfNone: true, clearSessionPreference: true });
133
158
  return !!session;
134
159
  });
135
160
  }
@@ -173,39 +198,6 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
173
198
  return fullSubscriptionIds.map(id => id.split('/')[1]);
174
199
  });
175
200
  }
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
201
  /**
210
202
  * Gets the subscriptions for a given tenant.
211
203
  *
@@ -214,7 +206,7 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
214
206
  * @returns The list of subscriptions for the tenant.
215
207
  */
216
208
  getSubscriptionsForTenant(tenantId) {
217
- var _a, e_2, _b, _c;
209
+ var _a, e_1, _b, _c;
218
210
  return __awaiter(this, void 0, void 0, function* () {
219
211
  const { client, credential, authentication } = yield this.getSubscriptionClient(tenantId);
220
212
  const environment = (0, configuredAzureEnv_1.getConfiguredAzureEnv)();
@@ -242,12 +234,12 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
242
234
  }
243
235
  }
244
236
  }
245
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
237
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
246
238
  finally {
247
239
  try {
248
240
  if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
249
241
  }
250
- finally { if (e_2) throw e_2.error; }
242
+ finally { if (e_1) throw e_1.error; }
251
243
  }
252
244
  return subscriptions;
253
245
  });
@@ -262,17 +254,17 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
262
254
  getSubscriptionClient(tenantId) {
263
255
  return __awaiter(this, void 0, void 0, function* () {
264
256
  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;
257
+ const getSession = (scopes) => __awaiter(this, void 0, void 0, function* () {
258
+ const session = yield vscode.authentication.getSession((0, configuredAzureEnv_1.getConfiguredAuthProviderId)(), this.getScopes(scopes, tenantId), { createIfNone: false, silent: true });
259
+ if (!session) {
260
+ throw new NotSignedInError_1.NotSignedInError();
261
+ }
262
+ return session;
263
+ });
267
264
  const credential = {
268
265
  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
266
  return {
275
- token: session.accessToken,
267
+ token: (yield getSession(this.getScopes(scopes, tenantId))).accessToken,
276
268
  expiresOnTimestamp: 0
277
269
  };
278
270
  })
@@ -281,28 +273,44 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
281
273
  client: new armSubs.SubscriptionClient(credential),
282
274
  credential: credential,
283
275
  authentication: {
284
- getSession: () => session // Rewrapped to make TS not confused about the weird initialization pattern
276
+ getSession
285
277
  }
286
278
  };
287
279
  });
288
280
  }
281
+ getToken(tenantId) {
282
+ return __awaiter(this, void 0, void 0, function* () {
283
+ const session = yield vscode.authentication.getSession((0, configuredAzureEnv_1.getConfiguredAuthProviderId)(), this.getScopes([], tenantId), { createIfNone: false, silent: true });
284
+ if (!session) {
285
+ throw new NotSignedInError_1.NotSignedInError();
286
+ }
287
+ return session.accessToken;
288
+ });
289
+ }
289
290
  /**
290
- * Gets a normalized list of scopes
291
+ * Gets a normalized list of scopes. If no scopes are provided, the return value of {@link getDefaultScope} is used.
292
+ *
293
+ * Only supports top-level resource scopes (e.g. http://management.azure.com, http://storage.azure.com) or .default scopes.
294
+ *
295
+ * All resources/scopes will be normalized to the `.default` scope for each resource.
291
296
  *
292
297
  * @param scopes An input scope string, list, or undefined
293
298
  * @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
299
  */
297
300
  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));
301
+ if (scopes === undefined || scopes === "" || scopes.length === 0) {
302
+ scopes = this.getDefaultScope();
305
303
  }
304
+ const arrScopes = (Array.isArray(scopes) ? scopes : [scopes])
305
+ .map((scope) => {
306
+ if (scope.endsWith('.default')) {
307
+ return scope;
308
+ }
309
+ else {
310
+ return `${scope}.default`;
311
+ }
312
+ });
313
+ const scopeSet = new Set(arrScopes);
306
314
  if (tenantId) {
307
315
  scopeSet.add(`VSCODE_TENANT:${tenantId}`);
308
316
  }
@@ -314,8 +322,8 @@ class VSCodeAzureSubscriptionProvider extends vscode.Disposable {
314
322
  *
315
323
  * @returns The default Azure scopes required
316
324
  */
317
- getDefaultScopes() {
318
- return [`${(0, configuredAzureEnv_1.getConfiguredAzureEnv)().resourceManagerEndpointUrl}.default`];
325
+ getDefaultScope() {
326
+ return `${(0, configuredAzureEnv_1.getConfiguredAzureEnv)().resourceManagerEndpointUrl}.default`;
319
327
  }
320
328
  }
321
329
  exports.VSCodeAzureSubscriptionProvider = VSCodeAzureSubscriptionProvider;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@microsoft/vscode-azext-azureauth",
3
3
  "author": "Microsoft Corporation",
4
- "version": "1.1.2",
4
+ "version": "1.2.1",
5
5
  "description": "Azure authentication helpers for Visual Studio Code",
6
6
  "tags": [
7
7
  "azure",
@@ -52,6 +52,7 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "@azure/arm-subscriptions": "^5.1.0",
55
- "@azure/ms-rest-azure-env": "^2.0.0"
55
+ "@azure/ms-rest-azure-env": "^2.0.0",
56
+ "cross-fetch": "^4.0.0"
56
57
  }
57
58
  }