Skip to content

Commit

Permalink
feat: update
Browse files Browse the repository at this point in the history
  • Loading branch information
wenytang-ms committed Feb 13, 2025
1 parent b7c90f8 commit 6f4a1d2
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 116 deletions.
14 changes: 14 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,20 @@
"items": {
"type": "string"
}
},
"azureApiManagement.selectedTenant": {
"type": "object",
"description": "A specific tenant to sign in to",
"properties": {
"name": {
"type": "string",
"description": "tenant name"
},
"id": {
"type": "string",
"description": "tenant id"
}
}
}
}
}
Expand Down
15 changes: 13 additions & 2 deletions src/azure/azureLogin/azureAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,27 @@
// Licensed under the MIT license.
import { SubscriptionClient, TenantIdDescription } from "@azure/arm-resources-subscriptions";
import { TokenCredential } from "@azure/core-auth";
import { AuthenticationSession, QuickPickItem, Uri, env, window } from "vscode";
import { AuthenticationSession, QuickPickItem, Uri, env, window, workspace, ConfigurationTarget } from "vscode";
import { UiStrings } from "../../uiStrings";
import { GeneralUtils } from "../../utils/generalUtils";
import { SelectionType, SignInStatus, SubscriptionFilter, Tenant } from "./authTypes";
import { AzureAuth } from "./azureAuth";
import { AzureSessionProviderHelper } from "./azureSessionProvider";
import { AzureSubscriptionHelper } from "./subscriptions";
import { AzureAccountUrl, extensionPrefix } from "../../constants";
import { AzureLoginConstantString } from "./constants";
export namespace AzureAccount {
export async function signInToAzure(): Promise<void> {
await AzureSessionProviderHelper.getSessionProvider().signIn();
}

export function getSelectedTenant(): Tenant | undefined {
return workspace.getConfiguration(extensionPrefix).get<Tenant>(AzureLoginConstantString.selectedTenant);
}

export async function updateSelectedTenant(value?: Tenant): Promise<void> {
await workspace.getConfiguration(extensionPrefix).update(AzureLoginConstantString.selectedTenant, value, ConfigurationTarget.Global, true);
}

export async function selectTenant(): Promise<void> {
const sessionProvider = AzureSessionProviderHelper.getSessionProvider();
Expand Down Expand Up @@ -42,6 +52,7 @@ export namespace AzureAccount {
}

sessionProvider.selectedTenant = selectedTenant;
await updateSelectedTenant(selectedTenant);
}

type SubscriptionQuickPickItem = QuickPickItem & { subscription: SubscriptionFilter };
Expand All @@ -64,7 +75,7 @@ export namespace AzureAccount {
const setupAccount = UiStrings.SetUpAzureAccount;
const response = await window.showInformationMessage(noSubscriptionsFound, setupAccount);
if (response === setupAccount) {
env.openExternal(Uri.parse("https://azure.microsoft.com/"));
env.openExternal(Uri.parse(AzureAccountUrl.azureMicrosoftLink));
}

return;
Expand Down
11 changes: 6 additions & 5 deletions src/azure/azureLogin/azureAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { UiStrings } from "../../uiStrings";
import { GeneralUtils } from "../../utils/generalUtils";
import { AzureSessionProvider, GetAuthSessionOptions, ReadyAzureSessionProvider, SignInStatus, Tenant } from "./authTypes";
import { AzureSessionProviderHelper } from "./azureSessionProvider";
import { AzureEnvType, AzureLoginConstantString } from "./constants";
export namespace AzureAuth {
export function getEnvironment(): Environment {
return getConfiguredAzureEnv();
Expand Down Expand Up @@ -98,16 +99,16 @@ export namespace AzureAuth {
// See:
// https://github.com/microsoft/vscode/blob/eac16e9b63a11885b538db3e0b533a02a2fb8143/extensions/microsoft-authentication/package.json#L40-L99
const section = "microsoft-sovereign-cloud";
const settingName = "environment";
const settingName = AzureLoginConstantString.environment;
const authProviderConfig = vscode.workspace.getConfiguration(section);
const environmentSettingValue = authProviderConfig.get<string | undefined>(settingName);

if (environmentSettingValue === "ChinaCloud") {
if (environmentSettingValue === AzureEnvType.ChinaCloud) {
return Environment.ChinaCloud;
} else if (environmentSettingValue === "USGovernment") {
} else if (environmentSettingValue === AzureEnvType.USGovernment) {
return Environment.USGovernment;
} else if (environmentSettingValue === "custom") {
const customCloud = authProviderConfig.get<EnvironmentParameters | undefined>("customEnvironment");
} else if (environmentSettingValue === AzureEnvType.custom) {
const customCloud = authProviderConfig.get<EnvironmentParameters | undefined>(AzureEnvType.customEnvironment);
if (customCloud) {
return new Environment(customCloud);
}
Expand Down
12 changes: 10 additions & 2 deletions src/azure/azureLogin/azureSessionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { GeneralUtils } from "../../utils/generalUtils";
import { AzureAuthenticationSession, AzureSessionProvider, GetAuthSessionOptions, SignInStatus, Tenant } from "./authTypes";
import { AzureAccount } from "./azureAccount";
import { AzureAuth } from "./azureAuth";
import { AzureLoginConstantString } from "./constants";

enum AuthScenario {
Initialization,
Expand Down Expand Up @@ -120,7 +121,7 @@ export namespace AzureSessionProviderHelper {
// This allows the user to sign in to the Microsoft provider and list tenants,
// but the resulting session will not allow tenant-level operations. For that,
// we need to get a session for a specific tenant.
const orgTenantId = "organizations";
const orgTenantId = AzureLoginConstantString.organizations;
const scopes = AzureAuth.getScopes(orgTenantId, {});
const getSessionResult = await this.getArmSession(orgTenantId, scopes, authScenario);

Expand All @@ -143,6 +144,9 @@ export namespace AzureSessionProviderHelper {
this.tenants = newTenants;
this.signInStatusValue = newSignInStatus;
if (signInStatusChanged || tenantsChanged || selectedTenantChanged) {
if (newSignInStatus === SignInStatus.SignedOut) {
await AzureAccount.updateSelectedTenant();
}
this.onSignInStatusChangeEmitter.fire(this.signInStatusValue);
}
}
Expand Down Expand Up @@ -220,7 +224,11 @@ export namespace AzureSessionProviderHelper {
);
const results = await Promise.all(getSessionPromises);
const accessibleTenants = results.filter(GeneralUtils.succeeded).map((r) => r.result);
return accessibleTenants.length === 1 ? AzureAccount.findTenant(tenants, accessibleTenants[0].tenantId) : null;
if (accessibleTenants.length === 1) {
return AzureAccount.findTenant(tenants, accessibleTenants[0].tenantId);
}
const lastTenant = AzureAccount.getSelectedTenant();
return lastTenant && accessibleTenants.some(item => item.tenantId === lastTenant.id) ? lastTenant : null;
}

private async getArmSession(
Expand Down
15 changes: 15 additions & 0 deletions src/azure/azureLogin/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export const AzureLoginConstantString = {
organizations: "organizations",
environment: "environment",
selectedSubscriptions: "selectedSubscriptions",
selectedTenant: "selectedTenant",
}

export const AzureEnvType = {
ChinaCloud: "ChinaCloud",
USGovernment: "USGovernment",
custom: "custom",
customEnvironment: "customEnvironment",
}
8 changes: 5 additions & 3 deletions src/azure/azureLogin/subscriptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import * as vscode from "vscode";
import { GeneralUtils } from "../../utils/generalUtils";
import { ReadyAzureSessionProvider, SelectionType, SubscriptionFilter } from "./authTypes";
import { AzureAuth } from "./azureAuth";
import { extensionPrefix } from "../../constants";
import { AzureLoginConstantString } from "./constants";

export namespace AzureSubscriptionHelper {
const onFilteredSubscriptionsChangeEmitter = new vscode.EventEmitter<void>();
Expand All @@ -15,7 +17,7 @@ export namespace AzureSubscriptionHelper {

export function getFilteredSubscriptions(): SubscriptionFilter[] {
try {
let values = vscode.workspace.getConfiguration("azureApiManagement").get<string[]>("selectedSubscriptions", []);
let values = vscode.workspace.getConfiguration(extensionPrefix).get<string[]>(AzureLoginConstantString.selectedSubscriptions, []);
return values.map(asSubscriptionFilter).filter((v) => v !== null) as SubscriptionFilter[];
} catch (e) {
return [];
Expand Down Expand Up @@ -73,8 +75,8 @@ export namespace AzureSubscriptionHelper {

if (filtersChanged) {
await vscode.workspace
.getConfiguration("azureApiManagement")
.update("selectedSubscriptions", values, vscode.ConfigurationTarget.Global, true);
.getConfiguration(extensionPrefix)
.update(AzureLoginConstantString.selectedSubscriptions, values, vscode.ConfigurationTarget.Global, true);
onFilteredSubscriptionsChangeEmitter.fire();
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/commands/openUrl.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { AzExtTreeItem, IActionContext, openUrl } from '@microsoft/vscode-azext-utils';
import { APIMAccount, AzureAccountCreateUrl } from "../constants";
import { APIMAccountCommandId, AzureAccountUrl } from "../constants";

export async function openUrlFromTreeNode(context: IActionContext, node?: AzExtTreeItem) {
context;
switch (node?.id) {
case APIMAccount.createAzureAccount: {
await openUrl(AzureAccountCreateUrl.createAzureAccountUrl);
case APIMAccountCommandId.createAzureAccount: {
await openUrl(AzureAccountUrl.createAzureAccountUrl);
break;
}
case APIMAccount.createAzureStudentAccount: {
await openUrl(AzureAccountCreateUrl.createAzureStudentUrl);
case APIMAccountCommandId.createAzureStudentAccount: {
await openUrl(AzureAccountUrl.createAzureStudentUrl);
break;
}
}
Expand Down
12 changes: 9 additions & 3 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,20 @@ export enum GatewayKeyType {
secondary = "secondary"
}

export const APIMAccount = {
export const APIMAccountCommandId = {
createAzureAccount: "Create an Azure Account...",
createAzureStudentAccount: "Create an Azure for Students Account...",
accountLoading: "azureManagementAccountLoading",
accountSignIn: "azureManagementAccountSignIn",
accountSigningIn: "azureManagementAccountSigningIn",
accountSelectTenant: "azureManagementAccountSelectTenant",
accountError: "AzureAccountError",
}

export const AzureAccountCreateUrl = {
export const AzureAccountUrl = {
createAzureAccountUrl: "https://aka.ms/VSCodeCreateAzureAccount",
createAzureStudentUrl: "https://aka.ms/student-account"
createAzureStudentUrl: "https://aka.ms/student-account",
azureMicrosoftLink: "https://azure.microsoft.com/",
};

// constants for extractor
Expand Down
22 changes: 11 additions & 11 deletions src/explorer/AzureAccountTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { AzureSubscriptionHelper } from "../azure/azureLogin/subscriptions";
import { AzureSessionProvider, ReadyAzureSessionProvider, SelectionType, SignInStatus } from "../azure/azureLogin/authTypes";
import { GeneralUtils } from "../utils/generalUtils";
import { AzureAuth } from "../azure/azureLogin/azureAuth";
import { APIMAccount } from "../constants";
import { APIMAccountCommandId } from "../constants";
import { Subscription } from "@azure/arm-resources-subscriptions";
import { createSubscriptionTreeItem } from "./ApiManagementProvider";

Expand All @@ -21,7 +21,7 @@ export function createAzureAccountTreeItem(

export class AzureAccountTreeItem extends AzExtParentTreeItem {
private subscriptionTreeItems: AzExtTreeItem[] | undefined;
public static contextValue: string = "azureApiCenterAzureAccount";
public static contextValue: string = "azureApiManagementAzureAccount";
public readonly contextValue: string = AzureAccountTreeItem.contextValue;
constructor(private readonly sessionProvider: AzureSessionProvider) {
super(undefined);
Expand Down Expand Up @@ -62,7 +62,7 @@ export class AzureAccountTreeItem extends AzExtParentTreeItem {
new GenericTreeItem(this, {
label: UiStrings.Loading,
contextValue: "azureCommand",
id: "azureapicenterAccountLoading",
id: APIMAccountCommandId.accountLoading,
iconPath: new vscode.ThemeIcon("loading~spin"),
}),
];
Expand All @@ -72,23 +72,23 @@ export class AzureAccountTreeItem extends AzExtParentTreeItem {
label: UiStrings.SignIntoAzure,
commandId: "azureApiManagement.signInToAzure",
contextValue: "azureCommand",
id: "azureapicenterAccountSignIn",
id: APIMAccountCommandId.accountSignIn,
iconPath: new vscode.ThemeIcon("sign-in"),
includeInTreeItemPicker: true,
}),
new GenericTreeItem(this, {
label: UiStrings.CreateAzureAccount,
commandId: "azureApiManagement.openUrl",
contextValue: "azureCommand",
id: APIMAccount.createAzureAccount,
id: APIMAccountCommandId.createAzureAccount,
iconPath: new vscode.ThemeIcon("add"),
includeInTreeItemPicker: true,
}),
new GenericTreeItem(this, {
label: UiStrings.CreateAzureStudentAccount,
commandId: "azureApiManagement.openUrl",
contextValue: "azureCommand",
id: APIMAccount.createAzureStudentAccount,
id: APIMAccountCommandId.createAzureStudentAccount,
iconPath: new vscode.ThemeIcon("mortar-board"),
includeInTreeItemPicker: true,
})
Expand All @@ -98,7 +98,7 @@ export class AzureAccountTreeItem extends AzExtParentTreeItem {
new GenericTreeItem(this, {
label: UiStrings.WaitForAzureSignIn,
contextValue: "azureCommand",
id: "azureapicenterAccountSigningIn",
id: APIMAccountCommandId.accountSigningIn,
iconPath: new vscode.ThemeIcon("loading~spin"),
}),
];
Expand All @@ -111,7 +111,7 @@ export class AzureAccountTreeItem extends AzExtParentTreeItem {
label: UiStrings.SelectTenant,
commandId: "azureApiManagement.selectTenant",
contextValue: "azureCommand",
id: "azureapicenterAccountSelectTenant",
id: APIMAccountCommandId.accountSelectTenant,
iconPath: new vscode.ThemeIcon("account"),
includeInTreeItemPicker: true,
}),
Expand All @@ -127,7 +127,7 @@ export class AzureAccountTreeItem extends AzExtParentTreeItem {
new GenericTreeItem(this, {
label: UiStrings.ErrorAuthenticating,
contextValue: "azureCommand",
id: "AzureAccountError",
id: APIMAccountCommandId.accountError,
iconPath: new vscode.ThemeIcon("error"),
}),
];
Expand All @@ -139,7 +139,7 @@ export class AzureAccountTreeItem extends AzExtParentTreeItem {
new GenericTreeItem(this, {
label: UiStrings.ErrorLoadingSubscriptions,
contextValue: "azureCommand",
id: "AzureAccountError",
id: APIMAccountCommandId.accountError,
iconPath: new vscode.ThemeIcon("error"),
description: subscriptions.error,
}),
Expand All @@ -151,7 +151,7 @@ export class AzureAccountTreeItem extends AzExtParentTreeItem {
new GenericTreeItem(this, {
label: UiStrings.NoSubscriptionsFound,
contextValue: "azureCommand",
id: "AzureAccountError",
id: APIMAccountCommandId.accountError,
iconPath: new vscode.ThemeIcon("info"),
}),
];
Expand Down
Loading

0 comments on commit 6f4a1d2

Please sign in to comment.