Skip to content

Commit b634072

Browse files
committed
use new sp login in sign in window
1 parent 808a2ef commit b634072

File tree

3 files changed

+55
-201
lines changed

3 files changed

+55
-201
lines changed

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/ui/SignInWindow.form

Lines changed: 3 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.microsoft.intellij.ui.SignInWindow">
3-
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="10" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
3+
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="9" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
44
<margin top="10" left="10" bottom="10" right="10"/>
55
<constraints>
66
<xy x="48" y="54" width="668" height="274"/>
@@ -88,49 +88,12 @@
8888
</constraints>
8989
<properties>
9090
<enabled value="true"/>
91-
<text value=" An authentication file with credentials for an Azure Active Directory service principal will be used for sign in."/>
92-
</properties>
93-
</component>
94-
<component id="1a9a8" class="javax.swing.JLabel" binding="authFileLabel">
95-
<constraints>
96-
<grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
97-
</constraints>
98-
<properties>
99-
<labelFor value="b9632"/>
100-
<text value=" Authentication file:" noi18n="true"/>
101-
</properties>
102-
</component>
103-
<component id="b9632" class="javax.swing.JTextField" binding="authFileTextField">
104-
<constraints>
105-
<grid row="8" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="1" indent="0" use-parent-layout="false">
106-
<minimum-size width="300" height="-1"/>
107-
</grid>
108-
</constraints>
109-
<properties>
110-
<editable value="false"/>
111-
<text value=""/>
112-
</properties>
113-
</component>
114-
<component id="3a659" class="javax.swing.JButton" binding="browseButton" default-binding="true">
115-
<constraints>
116-
<grid row="8" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
117-
</constraints>
118-
<properties>
119-
<horizontalAlignment value="0"/>
120-
<text value="Browse..."/>
121-
</properties>
122-
</component>
123-
<component id="19f87" class="javax.swing.JButton" binding="createNewAuthenticationFileButton" default-binding="true">
124-
<constraints>
125-
<grid row="8" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
126-
</constraints>
127-
<properties>
128-
<text value="New..."/>
91+
<text value="Use Azure Active Directory service principal for sign in."/>
12992
</properties>
13093
</component>
13194
<vspacer id="75b89">
13295
<constraints>
133-
<grid row="9" column="0" row-span="1" col-span="4" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
96+
<grid row="8" column="0" row-span="1" col-span="4" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
13497
</constraints>
13598
</vspacer>
13699
</children>

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/ui/SignInWindow.java

Lines changed: 33 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,18 @@
77

