mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
extract *KeePassDatabaseAction, move SynchronizedClearableLazy to platform
This commit is contained in:
@@ -168,49 +168,14 @@ internal class PasswordSafeConfigurableUi : ConfigurableUi<PasswordSafeSettings>
|
||||
}
|
||||
keePassDbFile = textFieldWithBrowseButton("KeePass Database File",
|
||||
fileChooserDescriptor = fileChooserDescriptor,
|
||||
fileChosen = ::normalizeSelectedFile,
|
||||
fileChosen = {
|
||||
normalizeSelectedFile(it)
|
||||
},
|
||||
comment = if (SystemInfo.isWindows) null else "Stored using weak encryption. It is recommended to store on encrypted volume for additional security.")
|
||||
gearButton(
|
||||
object : DumbAwareAction("Clear") {
|
||||
override fun actionPerformed(event: AnActionEvent) {
|
||||
if (!MessageDialogBuilder.yesNo("Clear Passwords", "Are you sure want to remove all passwords?").yesText("Remove Passwords").isYes) {
|
||||
return
|
||||
}
|
||||
|
||||
LOG.info("Passwords cleared", Error())
|
||||
createKeePassFileManager()?.clear()
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
e.presentation.isEnabled = getNewDbFile()?.exists() ?: false
|
||||
}
|
||||
},
|
||||
object : DumbAwareAction("Import") {
|
||||
override fun actionPerformed(event: AnActionEvent) {
|
||||
chooseFile(fileChooserDescriptor, event) {
|
||||
createKeePassFileManager()?.import(Paths.get(normalizeSelectedFile(it)), event)
|
||||
// force reload KeePass Store
|
||||
passwordSafe.closeCurrentProvider()
|
||||
}
|
||||
}
|
||||
},
|
||||
object : DumbAwareAction("${if (MasterKeyFileStorage(getDefaultMasterPasswordFile()).isAutoGenerated()) "Set" else "Change"} Master Password") {
|
||||
override fun actionPerformed(event: AnActionEvent) {
|
||||
// even if current provider is not KEEPASS, all actions for db file must be applied immediately (show error if new master password not applicable for existing db file)
|
||||
if (createKeePassFileManager()?.askAndSetMasterKey(event) == true) {
|
||||
if (passwordSafe.settings.providerType == ProviderType.KEEPASS) {
|
||||
// force reload KeePass Store
|
||||
passwordSafe.closeCurrentProvider()
|
||||
}
|
||||
|
||||
templatePresentation.text = "Change Master Password"
|
||||
}
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
e.presentation.isEnabled = getNewDbFileAsString() != null
|
||||
}
|
||||
}
|
||||
ClearKeePassDatabaseAction(),
|
||||
ImportKeePassDatabaseAction(passwordSafe),
|
||||
ChangeKeePassDatabaseMasterPasswordAction()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -237,6 +202,49 @@ internal class PasswordSafeConfigurableUi : ConfigurableUi<PasswordSafeSettings>
|
||||
else -> ProviderType.KEYCHAIN
|
||||
}
|
||||
}
|
||||
|
||||
private inner class ClearKeePassDatabaseAction : DumbAwareAction("Clear") {
|
||||
override fun actionPerformed(event: AnActionEvent) {
|
||||
if (!MessageDialogBuilder.yesNo("Clear Passwords", "Are you sure want to remove all passwords?").yesText("Remove Passwords").isYes) {
|
||||
return
|
||||
}
|
||||
|
||||
LOG.info("Passwords cleared", Error())
|
||||
createKeePassFileManager()?.clear() ?: return
|
||||
(PasswordSafe.instance as PasswordSafeImpl).closeCurrentStoreIfKeePass()
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
e.presentation.isEnabled = getNewDbFile()?.exists() ?: false
|
||||
}
|
||||
}
|
||||
|
||||
private inner class ImportKeePassDatabaseAction(private val passwordSafe: PasswordSafeImpl) : DumbAwareAction("Import") {
|
||||
override fun actionPerformed(event: AnActionEvent) {
|
||||
FileChooserDescriptorFactory.createSingleLocalFileDescriptor()
|
||||
.withFileFilter {
|
||||
it.nameSequence.endsWith(".kdbx")
|
||||
}
|
||||
.chooseFile(event) {
|
||||
createKeePassFileManager()?.import(Paths.get(normalizeSelectedFile(it)), event)
|
||||
passwordSafe.closeCurrentStoreIfKeePass()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inner class ChangeKeePassDatabaseMasterPasswordAction : DumbAwareAction("${if (MasterKeyFileStorage(getDefaultMasterPasswordFile()).isAutoGenerated()) "Set" else "Change"} Master Password") {
|
||||
override fun actionPerformed(event: AnActionEvent) {
|
||||
// even if current provider is not KEEPASS, all actions for db file must be applied immediately (show error if new master password not applicable for existing db file)
|
||||
if (createKeePassFileManager()?.askAndSetMasterKey(event) == true) {
|
||||
(PasswordSafe.instance as PasswordSafeImpl).closeCurrentStoreIfKeePass()
|
||||
templatePresentation.text = "Change Master Password"
|
||||
}
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
e.presentation.isEnabled = getNewDbFileAsString() != null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun normalizeSelectedFile(file: VirtualFile): String {
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.intellij.openapi.options.ShowSettingsUtil
|
||||
import com.intellij.openapi.util.ShutDownTracker
|
||||
import com.intellij.util.Alarm
|
||||
import com.intellij.util.SingleAlarm
|
||||
import com.intellij.util.concurrency.SynchronizedClearableLazy
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.concurrency.Promise
|
||||
import org.jetbrains.concurrency.runAsync
|
||||
@@ -62,14 +63,14 @@ private fun computeProvider(settings: PasswordSafeSettings): CredentialStore {
|
||||
}
|
||||
|
||||
class PasswordSafeImpl @JvmOverloads constructor(val settings: PasswordSafeSettings /* public - backward compatibility */,
|
||||
provider: CredentialStore? = null) : PasswordSafe(), SettingsSavingComponent {
|
||||
provider: CredentialStore? = null /* TestOnly */) : PasswordSafe(), SettingsSavingComponent {
|
||||
override var isRememberPasswordByDefault: Boolean
|
||||
get() = settings.state.isRememberPasswordByDefault
|
||||
set(value) {
|
||||
settings.state.isRememberPasswordByDefault = value
|
||||
}
|
||||
|
||||
private var _currentProvider: Lazy<CredentialStore> = if (provider == null) lazy { computeProvider(settings) } else lazyOf(provider)
|
||||
private var _currentProvider: Lazy<CredentialStore> = if (provider == null) SynchronizedClearableLazy { computeProvider(settings) } else lazyOf(provider)
|
||||
|
||||
internal val currentProviderIfComputed: CredentialStore?
|
||||
get() = if (_currentProvider.isInitialized()) _currentProvider.value else null
|
||||
@@ -80,8 +81,12 @@ class PasswordSafeImpl @JvmOverloads constructor(val settings: PasswordSafeSetti
|
||||
_currentProvider = lazyOf(value)
|
||||
}
|
||||
|
||||
internal fun closeCurrentProvider() {
|
||||
_currentProvider = lazy { computeProvider(settings) }
|
||||
// force reload KeePass Store if settings changed
|
||||
internal fun closeCurrentStoreIfKeePass() {
|
||||
val store = currentProviderIfComputed
|
||||
if (store is KeePassCredentialStore && !store.isMemoryOnly) {
|
||||
(_currentProvider as SynchronizedClearableLazy).drop()
|
||||
}
|
||||
}
|
||||
|
||||
// it is helper storage to support set password as memory-only (see setPassword memoryOnly flag)
|
||||
|
||||
@@ -48,13 +48,13 @@ class LayoutBuilder @PublishedApi internal constructor(@PublishedApi internal va
|
||||
return group
|
||||
}
|
||||
|
||||
fun chooseFile(descriptor: FileChooserDescriptor, event: AnActionEvent, fileChosen: (chosenFile: VirtualFile) -> Unit) {
|
||||
FileChooser.chooseFile(descriptor, event.getData(PlatformDataKeys.PROJECT), event.getData(PlatformDataKeys.CONTEXT_COMPONENT), null, fileChosen)
|
||||
}
|
||||
|
||||
@Suppress("PropertyName")
|
||||
@PublishedApi
|
||||
@Deprecated("", replaceWith = ReplaceWith("builder"), level = DeprecationLevel.ERROR)
|
||||
internal val `$`: LayoutBuilderImpl
|
||||
get() = builder
|
||||
}
|
||||
|
||||
fun FileChooserDescriptor.chooseFile(event: AnActionEvent, fileChosen: (chosenFile: VirtualFile) -> Unit) {
|
||||
FileChooser.chooseFile(this, event.getData(PlatformDataKeys.PROJECT), event.getData(PlatformDataKeys.CONTEXT_COMPONENT), null, fileChosen)
|
||||
}
|
||||
+7
-3
@@ -1,11 +1,15 @@
|
||||
@file:Suppress("ClassName")
|
||||
// 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.configurationScript
|
||||
package com.intellij.util.concurrency
|
||||
|
||||
@Suppress("ClassName")
|
||||
private object UNINITIALIZED_VALUE
|
||||
|
||||
/**
|
||||
* Kotlin-friendly version of ClearableLazyValue
|
||||
*/
|
||||
@Suppress("LocalVariableName")
|
||||
internal class SynchronizedClearableLazy<out T>(private val initializer: () -> T) : Lazy<T> {
|
||||
class SynchronizedClearableLazy<out T>(private val initializer: () -> T) : Lazy<T> {
|
||||
@Volatile
|
||||
private var _value: Any? = UNINITIALIZED_VALUE
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.vfs.newvfs.BulkFileListener
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileCopyEvent
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
||||
import com.intellij.util.concurrency.SynchronizedClearableLazy
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.io.exists
|
||||
import com.intellij.util.io.inputStreamIfExists
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.intellij.configurationScript.providers
|
||||
import com.intellij.configurationScript.ConfigurationFileManager
|
||||
import com.intellij.configurationScript.Keys
|
||||
import com.intellij.configurationScript.RunConfigurationListReader
|
||||
import com.intellij.configurationScript.SynchronizedClearableLazy
|
||||
import com.intellij.execution.configurations.ConfigurationFactory
|
||||
import com.intellij.execution.configurations.RunConfigurationBase
|
||||
import com.intellij.execution.impl.RunConfigurationTemplateProvider
|
||||
@@ -13,6 +12,7 @@ import com.intellij.openapi.components.BaseState
|
||||
import com.intellij.openapi.components.PersistentStateComponent
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.concurrency.SynchronizedClearableLazy
|
||||
import gnu.trove.THashMap
|
||||
import org.yaml.snakeyaml.nodes.MappingNode
|
||||
import org.yaml.snakeyaml.nodes.ScalarNode
|
||||
|
||||
@@ -2,12 +2,12 @@ package com.intellij.configurationScript.providers
|
||||
|
||||
import com.intellij.configurationScript.ConfigurationFileManager
|
||||
import com.intellij.configurationScript.Keys
|
||||
import com.intellij.configurationScript.SynchronizedClearableLazy
|
||||
import com.intellij.configurationScript.readObject
|
||||
import com.intellij.openapi.components.BaseState
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.updateSettings.impl.UpdateSettingsProvider
|
||||
import com.intellij.util.concurrency.SynchronizedClearableLazy
|
||||
import org.yaml.snakeyaml.nodes.MappingNode
|
||||
import org.yaml.snakeyaml.nodes.ScalarNode
|
||||
|
||||
|
||||
Reference in New Issue
Block a user