Skip to content

Commit e74e3c5

Browse files
authored
Merge pull request #5643 from microsoft/fix-bug-1863833
[Bugfix 1863833]: support cancel login
2 parents 2b787dd + c131989 commit e74e3c5

File tree

1 file changed

+32
-10
lines changed

1 file changed

+32
-10
lines changed

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

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@
4343
import com.microsoft.intellij.helpers.UIHelperImpl;
4444
import com.microsoft.intellij.serviceexplorer.azure.SignInOutAction;
4545
import com.microsoft.intellij.ui.DeviceLoginUI;
46+
import com.microsoft.intellij.ui.ErrorWindow;
4647
import com.microsoft.intellij.ui.ServicePrincipalLoginDialog;
4748
import com.microsoft.intellij.ui.SignInWindow;
4849
import com.microsoft.intellij.util.AzureLoginHelper;
4950
import com.microsoft.tooling.msservices.components.DefaultLoader;
5051
import com.microsoft.tooling.msservices.serviceexplorer.AzureIconSymbol;
52+
import lombok.Lombok;
5153
import org.apache.commons.collections4.CollectionUtils;
5254
import org.apache.commons.lang3.StringUtils;
5355
import org.jetbrains.annotations.NotNull;
@@ -64,6 +66,9 @@
6466
import java.util.Map;
6567
import java.util.Optional;
6668
import java.util.concurrent.Callable;
69+
import java.util.concurrent.CancellationException;
70+
import java.util.concurrent.CompletableFuture;
71+
import java.util.function.Supplier;
6772

6873
import static com.microsoft.azuretools.telemetry.TelemetryConstants.ACCOUNT;
6974
import static com.microsoft.azuretools.telemetry.TelemetryConstants.AZURE_ENVIRONMENT;
@@ -76,6 +81,7 @@ public class AzureSignInAction extends AzureAnAction {
7681
private static final Logger LOGGER = Logger.getInstance(AzureSignInAction.class);
7782
private static final String SIGN_IN = "Azure Sign In...";
7883
private static final String SIGN_OUT = "Azure Sign Out...";
84+
private static final String SIGN_IN_ERROR = "Sign In Error";
7985

8086
public AzureSignInAction() {
8187
super(AuthMethodManager.getInstance().isSignedIn() ? SIGN_OUT : SIGN_IN);
@@ -241,11 +247,22 @@ private static Mono<Boolean> signInIfNotSignedInInternal(Project project) {
241247
if (auth.getType() != AuthType.DEVICE_CODE) {
242248
single = loginNonDeviceCodeSingle(auth);
243249
} else {
244-
245250
single = loginDeviceCodeSingle().map(account -> {
246251
AzureTaskManager.getInstance().runLater(() -> deviceLoginUI.promptDeviceCode(account.getDeviceCode()));
247-
return account.continueLogin().map(ac -> fromAccountEntity(ac.getEntity())).doFinally(signal ->
248-
deviceLoginUI.closePrompt()).subscribeOn(Schedulers.boundedElastic()).block();
252+
253+
CompletableFuture<AuthMethodDetails> future =
254+
account.continueLogin().map(ac -> fromAccountEntity(ac.getEntity())).doFinally(signal -> deviceLoginUI.closePrompt()).toFuture();
255+
deviceLoginUI.setFuture(future);
256+
257+
try {
258+
return future.get();
259+
} catch (Throwable ex) {
260+
if (!(ex instanceof CancellationException)) {
261+
ex.printStackTrace();
262+
ErrorWindow.show(project, ex.getMessage(), SIGN_IN_ERROR);
263+
}
264+
return new AuthMethodDetails();
265+
}
249266
});
250267
}
251268

@@ -275,7 +292,9 @@ private static Single<DeviceCodeAccount> loginDeviceCodeSingle() {
275292
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
276293
indicator.setIndeterminate(true);
277294
final AzureAccount az = Azure.az(AzureAccount.class);
278-
return (DeviceCodeAccount) az.loginAsync(AuthType.DEVICE_CODE, true).block();
295+
return (DeviceCodeAccount) checkCanceled(indicator, az.loginAsync(AuthType.DEVICE_CODE, true), () -> {
296+
throw Lombok.sneakyThrow(new InterruptedException("user cancel"));
297+
});
279298
});
280299
return AzureTaskManager.getInstance().runInBackgroundAsObservable(deviceCodeTask).toSingle();
281300
}
@@ -295,13 +314,16 @@ private static AuthMethodDetails doLogin(ProgressIndicator indicator, AuthConfig
295314
AuthMethodDetails authMethodDetailsResult = new AuthMethodDetails();
296315
switch (auth.getType()) {
297316
case SERVICE_PRINCIPAL:
298-
authMethodDetailsResult = call(() -> checkCanceled(indicator, IdentityAzureManager.getInstance().signInServicePrincipal(auth)), "sp");
317+
authMethodDetailsResult = call(() -> checkCanceled(indicator, IdentityAzureManager.getInstance().signInServicePrincipal(auth),
318+
AuthMethodDetails::new), "sp");
299319
break;
300320
case AZURE_CLI:
301-
authMethodDetailsResult = call(() -> checkCanceled(indicator, IdentityAzureManager.getInstance().signInAzureCli()), "az");
321+
authMethodDetailsResult = call(() -> checkCanceled(indicator, IdentityAzureManager.getInstance().signInAzureCli(),
322+
AuthMethodDetails::new), "az");
302323
break;
303324
case OAUTH2:
304-
authMethodDetailsResult = call(() -> checkCanceled(indicator, IdentityAzureManager.getInstance().signInOAuth()), "oauth");
325+
authMethodDetailsResult = call(() -> checkCanceled(indicator, IdentityAzureManager.getInstance().signInOAuth(),
326+
AuthMethodDetails::new), "oauth");
305327
break;
306328
default:
307329
break;
@@ -328,9 +350,9 @@ private static <T> T call(Callable<T> loginCallable, String authMethod) {
328350
}
329351
}
330352

331-
private static AuthMethodDetails checkCanceled(ProgressIndicator indicator, Mono<? extends AuthMethodDetails> mono) {
332-
final Mono<AuthMethodDetails> cancelMono = Flux.interval(Duration.ofSeconds(1)).map(ignore -> indicator.isCanceled())
333-
.any(cancel -> cancel).map(ignore -> new AuthMethodDetails()).subscribeOn(Schedulers.boundedElastic());
353+
private static <T> T checkCanceled(ProgressIndicator indicator, Mono<? extends T> mono, Supplier<T> supplier) {
354+
final Mono<T> cancelMono = Flux.interval(Duration.ofSeconds(1)).map(ignore -> indicator.isCanceled())
355+
.any(cancel -> cancel).map(ignore -> supplier.get()).subscribeOn(Schedulers.boundedElastic());
334356
return Mono.firstWithSignal(cancelMono, mono.subscribeOn(Schedulers.boundedElastic())).block();
335357
}
336358

0 commit comments

Comments
 (0)