reduce usages of PasswordStorage

This commit is contained in:
Vladimir Krivosheev
2018-10-10 10:21:34 +02:00
parent c16cbc28f0
commit 9e567d04a3
11 changed files with 55 additions and 106 deletions
@@ -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<CredentialStoreFactory> CREDENTIAL_STORE_FACTORY = ExtensionPointName.create("com.intellij.credentialStore");
@Nullable
PasswordStorage create();
CredentialStore create();
}
@@ -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"))
}
@@ -214,7 +214,7 @@ internal class KeePassCredentialStore constructor(internal val dbFile: Path,
}
}
internal fun copyTo(from: Map<CredentialAttributes, Credentials>, store: PasswordStorage) {
internal fun copyTo(from: Map<CredentialAttributes, Credentials>, store: CredentialStore) {
for ((k, v) in from) {
store.set(k, v)
}
@@ -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")
@@ -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);
}
@@ -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);
}
@@ -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()));
}
@@ -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()));
}
}
}
@@ -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()
@@ -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) {
@@ -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<IpnbSettings> {
private static final String IPNB_PASSWORD_KEY = "IPNB_SSH_SETTINGS_PASSWORD_KEY";
@@ -64,7 +67,7 @@ public class IpnbSettings implements PersistentStateComponent<IpnbSettings> {
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) {