mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[github] Multiple accounts support for repo list loader
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
<applicationService serviceImplementation="org.jetbrains.plugins.github.authentication.GithubAuthenticationManager"/>
|
||||
<applicationService serviceImplementation="org.jetbrains.plugins.github.api.GithubApiTaskExecutor"/>
|
||||
<applicationService serviceImplementation="org.jetbrains.plugins.github.authentication.accounts.GithubAccountInformationProvider"/>
|
||||
<applicationService serviceImplementation="org.jetbrains.plugins.github.util.GithubGitHelper"/>
|
||||
<projectService serviceInterface="org.jetbrains.plugins.github.util.GithubProjectSettings"
|
||||
serviceImplementation="org.jetbrains.plugins.github.util.GithubProjectSettings"/>
|
||||
<projectService serviceImplementation="org.jetbrains.plugins.github.authentication.accounts.GithubProjectDefaultAccountHolder"/>
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
@@ -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<GithubAccount> = 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))
|
||||
|
||||
+32
-27
@@ -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<String> 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<String> 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);
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user