diff --git a/plugins/github/src/META-INF/plugin.xml b/plugins/github/src/META-INF/plugin.xml
index ab5c98b0b48b..0a10d8490308 100644
--- a/plugins/github/src/META-INF/plugin.xml
+++ b/plugins/github/src/META-INF/plugin.xml
@@ -25,6 +25,7 @@
+
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiTaskExecutor.kt b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiTaskExecutor.kt
index 657e0d13d2df..e25560153a4a 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiTaskExecutor.kt
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiTaskExecutor.kt
@@ -2,6 +2,7 @@
package org.jetbrains.plugins.github.api
import com.intellij.openapi.application.invokeAndWaitIfNeed
+import com.intellij.openapi.components.service
import com.intellij.openapi.progress.EmptyProgressIndicator
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.ui.Messages
@@ -91,6 +92,11 @@ class GithubApiTaskExecutor(private val authenticationManager: GithubAuthenticat
return originalAuth.copyWithTwoFactorCode(code)
}
+
+ @JvmStatic
+ fun getInstance(): GithubApiTaskExecutor {
+ return service()
+ }
}
}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/authentication/GithubAuthenticationManager.kt b/plugins/github/src/org/jetbrains/plugins/github/authentication/GithubAuthenticationManager.kt
index 0e9d7ed313cb..20a7b54c4ee3 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/authentication/GithubAuthenticationManager.kt
+++ b/plugins/github/src/org/jetbrains/plugins/github/authentication/GithubAuthenticationManager.kt
@@ -1,18 +1,28 @@
// 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 org.jetbrains.plugins.github.authentication
+import com.intellij.openapi.project.Project
+import git4idea.DialogManager
import com.intellij.openapi.components.service
import org.jetbrains.annotations.CalledInAny
+import org.jetbrains.annotations.CalledInAwt
import org.jetbrains.annotations.TestOnly
import org.jetbrains.plugins.github.api.GithubServerPath
import org.jetbrains.plugins.github.authentication.accounts.GithubAccount
import org.jetbrains.plugins.github.authentication.accounts.GithubAccountManager
import org.jetbrains.plugins.github.exceptions.GithubAuthenticationException
+import org.jetbrains.plugins.github.authentication.ui.GithubLoginDialog
/**
* Entry point for interactions with Github authentication subsystem
*/
class GithubAuthenticationManager internal constructor(private val accountManager: GithubAccountManager) {
+ @CalledInAny
+ fun hasAccounts() = accountManager.accounts.isNotEmpty()
+
+ @CalledInAny
+ fun getAccounts(): Set = accountManager.accounts
+
@CalledInAny
internal fun getTokenForAccount(account: GithubAccount): String {
val token = accountManager.getTokenForAccount(account)
@@ -20,6 +30,22 @@ class GithubAuthenticationManager internal constructor(private val accountManage
else return token
}
+ @CalledInAwt
+ fun requestNewAccount(project: Project): GithubAccount? {
+ fun isAccountUnique(name: String, server: GithubServerPath) =
+ accountManager.accounts.none { it.name == name && it.server == server }
+
+ val dialog = GithubLoginDialog(project, ::isAccountUnique)
+ DialogManager.show(dialog)
+ if (dialog.isOK) {
+ val account = GithubAccount(dialog.getLogin(), dialog.getServer())
+ accountManager.accounts += account
+ accountManager.updateAccountToken(account, dialog.getToken())
+ return account
+ }
+ return null
+ }
+
@TestOnly
fun registerAccount(name: String, host: String, token: String): GithubAccount {
val account = GithubAccount(name, GithubServerPath.from(host))
diff --git a/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubRepositoryHostingService.java b/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubRepositoryHostingService.java
index 23eda1a14619..1093ba7e3634 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubRepositoryHostingService.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubRepositoryHostingService.java
@@ -5,64 +5,69 @@ import com.intellij.dvcs.hosting.RepositoryListLoader;
import com.intellij.dvcs.hosting.RepositoryListLoadingException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
-import git4idea.DialogManager;
import git4idea.remote.GitRepositoryHostingService;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.github.api.GithubApiTaskExecutor;
import org.jetbrains.plugins.github.api.GithubApiUtil;
import org.jetbrains.plugins.github.api.data.GithubRepo;
-import org.jetbrains.plugins.github.ui.GithubLoginDialog;
-import org.jetbrains.plugins.github.util.*;
+import org.jetbrains.plugins.github.authentication.GithubAuthenticationManager;
+import org.jetbrains.plugins.github.authentication.accounts.GithubAccount;
+import org.jetbrains.plugins.github.util.GithubGitHelper;
+import org.jetbrains.plugins.github.util.GithubUtil;
+import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class GithubRepositoryHostingService extends GitRepositoryHostingService {
+ @NotNull private final GithubAuthenticationManager myAuthenticationManager;
+ @NotNull private final GithubGitHelper myGitHelper;
+
+ public GithubRepositoryHostingService(@NotNull GithubAuthenticationManager manager,
+ @NotNull GithubGitHelper gitHelper) {
+ myAuthenticationManager = manager;
+ myGitHelper = gitHelper;
+ }
+
@NotNull
@Override
public String getServiceDisplayName() {
- return "GitHub";
+ return GithubUtil.SERVICE_DISPLAY_NAME;
}
@Override
@NotNull
public RepositoryListLoader getRepositoryListLoader(@NotNull Project project) {
return new RepositoryListLoader() {
- @NotNull private final GithubAuthDataHolder myAuthDataHolder = GithubAuthDataHolder.createFromSettings();
-
@Override
public boolean isEnabled() {
- return AuthLevel.LOGGED.accepts(myAuthDataHolder.getAuthData());
+ return myAuthenticationManager.hasAccounts();
}
@Override
public boolean enable() {
- GithubAuthData currentAuthData = myAuthDataHolder.getAuthData();
- myAuthDataHolder.runTransaction(currentAuthData, () -> {
- GithubLoginDialog dialog = new GithubLoginDialog(project, currentAuthData, AuthLevel.LOGGED);
- DialogManager.show(dialog);
- if (dialog.isOK()) {
- GithubAuthData authData = dialog.getAuthData();
- GithubSettings.getInstance().setAuthData(authData, dialog.isSavePasswordSelected());
- return authData;
- }
- return currentAuthData;
- });
- return isEnabled();
+ return myAuthenticationManager.requestNewAccount(project) != null;
}
@NotNull
@Override
public List getAvailableRepositories(@NotNull ProgressIndicator progressIndicator) throws RepositoryListLoadingException {
try {
- return GithubUtil.runTask(project, myAuthDataHolder, progressIndicator, connection -> GithubApiUtil.getAvailableRepos(connection))
- .stream()
- .sorted(Comparator.comparing(GithubRepo::getUserName).thenComparing(GithubRepo::getName))
- .map(repo -> GithubUrlUtil
- .getCloneUrl(GithubUrlUtil.getGitHostWithoutProtocol(myAuthDataHolder.getAuthData().getHost()),
- repo.getUserName(),
- repo.getName()))
- .collect(Collectors.toList());
+ List urls = new ArrayList<>();
+ for (GithubAccount account : myAuthenticationManager.getAccounts()) {
+ urls.addAll(
+ GithubApiTaskExecutor.getInstance().execute(progressIndicator, account,
+ connection -> GithubApiUtil.getAvailableRepos(connection))
+ .stream()
+ .sorted(Comparator.comparing(GithubRepo::getUserName).thenComparing(GithubRepo::getName))
+ .map(repo -> myGitHelper.getRemoteUrl(account.getServer(),
+ repo.getUserName(),
+ repo.getName()))
+ .collect(Collectors.toList())
+ );
+ }
+ return urls;
}
catch (Exception e) {
throw new RepositoryListLoadingException("Error connecting to Github", e);
diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubGitHelper.kt b/plugins/github/src/org/jetbrains/plugins/github/util/GithubGitHelper.kt
new file mode 100644
index 000000000000..70e2267a9c0c
--- /dev/null
+++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubGitHelper.kt
@@ -0,0 +1,19 @@
+// 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 org.jetbrains.plugins.github.util
+
+import org.jetbrains.plugins.github.api.GithubServerPath
+
+/**
+ * Utilities for Github-Git interactions
+ */
+class GithubGitHelper(private val githubSettings: GithubSettings) {
+
+ fun getRemoteUrl(server: GithubServerPath, user: String, repo: String): String {
+ return if (githubSettings.isCloneGitUsingSsh) {
+ "git@${server.host}:${server.suffix?.substring(1).orEmpty()}/$user/$repo.git"
+ }
+ else {
+ "https://${server.host}${server.suffix.orEmpty()}/$user/$repo.git"
+ }
+ }
+}
\ No newline at end of file