Skip to content

Commit e3c8fd9

Browse files
committed
Fix some code comments during code review:
1. use the correct api for storing password 2. preload regions for the first 5 subs
1 parent b634072 commit e3c8fd9

File tree

11 files changed

+153
-181
lines changed

11 files changed

+153
-181
lines changed

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/ui/AzureCommentLabel.java renamed to PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-lib/src/main/java/com/microsoft/azure/toolkit/intellij/common/AzureCommentLabel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*/
55

6-
package com.microsoft.intellij.ui;
6+
package com.microsoft.azure.toolkit.intellij.common;
77

88
import com.intellij.openapi.util.SystemInfo;
99
import com.intellij.ui.components.JBLabel;

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/actions/AzureSignInAction.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import com.intellij.openapi.project.Project;
1212
import com.intellij.openapi.ui.DialogWrapper;
1313
import com.intellij.openapi.wm.WindowManager;
14+
import com.microsoft.azure.toolkit.lib.Azure;
15+
import com.microsoft.azure.toolkit.lib.auth.AzureAccount;
1416
import com.microsoft.azure.toolkit.lib.auth.exception.AzureToolkitAuthenticationException;
1517
import com.microsoft.azure.toolkit.lib.auth.model.AuthType;
1618
import com.microsoft.azure.toolkit.lib.common.operation.AzureOperation;
@@ -123,7 +125,16 @@ public static void onAzureSignIn(Project project) {
123125
});
124126
}
125127
} else {
126-
doSignIn(authMethodManager, project).subscribe();
128+
doSignIn(authMethodManager, project).subscribe(r -> {
129+
if (r) {
130+
AzureAccount az = Azure.az(AzureAccount.class);
131+
authMethodManager.getAzureManager().getSelectedSubscriptions().stream().limit(5).forEach(s -> {
132+
// pre-load regions;
133+
az.listRegions(s.getId());
134+
});
135+
}
136+
137+
});
127138
}
128139
}
129140

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/helpers/MvpUIHelperImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public void showException(String msg, Exception e) {
2626

2727
@Deprecated
2828
@Override
29-
public String loadPasswordFromSecureStore(@NotNull String serviceName, @NotNull String userName) {
30-
return IdeaSecureStore.getInstance().loadPassword(serviceName, userName);
29+
public String loadPasswordFromSecureStore(@NotNull String key) {
30+
return IdeaSecureStore.getInstance().loadPassword(key);
3131
}
3232
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<xy x="0" y="0" width="604" height="346"/>
77
</constraints>
88
<properties>
9-
<minimumSize width="386" height="246"/>
9+
<minimumSize width="430" height="246"/>
1010
</properties>
1111
<border type="none"/>
1212
<children>
@@ -145,10 +145,11 @@
145145
<text value="JSON:"/>
146146
</properties>
147147
</component>
148-
<component id="9015b" class="com.microsoft.intellij.ui.AzureCommentLabel" binding="comment" custom-create="true">
148+
<component id="9015b" class="com.microsoft.azure.toolkit.intellij.common.AzureCommentLabel" binding="comment" custom-create="true">
149149
<constraints>
150150
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
151151
</constraints>
152+
<properties/>
152153
</component>
153154
</children>
154155
</grid>

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

Lines changed: 101 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import com.intellij.openapi.ide.CopyPasteManager;
1616
import com.intellij.openapi.project.Project;
1717
import com.intellij.openapi.ui.ComponentWithBrowseButton;
18-
import com.intellij.openapi.ui.DialogWrapper;
1918
import com.intellij.openapi.ui.TextComponentAccessor;
2019
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
2120
import com.intellij.openapi.ui.ValidationInfo;
@@ -26,15 +25,21 @@
2625
import com.intellij.ui.EditorTextField;
2726
import com.intellij.ui.EditorTextFieldProvider;
2827
import com.intellij.ui.SoftWrapsEditorCustomization;
28+
import com.microsoft.azure.toolkit.intellij.common.AzureCommentLabel;
29+
import com.microsoft.azure.toolkit.intellij.common.AzureDialog;
2930
import com.microsoft.azure.toolkit.intellij.common.TextDocumentListenerAdapter;
3031
import com.microsoft.azure.toolkit.lib.auth.model.AuthConfiguration;
3132
import com.microsoft.azure.toolkit.lib.auth.model.AuthType;
33+
import com.microsoft.azure.toolkit.lib.common.form.AzureForm;
34+
import com.microsoft.azure.toolkit.lib.common.form.AzureFormInput;
35+
import com.microsoft.azure.toolkit.lib.common.form.AzureValidationInfo;
3236
import com.microsoft.azuretools.azurecommons.util.FileUtil;
3337
import com.microsoft.azuretools.utils.JsonUtils;
3438
import org.apache.commons.lang3.StringUtils;
3539
import org.jetbrains.annotations.NotNull;
3640
import org.jetbrains.annotations.Nullable;
3741

42+
import javax.annotation.Nonnull;
3843
import javax.swing.JComponent;
3944
import javax.swing.JPanel;
4045
import javax.swing.JPasswordField;
@@ -47,6 +52,7 @@
4752
import java.io.File;
4853
import java.util.ArrayList;
4954
import java.util.Arrays;
55+
import java.util.Collections;
5056
import java.util.HashMap;
5157
import java.util.HashSet;
5258
import java.util.LinkedHashMap;
@@ -58,7 +64,9 @@
5864
import java.util.regex.Pattern;
5965
import java.util.stream.Stream;
6066

61-
public class ServicePrincipalLoginDialog extends DialogWrapper {
67+
public class ServicePrincipalLoginDialog extends AzureDialog<AuthConfiguration> implements AzureForm<AuthConfiguration> {
68+
private static final String GUID_REGEX = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"; //UUID v1-v5
69+
private static final Pattern GUID_PATTERN = Pattern.compile(GUID_REGEX, Pattern.CASE_INSENSITIVE);
6270
private JTextField clientIdTextField;
6371
private JTextField tenantIdTextField;
6472
private JPanel rootPanel;
@@ -69,17 +77,17 @@ public class ServicePrincipalLoginDialog extends DialogWrapper {
6977
private TextFieldWithBrowseButton certFileTextField;
7078
private AzureCommentLabel comment;
7179
private final Project project;
72-
private String memo; // save current json to avoid infinite update loops
7380
private boolean intermediateState = false;
81+
private AuthConfiguration auth = new AuthConfiguration();
7482

75-
private static final String GUID_REGEX = "^[{]?[0-9a-fA-F]{8}" + "-([0-9a-fA-F]{4}-)" + "{3}[0-9a-fA-F]{12}[}]?$";
7683

77-
protected ServicePrincipalLoginDialog(@Nullable Project project) {
78-
super(project, true);
84+
protected ServicePrincipalLoginDialog(@Nonnull Project project) {
85+
super(project);
7986
this.project = project;
80-
init();
87+
8188
$$$setupUI$$$(); // tell IntelliJ to call createUIComponents() here.
82-
this.setTitle("Sign in Service Principal");
89+
90+
init();
8391
super.setOKButtonText("Sign In");
8492

8593
pasteFromClipboard();
@@ -89,30 +97,27 @@ protected ServicePrincipalLoginDialog(@Nullable Project project) {
8997
FileChooserDescriptor pem = FileChooserDescriptorFactory.createSingleFileDescriptor("pem");
9098
pem.withFileFilter(file -> StringUtils.equalsIgnoreCase(file.getExtension(), "pem"));
9199
certFileTextField.addActionListener(new ComponentWithBrowseButton.BrowseFolderActionListener<>("Select Certificate File", null, certFileTextField, null,
92-
pem, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT) {
100+
pem, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT) {
93101
@Nullable
94102
protected VirtualFile getInitialFile() {
95103
return LocalFileSystem.getInstance().findFileByPath(FileUtil.getDirectoryWithinUserHome("/").toString());
96104
}
97105
});
98106

99107
Stream.of(clientIdTextField, tenantIdTextField, keyPasswordField, certFileTextField.getTextField()).map(JTextComponent::getDocument)
100-
.forEach(document -> document.addDocumentListener(new TextDocumentListenerAdapter() {
101-
@Override
102-
public void onDocumentChanged() {
103-
uiTextComponents2Json();
104-
}
105-
}));
108+
.forEach(document -> document.addDocumentListener(new TextDocumentListenerAdapter() {
109+
@Override
110+
public void onDocumentChanged() {
111+
uiTextComponents2Json();
112+
}
113+
}));
106114

107-
this.certificateRadioButton.addActionListener((e) -> uiTextComponents2Json());
108-
this.passwordRadioButton.addActionListener((e) -> uiTextComponents2Json());
115+
this.certificateRadioButton.addActionListener(e -> uiTextComponents2Json());
116+
this.passwordRadioButton.addActionListener(e -> uiTextComponents2Json());
109117

110118
this.jsonDataEditor.addDocumentListener(new DocumentListener() {
111119
@Override
112120
public void documentChanged(@NotNull DocumentEvent event) {
113-
if (jsonDataEditor.getText().equals(memo)) {
114-
return;
115-
}
116121
json2UIComponents(jsonDataEditor.getText());
117122
}
118123
});
@@ -128,43 +133,53 @@ public void documentChanged(@NotNull DocumentEvent event) {
128133
@Override
129134
protected @NotNull List<ValidationInfo> doValidateAll() {
130135
List<ValidationInfo> res = new ArrayList<>();
131-
AuthConfiguration auth = getData();
132-
if (StringUtils.isBlank(auth.getTenant())) {
136+
AuthConfiguration data = getData();
137+
if (StringUtils.isBlank(data.getTenant())) {
133138
res.add(new ValidationInfo("tenant is required.", tenantIdTextField));
134139
}
135-
if (!isGuid(auth.getTenant())) {
136-
res.add(new ValidationInfo("tenant should be a guild.", tenantIdTextField));
140+
if (!isGuid(data.getTenant())) {
141+
res.add(new ValidationInfo("tenant should be a valid guid.", tenantIdTextField));
137142
}
138143

139-
if (StringUtils.isBlank(auth.getClient())) {
144+
if (StringUtils.isBlank(data.getClient())) {
140145
res.add(new ValidationInfo("clientId(appId) is required.", clientIdTextField));
141146
}
142-
if (!isGuid(auth.getClient())) {
143-
res.add(new ValidationInfo("clientId(appId) should be a guild.", clientIdTextField));
147+
if (!isGuid(data.getClient())) {
148+
res.add(new ValidationInfo("clientId(appId) should be a valid guid.", clientIdTextField));
144149
}
145150

146151
if (this.passwordRadioButton.isSelected()) {
147-
if (StringUtils.isBlank(auth.getKey())) {
152+
if (StringUtils.isBlank(data.getKey())) {
148153
res.add(new ValidationInfo("Password is required.", keyPasswordField));
149154
}
150155
} else {
151-
if (StringUtils.isBlank(auth.getCertificate())) {
156+
if (StringUtils.isBlank(data.getCertificate())) {
152157
res.add(new ValidationInfo("Please select a cert file.", certFileTextField));
153-
} else if (!new File(auth.getCertificate()).exists()) {
158+
} else if (!new File(data.getCertificate()).exists()) {
154159
res.add(new ValidationInfo(String.format("Cannot find cert file(%s).", certFileTextField.getText()), certFileTextField));
155160
}
156161
}
157162
return res;
158163
}
159164

165+
@Override
166+
public AzureForm<AuthConfiguration> getForm() {
167+
return this;
168+
}
169+
170+
@Override
171+
protected String getDialogTitle() {
172+
return "Sign In - Service Principal";
173+
}
174+
160175
private void syncComponentStatusWhenRadioButtonChanges() {
161176
certFileTextField.setEnabled(certificateRadioButton.isSelected());
162177
keyPasswordField.setEnabled(passwordRadioButton.isSelected());
163178
}
164179

165180
private void createUIComponents() {
166181
this.jsonDataEditor = this.buildCodeViewer();
167-
this.comment = new AzureCommentLabel("You can copy the JSON result of 'az sp create ...' and paste it here");
182+
this.comment = new AzureCommentLabel("You can copy the JSON output of 'az sp create ...' and paste it here");
168183
}
169184

170185
private EditorTextField buildCodeViewer() {
@@ -178,22 +193,37 @@ private EditorTextField buildCodeViewer() {
178193
}
179194

180195
public AuthConfiguration getData() {
181-
AuthConfiguration auth = new AuthConfiguration();
196+
AuthConfiguration data = new AuthConfiguration();
182197

183-
auth.setClient(clientIdTextField.getText());
184-
auth.setTenant(tenantIdTextField.getText());
198+
data.setClient(clientIdTextField.getText());
199+
data.setTenant(tenantIdTextField.getText());
185200
if (passwordRadioButton.isSelected()) {
186-
auth.setKey(String.valueOf(keyPasswordField.getPassword()));
201+
data.setKey(String.valueOf(keyPasswordField.getPassword()));
187202
} else {
188-
auth.setCertificate(this.certFileTextField.getText());
203+
data.setCertificate(this.certFileTextField.getText());
189204
}
190-
auth.setType(AuthType.SERVICE_PRINCIPAL);
191-
return auth;
205+
data.setType(AuthType.SERVICE_PRINCIPAL);
206+
return data;
207+
}
208+
209+
@Override
210+
public void setData(AuthConfiguration data) {
211+
this.auth = data;
212+
}
213+
214+
@Override
215+
public List<AzureFormInput<?>> getInputs() {
216+
return new ArrayList<>();
217+
}
218+
219+
@Override
220+
public List<AzureValidationInfo> validateData() {
221+
return Collections.emptyList();
192222
}
193223

194224
private void pasteFromClipboard() {
195225
String textFromClip = findTextInClipboard(str ->
196-
StringUtils.contains(str, "appId") && StringUtils.contains(str, "tenant") && StringUtils.contains(str, "password")
226+
StringUtils.contains(str, "appId") && StringUtils.contains(str, "tenant") && StringUtils.contains(str, "password")
197227
);
198228
if (StringUtils.isNotBlank(textFromClip)) {
199229
json2UIComponents(textFromClip);
@@ -216,6 +246,8 @@ public static String findTextInClipboard(Predicate<String> func) {
216246
e.printStackTrace();
217247
}
218248
}
249+
// only for the first clip board
250+
break;
219251
}
220252

221253
return null;
@@ -226,47 +258,49 @@ private void uiTextComponents2Json() {
226258
return;
227259
}
228260
Map<String, String> map = new LinkedHashMap<>();
229-
AuthConfiguration auth = getData();
261+
AuthConfiguration data = getData();
230262

231263
if (this.certificateRadioButton.isSelected()) {
232-
map.put("fileWithCertAndPrivateKey", auth.getCertificate());
264+
map.put("fileWithCertAndPrivateKey", data.getCertificate());
233265
} else {
234-
String password = StringUtils.isNotBlank(auth.getKey()) ? "<hidden>" : "<empty>";
266+
String password = StringUtils.isNotBlank(data.getKey()) ? "<hidden>" : "<empty>";
235267
map.put("password", password);
236268
}
237-
map.put("appId", auth.getClient());
238-
map.put("tenant", auth.getTenant());
269+
map.put("appId", data.getClient());
270+
map.put("tenant", data.getTenant());
239271
String text = JsonUtils.getGson().toJson(map);
240-
memo = text;
241-
this.jsonDataEditor.setText(text);
242-
this.jsonDataEditor.setCaretPosition(0);
272+
if (!StringUtils.equals(jsonDataEditor.getText(), text)) {
273+
this.jsonDataEditor.setText(text);
274+
this.jsonDataEditor.setCaretPosition(0);
275+
}
243276
}
244277

245278
private void json2UIComponents(String json) {
246279
intermediateState = true;
247280
try {
248281
if (StringUtils.isNotBlank(json)) {
249282
try {
250-
Map<String, String> map = new HashMap<>();
251-
map = JsonUtils.fromJson(json, map.getClass());
283+
Map<String, String> map = JsonUtils.fromJson(json, HashMap.class);
252284
if (map != null) {
253-
if (map.containsKey("appId")) {
254-
this.clientIdTextField.setText(StringUtils.defaultString(map.get("appId")));
255-
}
256-
257-
if (map.containsKey("tenant")) {
258-
this.tenantIdTextField.setText(StringUtils.defaultString(map.get("tenant")));
259-
}
260-
261-
if (map.containsKey("password") && !isPlaceHolder(map.get("password"))) {
262-
this.passwordRadioButton.setSelected(true);
263-
this.keyPasswordField.setText(StringUtils.defaultString(map.get("password")));
264-
}
265-
266-
if (map.containsKey("fileWithCertAndPrivateKey")) {
267-
this.certificateRadioButton.setSelected(true);
268-
this.certFileTextField.setText(StringUtils.defaultString(map.get("fileWithCertAndPrivateKey")));
269-
}
285+
ApplicationManager.getApplication().invokeAndWait(() -> {
286+
if (map.containsKey("appId")) {
287+
this.clientIdTextField.setText(StringUtils.defaultString(map.get("appId")));
288+
}
289+
290+
if (map.containsKey("tenant")) {
291+
this.tenantIdTextField.setText(StringUtils.defaultString(map.get("tenant")));
292+
}
293+
294+
if (map.containsKey("password") && !isPlaceHolder(map.get("password"))) {
295+
this.passwordRadioButton.setSelected(true);
296+
this.keyPasswordField.setText(StringUtils.defaultString(map.get("password")));
297+
}
298+
299+
if (map.containsKey("fileWithCertAndPrivateKey")) {
300+
this.certificateRadioButton.setSelected(true);
301+
this.certFileTextField.setText(StringUtils.defaultString(map.get("fileWithCertAndPrivateKey")));
302+
}
303+
});
270304
}
271305

272306
} catch (JsonSyntaxException ex) {
@@ -283,11 +317,10 @@ private static boolean isPlaceHolder(String password) {
283317
}
284318

285319
private static boolean isGuid(String str) {
286-
final Pattern p = Pattern.compile(GUID_REGEX);
287320
if (StringUtils.isBlank(str)) {
288321
return false;
289322
}
290-
return p.matcher(str).matches();
323+
return GUID_PATTERN.matcher(str).matches();
291324
}
292325

293326
// CHECKSTYLE IGNORE check FOR NEXT 1 LINES

0 commit comments

Comments
 (0)