From 1a5cf59c9ce803c4a48379fea424e86aec3fdd4b Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 17 Jul 2014 16:23:18 +0400 Subject: [PATCH] IDEA-127343 Pass ModalityState to PasswordSafe.store/removePassword Since PasswordSafe may request for the master password, and since this request can be made from any thread, it needs the proper ModalityState to execute invokeAndWait(), otherwise the master password dialog won't appear above some modal progresses which requested the password, just like in IDEA-127343. getPassword & underlying methods actually showing the dialog were patched in 1396322, but store- and removePassword may happen before any getPassword request, so they also must be patched. --- .../ide/passwordSafe/PasswordStorage.java | 75 +++++++++++++------ .../passwordSafe/impl/PasswordSafeImpl.java | 23 +++++- .../impl/PasswordSafeProvider.java | 10 +++ .../providers/BasePasswordSafeProvider.java | 12 +-- .../impl/providers/nil/NilProvider.java | 8 +- 5 files changed, 93 insertions(+), 35 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java index 6b09b2266d7b..e5b9f1530256 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java @@ -25,15 +25,21 @@ import org.jetbrains.annotations.Nullable; * The interface defines basic password management operations */ public interface PasswordStorage { + /** - *

Get password stored in a password safe.

- * - *

NB: - * This method may be called from the background, - * and it may need to ask user to enter the master password to access the database by calling - * {@link Application#invokeAndWait(Runnable, ModalityState) invokeAndWait()} to show a modal dialog. - * So make sure not to call it from the read action. - * Calling this method from the dispatch thread is allowed.

+ * @deprecated To remove in IDEA 15. Use {@link #getPassword(Project, Class, String, ModalityState)} + */ + @Deprecated + @Nullable + String getPassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException; + + /** + * Get password stored in a password safe. + *

+ * The method may be called from any thread. It may need to show a master password dialog to unlock the password database, + * and then will use {@link Application#invokeAndWait(Runnable, ModalityState) invokeAndWait()}. + * So make sure to pass correct {@link ModalityState} to the method to make sure the dialog is shown above all other dialog or progress + * windows. * * @param project the project, that is used to ask for the master password if this is the first access to password safe * @param requestor the requestor class @@ -41,28 +47,18 @@ public interface PasswordStorage { * @return the stored password or null if the password record was not found or was removed * @throws PasswordSafeException if password safe cannot be accessed * @throws IllegalStateException if the method is called from the read action. - * - * @deprecated To remove in IDEA 15. Use {@link #getPassword(Project, Class, String, ModalityState)} */ - @Deprecated - @Nullable - String getPassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException; - @Nullable String getPassword(@Nullable Project project, @NotNull Class requestor, String key, @Nullable ModalityState state) throws PasswordSafeException; - /** - * Remove password stored in a password safe - * - * @param project the project, that is used to ask for the master password if this is the first access to password safe - * @param requestor the requestor class - * @param key the key for the password - * @return the plugin key - * @throws PasswordSafeException if password safe cannot be accessed - */ - void removePassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException; + /** * Store password in password safe + *

+ * The method may be called from any thread. It may need to show a master password dialog to unlock the password database, + * and then will use {@link Application#invokeAndWait(Runnable, ModalityState) invokeAndWait()}. + * So make sure to pass correct {@link ModalityState} to the method to make sure the dialog is shown above all other dialog or progress + * windows. * * @param project the project, that is used to ask for the master password if this is the first access to password safe * @param requestor the requestor class @@ -70,5 +66,36 @@ public interface PasswordStorage { * @param value the value to store * @throws PasswordSafeException if password safe cannot be accessed */ + void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value, + @Nullable ModalityState modalityState) throws PasswordSafeException; + + /** + * @deprecated To remove in IDEA 15. Use {@link #storePassword(Project, Class, String, String, ModalityState)} + */ + @Deprecated void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException; + + /** + * @deprecated To remove in IDEA 15. Use {@link #removePassword(Project, Class, String, ModalityState)} + */ + @Deprecated + void removePassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException; + + /** + * Remove password stored in a password safe + *

+ * The method may be called from any thread. It may need to show a master password dialog to unlock the password database, + * and then will use {@link Application#invokeAndWait(Runnable, ModalityState) invokeAndWait()}. + * So make sure to pass correct {@link ModalityState} to the method to make sure the dialog is shown above all other dialog or progress + * windows. + * + * @param project the project, that is used to ask for the master password if this is the first access to password safe + * @param requestor the requestor class + * @param key the key for the password + * @return the plugin key + * @throws PasswordSafeException if password safe cannot be accessed + */ + void removePassword(@Nullable Project project, @NotNull Class requestor, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException; + } diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java index e71f18cfdaf9..34aee7aaad38 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java @@ -71,6 +71,7 @@ public class PasswordSafeImpl extends PasswordSafe { } @Nullable + @Override public String getPassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException { return getPassword(project, requester, key, null); } @@ -93,18 +94,32 @@ public class PasswordSafeImpl extends PasswordSafe { return provider().getPassword(project, requester, key, modalityState); } - public void removePassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException { + @Override + public void removePassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException { + removePassword(project, requestor, key, null); + } + + @Override + public void removePassword(@Nullable Project project, @NotNull Class requester, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException { if (mySettings.getProviderType().equals(PasswordSafeSettings.ProviderType.MASTER_PASSWORD)) { getMemoryProvider().removePassword(project, requester, key); } - provider().removePassword(project, requester, key); + provider().removePassword(project, requester, key, modalityState); } - public void storePassword(@Nullable Project project, @NotNull Class requester, String key, String value) throws PasswordSafeException { + @Override + public void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException { + storePassword(project, requestor, key, value, null); + } + + @Override + public void storePassword(@Nullable Project project, @NotNull Class requester, String key, String value, + @Nullable ModalityState modalityState) throws PasswordSafeException { if (mySettings.getProviderType().equals(PasswordSafeSettings.ProviderType.MASTER_PASSWORD)) { getMemoryProvider().storePassword(project, requester, key, value); } - provider().storePassword(project, requester, key, value); + provider().storePassword(project, requester, key, value, modalityState); } /** diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java index bf531277b130..3a40d617e99b 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java @@ -45,4 +45,14 @@ public abstract class PasswordSafeProvider implements PasswordStorage { return getPassword(project, requestor, key, null); } + @Override + public void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException { + storePassword(project, requestor, key, value, null); + } + + @Override + public void removePassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException { + removePassword(project, requestor, key, null); + } + } diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java index 6d52ce8756cf..8c8f921f18b8 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java @@ -76,8 +76,9 @@ public abstract class BasePasswordSafeProvider extends PasswordSafeProvider { return EncryptionUtil.dbKey(key(project, requestor, modalityState), requestor, key); } - public void removePassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException { - byte[] k = dbKey(project, requester, key, null); + public void removePassword(@Nullable Project project, @NotNull Class requester, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException { + byte[] k = dbKey(project, requester, key, modalityState); removeEncryptedPassword(k); } @@ -88,9 +89,10 @@ public abstract class BasePasswordSafeProvider extends PasswordSafeProvider { */ protected abstract void removeEncryptedPassword(byte[] key); - public void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException { - byte[] k = dbKey(project, requestor, key, null); - byte[] ct = EncryptionUtil.encryptText(key(project, requestor, null), value); + public void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value, + @Nullable ModalityState modalityState) throws PasswordSafeException { + byte[] k = dbKey(project, requestor, key, modalityState); + byte[] ct = EncryptionUtil.encryptText(key(project, requestor, modalityState), value); storeEncryptedPassword(k, ct); } diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java index 2c83b195d912..e3a77325b06e 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java @@ -49,11 +49,15 @@ public final class NilProvider extends PasswordSafeProvider { return null; } - public void removePassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException { + @Override + public void removePassword(@Nullable Project project, @NotNull Class requester, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException { // do nothing } - public void storePassword(@Nullable Project project, @NotNull Class requester, String key, String value) throws PasswordSafeException { + @Override + public void storePassword(@Nullable Project project, @NotNull Class requester, String key, String value, + @Nullable ModalityState modalityState) throws PasswordSafeException { // just forget about password } }