From 9e567d04a30bfab73a970d147b1e87f43cb3e58e Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 8 Oct 2018 17:44:44 +0200 Subject: [PATCH] reduce usages of PasswordStorage --- .../src/CredentialStoreFactory.java | 19 +------- .../src/CredentialStoreWrapper.kt | 7 ++- .../src/KeePassCredentialStore.kt | 2 +- .../credential-store/src/PasswordSafeImpl.kt | 2 +- .../ide/passwordSafe/PasswordStorage.java | 21 ++++----- .../providers/BasePasswordSafeProvider.java | 43 ------------------- .../impl/providers/EncryptionUtil.java | 18 +------- .../providers/memory/MemoryPasswordSafe.java | 32 +++++++++++--- .../util/GithubAccountsMigrationHelper.kt | 6 --- .../facet/AppEngineAccountDialog.java | 6 ++- .../ipnb/configuration/IpnbSettings.java | 5 ++- 11 files changed, 55 insertions(+), 106 deletions(-) delete mode 100644 platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java diff --git a/platform/credential-store/src/CredentialStoreFactory.java b/platform/credential-store/src/CredentialStoreFactory.java index b9cc5a0e85a2..068d80d97f70 100644 --- a/platform/credential-store/src/CredentialStoreFactory.java +++ b/platform/credential-store/src/CredentialStoreFactory.java @@ -1,21 +1,6 @@ -/* - * Copyright 2000-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.credentialStore; -import com.intellij.ide.passwordSafe.PasswordStorage; import com.intellij.openapi.extensions.ExtensionPointName; import org.jetbrains.annotations.Nullable; @@ -23,5 +8,5 @@ public interface CredentialStoreFactory { ExtensionPointName CREDENTIAL_STORE_FACTORY = ExtensionPointName.create("com.intellij.credentialStore"); @Nullable - PasswordStorage create(); + CredentialStore create(); } diff --git a/platform/credential-store/src/CredentialStoreWrapper.kt b/platform/credential-store/src/CredentialStoreWrapper.kt index 3853dbee3097..11fb82c80f92 100644 --- a/platform/credential-store/src/CredentialStoreWrapper.kt +++ b/platform/credential-store/src/CredentialStoreWrapper.kt @@ -2,7 +2,6 @@ package com.intellij.credentialStore import com.google.common.cache.CacheBuilder -import com.intellij.ide.passwordSafe.PasswordStorage import com.intellij.notification.NotificationDisplayType import com.intellij.notification.NotificationGroup import com.intellij.notification.NotificationType @@ -21,7 +20,7 @@ internal val NOTIFICATION_MANAGER by lazy { SingletonNotificationManager(NotificationGroup("Password Safe", NotificationDisplayType.STICKY_BALLOON, true), NotificationType.ERROR) } -private class CredentialStoreWrapper(private val store: CredentialStore) : PasswordStorage { +private class CredentialStoreWrapper(private val store: CredentialStore) : CredentialStore { private val fallbackStore = lazy { createInMemoryKeePassCredentialStore() } private val queueProcessor = QueueProcessor<() -> Unit> { it() } @@ -98,7 +97,7 @@ private fun notifyUnsatisfiedLinkError(e: UnsatisfiedLinkError) { } private class MacOsCredentialStoreFactory : CredentialStoreFactory { - override fun create(): PasswordStorage? { + override fun create(): CredentialStore? { if (isMacOsCredentialStoreSupported && SystemProperties.getBooleanProperty("use.mac.keychain", true)) { return CredentialStoreWrapper(KeyChainCredentialStore()) } @@ -107,7 +106,7 @@ private class MacOsCredentialStoreFactory : CredentialStoreFactory { } private class LinuxSecretCredentialStoreFactory : CredentialStoreFactory { - override fun create(): PasswordStorage? { + override fun create(): CredentialStore? { if (SystemInfo.isLinux && SystemProperties.getBooleanProperty("use.linux.keychain", true)) { return CredentialStoreWrapper(SecretCredentialStore("com.intellij.credentialStore.Credential")) } diff --git a/platform/credential-store/src/KeePassCredentialStore.kt b/platform/credential-store/src/KeePassCredentialStore.kt index 8cb9569a460d..32144ddbed15 100644 --- a/platform/credential-store/src/KeePassCredentialStore.kt +++ b/platform/credential-store/src/KeePassCredentialStore.kt @@ -214,7 +214,7 @@ internal class KeePassCredentialStore constructor(internal val dbFile: Path, } } -internal fun copyTo(from: Map, store: PasswordStorage) { +internal fun copyTo(from: Map, store: CredentialStore) { for ((k, v) in from) { store.set(k, v) } diff --git a/platform/credential-store/src/PasswordSafeImpl.kt b/platform/credential-store/src/PasswordSafeImpl.kt index 9fd8e5c7a3cd..b1bfce1ae93a 100644 --- a/platform/credential-store/src/PasswordSafeImpl.kt +++ b/platform/credential-store/src/PasswordSafeImpl.kt @@ -187,7 +187,7 @@ class PasswordSafeImpl @JvmOverloads constructor(val settings: PasswordSafeSetti get() = memoryHelperProvider.value } -internal fun createPersistentCredentialStore(): PasswordStorage? { +internal fun createPersistentCredentialStore(): CredentialStore? { LOG.runAndLogException { for (factory in CredentialStoreFactory.CREDENTIAL_STORE_FACTORY.extensionList) { @Suppress("UnnecessaryVariable") diff --git a/platform/platform-api/src/com/intellij/ide/passwordSafe/PasswordStorage.java b/platform/platform-api/src/com/intellij/ide/passwordSafe/PasswordStorage.java index 7ebe99f7957c..a1090edd508a 100644 --- a/platform/platform-api/src/com/intellij/ide/passwordSafe/PasswordStorage.java +++ b/platform/platform-api/src/com/intellij/ide/passwordSafe/PasswordStorage.java @@ -1,7 +1,7 @@ // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.passwordSafe; -import com.intellij.credentialStore.CredentialStore; +import com.intellij.credentialStore.CredentialAttributes; import com.intellij.credentialStore.Credentials; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; @@ -9,19 +9,14 @@ import org.jetbrains.annotations.Nullable; import static com.intellij.credentialStore.CredentialAttributesKt.CredentialAttributes; -public interface PasswordStorage extends CredentialStore { - @Deprecated - default void setPassword(@NotNull Class requestor, @NotNull String accountName, @Nullable String value) { - set(CredentialAttributes(requestor, accountName), value == null ? null : new Credentials(accountName, value)); - } - +public interface PasswordStorage { /** * @deprecated Please use {@link #setPassword} and pass value as null */ @SuppressWarnings("unused") @Deprecated default void removePassword(@SuppressWarnings("UnusedParameters") @Nullable Project project, @NotNull Class requestor, String key) { - setPassword(requestor, key, null); + set(CredentialAttributes(requestor, key), null); } /** @@ -29,12 +24,18 @@ public interface PasswordStorage extends CredentialStore { */ @Deprecated default void storePassword(@SuppressWarnings("UnusedParameters") @Nullable Project project, @NotNull Class requestor, @NotNull String key, @Nullable String value) { - setPassword(requestor, key, value); + set(CredentialAttributes(requestor, key), value == null ? null : new Credentials(key, value)); } @Deprecated @Nullable default String getPassword(@SuppressWarnings("UnusedParameters") @Nullable Project project, @NotNull Class requestor, @NotNull String key) { - return getPassword(CredentialAttributes(requestor, key)); + Credentials credentials = get(CredentialAttributes(requestor, key)); + return credentials == null ? null : credentials.getPasswordAsString(); } + + @Nullable + Credentials get(@NotNull CredentialAttributes attributes); + + void set(@NotNull CredentialAttributes attributes, @Nullable Credentials credentials); } 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 deleted file mode 100644 index b8b50200ade8..000000000000 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.ide.passwordSafe.impl.providers; - -import com.intellij.credentialStore.CredentialAttributes; -import com.intellij.credentialStore.Credentials; -import com.intellij.credentialStore.OneTimeString; -import com.intellij.ide.passwordSafe.PasswordStorage; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public abstract class BasePasswordSafeProvider implements PasswordStorage { - /** - * Get secret key for the provider - */ - @NotNull - protected abstract byte[] key(); - - @Override - @Nullable - public Credentials get(@NotNull CredentialAttributes attributes) { - byte[] masterKey = key(); - byte[] encryptedPassword = getEncryptedPassword(EncryptionUtil.encryptKey(masterKey, EncryptionUtil.rawKey(attributes))); - OneTimeString password = encryptedPassword == null ? null : EncryptionUtil.decryptText(masterKey, encryptedPassword); - return password == null ? null : new Credentials(attributes.getUserName(), password); - } - - protected abstract byte[] getEncryptedPassword(@NotNull byte[] key); - - protected abstract void removeEncryptedPassword(byte[] key); - - @Override - public final void set(@NotNull CredentialAttributes attributes, @Nullable Credentials value) { - byte[] key = EncryptionUtil.encryptKey(key(), EncryptionUtil.rawKey(attributes)); - if (value == null || value.getPassword() == null) { - removeEncryptedPassword(key); - } - else { - storeEncryptedPassword(key, EncryptionUtil.encryptText(key(), value.getPassword())); - } - } - - protected abstract void storeEncryptedPassword(byte[] key, byte[] encryptedPassword); -} diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/EncryptionUtil.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/EncryptionUtil.java index c963434c5f10..51412bf1e67e 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/EncryptionUtil.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/EncryptionUtil.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.passwordSafe.impl.providers; import com.intellij.credentialStore.CredentialAttributes; @@ -77,7 +63,7 @@ public class EncryptionUtil { // do nothing } - static byte[] rawKey(@NotNull CredentialAttributes attributes) { + public static byte[] rawKey(@NotNull CredentialAttributes attributes) { return hash(getUTF8Bytes(attributes.getServiceName() + "/" + attributes.getUserName())); } diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java index 18d960240893..b6866e20fafc 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java @@ -1,13 +1,17 @@ // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.passwordSafe.impl.providers.memory; +import com.intellij.credentialStore.CredentialAttributes; +import com.intellij.credentialStore.Credentials; +import com.intellij.credentialStore.OneTimeString; +import com.intellij.ide.passwordSafe.PasswordStorage; import com.intellij.ide.passwordSafe.impl.PasswordSafeTimed; -import com.intellij.ide.passwordSafe.impl.providers.BasePasswordSafeProvider; import com.intellij.ide.passwordSafe.impl.providers.ByteArrayWrapper; import com.intellij.ide.passwordSafe.impl.providers.EncryptionUtil; import com.intellij.openapi.util.registry.Registry; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.security.SecureRandom; import java.util.Collections; @@ -21,7 +25,7 @@ import java.util.concurrent.atomic.AtomicReference; */ @Deprecated // used in https://github.com/groboclown/p4ic4idea, cannot be deleted -public class MemoryPasswordSafe extends BasePasswordSafeProvider { +public class MemoryPasswordSafe implements PasswordStorage { /** * The key to use to encrypt data */ @@ -46,7 +50,6 @@ public class MemoryPasswordSafe extends BasePasswordSafeProvider { } @NotNull - @Override protected byte[] key() { if (key.get() == null) { byte[] rnd = new byte[EncryptionUtil.SECRET_KEY_SIZE_BYTES * 16]; @@ -56,17 +59,14 @@ public class MemoryPasswordSafe extends BasePasswordSafeProvider { return key.get(); } - @Override protected byte[] getEncryptedPassword(@NotNull byte[] key) { return database.get().get(new ByteArrayWrapper(key)); } - @Override protected void removeEncryptedPassword(byte[] key) { database.get().remove(new ByteArrayWrapper(key)); } - @Override protected void storeEncryptedPassword(byte[] key, byte[] encryptedPassword) { database.get().put(new ByteArrayWrapper(key), encryptedPassword); } @@ -74,4 +74,24 @@ public class MemoryPasswordSafe extends BasePasswordSafeProvider { public void clear() { database.get().clear(); } + + @Override + @Nullable + public Credentials get(@NotNull CredentialAttributes attributes) { + byte[] masterKey = key(); + byte[] encryptedPassword = getEncryptedPassword(EncryptionUtil.encryptKey(masterKey, EncryptionUtil.rawKey(attributes))); + OneTimeString password = encryptedPassword == null ? null : EncryptionUtil.decryptText(masterKey, encryptedPassword); + return password == null ? null : new Credentials(attributes.getUserName(), password); + } + + @Override + public final void set(@NotNull CredentialAttributes attributes, @Nullable Credentials value) { + byte[] key = EncryptionUtil.encryptKey(key(), EncryptionUtil.rawKey(attributes)); + if (value == null || value.getPassword() == null) { + removeEncryptedPassword(key); + } + else { + storeEncryptedPassword(key, EncryptionUtil.encryptText(key(), value.getPassword())); + } + } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubAccountsMigrationHelper.kt b/plugins/github/src/org/jetbrains/plugins/github/util/GithubAccountsMigrationHelper.kt index b9b4c714bd72..c27204560ed6 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubAccountsMigrationHelper.kt +++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubAccountsMigrationHelper.kt @@ -104,7 +104,6 @@ class GithubAccountsMigrationHelper internal constructor(private val settings: G } } } - if (!dialogCancelled) clearOldAuth() return !dialogCancelled } @@ -123,11 +122,6 @@ class GithubAccountsMigrationHelper internal constructor(private val settings: G LOG.debug("Registered account $account") } - private fun clearOldAuth() { - settings.clearAuth() - passwordSafe.setPassword(GithubSettings::class.java, GITHUB_SETTINGS_PASSWORD_KEY, null) - } - companion object { @JvmStatic fun getInstance(): GithubAccountsMigrationHelper = service() diff --git a/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineAccountDialog.java b/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineAccountDialog.java index 366f7febfa93..28511f6ee036 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineAccountDialog.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineAccountDialog.java @@ -5,6 +5,7 @@ import com.intellij.appengine.cloud.AppEngineAuthData; import com.intellij.appengine.cloud.AppEngineCloudConfigurable; import com.intellij.appengine.cloud.AppEngineServerConfiguration; import com.intellij.credentialStore.CredentialAttributesKt; +import com.intellij.credentialStore.Credentials; import com.intellij.ide.passwordSafe.PasswordSafe; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.Project; @@ -12,6 +13,8 @@ import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static com.intellij.credentialStore.CredentialAttributesKt.CredentialAttributes; + /** * @author nik */ @@ -44,7 +47,8 @@ public class AppEngineAccountDialog { } public static void storePassword(@NotNull String email, @NotNull String password) { - PasswordSafe.getInstance().setPassword(AppEngineAccountDialog.class, getPasswordKey(email), password); + String accountName = getPasswordKey(email); + PasswordSafe.getInstance().set(CredentialAttributes(AppEngineAccountDialog.class, accountName), password == null ? null : new Credentials(accountName, password)); } private static String getPasswordKey(String email) { diff --git a/python/ipnb/src/org/jetbrains/plugins/ipnb/configuration/IpnbSettings.java b/python/ipnb/src/org/jetbrains/plugins/ipnb/configuration/IpnbSettings.java index 605cd5095273..933a11972422 100644 --- a/python/ipnb/src/org/jetbrains/plugins/ipnb/configuration/IpnbSettings.java +++ b/python/ipnb/src/org/jetbrains/plugins/ipnb/configuration/IpnbSettings.java @@ -2,6 +2,7 @@ package org.jetbrains.plugins.ipnb.configuration; import com.intellij.credentialStore.CredentialAttributesKt; +import com.intellij.credentialStore.Credentials; import com.intellij.ide.passwordSafe.PasswordSafe; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ServiceManager; @@ -14,6 +15,8 @@ import javafx.application.Platform; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static com.intellij.credentialStore.CredentialAttributesKt.CredentialAttributes; + @State(name = "IpnbSettings") public class IpnbSettings implements PersistentStateComponent { private static final String IPNB_PASSWORD_KEY = "IPNB_SSH_SETTINGS_PASSWORD_KEY"; @@ -64,7 +67,7 @@ public class IpnbSettings implements PersistentStateComponent { final String username = getUsername(); final String url = ""; final String accountName = createAccountName(username, url, projectPathHash); - PasswordSafe.getInstance().setPassword(IpnbSettings.class, accountName, password); + PasswordSafe.getInstance().set(CredentialAttributes(IpnbSettings.class, accountName), password == null ? null : new Credentials(accountName, password)); } private static String createAccountName(@NotNull String username, @NotNull String url, @NotNull String projectPath) {