88
import com.intellij.openapi.application.ApplicationManager;
99
import com.intellij.openapi.diagnostic.Logger;
10-
import com.intellij.openapi.fileChooser.FileChooser;
11-
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
12-
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
1310
import com.intellij.openapi.progress.ProcessCanceledException;
1411
import com.intellij.openapi.progress.ProgressIndicator;
1512
import com.intellij.openapi.progress.ProgressManager;
1613
import com.intellij.openapi.project.Project;
1714
import com.intellij.openapi.ui.DialogWrapper;
18-
import com.intellij.openapi.ui.Messages;
19-
import com.intellij.openapi.vfs.LocalFileSystem;
20-
import com.intellij.openapi.vfs.VirtualFile;
2115
import com.intellij.ui.AnimatedIcon;
2216
import com.microsoft.azure.toolkit.lib.Azure;
2317
import com.microsoft.azure.toolkit.lib.auth.Account;
2418
import com.microsoft.azure.toolkit.lib.auth.AzureAccount;
2519
import com.microsoft.azure.toolkit.lib.auth.core.devicecode.DeviceCodeAccount;
2620
import com.microsoft.azure.toolkit.lib.auth.model.AccountEntity;
21+
import com.microsoft.azure.toolkit.lib.auth.model.AuthConfiguration;
2722
import com.microsoft.azure.toolkit.lib.auth.model.AuthType;
2823
import com.microsoft.azure.toolkit.lib.auth.util.AzureEnvironmentUtils;
2924
import com.microsoft.azure.toolkit.lib.common.exception.AzureToolkitRuntimeException;
@@ -32,16 +27,14 @@
3227
import com.microsoft.azure.toolkit.lib.common.task.AzureTask;
3328
import com.microsoft.azure.toolkit.lib.common.task.AzureTaskManager;
3429
import com.microsoft.azuretools.adauth.IDeviceLoginUI;
35-
import com.microsoft.azuretools.adauth.StringUtils;
3630
import com.microsoft.azuretools.authmanage.*;
3731
import com.microsoft.azuretools.authmanage.models.AuthMethodDetails;
38-
import com.microsoft.azuretools.authmanage.models.SubscriptionDetail;
3932
import com.microsoft.azuretools.sdkmanage.IdentityAzureManager;
4033
import com.microsoft.azuretools.telemetrywrapper.*;
34+
import com.microsoft.intellij.secure.IdeaSecureStore;
4135
import com.microsoft.intellij.ui.components.AzureDialogWrapper;
42-
import com.microsoft.intellij.util.PluginUtil;
43-
import com.microsoft.tooling.msservices.components.DefaultLoader;
4436
import org.apache.commons.collections4.CollectionUtils;
37+
import org.apache.commons.lang3.StringUtils;
4538
import org.jdesktop.swingx.JXHyperlink;
4639
import org.jetbrains.annotations.Nullable;
4740
import reactor.core.Disposable;
@@ -55,7 +48,6 @@
5548
import java.awt.*;
5649
import java.net.URI;
5750
import java.time.Duration;
58-
import java.util.List;
5951
import java.util.*;
6052
import java.util.concurrent.Callable;
6153
import java.util.concurrent.CancellationException;
@@ -73,10 +65,6 @@ public class SignInWindow extends AzureDialogWrapper {
7365
private JRadioButton deviceLoginRadioButton;
7466

7567
private JRadioButton spRadioButton;
76-
private JLabel authFileLabel;
77-
private JTextField authFileTextField;
78-
private JButton browseButton;
79-
private JButton createNewAuthenticationFileButton;
8068
private JLabel servicePrincipalCommentLabel;
8169
private JLabel deviceLoginCommentLabel;
8270
private JRadioButton azureCliRadioButton;
@@ -90,7 +78,7 @@ public class SignInWindow extends AzureDialogWrapper {
9078
private String accountEmail;
9179

9280
private Project project;
93-
private Map<AbstractButton, List<JComponent>> radioButtonComponentsMap = new HashMap<>(3);
81+
private Map<AbstractButton, JComponent> radioButtonComponentsMap = new HashMap<>(3);
9482

9583
public SignInWindow(AuthMethodDetails authMethodDetails, Project project) {
9684
super(project, true, IdeModalityType.PROJECT);
@@ -100,7 +88,6 @@ public SignInWindow(AuthMethodDetails authMethodDetails, Project project) {
10088
setOKButtonText("Sign in");
10189

10290
this.authMethodDetails = authMethodDetails;
103-
authFileTextField.setText(authMethodDetails == null ? null : authMethodDetails.getCredFilePath());
10491

10592
oauthLoginRadioButton.addItemListener(e -> refreshAuthControlElements());
10693

@@ -110,15 +97,6 @@ public SignInWindow(AuthMethodDetails authMethodDetails, Project project) {
11097

11198
azureCliRadioButton.addActionListener(e -> refreshAuthControlElements());
11299

113-
browseButton.addActionListener(e -> {
114-
refreshAuthControlElements();
115-
doSelectCredFilepath();
116-
});
117-
118-
createNewAuthenticationFileButton.addActionListener(e -> {
119-
refreshAuthControlElements();
120-
doCreateServicePrincipal();
121-
});
122100

123101
ButtonGroup buttonGroup = new ButtonGroup();
124102
buttonGroup.add(oauthLoginRadioButton);
@@ -127,14 +105,12 @@ public SignInWindow(AuthMethodDetails authMethodDetails, Project project) {
127105
buttonGroup.add(azureCliRadioButton);
128106
azureCliRadioButton.setSelected(true);
129107

130-
radioButtonComponentsMap.put(spRadioButton, Arrays.asList(servicePrincipalCommentLabel,
131-
authFileLabel, authFileTextField, browseButton, createNewAuthenticationFileButton));
132-
radioButtonComponentsMap.put(deviceLoginRadioButton, Collections.singletonList(deviceLoginCommentLabel));
133-
134-
radioButtonComponentsMap.put(oauthLoginRadioButton, Collections.singletonList(labelOAuthLogin));
135-
136-
radioButtonComponentsMap.put(azureCliRadioButton, Collections.singletonList(azureCliCommentLabel));
108+
radioButtonComponentsMap.put(spRadioButton, servicePrincipalCommentLabel);
109+
radioButtonComponentsMap.put(deviceLoginRadioButton, deviceLoginCommentLabel);
110+
radioButtonComponentsMap.put(oauthLoginRadioButton, labelOAuthLogin);
111+
radioButtonComponentsMap.put(azureCliRadioButton, azureCliCommentLabel);
137112
init();
113+
this.setOKActionEnabled(false);
138114
checkAccountAvailability();
139115
}
140116

@@ -188,22 +164,21 @@ public Single<AuthMethodDetails> login() {
188164
return AzureTaskManager.getInstance().runInModalAsObservable(task).toSingle();
189165
}
190166

167+
private static final IdeaSecureStore secureStore = IdeaSecureStore.getInstance();
168+
191169
private @Nullable AuthMethodDetails doLogin(ProgressIndicator indicator) {
192170
authMethodDetailsResult = new AuthMethodDetails();
193171
if (spRadioButton.isSelected()) { // automated
194172
final Map<String, String> properties = new HashMap<>();
195173
properties.put(AZURE_ENVIRONMENT, CommonSettings.getEnvironment().getName());
196174
properties.putAll(signInSPProp);
197175
EventUtil.logEvent(EventType.info, ACCOUNT, SIGNIN, properties, null);
198-
final String authPath = authFileTextField.getText();
199-
if (StringUtils.isNullOrWhiteSpace(authPath)) {
200-
final String title = "Sign in dialog info";
201-
final String message = "Select authentication file";
202-
DefaultLoader.getUIHelper().showMessageDialog(contentPane, message, title, Messages.getInformationIcon());
203-
return null;
204-
}
205176

206-
authMethodDetailsResult = doServicePrincipalLogin(authPath);
177+
if (ApplicationManager.getApplication().isDispatchThread()) {
178+
doServicePrincipalLogin();
179+
} else {
180+
AzureTaskManager.getInstance().runAndWait(() -> doServicePrincipalLogin());
181+
}
207182
} else if (deviceLoginRadioButton.isSelected()) {
208183
authMethodDetailsResult = doDeviceLogin();
209184
} else if (azureCliRadioButton.isSelected()) {
@@ -214,6 +189,18 @@ public Single<AuthMethodDetails> login() {
214189
return authMethodDetailsResult;
215190
}
216191

192+
private void doServicePrincipalLogin() {
193+
final ServicePrincipalLoginDialog dialog = new ServicePrincipalLoginDialog(project);
194+
if (dialog.showAndGet()) {
195+
AuthConfiguration data = dialog.getData();
196+
authMethodDetailsResult = doServicePrincipalLoginInternal(data);
197+
if (StringUtils.isNotBlank(data.getKey())) {
198+
secureStore.savePassword("account", data.getClient(), data.getKey());
199+
}
200+
201+
}
202+
}
203+
217204
private static AuthMethodDetails checkCanceled(ProgressIndicator indicator, Mono<? extends AuthMethodDetails> mono) {
218205
CompletableFuture<? extends AuthMethodDetails> future = mono.toFuture();
219206
Disposable disposable = Flux.interval(Duration.ofSeconds(1)).map(ts -> {
@@ -249,7 +236,8 @@ protected void init() {
249236
}
250237

251238
private void refreshAuthControlElements() {
252-
radioButtonComponentsMap.keySet().forEach(radio -> radioButtonComponentsMap.get(radio).forEach(comp -> comp.setEnabled(radio.isSelected())));
239+
radioButtonComponentsMap.keySet().forEach(radio -> radioButtonComponentsMap.get(radio).setEnabled(radio.isSelected()));
240+
this.setOKActionEnabled(true);
253241
}
254242

255243
private void checkAccountAvailability() {
@@ -268,7 +256,7 @@ private void checkAccountAvailability() {
268256
oauthLoginRadioButton.setEnabled(false);
269257
labelOAuthLogin.setEnabled(false);
270258
}
271-
259+
this.setOKActionEnabled(true);
272260
if (accounts.stream().anyMatch(ac -> ac.getAuthType() == AuthType.DEVICE_CODE)) {
273261
deviceLoginRadioButton.setEnabled(true);
274262
deviceLoginCommentLabel.setEnabled(true);
@@ -301,27 +289,13 @@ private void disableAzureCliLogin() {
301289
azureCliRadioButton.setText("Azure CLI (Not logged in)");
302290
}
303291

304-
private void doSelectCredFilepath() {
305-
FileChooserDescriptor fileDescriptor = FileChooserDescriptorFactory.createSingleFileDescriptor("azureauth");
306-
fileDescriptor.setTitle("Select Authentication File");
307-
final VirtualFile file = FileChooser.chooseFile(
308-
fileDescriptor,
309-
this.project,
310-
LocalFileSystem.getInstance().findFileByPath(System.getProperty("user.home"))
311-
);
312-
if (file != null) {
313-
authFileTextField.setText(file.getPath());
314-
}
315-
}
316-
317-
private AuthMethodDetails doServicePrincipalLogin(final String authPath) {
292+
private AuthMethodDetails doServicePrincipalLoginInternal(AuthConfiguration auth) {
318293
try {
319294
IdentityAzureManager authManager = IdentityAzureManager.getInstance();
320295
if (AuthMethodManager.getInstance().isSignedIn()) {
321296
doSignOut();
322297
}
323-
return authManager.signInServicePrincipal(AuthFile.fromFile(authPath)).block();
324-
298+
return authManager.signInServicePrincipal(auth).block();
325299
} catch (Exception ex) {
326300
ex.printStackTrace();
327301
ErrorWindow.show(project, ex.getMessage(), SIGN_IN_ERROR);
@@ -400,82 +374,4 @@ private void doSignOut() {
400374
ErrorWindow.show(project, ex.getMessage(), "Sign Out Error");
401375
}
402376
}
403-
404-
private void doCreateServicePrincipal() {
405-
final AuthMethodManager authMethodManager = AuthMethodManager.getInstance();
406-
final IdentityAzureManager dcAuthManager = IdentityAzureManager.getInstance();
407-
try {
408-
if (authMethodManager.isSignedIn()) {
409-
authMethodManager.signOut();
410-
}
411-
doDeviceLogin();
412-
if (!dcAuthManager.isSignedIn()) {
413-
System.out.println(">> Canceled by the user");
414-
return;
415-
}
416-
417-
final SubscriptionManager subscriptionManager = dcAuthManager.getSubscriptionManager();
418-
419-
Optional.ofNullable(ProgressManager.getInstance().getProgressIndicator()).ifPresent(indicator -> indicator.setText2("Loading subscriptions..."));
420-
subscriptionManager.getSubscriptionDetails();
421-
422-
final SrvPriSettingsDialog d = SrvPriSettingsDialog.go(subscriptionManager.getSubscriptionDetails(), project);
423-
final List<SubscriptionDetail> subscriptionDetailsUpdated;
424-
final String destinationFolder;
425-
if (d != null) {
426-
subscriptionDetailsUpdated = d.getSubscriptionDetails();
427-
destinationFolder = d.getDestinationFolder();
428-
} else {
429-
System.out.println(">> Canceled by the user");
430-
return;
431-
}
432-
433-
Map<String, List<String>> tidSidsMap = new HashMap<>();
434-
for (SubscriptionDetail sd : subscriptionDetailsUpdated) {
435-
if (sd.isSelected()) {
436-
System.out.format(">> %s\n", sd.getSubscriptionName());
437-
String tid = sd.getTenantId();
438-
List<String> sidList;
439-
if (!tidSidsMap.containsKey(tid)) {
440-
sidList = new LinkedList<>();
441-
} else {
442-
sidList = tidSidsMap.get(tid);
443-
}
444-
sidList.add(sd.getSubscriptionId());
445-
tidSidsMap.put(tid, sidList);
446-
}
447-
}
448-
449-
SrvPriCreationStatusDialog d1 = SrvPriCreationStatusDialog
450-
.go(dcAuthManager, tidSidsMap, destinationFolder, project);
451-
if (d1 == null) {
452-
System.out.println(">> Canceled by the user");
453-
return;
454-
}
455-
456-
String path = d1.getSelectedAuthFilePath();
457-
if (path == null) {
458-
System.out.println(">> No file was created");
459-
return;
460-
}
461-
462-
authFileTextField.setText(path);
463-
PluginUtil.displayInfoDialog("Authentication File Created", String.format(
464-
"Your credentials have been exported to %s, please keep the authentication file safe", path));
465-
} catch (Exception ex) {
466-
ex.printStackTrace();
467-
//LOGGER.error("doCreateServicePrincipal", ex);
468-
ErrorWindow.show(project, ex.getMessage(), "Get Subscription Error");
469-
470-
} finally {
471-
if (dcAuthManager != null) {
472-
try {
473-
System.out.println(">> Signing out...");
474-
AuthMethodManager.getInstance().signOut();
475-
} catch (Exception e) {
476-
e.printStackTrace();
477-
}
478-
}
479-
}
480-
}
481377
}

0 commit comments

Comments
 (0)