Commit 7533bbff authored by Vladimir Krivosheev's avatar Vladimir Krivosheev
Browse files

IDEA-159787 ICS + PS

parent d994f609
Showing with 42 additions and 78 deletions
+42 -78
...@@ -51,6 +51,9 @@ ...@@ -51,6 +51,9 @@
<item name='org.eclipse.jgit.transport.Transport org.eclipse.jgit.transport.Transport open(org.eclipse.jgit.lib.Repository, org.eclipse.jgit.transport.RemoteConfig)'> <item name='org.eclipse.jgit.transport.Transport org.eclipse.jgit.transport.Transport open(org.eclipse.jgit.lib.Repository, org.eclipse.jgit.transport.RemoteConfig)'>
<annotation name='org.jetbrains.annotations.NotNull'/> <annotation name='org.jetbrains.annotations.NotNull'/>
</item> </item>
<item name='org.eclipse.jgit.transport.URIish java.lang.String getHost()'>
<annotation name='org.jetbrains.annotations.Nullable'/>
</item>
<item name='org.eclipse.jgit.transport.URIish java.lang.String toPrivateString()'> <item name='org.eclipse.jgit.transport.URIish java.lang.String toPrivateString()'>
<annotation name='org.jetbrains.annotations.NotNull'/> <annotation name='org.jetbrains.annotations.NotNull'/>
</item> </item>
......
...@@ -28,15 +28,11 @@ import com.intellij.openapi.diagnostic.Logger ...@@ -28,15 +28,11 @@ import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.progress.runBackgroundableTask import com.intellij.openapi.progress.runBackgroundableTask
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.project.impl.ProjectLifecycleListener import com.intellij.openapi.project.impl.ProjectLifecycleListener
import com.intellij.openapi.util.AtomicNotNullLazyValue
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.util.SingleAlarm import com.intellij.util.SingleAlarm
import com.intellij.util.SystemProperties import com.intellij.util.SystemProperties
import com.intellij.util.exists import com.intellij.util.exists
import com.intellij.util.move import com.intellij.util.move
import org.jetbrains.keychain.CredentialsStore
import org.jetbrains.keychain.FileCredentialsStore
import org.jetbrains.keychain.OsXCredentialsStore
import org.jetbrains.settingsRepository.git.GitRepositoryManager import org.jetbrains.settingsRepository.git.GitRepositoryManager
import org.jetbrains.settingsRepository.git.GitRepositoryService import org.jetbrains.settingsRepository.git.GitRepositoryService
import org.jetbrains.settingsRepository.git.processChildren import org.jetbrains.settingsRepository.git.processChildren
...@@ -54,15 +50,13 @@ val icsManager by lazy(LazyThreadSafetyMode.NONE) { ...@@ -54,15 +50,13 @@ val icsManager by lazy(LazyThreadSafetyMode.NONE) {
} }
class IcsManager(dir: Path) { class IcsManager(dir: Path) {
val credentialsStore = object : AtomicNotNullLazyValue<CredentialsStore>() { val credentialsStore = lazy {
override fun compute(): CredentialsStore { if (isMacOsCredentialStoreSupported && SystemProperties.getBooleanProperty("use.mac.keychain", true)) {
if (isMacOsCredentialStoreSupported && SystemProperties.getBooleanProperty("use.mac.keychain", true)) { catchAndLog {
catchAndLog { return@lazy IcsMacOsCredentialsStore("IntelliJ Platform Settings Repository")
return OsXCredentialsStore("IntelliJ Platform Settings Repository")
}
} }
return FileCredentialsStore()
} }
IcsCredentialsStoreWrapper()
} }
val settingsFile: Path = dir.resolve("config.json") val settingsFile: Path = dir.resolve("config.json")
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
package org.jetbrains.settingsRepository.git package org.jetbrains.settingsRepository.git
import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.util.NotNullLazyValue
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import org.eclipse.jgit.api.CommitCommand import org.eclipse.jgit.api.CommitCommand
import org.eclipse.jgit.api.ResetCommand import org.eclipse.jgit.api.ResetCommand
...@@ -36,8 +35,8 @@ import org.eclipse.jgit.transport.Transport ...@@ -36,8 +35,8 @@ import org.eclipse.jgit.transport.Transport
import org.eclipse.jgit.treewalk.FileTreeIterator import org.eclipse.jgit.treewalk.FileTreeIterator
import org.eclipse.jgit.treewalk.TreeWalk import org.eclipse.jgit.treewalk.TreeWalk
import org.eclipse.jgit.treewalk.filter.TreeFilter import org.eclipse.jgit.treewalk.filter.TreeFilter
import org.jetbrains.keychain.CredentialsStore
import org.jetbrains.settingsRepository.AuthenticationException import org.jetbrains.settingsRepository.AuthenticationException
import org.jetbrains.settingsRepository.IcsCredentialsStore
import org.jetbrains.settingsRepository.LOG import org.jetbrains.settingsRepository.LOG
import java.io.InputStream import java.io.InputStream
import java.nio.file.Path import java.nio.file.Path
...@@ -165,7 +164,7 @@ fun Repository.computeIndexDiff(): IndexDiff { ...@@ -165,7 +164,7 @@ fun Repository.computeIndexDiff(): IndexDiff {
} }
} }
fun cloneBare(uri: String, dir: Path, credentialsStore: NotNullLazyValue<CredentialsStore>? = null, progressMonitor: ProgressMonitor = NullProgressMonitor.INSTANCE): Repository { fun cloneBare(uri: String, dir: Path, credentialsStore: Lazy<IcsCredentialsStore>? = null, progressMonitor: ProgressMonitor = NullProgressMonitor.INSTANCE): Repository {
val repository = createBareRepository(dir) val repository = createBareRepository(dir)
val config = repository.setUpstream(uri) val config = repository.setUpstream(uri)
val remoteConfig = RemoteConfig(config, Constants.DEFAULT_REMOTE_NAME) val remoteConfig = RemoteConfig(config, Constants.DEFAULT_REMOTE_NAME)
...@@ -206,7 +205,7 @@ private fun findBranchToCheckout(result: FetchResult): Ref? { ...@@ -206,7 +205,7 @@ private fun findBranchToCheckout(result: FetchResult): Ref? {
val idHead = result.getAdvertisedRef(Constants.HEAD) ?: return null val idHead = result.getAdvertisedRef(Constants.HEAD) ?: return null
val master = result.getAdvertisedRef(Constants.R_HEADS + Constants.MASTER) val master = result.getAdvertisedRef(Constants.R_HEADS + Constants.MASTER)
if (master != null && master.objectId.equals(idHead.objectId)) { if (master != null && master.objectId == idHead.objectId) {
return master return master
} }
...@@ -214,7 +213,7 @@ private fun findBranchToCheckout(result: FetchResult): Ref? { ...@@ -214,7 +213,7 @@ private fun findBranchToCheckout(result: FetchResult): Ref? {
if (!r.name.startsWith(Constants.R_HEADS)) { if (!r.name.startsWith(Constants.R_HEADS)) {
continue continue
} }
if (r.objectId.equals(idHead.objectId)) { if (r.objectId == idHead.objectId) {
return r return r
} }
} }
...@@ -308,7 +307,7 @@ private class InputStreamWrapper(private val delegate: InputStream, private val ...@@ -308,7 +307,7 @@ private class InputStreamWrapper(private val delegate: InputStream, private val
override fun markSupported() = delegate.markSupported() override fun markSupported() = delegate.markSupported()
override fun equals(other: Any?) = delegate.equals(other) override fun equals(other: Any?) = delegate == other
override fun available() = delegate.available() override fun available() = delegate.available()
......
...@@ -18,7 +18,6 @@ package org.jetbrains.settingsRepository.git ...@@ -18,7 +18,6 @@ package org.jetbrains.settingsRepository.git
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.progress.EmptyProgressIndicator import com.intellij.openapi.progress.EmptyProgressIndicator
import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.util.NotNullLazyValue
import com.intellij.openapi.util.ShutDownTracker import com.intellij.openapi.util.ShutDownTracker
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import com.intellij.util.* import com.intellij.util.*
...@@ -37,7 +36,6 @@ import org.jetbrains.jgit.dirCache.AddLoadedFile ...@@ -37,7 +36,6 @@ import org.jetbrains.jgit.dirCache.AddLoadedFile
import org.jetbrains.jgit.dirCache.DeleteDirectory import org.jetbrains.jgit.dirCache.DeleteDirectory
import org.jetbrains.jgit.dirCache.deletePath import org.jetbrains.jgit.dirCache.deletePath
import org.jetbrains.jgit.dirCache.edit import org.jetbrains.jgit.dirCache.edit
import org.jetbrains.keychain.CredentialsStore
import org.jetbrains.settingsRepository.* import org.jetbrains.settingsRepository.*
import org.jetbrains.settingsRepository.RepositoryManager.Updater import org.jetbrains.settingsRepository.RepositoryManager.Updater
import java.io.IOException import java.io.IOException
...@@ -45,7 +43,7 @@ import java.nio.file.Files ...@@ -45,7 +43,7 @@ import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import kotlin.concurrent.write import kotlin.concurrent.write
class GitRepositoryManager(private val credentialsStore: NotNullLazyValue<CredentialsStore>, dir: Path) : BaseRepositoryManager(dir) { class GitRepositoryManager(private val credentialsStore: Lazy<IcsCredentialsStore>, dir: Path) : BaseRepositoryManager(dir) {
val repository: Repository val repository: Repository
get() { get() {
var r = _repository var r = _repository
......
...@@ -20,18 +20,17 @@ import com.intellij.credentialStore.isFulfilled ...@@ -20,18 +20,17 @@ import com.intellij.credentialStore.isFulfilled
import com.intellij.credentialStore.macOs.isMacOsCredentialStoreSupported import com.intellij.credentialStore.macOs.isMacOsCredentialStoreSupported
import com.intellij.openapi.ui.MessageDialogBuilder import com.intellij.openapi.ui.MessageDialogBuilder
import com.intellij.openapi.ui.Messages import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.NotNullLazyValue
import com.intellij.util.nullize import com.intellij.util.nullize
import com.intellij.util.ui.UIUtil import com.intellij.util.ui.UIUtil
import org.eclipse.jgit.lib.Repository import org.eclipse.jgit.lib.Repository
import org.eclipse.jgit.transport.CredentialItem import org.eclipse.jgit.transport.CredentialItem
import org.eclipse.jgit.transport.CredentialsProvider import org.eclipse.jgit.transport.CredentialsProvider
import org.eclipse.jgit.transport.URIish import org.eclipse.jgit.transport.URIish
import org.jetbrains.keychain.CredentialsStore import org.jetbrains.settingsRepository.IcsCredentialsStore
import org.jetbrains.settingsRepository.LOG import org.jetbrains.settingsRepository.catchAndLog
import org.jetbrains.settingsRepository.showAuthenticationForm import org.jetbrains.settingsRepository.showAuthenticationForm
class JGitCredentialsProvider(private val credentialsStore: NotNullLazyValue<CredentialsStore>, private val repository: Repository) : CredentialsProvider() { class JGitCredentialsProvider(private val credentialsStore: Lazy<IcsCredentialsStore>, private val repository: Repository) : CredentialsProvider() {
private var credentialsFromGit: Credentials? = null private var credentialsFromGit: Credentials? = null
override fun isInteractive() = true override fun isInteractive() = true
...@@ -105,12 +104,9 @@ class JGitCredentialsProvider(private val credentialsStore: NotNullLazyValue<Cre ...@@ -105,12 +104,9 @@ class JGitCredentialsProvider(private val credentialsStore: NotNullLazyValue<Cre
} }
if (credentials == null) { if (credentials == null) {
try { catchAndLog {
credentials = credentialsStore.value.get(uri.host, sshKeyFile) credentials = credentialsStore.value.get(uri.host, sshKeyFile)
} }
catch (e: Throwable) {
LOG.error(e)
}
saveCredentialsToStore = true saveCredentialsToStore = true
...@@ -131,7 +127,7 @@ class JGitCredentialsProvider(private val credentialsStore: NotNullLazyValue<Cre ...@@ -131,7 +127,7 @@ class JGitCredentialsProvider(private val credentialsStore: NotNullLazyValue<Cre
} }
if (saveCredentialsToStore && credentials.isFulfilled()) { if (saveCredentialsToStore && credentials.isFulfilled()) {
credentialsStore.value.save(uri.host, credentials!!, sshKeyFile) credentialsStore.value.set(uri.host, credentials!!, sshKeyFile)
} }
userNameItem?.value = credentials?.user userNameItem?.value = credentials?.user
......
...@@ -45,7 +45,7 @@ fun getCredentialsUsingGit(uri: URIish, repository: Repository): Credentials? { ...@@ -45,7 +45,7 @@ fun getCredentialsUsingGit(uri: URIish, repository: Repository): Credentials? {
writer.write("url=") writer.write("url=")
writer.write(uri.toPrivateString()) writer.write(uri.toPrivateString())
writer.write("\n\n") writer.write("\n\n")
writer.close(); writer.close()
val reader = process.inputStream.reader().buffered() val reader = process.inputStream.reader().buffered()
var username: String? = null var username: String? = null
......
/*
* 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.
*/
package org.jetbrains.keychain
import com.intellij.credentialStore.Credentials
import com.intellij.openapi.diagnostic.Logger
val LOG: Logger = Logger.getInstance(CredentialsStore::class.java)
interface CredentialsStore {
fun get(host: String?, sshKeyFile: String? = null): Credentials?
fun save(host: String?, credentials: Credentials, sshKeyFile: String? = null)
fun reset(host: String)
}
...@@ -13,18 +13,24 @@ ...@@ -13,18 +13,24 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.keychain package org.jetbrains.settingsRepository
import com.intellij.credentialStore.CredentialAttributes import com.intellij.credentialStore.CredentialAttributes
import com.intellij.credentialStore.Credentials import com.intellij.credentialStore.Credentials
import com.intellij.ide.passwordSafe.PasswordSafe import com.intellij.ide.passwordSafe.PasswordSafe
class FileCredentialsStore() : CredentialsStore { interface IcsCredentialsStore {
override fun get(host: String?, sshKeyFile: String?): Credentials? { fun get(host: String?, sshKeyFile: String? = null): Credentials?
return if (host == null) null else PasswordSafe.getInstance().get(getAttributes(host, sshKeyFile))
} fun set(host: String?, credentials: Credentials, sshKeyFile: String? = null)
fun reset(host: String)
}
class IcsCredentialsStoreWrapper() : IcsCredentialsStore {
override fun get(host: String?, sshKeyFile: String?) = getAttributes(host, sshKeyFile)?.let { PasswordSafe.getInstance().get(it) }
private fun getAttributes(host: String?, sshKeyFile: String?): CredentialAttributes { private fun getAttributes(host: String?, sshKeyFile: String?): CredentialAttributes? {
if (sshKeyFile == null) { if (sshKeyFile == null) {
return CredentialAttributes("IntelliJ Platform Settings Repository — $host") return CredentialAttributes("IntelliJ Platform Settings Repository — $host")
} }
...@@ -37,7 +43,7 @@ class FileCredentialsStore() : CredentialsStore { ...@@ -37,7 +43,7 @@ class FileCredentialsStore() : CredentialsStore {
PasswordSafe.getInstance().setPassword(CredentialAttributes("IntelliJ Platform Settings Repository — $host"), null) PasswordSafe.getInstance().setPassword(CredentialAttributes("IntelliJ Platform Settings Repository — $host"), null)
} }
override fun save(host: String?, credentials: Credentials, sshKeyFile: String?) { override fun set(host: String?, credentials: Credentials, sshKeyFile: String?) {
PasswordSafe.getInstance().set(getAttributes(host, sshKeyFile), credentials) getAttributes(host, sshKeyFile)?.let { PasswordSafe.getInstance().set(it, credentials) }
} }
} }
\ No newline at end of file
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.keychain package org.jetbrains.settingsRepository
import com.intellij.credentialStore.Credentials import com.intellij.credentialStore.Credentials
import com.intellij.credentialStore.macOs.deleteGenericPassword import com.intellij.credentialStore.macOs.deleteGenericPassword
...@@ -22,7 +22,7 @@ import com.intellij.credentialStore.macOs.saveGenericPassword ...@@ -22,7 +22,7 @@ import com.intellij.credentialStore.macOs.saveGenericPassword
import com.intellij.openapi.util.PasswordUtil import com.intellij.openapi.util.PasswordUtil
import gnu.trove.THashMap import gnu.trove.THashMap
class OsXCredentialsStore(serviceName: String) : CredentialsStore { internal class IcsMacOsCredentialsStore(serviceName: String) : IcsCredentialsStore {
private val serviceName = serviceName.toByteArray() private val serviceName = serviceName.toByteArray()
companion object { companion object {
...@@ -68,7 +68,7 @@ class OsXCredentialsStore(serviceName: String) : CredentialsStore { ...@@ -68,7 +68,7 @@ class OsXCredentialsStore(serviceName: String) : CredentialsStore {
* Note - in case of SSH, our added password will not be used until ssh-agent will not be restarted (simply execute "killall ssh-agent"). * Note - in case of SSH, our added password will not be used until ssh-agent will not be restarted (simply execute "killall ssh-agent").
* Also, if you remove password from keychain, ssh-agent will continue to use cached password. * Also, if you remove password from keychain, ssh-agent will continue to use cached password.
*/ */
override fun save(host: String?, credentials: Credentials, sshKeyFile: String?) { override fun set(host: String?, credentials: Credentials, sshKeyFile: String?) {
val accountName: String = sshKeyFile ?: host!! val accountName: String = sshKeyFile ?: host!!
val oldCredentials = accountToCredentials.put(accountName, credentials) val oldCredentials = accountToCredentials.put(accountName, credentials)
if (credentials == oldCredentials) { if (credentials == oldCredentials) {
......
package org.jetbrains.settingsRepository.test package org.jetbrains.settingsRepository
import com.intellij.credentialStore.Credentials import com.intellij.credentialStore.Credentials
import com.intellij.openapi.util.NotNullLazyValue
import com.intellij.testFramework.ApplicationRule import com.intellij.testFramework.ApplicationRule
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.eclipse.jgit.storage.file.FileRepositoryBuilder import org.eclipse.jgit.storage.file.FileRepositoryBuilder
import org.eclipse.jgit.transport.CredentialItem import org.eclipse.jgit.transport.CredentialItem
import org.eclipse.jgit.transport.URIish import org.eclipse.jgit.transport.URIish
import org.jetbrains.keychain.CredentialsStore
import org.jetbrains.keychain.FileCredentialsStore
import org.jetbrains.settingsRepository.git.JGitCredentialsProvider import org.jetbrains.settingsRepository.git.JGitCredentialsProvider
import org.junit.ClassRule import org.junit.ClassRule
import org.junit.Test import org.junit.Test
...@@ -21,11 +18,11 @@ internal class IcsCredentialTest { ...@@ -21,11 +18,11 @@ internal class IcsCredentialTest {
val projectRule = ApplicationRule() val projectRule = ApplicationRule()
} }
private fun createProvider(credentialsStore: CredentialsStore): JGitCredentialsProvider { private fun createProvider(credentialsStore: IcsCredentialsStore): JGitCredentialsProvider {
return JGitCredentialsProvider(NotNullLazyValue.createConstantValue(credentialsStore), FileRepositoryBuilder().setBare().setGitDir(File("/tmp/fake")).build()) return JGitCredentialsProvider(lazyOf(credentialsStore), FileRepositoryBuilder().setBare().setGitDir(File("/tmp/fake")).build())
} }
private fun createFileStore() = FileCredentialsStore() private fun createFileStore() = IcsCredentialsStoreWrapper()
@Test @Test
fun explicitSpecifiedInURL() { fun explicitSpecifiedInURL() {
...@@ -43,7 +40,7 @@ internal class IcsCredentialTest { ...@@ -43,7 +40,7 @@ internal class IcsCredentialTest {
@Test @Test
fun gitCredentialHelper() { fun gitCredentialHelper() {
val credentialStore = createFileStore() val credentialStore = createFileStore()
credentialStore.save("bitbucket.org", Credentials("develar", "bike")) credentialStore.set("bitbucket.org", Credentials("develar", "bike"))
val username = CredentialItem.Username() val username = CredentialItem.Username()
val password = CredentialItem.Password() val password = CredentialItem.Password()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment