@microsoft/vscode-azext-azureauth 5.1.1 → 6.0.0-alpha.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/CHANGELOG.md +8 -0
- package/README.md +9 -79
- package/dist/cjs/src/contracts/AzureAccount.js +7 -0
- package/dist/cjs/src/contracts/AzureSubscriptionProviderRequestOptions.js +48 -0
- package/dist/cjs/src/index.js +13 -10
- package/dist/cjs/src/providers/AzureDevOpsSubscriptionProvider.js +178 -0
- package/dist/cjs/src/providers/AzureSubscriptionProviderBase.js +393 -0
- package/dist/cjs/src/providers/VSCodeAzureSubscriptionProvider.js +269 -0
- package/dist/cjs/src/utils/Limiter.js +41 -0
- package/dist/cjs/src/{NotSignedInError.js → utils/NotSignedInError.js} +3 -2
- package/dist/cjs/src/utils/configuredAzureEnv.js +14 -16
- package/dist/cjs/src/utils/dedupeSubscriptions.js +27 -0
- package/dist/cjs/src/utils/getMetricsForTelemetry.js +47 -0
- package/dist/cjs/src/{getSessionFromVSCode.js → utils/getSessionFromVSCode.js} +5 -2
- package/dist/cjs/src/utils/getSignalForToken.js +29 -0
- package/dist/cjs/src/utils/map/CaselessMap.js +71 -0
- package/dist/cjs/src/utils/map/TwoKeyCaselessMap.js +194 -0
- package/dist/cjs/src/utils/screen.js +62 -0
- package/dist/cjs/src/{signInToTenant.js → utils/signInToTenant.js} +15 -13
- package/dist/cjs/src/utils/tryGetTokenExpiration.js +25 -0
- package/dist/esm/src/contracts/AzureAccount.d.ts +5 -0
- package/dist/esm/src/contracts/AzureAccount.js +6 -0
- package/dist/esm/src/{AzureAuthentication.d.ts → contracts/AzureAuthentication.d.ts} +1 -1
- package/dist/esm/src/{AzureSubscription.d.ts → contracts/AzureSubscription.d.ts} +4 -4
- package/dist/esm/src/contracts/AzureSubscriptionProvider.d.ts +112 -0
- package/dist/esm/src/contracts/AzureSubscriptionProviderRequestOptions.d.ts +103 -0
- package/dist/esm/src/contracts/AzureSubscriptionProviderRequestOptions.js +44 -0
- package/dist/esm/src/contracts/AzureTenant.d.ts +15 -0
- package/dist/esm/src/index.d.ts +13 -10
- package/dist/esm/src/index.js +13 -10
- package/dist/esm/src/providers/AzureDevOpsSubscriptionProvider.d.ts +68 -0
- package/dist/esm/src/providers/AzureDevOpsSubscriptionProvider.js +140 -0
- package/dist/esm/src/providers/AzureSubscriptionProviderBase.d.ts +74 -0
- package/dist/esm/src/providers/AzureSubscriptionProviderBase.js +356 -0
- package/dist/esm/src/providers/VSCodeAzureSubscriptionProvider.d.ts +70 -0
- package/dist/esm/src/providers/VSCodeAzureSubscriptionProvider.js +232 -0
- package/dist/esm/src/utils/Limiter.d.ts +9 -0
- package/dist/esm/src/utils/Limiter.js +37 -0
- package/dist/esm/src/{NotSignedInError.d.ts → utils/NotSignedInError.d.ts} +2 -2
- package/dist/esm/src/{NotSignedInError.js → utils/NotSignedInError.js} +3 -2
- package/dist/esm/src/utils/configuredAzureEnv.d.ts +7 -4
- package/dist/esm/src/utils/configuredAzureEnv.js +14 -16
- package/dist/esm/src/utils/dedupeSubscriptions.d.ts +14 -0
- package/dist/esm/src/utils/dedupeSubscriptions.js +24 -0
- package/dist/esm/src/utils/getMetricsForTelemetry.d.ts +32 -0
- package/dist/esm/src/utils/getMetricsForTelemetry.js +44 -0
- package/dist/esm/src/{getSessionFromVSCode.js → utils/getSessionFromVSCode.js} +5 -2
- package/dist/esm/src/utils/getSignalForToken.d.ts +7 -0
- package/dist/esm/src/utils/getSignalForToken.js +26 -0
- package/dist/esm/src/utils/map/CaselessMap.d.ts +28 -0
- package/dist/esm/src/utils/map/CaselessMap.js +67 -0
- package/dist/esm/src/utils/map/TwoKeyCaselessMap.d.ts +49 -0
- package/dist/esm/src/utils/map/TwoKeyCaselessMap.js +190 -0
- package/dist/esm/src/utils/screen.d.ts +9 -0
- package/dist/esm/src/utils/screen.js +59 -0
- package/dist/esm/src/utils/signInToTenant.d.ts +7 -0
- package/dist/esm/src/{signInToTenant.js → utils/signInToTenant.js} +16 -14
- package/dist/esm/src/utils/tryGetTokenExpiration.d.ts +2 -0
- package/dist/esm/src/utils/tryGetTokenExpiration.js +22 -0
- package/package.json +33 -23
- package/AzureFederatedCredentialsGuide.md +0 -174
- package/dist/cjs/src/AzureDevOpsSubscriptionProvider.js +0 -215
- package/dist/cjs/src/VSCodeAzureSubscriptionProvider.js +0 -395
- package/dist/cjs/src/utils/getUnauthenticatedTenants.js +0 -23
- package/dist/cjs/src/utils/isGetSubscriptionsFilter.js +0 -27
- package/dist/esm/src/AzureDevOpsSubscriptionProvider.d.ts +0 -68
- package/dist/esm/src/AzureDevOpsSubscriptionProvider.js +0 -210
- package/dist/esm/src/AzureSubscriptionProvider.d.ts +0 -82
- package/dist/esm/src/AzureTenant.d.ts +0 -5
- package/dist/esm/src/VSCodeAzureSubscriptionProvider.d.ts +0 -116
- package/dist/esm/src/VSCodeAzureSubscriptionProvider.js +0 -358
- package/dist/esm/src/signInToTenant.d.ts +0 -6
- package/dist/esm/src/utils/getUnauthenticatedTenants.d.ts +0 -9
- package/dist/esm/src/utils/getUnauthenticatedTenants.js +0 -20
- package/dist/esm/src/utils/isGetSubscriptionsFilter.d.ts +0 -14
- package/dist/esm/src/utils/isGetSubscriptionsFilter.js +0 -23
- /package/dist/cjs/src/{AzureAuthentication.js → contracts/AzureAuthentication.js} +0 -0
- /package/dist/cjs/src/{AzureSubscription.js → contracts/AzureSubscription.js} +0 -0
- /package/dist/cjs/src/{AzureSubscriptionProvider.js → contracts/AzureSubscriptionProvider.js} +0 -0
- /package/dist/cjs/src/{AzureTenant.js → contracts/AzureTenant.js} +0 -0
- /package/dist/esm/src/{AzureAuthentication.js → contracts/AzureAuthentication.js} +0 -0
- /package/dist/esm/src/{AzureSubscription.js → contracts/AzureSubscription.js} +0 -0
- /package/dist/esm/src/{AzureSubscriptionProvider.js → contracts/AzureSubscriptionProvider.js} +0 -0
- /package/dist/esm/src/{AzureTenant.js → contracts/AzureTenant.js} +0 -0
- /package/dist/esm/src/{getSessionFromVSCode.d.ts → utils/getSessionFromVSCode.d.ts} +0 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { TokenCredential } from '@azure/core-auth';
|
|
2
2
|
import type { Environment } from '@azure/ms-rest-azure-env';
|
|
3
|
-
import type
|
|
3
|
+
import type { AzureAccount } from './AzureAccount';
|
|
4
4
|
import type { AzureAuthentication } from './AzureAuthentication';
|
|
5
5
|
/**
|
|
6
6
|
* A type representing an Azure subscription ID, not including the tenant ID.
|
|
7
7
|
*/
|
|
8
|
-
export type SubscriptionId = string
|
|
8
|
+
export type SubscriptionId = Readonly<string>;
|
|
9
9
|
/**
|
|
10
10
|
* A type representing an Azure tenant ID.
|
|
11
11
|
*/
|
|
12
|
-
export type TenantId = string
|
|
12
|
+
export type TenantId = Readonly<string>;
|
|
13
13
|
/**
|
|
14
14
|
* Represents an Azure subscription.
|
|
15
15
|
*/
|
|
@@ -45,5 +45,5 @@ export interface AzureSubscription {
|
|
|
45
45
|
/**
|
|
46
46
|
* The account associated with this subscription.
|
|
47
47
|
*/
|
|
48
|
-
readonly account:
|
|
48
|
+
readonly account: AzureAccount;
|
|
49
49
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type * as vscode from 'vscode';
|
|
2
|
+
import type { AzureAccount } from './AzureAccount';
|
|
3
|
+
import type { AzureSubscription } from './AzureSubscription';
|
|
4
|
+
import type { GetAccountsOptions, GetAvailableSubscriptionsOptions, GetSubscriptionsForTenantOptions, GetTenantsForAccountOptions, SignInOptions } from './AzureSubscriptionProviderRequestOptions';
|
|
5
|
+
import type { AzureTenant } from './AzureTenant';
|
|
6
|
+
/**
|
|
7
|
+
* An interface for obtaining Azure subscription information
|
|
8
|
+
*/
|
|
9
|
+
export interface AzureSubscriptionProvider {
|
|
10
|
+
/**
|
|
11
|
+
* Fires when the list of available subscriptions may have changed, and a refresh is suggested.
|
|
12
|
+
* The callback will be given a {@link RefreshSuggestedEvent} with more information.
|
|
13
|
+
* @note This will be fired at most every 5 seconds, to avoid flooding. It is also suppressed
|
|
14
|
+
* during operations this provider is performing itself, such as during sign-in.
|
|
15
|
+
*/
|
|
16
|
+
onRefreshSuggested: vscode.Event<RefreshSuggestedEvent>;
|
|
17
|
+
/**
|
|
18
|
+
* Signs in to Azure, if not already signed in. This will suppress {@link onRefreshSuggested} events until the sign-in is complete.
|
|
19
|
+
*
|
|
20
|
+
* @param tenant (Optional) If provided, signs in to the specified tenant and account.
|
|
21
|
+
* @param options (Optional) Additional options for signing in.
|
|
22
|
+
*
|
|
23
|
+
* @returns True if sign-in was successful, false otherwise.
|
|
24
|
+
*/
|
|
25
|
+
signIn(tenant?: TenantIdAndAccount, options?: SignInOptions): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* The easier API. Across all accounts and all tenants*, returns the list of {@link AzureSubscription}s the user can access.
|
|
28
|
+
* No additional automatic sign-in is performed; unauthenticated accounts or tenants will simply be skipped.
|
|
29
|
+
*
|
|
30
|
+
* If you aren't interested in managing multiple accounts or tenant sign ins, this is the only method you need to call.
|
|
31
|
+
*
|
|
32
|
+
* The subscriptions will be deduplicated according to the strategy in {@link dedupeSubscriptions}. If you want a different
|
|
33
|
+
* strategy, you can use request all and deduplicate according to your needs.
|
|
34
|
+
*
|
|
35
|
+
* *The number of tenants processed will be limited to `options.maximumTenants` (default 10),
|
|
36
|
+
* to avoid excessive requests.
|
|
37
|
+
*
|
|
38
|
+
* @param options (Optional) Additional options for getting the subscriptions.
|
|
39
|
+
*
|
|
40
|
+
* @throws A {@link NotSignedInError} if the user is not signed in to any accounts. It will *not* throw if
|
|
41
|
+
* at least one account is signed in, even if no subscriptions are found.
|
|
42
|
+
* @throws A {@link vscode.CancellationError} if the operation is cancelled via the provided cancellation token.
|
|
43
|
+
*/
|
|
44
|
+
getAvailableSubscriptions(options?: GetAvailableSubscriptionsOptions): Promise<AzureSubscription[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Returns a list of all accounts. It is up to the caller to get tenants and subscriptions if needed, and the caller
|
|
47
|
+
* is also responsible for limiting the amount of subsequent requests made.
|
|
48
|
+
*
|
|
49
|
+
* @param options (Optional) Additional options for getting the accounts.
|
|
50
|
+
*
|
|
51
|
+
* @throws A {@link NotSignedInError} if the user is not signed in to any accounts.
|
|
52
|
+
* @throws A {@link vscode.CancellationError} if the operation is cancelled via the provided cancellation token.
|
|
53
|
+
*/
|
|
54
|
+
getAccounts(options?: GetAccountsOptions): Promise<AzureAccount[]>;
|
|
55
|
+
/**
|
|
56
|
+
* Returns a list of all unauthenticated tenants for a given account.
|
|
57
|
+
*
|
|
58
|
+
* @param account The account to get unauthenticated tenants for.
|
|
59
|
+
* @param options (Optional) Additional options for getting the tenants.
|
|
60
|
+
*
|
|
61
|
+
* @throws A {@link NotSignedInError} if the user is not signed in to the specified account.
|
|
62
|
+
* @throws A {@link vscode.CancellationError} if the operation is cancelled via the provided cancellation token.
|
|
63
|
+
*/
|
|
64
|
+
getUnauthenticatedTenantsForAccount(account: AzureAccount, options?: Omit<GetTenantsForAccountOptions, 'filter'>): Promise<AzureTenant[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Returns a list of tenants for a given account. It is up to the caller to get subscriptions if needed, and the caller
|
|
67
|
+
* is also responsible for limiting the amount of subsequent requests made.
|
|
68
|
+
*
|
|
69
|
+
* @param account The account to get tenants for.
|
|
70
|
+
* @param options (Optional) Additional options for getting the tenants.
|
|
71
|
+
*
|
|
72
|
+
* @throws A {@link NotSignedInError} if the user is not signed in to the specified account.
|
|
73
|
+
* @throws A {@link vscode.CancellationError} if the operation is cancelled via the provided cancellation token.
|
|
74
|
+
*/
|
|
75
|
+
getTenantsForAccount(account: AzureAccount, options?: GetTenantsForAccountOptions): Promise<AzureTenant[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Returns a list of {@link AzureSubscription}s for a given tenant and account. The caller is responsible for
|
|
78
|
+
* limiting the amount of subsequent requests made.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const accounts = await subscriptionProvider.getAccounts();
|
|
83
|
+
* for (const account of accounts) {
|
|
84
|
+
* const tenants = await subscriptionProvider.getTenantsForAccount(account);
|
|
85
|
+
* for (const tenant of tenants) {
|
|
86
|
+
* const subscriptions = await subscriptionProvider.getSubscriptionsForTenant(tenant);
|
|
87
|
+
* // do something with subscriptions
|
|
88
|
+
* }
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @param tenant The tenant (and account) to get subscriptions for.
|
|
93
|
+
* @param options (Optional) Additional options for getting the subscriptions.
|
|
94
|
+
*
|
|
95
|
+
* @throws A {@link NotSignedInError} if the user is not signed in to the specified account *and* tenant.
|
|
96
|
+
* @throws A {@link vscode.CancellationError} if the operation is cancelled via the provided cancellation token.
|
|
97
|
+
*/
|
|
98
|
+
getSubscriptionsForTenant(tenant: TenantIdAndAccount, options?: GetSubscriptionsForTenantOptions): Promise<AzureSubscription[]>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* A type representing just the tenant ID and account information of an Azure tenant.
|
|
102
|
+
*/
|
|
103
|
+
export type TenantIdAndAccount = Required<Pick<AzureTenant, 'tenantId' | 'account'>>;
|
|
104
|
+
/**
|
|
105
|
+
* Information included when a refresh is suggested.
|
|
106
|
+
*/
|
|
107
|
+
export interface RefreshSuggestedEvent {
|
|
108
|
+
/**
|
|
109
|
+
* The reason a refresh was suggested.
|
|
110
|
+
*/
|
|
111
|
+
reason: 'sessionChange' | 'subscriptionFilterChange';
|
|
112
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type * as vscode from 'vscode';
|
|
2
|
+
/**
|
|
3
|
+
* Options for signing in to a tenant.
|
|
4
|
+
*/
|
|
5
|
+
export type SignInOptions = {
|
|
6
|
+
/**
|
|
7
|
+
* (Optional, default false) Whether to force the account picker to reappear.
|
|
8
|
+
* Equivalent to setting {@link vscode.AuthenticationGetSessionOptions.clearSessionPreference} to true.
|
|
9
|
+
*/
|
|
10
|
+
clearSessionPreference?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* (Optional, default true) If true, the user will be prompted to sign in if needed.
|
|
13
|
+
* If false, the {@link AzureSubscriptionProvider.signIn} method will return false if
|
|
14
|
+
* interactive sign-in is required.
|
|
15
|
+
*/
|
|
16
|
+
promptIfNeeded?: boolean;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Default options for signing in to a tenant
|
|
20
|
+
*/
|
|
21
|
+
export declare const DefaultSignInOptions: {
|
|
22
|
+
readonly clearSessionPreference: false;
|
|
23
|
+
readonly promptIfNeeded: true;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Options for getting items from the subscription provider
|
|
27
|
+
* @note As needed, remember to update the {@link getCoalescenceKey} function when modifying this type.
|
|
28
|
+
*/
|
|
29
|
+
export type BaseOptions = {
|
|
30
|
+
/**
|
|
31
|
+
* (Optional, default true) If true, only items explicitly selected by the user will be returned.
|
|
32
|
+
*/
|
|
33
|
+
filter?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* (Optional, default false) Whether to bypass any cached data and refresh from the source.
|
|
36
|
+
*
|
|
37
|
+
* @note In the reference implementation, `VSCodeAzureSubscriptionProvider`, it is NOT necessary to use
|
|
38
|
+
* `noCache: true` in the following cases:
|
|
39
|
+
* - Subscription filters have changed (caching is done before filtering)
|
|
40
|
+
* - A new sign-in has occurred (a partial cache refill will occur automatically)
|
|
41
|
+
*
|
|
42
|
+
* It is only necessary to use `noCache: true` if you expect that the subscriptions/tenants that an
|
|
43
|
+
* account has access to have changed--e.g. a subscription is created or removed, or RBAC changes.
|
|
44
|
+
*
|
|
45
|
+
* @note When `noCache: true` is used, it applies *only to that function call*. The entire cache will
|
|
46
|
+
* not be cleared--only the data needed for that call will be refreshed.
|
|
47
|
+
*/
|
|
48
|
+
noCache?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* (Optional) A cancellation token to cancel the operation.
|
|
51
|
+
*/
|
|
52
|
+
token?: vscode.CancellationToken;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Options when requesting accounts
|
|
56
|
+
*/
|
|
57
|
+
export type GetAccountsOptions = BaseOptions;
|
|
58
|
+
/**
|
|
59
|
+
* Options when requesting tenants for an account
|
|
60
|
+
*/
|
|
61
|
+
export type GetTenantsForAccountOptions = BaseOptions;
|
|
62
|
+
/**
|
|
63
|
+
* Options when requesting subscriptions for a tenant+account
|
|
64
|
+
*/
|
|
65
|
+
export type GetSubscriptionsForTenantOptions = BaseOptions & {
|
|
66
|
+
/**
|
|
67
|
+
* (Optional, default true) Whether to deduplicate the subscriptions returned, according to the
|
|
68
|
+
* strategy in {@link dedupeSubscriptions}.
|
|
69
|
+
*/
|
|
70
|
+
dedupe?: boolean;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Options when requesting available subscriptions across all accounts and tenants.
|
|
74
|
+
*/
|
|
75
|
+
export type GetAvailableSubscriptionsOptions = GetAccountsOptions & GetTenantsForAccountOptions & GetSubscriptionsForTenantOptions & {
|
|
76
|
+
/**
|
|
77
|
+
* (Optional, default 10) The maximum number of tenants for which to get subscriptions. This is
|
|
78
|
+
* necessary because each account+tenant requires a token request plus a subscription list request.
|
|
79
|
+
* No subscription list maximum is applied; once a tenant is reached, all its subscriptions are retrieved.
|
|
80
|
+
*/
|
|
81
|
+
maximumTenants?: number;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* The default options when getting available subscriptions.
|
|
85
|
+
* @note This same value also is passed as the default to all the get* methods, since it
|
|
86
|
+
* is a superset of all of the available options.
|
|
87
|
+
*/
|
|
88
|
+
export declare const DefaultOptions: {
|
|
89
|
+
readonly filter: true;
|
|
90
|
+
readonly noCache: false;
|
|
91
|
+
readonly token: undefined;
|
|
92
|
+
readonly dedupe: true;
|
|
93
|
+
readonly maximumTenants: 10;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Gets a promise coalescence key for the given {@link GetAvailableSubscriptionsOptions}.
|
|
97
|
+
* @param options The options to get the key for
|
|
98
|
+
* @returns A string key for coalescing promises, or undefined if coalescing is not applicable
|
|
99
|
+
* @internal This should not be used by external code. This is placed here so it can be adjacent
|
|
100
|
+
* to the {@link GetAvailableSubscriptionsOptions} type, but should be used only by internal
|
|
101
|
+
* implementations
|
|
102
|
+
*/
|
|
103
|
+
export declare function getCoalescenceKey(options: GetAvailableSubscriptionsOptions): string | undefined;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
/**
|
|
6
|
+
* Default options for signing in to a tenant
|
|
7
|
+
*/
|
|
8
|
+
export const DefaultSignInOptions = {
|
|
9
|
+
clearSessionPreference: false,
|
|
10
|
+
promptIfNeeded: true,
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* The default options when getting available subscriptions.
|
|
14
|
+
* @note This same value also is passed as the default to all the get* methods, since it
|
|
15
|
+
* is a superset of all of the available options.
|
|
16
|
+
*/
|
|
17
|
+
export const DefaultOptions = {
|
|
18
|
+
filter: true,
|
|
19
|
+
noCache: false,
|
|
20
|
+
token: undefined,
|
|
21
|
+
dedupe: true,
|
|
22
|
+
maximumTenants: 10,
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Gets a promise coalescence key for the given {@link GetAvailableSubscriptionsOptions}.
|
|
26
|
+
* @param options The options to get the key for
|
|
27
|
+
* @returns A string key for coalescing promises, or undefined if coalescing is not applicable
|
|
28
|
+
* @internal This should not be used by external code. This is placed here so it can be adjacent
|
|
29
|
+
* to the {@link GetAvailableSubscriptionsOptions} type, but should be used only by internal
|
|
30
|
+
* implementations
|
|
31
|
+
*/
|
|
32
|
+
export function getCoalescenceKey(options) {
|
|
33
|
+
// Never coalesce if there is a cancellation token--no way to do it safely
|
|
34
|
+
if (options.token) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
return Object
|
|
38
|
+
.keys(options)
|
|
39
|
+
.filter(k => k !== 'token') // ignore token
|
|
40
|
+
.sort()
|
|
41
|
+
.map(k => `${k}:${options[k] ?? DefaultOptions[k]}`)
|
|
42
|
+
.join(',');
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=AzureSubscriptionProviderRequestOptions.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { TenantIdDescription } from "@azure/arm-resources-subscriptions";
|
|
2
|
+
import type { AzureAccount } from "./AzureAccount";
|
|
3
|
+
/**
|
|
4
|
+
* An Azure tenant associated with a specific account
|
|
5
|
+
*/
|
|
6
|
+
export interface AzureTenant extends TenantIdDescription {
|
|
7
|
+
/**
|
|
8
|
+
* The account associated with this tenant
|
|
9
|
+
*/
|
|
10
|
+
readonly account: AzureAccount;
|
|
11
|
+
/**
|
|
12
|
+
* @inheritdoc
|
|
13
|
+
*/
|
|
14
|
+
readonly tenantId: string;
|
|
15
|
+
}
|
package/dist/esm/src/index.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './AzureSubscription';
|
|
4
|
-
export * from './AzureSubscriptionProvider';
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './
|
|
1
|
+
export * from './contracts/AzureAccount';
|
|
2
|
+
export * from './contracts/AzureAuthentication';
|
|
3
|
+
export * from './contracts/AzureSubscription';
|
|
4
|
+
export * from './contracts/AzureSubscriptionProvider';
|
|
5
|
+
export type * from './contracts/AzureSubscriptionProviderRequestOptions';
|
|
6
|
+
export * from './contracts/AzureTenant';
|
|
7
|
+
export * from './providers/AzureSubscriptionProviderBase';
|
|
8
|
+
export * from './providers/VSCodeAzureSubscriptionProvider';
|
|
9
9
|
export * from './utils/configuredAzureEnv';
|
|
10
|
-
export * from './utils/
|
|
11
|
-
export * from './
|
|
10
|
+
export * from './utils/dedupeSubscriptions';
|
|
11
|
+
export * from './utils/getMetricsForTelemetry';
|
|
12
|
+
export * from './utils/getSessionFromVSCode';
|
|
13
|
+
export * from './utils/NotSignedInError';
|
|
14
|
+
export * from './utils/signInToTenant';
|
package/dist/esm/src/index.js
CHANGED
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './AzureSubscription';
|
|
8
|
-
export * from './AzureSubscriptionProvider';
|
|
9
|
-
export * from './AzureTenant';
|
|
10
|
-
|
|
11
|
-
export * from './
|
|
12
|
-
export * from './
|
|
5
|
+
export * from './contracts/AzureAccount';
|
|
6
|
+
export * from './contracts/AzureAuthentication';
|
|
7
|
+
export * from './contracts/AzureSubscription';
|
|
8
|
+
export * from './contracts/AzureSubscriptionProvider';
|
|
9
|
+
export * from './contracts/AzureTenant';
|
|
10
|
+
// The `AzureDevOpsSubscriptionProvider` is intentionally not exported, it must be imported from `'@microsoft/vscode-azext-azureauth/azdo'`
|
|
11
|
+
export * from './providers/AzureSubscriptionProviderBase';
|
|
12
|
+
export * from './providers/VSCodeAzureSubscriptionProvider';
|
|
13
13
|
export * from './utils/configuredAzureEnv';
|
|
14
|
-
export * from './utils/
|
|
15
|
-
export * from './
|
|
14
|
+
export * from './utils/dedupeSubscriptions';
|
|
15
|
+
export * from './utils/getMetricsForTelemetry';
|
|
16
|
+
export * from './utils/getSessionFromVSCode';
|
|
17
|
+
export * from './utils/NotSignedInError';
|
|
18
|
+
export * from './utils/signInToTenant';
|
|
16
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { SubscriptionClient } from '@azure/arm-resources-subscriptions';
|
|
2
|
+
import type { TokenCredential } from '@azure/core-auth';
|
|
3
|
+
import type * as vscode from 'vscode';
|
|
4
|
+
import type { AzureAccount } from '../contracts/AzureAccount';
|
|
5
|
+
import type { AzureAuthentication } from '../contracts/AzureAuthentication';
|
|
6
|
+
import type { TenantIdAndAccount } from '../contracts/AzureSubscriptionProvider';
|
|
7
|
+
import type { AzureTenant } from '../contracts/AzureTenant';
|
|
8
|
+
import { AzureSubscriptionProviderBase } from './AzureSubscriptionProviderBase';
|
|
9
|
+
export interface AzureDevOpsSubscriptionProviderInitializer {
|
|
10
|
+
/**
|
|
11
|
+
* The resource ID of the Azure DevOps federated service connection,
|
|
12
|
+
* which can be found on the `resourceId` field of the URL at the address bar
|
|
13
|
+
* when viewing the service connection in the Azure DevOps portal
|
|
14
|
+
*/
|
|
15
|
+
serviceConnectionId: string;
|
|
16
|
+
/**
|
|
17
|
+
* The `Tenant ID` field of the service connection properties
|
|
18
|
+
*/
|
|
19
|
+
tenantId: string;
|
|
20
|
+
/**
|
|
21
|
+
* The `Service Principal Id` field of the service connection properties
|
|
22
|
+
*/
|
|
23
|
+
clientId: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function createAzureDevOpsSubscriptionProviderFactory(initializer: AzureDevOpsSubscriptionProviderInitializer): () => Promise<AzureDevOpsSubscriptionProvider>;
|
|
26
|
+
/**
|
|
27
|
+
* AzureSubscriptionProvider implemented to authenticate via federated DevOps service connection, using workflow identity federation
|
|
28
|
+
* To learn how to configure your DevOps environment to use this provider, refer to the README.md
|
|
29
|
+
* NOTE: This provider is only available when running in an Azure DevOps pipeline
|
|
30
|
+
* Reference: https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation
|
|
31
|
+
*/
|
|
32
|
+
export declare class AzureDevOpsSubscriptionProvider extends AzureSubscriptionProviderBase {
|
|
33
|
+
private _tokenCredential;
|
|
34
|
+
private _serviceConnectionId;
|
|
35
|
+
private _tenantId;
|
|
36
|
+
private _clientId;
|
|
37
|
+
constructor({ serviceConnectionId, tenantId, clientId }: AzureDevOpsSubscriptionProviderInitializer, logger?: vscode.LogOutputChannel);
|
|
38
|
+
/**
|
|
39
|
+
* For {@link AzureSubscriptionProviderBase}, this event will never fire
|
|
40
|
+
*/
|
|
41
|
+
onRefreshSuggested: () => {
|
|
42
|
+
dispose: () => void;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* For {@link AzureSubscriptionProviderBase}, this returns a single account with a fixed ID and label
|
|
46
|
+
*/
|
|
47
|
+
getAccounts(): Promise<AzureAccount[]>;
|
|
48
|
+
/**
|
|
49
|
+
* For {@link AzureSubscriptionProviderBase}, this returns an empty array
|
|
50
|
+
*/
|
|
51
|
+
getUnauthenticatedTenantsForAccount(): Promise<AzureTenant[]>;
|
|
52
|
+
/**
|
|
53
|
+
* For {@link AzureSubscriptionProviderBase}, this returns a single tenant associated with the service principal
|
|
54
|
+
*/
|
|
55
|
+
getTenantsForAccount(account: AzureAccount): Promise<AzureTenant[]>;
|
|
56
|
+
/**
|
|
57
|
+
* @inheritdoc
|
|
58
|
+
*/
|
|
59
|
+
signIn(): Promise<boolean>;
|
|
60
|
+
/**
|
|
61
|
+
* @inheritdoc
|
|
62
|
+
*/
|
|
63
|
+
protected getSubscriptionClient(tenant: TenantIdAndAccount): Promise<{
|
|
64
|
+
client: SubscriptionClient;
|
|
65
|
+
credential: TokenCredential;
|
|
66
|
+
authentication: AzureAuthentication;
|
|
67
|
+
}>;
|
|
68
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import * as azureEnv from '@azure/ms-rest-azure-env'; // This package is so small that it's not worth lazy loading
|
|
6
|
+
import * as crypto from 'crypto';
|
|
7
|
+
import { isAuthenticationWwwAuthenticateRequest } from '../utils/isAuthenticationWwwAuthenticateRequest';
|
|
8
|
+
import { NotSignedInError } from '../utils/NotSignedInError';
|
|
9
|
+
import { AzureSubscriptionProviderBase } from './AzureSubscriptionProviderBase';
|
|
10
|
+
let azureDevOpsSubscriptionProvider;
|
|
11
|
+
export function createAzureDevOpsSubscriptionProviderFactory(initializer) {
|
|
12
|
+
return () => {
|
|
13
|
+
azureDevOpsSubscriptionProvider ??= new AzureDevOpsSubscriptionProvider(initializer);
|
|
14
|
+
return Promise.resolve(azureDevOpsSubscriptionProvider);
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
let armSubs;
|
|
18
|
+
let azIdentity;
|
|
19
|
+
/**
|
|
20
|
+
* AzureSubscriptionProvider implemented to authenticate via federated DevOps service connection, using workflow identity federation
|
|
21
|
+
* To learn how to configure your DevOps environment to use this provider, refer to the README.md
|
|
22
|
+
* NOTE: This provider is only available when running in an Azure DevOps pipeline
|
|
23
|
+
* Reference: https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation
|
|
24
|
+
*/
|
|
25
|
+
export class AzureDevOpsSubscriptionProvider extends AzureSubscriptionProviderBase {
|
|
26
|
+
_tokenCredential;
|
|
27
|
+
_serviceConnectionId;
|
|
28
|
+
_tenantId;
|
|
29
|
+
_clientId;
|
|
30
|
+
constructor({ serviceConnectionId, tenantId, clientId }, logger) {
|
|
31
|
+
super(logger);
|
|
32
|
+
if (!serviceConnectionId || !tenantId || !clientId) {
|
|
33
|
+
throw new Error(`Missing initializer values to identify Azure DevOps federated service connection\n
|
|
34
|
+
Values provided:\n
|
|
35
|
+
serviceConnectionId: ${serviceConnectionId ? "✅" : "❌"}\n
|
|
36
|
+
tenantId: ${tenantId ? "✅" : "❌"}\n
|
|
37
|
+
clientId: ${clientId ? "✅" : "❌"}\n
|
|
38
|
+
`);
|
|
39
|
+
}
|
|
40
|
+
this._serviceConnectionId = serviceConnectionId;
|
|
41
|
+
this._tenantId = tenantId;
|
|
42
|
+
this._clientId = clientId;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* For {@link AzureSubscriptionProviderBase}, this event will never fire
|
|
46
|
+
*/
|
|
47
|
+
onRefreshSuggested = () => { return { dispose: () => { } }; };
|
|
48
|
+
/**
|
|
49
|
+
* For {@link AzureSubscriptionProviderBase}, this returns a single account with a fixed ID and label
|
|
50
|
+
*/
|
|
51
|
+
getAccounts() {
|
|
52
|
+
return Promise.resolve([
|
|
53
|
+
{
|
|
54
|
+
id: 'test-account-id',
|
|
55
|
+
label: 'test-account',
|
|
56
|
+
}
|
|
57
|
+
]);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* For {@link AzureSubscriptionProviderBase}, this returns an empty array
|
|
61
|
+
*/
|
|
62
|
+
getUnauthenticatedTenantsForAccount() {
|
|
63
|
+
// For DevOps federated service connection, there is only one tenant associated with the service principal, and we will be authenticated
|
|
64
|
+
return Promise.resolve([]);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* For {@link AzureSubscriptionProviderBase}, this returns a single tenant associated with the service principal
|
|
68
|
+
*/
|
|
69
|
+
getTenantsForAccount(account) {
|
|
70
|
+
return Promise.resolve([{
|
|
71
|
+
tenantId: this._tenantId,
|
|
72
|
+
account: account,
|
|
73
|
+
}]);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* @inheritdoc
|
|
77
|
+
*/
|
|
78
|
+
async signIn() {
|
|
79
|
+
this._tokenCredential ??= await getTokenCredential(this._serviceConnectionId, this._tenantId, this._clientId);
|
|
80
|
+
return !!this._tokenCredential;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* @inheritdoc
|
|
84
|
+
*/
|
|
85
|
+
async getSubscriptionClient(tenant) {
|
|
86
|
+
if (!this._tokenCredential) {
|
|
87
|
+
throw new NotSignedInError();
|
|
88
|
+
}
|
|
89
|
+
const getSessionWithScopes = async (scopes) => {
|
|
90
|
+
if (isAuthenticationWwwAuthenticateRequest(scopes)) {
|
|
91
|
+
throw new Error('Getting session with challenge is not supported in AzureDevOpsSubscriptionProvider.');
|
|
92
|
+
}
|
|
93
|
+
const token = await this._tokenCredential?.getToken(scopes);
|
|
94
|
+
if (!token) {
|
|
95
|
+
throw new NotSignedInError();
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
accessToken: token.token,
|
|
99
|
+
id: crypto.randomUUID(),
|
|
100
|
+
account: tenant.account,
|
|
101
|
+
scopes: scopes,
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
armSubs ??= await import('@azure/arm-resources-subscriptions');
|
|
105
|
+
return {
|
|
106
|
+
client: new armSubs.SubscriptionClient(this._tokenCredential),
|
|
107
|
+
credential: this._tokenCredential,
|
|
108
|
+
authentication: {
|
|
109
|
+
getSession: () => {
|
|
110
|
+
return getSessionWithScopes([azureEnv.Environment.AzureCloud.managementEndpointUrl + '/.default']);
|
|
111
|
+
},
|
|
112
|
+
getSessionWithScopes: getSessionWithScopes,
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* @param serviceConnectionId The resource ID of the Azure DevOps federated service connection,
|
|
119
|
+
* which can be found on the `resourceId` field of the URL at the address bar when viewing the service connection in the Azure DevOps portal
|
|
120
|
+
* @param tenantId The `Tenant ID` field of the service connection properties
|
|
121
|
+
* @param clientId The `Service Principal Id` field of the service connection properties
|
|
122
|
+
*/
|
|
123
|
+
async function getTokenCredential(serviceConnectionId, tenantId, clientId) {
|
|
124
|
+
if (!process.env.AGENT_BUILDDIRECTORY) {
|
|
125
|
+
// Assume that AGENT_BUILDDIRECTORY is set if running in an Azure DevOps pipeline.
|
|
126
|
+
// So when not running in an Azure DevOps pipeline, throw an error since we cannot use the DevOps federated service connection credential.
|
|
127
|
+
throw new Error('Cannot create DevOps federated service connection credential outside of an Azure DevOps pipeline.');
|
|
128
|
+
}
|
|
129
|
+
else if (!process.env.SYSTEM_ACCESSTOKEN) {
|
|
130
|
+
throw new Error('Cannot create DevOps federated service connection credential because the SYSTEM_ACCESSTOKEN environment variable is not set.');
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
134
|
+
// @ts-ignore @azure/identity contains a bug where this type mismatches between CJS and ESM, we must ignore it. We also can't do @ts-expect-error because the error only happens when building CJS.
|
|
135
|
+
azIdentity ??= await import('@azure/identity');
|
|
136
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unnecessary-type-assertion
|
|
137
|
+
return new azIdentity.AzurePipelinesCredential(tenantId, clientId, serviceConnectionId, process.env.SYSTEM_ACCESSTOKEN);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=AzureDevOpsSubscriptionProvider.js.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { SubscriptionClient } from '@azure/arm-resources-subscriptions';
|
|
2
|
+
import type { TokenCredential } from '@azure/core-auth';
|
|
3
|
+
import * as vscode from 'vscode';
|
|
4
|
+
import type { AzureAccount } from '../contracts/AzureAccount';
|
|
5
|
+
import type { AzureAuthentication } from '../contracts/AzureAuthentication';
|
|
6
|
+
import type { AzureSubscription } from '../contracts/AzureSubscription';
|
|
7
|
+
import type { AzureSubscriptionProvider, RefreshSuggestedEvent, TenantIdAndAccount } from '../contracts/AzureSubscriptionProvider';
|
|
8
|
+
import { type GetAccountsOptions, type GetAvailableSubscriptionsOptions, type GetSubscriptionsForTenantOptions, type GetTenantsForAccountOptions, type SignInOptions } from '../contracts/AzureSubscriptionProviderRequestOptions';
|
|
9
|
+
import type { AzureTenant } from '../contracts/AzureTenant';
|
|
10
|
+
/**
|
|
11
|
+
* Base class for Azure subscription providers that use VS Code authentication.
|
|
12
|
+
* Handles actual communication with Azure via the Azure SDK, as well as
|
|
13
|
+
* controlling the firing of `onRefreshSuggested` events.
|
|
14
|
+
*/
|
|
15
|
+
export declare abstract class AzureSubscriptionProviderBase implements AzureSubscriptionProvider, vscode.Disposable {
|
|
16
|
+
private readonly logger?;
|
|
17
|
+
private sessionChangeListener;
|
|
18
|
+
private readonly refreshSuggestedEmitter;
|
|
19
|
+
private lastRefreshSuggestedTime;
|
|
20
|
+
private suppressRefreshSuggestedEvents;
|
|
21
|
+
/**
|
|
22
|
+
* Constructs a new {@link AzureSubscriptionProviderBase}.
|
|
23
|
+
* @param logger (Optional) A logger to record information to
|
|
24
|
+
*/
|
|
25
|
+
constructor(logger?: vscode.LogOutputChannel | undefined);
|
|
26
|
+
dispose(): void;
|
|
27
|
+
/**
|
|
28
|
+
* @inheritdoc
|
|
29
|
+
*/
|
|
30
|
+
onRefreshSuggested(callback: (evtArgs: RefreshSuggestedEvent) => unknown, thisArg?: unknown, disposables?: vscode.Disposable[]): vscode.Disposable;
|
|
31
|
+
protected fireRefreshSuggestedIfNeeded(evtArgs: RefreshSuggestedEvent): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* @inheritdoc
|
|
34
|
+
*/
|
|
35
|
+
signIn(tenant?: Partial<TenantIdAndAccount>, options?: SignInOptions): Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* @inheritdoc
|
|
38
|
+
*/
|
|
39
|
+
getAvailableSubscriptions(options?: GetAvailableSubscriptionsOptions): Promise<AzureSubscription[]>;
|
|
40
|
+
/**
|
|
41
|
+
* @inheritdoc
|
|
42
|
+
*/
|
|
43
|
+
getAccounts(options?: GetAccountsOptions): Promise<AzureAccount[]>;
|
|
44
|
+
/**
|
|
45
|
+
* @inheritdoc
|
|
46
|
+
*/
|
|
47
|
+
getUnauthenticatedTenantsForAccount(account: AzureAccount, options?: Omit<GetTenantsForAccountOptions, 'filter'>): Promise<AzureTenant[]>;
|
|
48
|
+
/**
|
|
49
|
+
* @inheritdoc
|
|
50
|
+
*/
|
|
51
|
+
getTenantsForAccount(account: AzureAccount, options?: GetTenantsForAccountOptions): Promise<AzureTenant[]>;
|
|
52
|
+
/**
|
|
53
|
+
* @inheritdoc
|
|
54
|
+
*/
|
|
55
|
+
getSubscriptionsForTenant(tenant: TenantIdAndAccount, options?: GetSubscriptionsForTenantOptions): Promise<AzureSubscription[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Gets a {@link SubscriptionClient} plus extras for the given account+tenant.
|
|
58
|
+
* @param tenant (Optional) The account+tenant to get a subscription client for. If not specified, the default account and home tenant
|
|
59
|
+
* will be used.
|
|
60
|
+
* @returns A {@link SubscriptionClient}, {@link TokenCredential}, and {@link AzureAuthentication} for the given account+tenant.
|
|
61
|
+
*/
|
|
62
|
+
protected getSubscriptionClient(tenant: Partial<TenantIdAndAccount>): Promise<{
|
|
63
|
+
client: SubscriptionClient;
|
|
64
|
+
credential: TokenCredential;
|
|
65
|
+
authentication: AzureAuthentication;
|
|
66
|
+
}>;
|
|
67
|
+
protected log(message: string): void;
|
|
68
|
+
protected logForAccount(account: AzureAccount, message: string): void;
|
|
69
|
+
protected logForTenant(tenant: TenantIdAndAccount, message: string): void;
|
|
70
|
+
protected throwIfCancelled(token: vscode.CancellationToken | undefined): void;
|
|
71
|
+
private timeout;
|
|
72
|
+
private silenceRefreshEvents;
|
|
73
|
+
private remapLogRethrow;
|
|
74
|
+
}
|