notify about missed native lib on set

This commit is contained in:
Vladimir Krivosheev
2016-09-05 18:14:31 +02:00
parent 9e8f2a30cc
commit 57b69f74be
@@ -22,6 +22,7 @@ import com.intellij.ide.passwordSafe.PasswordStorage
import com.intellij.notification.NotificationGroup
import com.intellij.notification.NotificationType
import com.intellij.notification.SingletonNotificationManager
import com.intellij.openapi.application.ApplicationNamesInfo
import com.intellij.openapi.application.ex.ApplicationInfoEx
import com.intellij.openapi.diagnostic.catchAndLog
import com.intellij.openapi.util.SystemInfo
@@ -29,7 +30,7 @@ import com.intellij.util.SystemProperties
import com.intellij.util.concurrency.QueueProcessor
import com.intellij.util.containers.ContainerUtil
private val nullPassword = Credentials("\u0000", OneTimeString("\u0000"))
private val nullCredentials = Credentials("\u0000", OneTimeString("\u0000"))
private val NOTIFICATION_MANAGER by lazy {
// we use name "Password Safe" instead of "Credentials Store" because it was named so previously (and no much sense to rename it)
@@ -39,15 +40,13 @@ private val NOTIFICATION_MANAGER by lazy {
private class CredentialStoreWrapper(private val store: CredentialStore) : PasswordStorage {
private val fallbackStore = lazy { KeePassCredentialStore(memoryOnly = true) }
private val queueProcessor = QueueProcessor<() -> Unit>({
it()
})
private val queueProcessor = QueueProcessor<() -> Unit>({ it() })
private val postponedCredentials = ContainerUtil.newConcurrentMap<CredentialAttributes, Credentials>()
override fun get(attributes: CredentialAttributes): Credentials? {
postponedCredentials.get(attributes)?.let {
return if (it == nullPassword) null else it
return if (it == nullCredentials) null else it
}
var store = if (fallbackStore.isInitialized()) fallbackStore.value else store
@@ -61,8 +60,7 @@ private class CredentialStoreWrapper(private val store: CredentialStore) : Passw
}
catch (e: UnsatisfiedLinkError) {
store = fallbackStore.value
LOG.error(e)
NOTIFICATION_MANAGER.notify("Native Keychain is not used", "Failed to use native keychain — credentials will be stored in memory (until application is closed).")
notifyUnsatisfiedLinkError(e)
return store.get(attributes)
}
catch (e: Throwable) {
@@ -93,29 +91,44 @@ private class CredentialStoreWrapper(private val store: CredentialStore) : Passw
}
override fun set(attributes: CredentialAttributes, credentials: Credentials?) {
LOG.catchAndLog {
val store = if (fallbackStore.isInitialized()) fallbackStore.value else store
if (fallbackStore.isInitialized()) {
fun doSave() {
var store = if (fallbackStore.isInitialized()) fallbackStore.value else store
try {
store.set(attributes, credentials)
}
catch (e: UnsatisfiedLinkError) {
store = fallbackStore.value
notifyUnsatisfiedLinkError(e)
store.set(attributes, credentials)
}
catch (e: Throwable) {
LOG.error(e)
}
postponedCredentials.remove(attributes)
}
LOG.catchAndLog {
if (fallbackStore.isInitialized()) {
fallbackStore.value.set(attributes, credentials)
}
else {
postponedCredentials.put(attributes, credentials ?: nullPassword)
queueProcessor.add {
if (!fallbackStore.isInitialized()) {
LOG.catchAndLog {
store.set(attributes, credentials)
postponedCredentials.remove(attributes)
return@add
}
}
fallbackStore.value.set(attributes, credentials)
postponedCredentials.remove(attributes)
}
postponedCredentials.put(attributes, credentials ?: nullCredentials)
queueProcessor.add { doSave() }
}
}
}
}
private fun notifyUnsatisfiedLinkError(e: UnsatisfiedLinkError) {
LOG.error(e)
var message = "Credentials are remembered until ${ApplicationNamesInfo.getInstance().fullProductName} is closed."
if (SystemInfo.isLinux) {
message += "\nPlease install required package libsecret-1-0: sudo apt-get install libsecret-1-0 gnome-keyring"
}
NOTIFICATION_MANAGER.notify("Cannot Access Native Keychain", message)
}
private class MacOsCredentialStoreFactory : CredentialStoreFactory {
override fun create(): PasswordStorage? {
if (isMacOsCredentialStoreSupported && SystemProperties.getBooleanProperty("use.mac.keychain", true)) {