Add support for PATs in GitHub Enterprise server (#603)

Add necessary checks to the GithubURLParser and AbstractGithubURLParser classes in order to support PAT for GitHub Enterprise server without configuring oAuth.
pull/616/head
Igor Vinokur 2023-11-21 11:11:06 +02:00 committed by GitHub
parent 6ca7127939
commit 974c1b1890
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 254 additions and 57 deletions

View File

@ -205,13 +205,21 @@ public abstract class AbstractGithubPersonalAccessTokenFetcher
@Override
public Optional<Pair<Boolean, String>> isValid(PersonalAccessTokenParams params) {
if (!githubApiClient.isConnected(params.getScmProviderUrl())) {
LOG.debug("not a valid url {} for current fetcher ", params.getScmProviderUrl());
return Optional.empty();
GithubApiClient apiClient;
if (githubApiClient.isConnected(params.getScmProviderUrl())) {
// The url from the token has the same url as the api client, no need to create a new one.
apiClient = githubApiClient;
} else {
if ("github".equals(params.getScmTokenName())) {
apiClient = new GithubApiClient(params.getScmProviderUrl());
} else {
LOG.debug("not a valid url {} for current fetcher ", params.getScmProviderUrl());
return Optional.empty();
}
}
try {
if (params.getScmTokenName() != null && params.getScmTokenName().startsWith(OAUTH_2_PREFIX)) {
Pair<String, String[]> pair = githubApiClient.getTokenScopes(params.getToken());
Pair<String, String[]> pair = apiClient.getTokenScopes(params.getToken());
return Optional.of(
Pair.of(
containsScopes(pair.second, DEFAULT_TOKEN_SCOPES) ? Boolean.TRUE : Boolean.FALSE,
@ -219,7 +227,7 @@ public abstract class AbstractGithubPersonalAccessTokenFetcher
} else {
// TODO: add PAT scope validation
// No REST API for PAT-s in Github found yet. Just try to do some action.
GithubUser user = githubApiClient.getUser(params.getToken());
GithubUser user = apiClient.getUser(params.getToken());
return Optional.of(Pair.of(Boolean.TRUE, user.getLogin()));
}
} catch (ScmItemNotFoundException | ScmCommunicationException | ScmBadRequestException e) {

View File

@ -14,6 +14,7 @@ package org.eclipse.che.api.factory.server.github;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
import static java.util.regex.Pattern.compile;
import static org.eclipse.che.api.factory.server.ApiExceptionMapper.toApiException;
import static org.eclipse.che.api.factory.server.github.GithubApiClient.GITHUB_SAAS_ENDPOINT;
@ -46,15 +47,19 @@ public abstract class AbstractGithubURLParser {
private final PersonalAccessTokenManager tokenManager;
private final DevfileFilenamesProvider devfileFilenamesProvider;
private final GithubApiClient apiClient;
private final String oauthEndpoint;
/**
* Regexp to find repository details (repository name, project name and branch and subfolder)
* Examples of valid URLs are in the test class.
*/
private final Pattern githubPattern;
private final String githubPatternTemplate =
"^%s/(?<repoUser>[^/]+)/(?<repoName>[^/]++)((/)|(?:/tree/(?<branchName>.++))|(/pull/(?<pullRequestId>\\d++)))?$";
private final Pattern githubSSHPattern;
private final String githubSSHPatternTemplate = "^git@%s:(?<repoUser>.*)/(?<repoName>.*)$";
private final boolean disableSubdomainIsolation;
private final String providerName;
@ -70,26 +75,80 @@ public abstract class AbstractGithubURLParser {
this.tokenManager = tokenManager;
this.devfileFilenamesProvider = devfileFilenamesProvider;
this.apiClient = githubApiClient;
this.oauthEndpoint = oauthEndpoint;
this.disableSubdomainIsolation = disableSubdomainIsolation;
this.providerName = providerName;
String endpoint =
isNullOrEmpty(oauthEndpoint) ? GITHUB_SAAS_ENDPOINT : trimEnd(oauthEndpoint, '/');
this.githubPattern =
compile(
format(
"^%s/(?<repoUser>[^/]+)/(?<repoName>[^/]++)((/)|(?:/tree/(?<branchName>.++))|(/pull/(?<pullRequestId>\\d++)))?$",
endpoint));
this.githubPattern = compile(format(githubPatternTemplate, endpoint));
this.githubSSHPattern =
compile(format("^git@%s:(?<repoUser>.*)/(?<repoName>.*)$", URI.create(endpoint).getHost()));
compile(format(githubSSHPatternTemplate, URI.create(endpoint).getHost()));
}
public boolean isValid(@NotNull String url) {
String trimmedUrl = trimEnd(url, '/');
return githubPattern.matcher(trimmedUrl).matches()
|| githubSSHPattern.matcher(trimmedUrl).matches();
|| githubSSHPattern.matcher(trimmedUrl).matches()
// If the GitHub URL is not configured, try to find it in a manually added user namespace
// token.
|| isUserTokenPresent(trimmedUrl)
// Try to call an API request to see if the URL matches GitHub.
|| isApiRequestRelevant(trimmedUrl);
}
private boolean isUserTokenPresent(String repositoryUrl) {
Optional<String> serverUrlOptional = getServerUrl(repositoryUrl);
if (serverUrlOptional.isPresent()) {
String serverUrl = serverUrlOptional.get();
try {
Optional<PersonalAccessToken> token =
tokenManager.get(EnvironmentContext.getCurrent().getSubject(), serverUrl);
if (token.isPresent()) {
PersonalAccessToken accessToken = token.get();
return accessToken.getScmTokenName().equals(providerName);
}
} catch (ScmConfigurationPersistenceException
| ScmUnauthorizedException
| ScmCommunicationException exception) {
return false;
}
}
return false;
}
private boolean isApiRequestRelevant(String repositoryUrl) {
Optional<String> serverUrlOptional = getServerUrl(repositoryUrl);
if (serverUrlOptional.isPresent()) {
GithubApiClient GithubApiClient = new GithubApiClient(serverUrlOptional.get());
try {
// If the user request catches the unauthorised error, it means that the provided url
// belongs to GitHub.
GithubApiClient.getUser("");
} catch (ScmCommunicationException e) {
return e.getStatusCode() == HTTP_UNAUTHORIZED;
} catch (ScmItemNotFoundException | ScmBadRequestException | IllegalArgumentException e) {
return false;
}
}
return false;
}
private Optional<String> getServerUrl(String repositoryUrl) {
// If the given repository url is an SSH url, generate the base url from the pattern:
// https://<hostname extracted from the SSH url>.
if (repositoryUrl.startsWith("git@")) {
String substring = repositoryUrl.substring(4);
return Optional.of("https://" + substring.substring(0, substring.indexOf(":")));
}
// Otherwise, extract the base url from the given repository url by cutting the url after the
// first slash.
Matcher serverUrlMatcher = compile("[^/|:]/").matcher(repositoryUrl);
if (serverUrlMatcher.find()) {
return Optional.of(
repositoryUrl.substring(0, repositoryUrl.indexOf(serverUrlMatcher.group()) + 1));
}
return Optional.empty();
}
public GithubUrl parseWithoutAuthentication(String url) throws ApiException {
@ -100,18 +159,27 @@ public abstract class AbstractGithubURLParser {
return parse(trimEnd(url, '/'), true);
}
private IllegalArgumentException buildIllegalArgumentException(String url) {
return new IllegalArgumentException(
format("The given url %s is not a valid github URL. ", url));
}
private GithubUrl parse(String url, boolean authenticationRequired) throws ApiException {
Matcher matcher;
boolean isHTTPSUrl = githubPattern.matcher(url).matches();
Matcher matcher = isHTTPSUrl ? githubPattern.matcher(url) : githubSSHPattern.matcher(url);
if (isHTTPSUrl) {
matcher = githubPattern.matcher(url);
} else if (githubSSHPattern.matcher(url).matches()) {
matcher = githubSSHPattern.matcher(url);
} else {
matcher = getPatternMatcherByUrl(url).orElseThrow(() -> buildIllegalArgumentException(url));
isHTTPSUrl = url.startsWith("http");
}
if (!matcher.matches()) {
throw new IllegalArgumentException(
format("The given url %s is not a valid github URL. ", url));
throw buildIllegalArgumentException(url);
}
String serverUrl =
isNullOrEmpty(oauthEndpoint) || trimEnd(oauthEndpoint, '/').equals(GITHUB_SAAS_ENDPOINT)
? null
: trimEnd(oauthEndpoint, '/');
String serverUrl = getServerUrl(url).orElseThrow(() -> buildIllegalArgumentException(url));
String repoUser = matcher.group("repoUser");
String repoName = matcher.group("repoName");
if (repoName.matches("^[\\w-][\\w.-]*?\\.git$")) {
@ -127,7 +195,7 @@ public abstract class AbstractGithubURLParser {
if (pullRequestId != null) {
GithubPullRequest pullRequest =
this.getPullRequest(pullRequestId, repoUser, repoName, authenticationRequired);
this.getPullRequest(serverUrl, pullRequestId, repoUser, repoName, authenticationRequired);
if (pullRequest != null) {
String state = pullRequest.getState();
if (!"open".equalsIgnoreCase(state)) {
@ -146,8 +214,12 @@ public abstract class AbstractGithubURLParser {
String latestCommit = null;
GithubCommit commit =
this.getLatestCommit(
repoUser, repoName, firstNonNull(branchName, "HEAD"), authenticationRequired);
getLatestCommit(
serverUrl,
repoUser,
repoName,
firstNonNull(branchName, "HEAD"),
authenticationRequired);
if (commit != null) {
latestCommit = commit.getSha();
}
@ -165,12 +237,14 @@ public abstract class AbstractGithubURLParser {
}
private GithubPullRequest getPullRequest(
String pullRequestId, String repoUser, String repoName, boolean authenticationRequired)
String githubEndpoint,
String pullRequestId,
String repoUser,
String repoName,
boolean authenticationRequired)
throws ApiException {
try {
// prepare token
String githubEndpoint =
isNullOrEmpty(oauthEndpoint) ? GITHUB_SAAS_ENDPOINT : trimEnd(oauthEndpoint, '/');
Subject subject = EnvironmentContext.getCurrent().getSubject();
PersonalAccessToken personalAccessToken = null;
Optional<PersonalAccessToken> token = tokenManager.get(subject, githubEndpoint);
@ -180,8 +254,13 @@ public abstract class AbstractGithubURLParser {
personalAccessToken = tokenManager.fetchAndSave(subject, githubEndpoint);
}
GithubApiClient apiClient =
this.apiClient.isConnected(githubEndpoint)
? this.apiClient
: new GithubApiClient(githubEndpoint);
// get pull request
return this.apiClient.getPullRequest(
return apiClient.getPullRequest(
pullRequestId,
repoUser,
repoName,
@ -190,7 +269,7 @@ public abstract class AbstractGithubURLParser {
// get pull request without authentication
try {
return this.apiClient.getPullRequest(pullRequestId, repoUser, repoName, null);
return apiClient.getPullRequest(pullRequestId, repoUser, repoName, null);
} catch (ScmItemNotFoundException
| ScmCommunicationException
| ScmBadRequestException exception) {
@ -211,12 +290,17 @@ public abstract class AbstractGithubURLParser {
}
private GithubCommit getLatestCommit(
String repoUser, String repoName, String branchName, boolean authenticationRequired)
throws ApiException {
String githubEndpoint,
String repoUser,
String repoName,
String branchName,
boolean authenticationRequired) {
GithubApiClient apiClient =
this.apiClient.isConnected(githubEndpoint)
? this.apiClient
: new GithubApiClient(githubEndpoint);
try {
// prepare token
String githubEndpoint =
isNullOrEmpty(oauthEndpoint) ? GITHUB_SAAS_ENDPOINT : trimEnd(oauthEndpoint, '/');
Subject subject = EnvironmentContext.getCurrent().getSubject();
PersonalAccessToken personalAccessToken = null;
Optional<PersonalAccessToken> token = tokenManager.get(subject, githubEndpoint);
@ -227,7 +311,7 @@ public abstract class AbstractGithubURLParser {
}
// get latest commit
return this.apiClient.getLatestCommit(
return apiClient.getLatestCommit(
repoUser,
repoName,
branchName,
@ -235,7 +319,7 @@ public abstract class AbstractGithubURLParser {
} catch (UnknownScmProviderException | ScmUnauthorizedException e) {
// get latest commit without authentication
try {
return this.apiClient.getLatestCommit(repoUser, repoName, branchName, null);
return apiClient.getLatestCommit(repoUser, repoName, branchName, null);
} catch (ScmItemNotFoundException
| ScmCommunicationException
| ScmBadRequestException
@ -253,4 +337,21 @@ public abstract class AbstractGithubURLParser {
return null;
}
private Optional<Matcher> getPatternMatcherByUrl(String url) {
URI uri =
URI.create(
url.matches(format(githubSSHPatternTemplate, ".*"))
? "ssh://" + url.replace(":", "/")
: url);
String scheme = uri.getScheme();
String host = uri.getHost();
Matcher matcher = compile(format(githubPatternTemplate, scheme + "://" + host)).matcher(url);
if (matcher.matches()) {
return Optional.of(matcher);
} else {
matcher = compile(format(githubSSHPatternTemplate, host)).matcher(url);
return matcher.matches() ? Optional.of(matcher) : Optional.empty();
}
}
}

View File

@ -11,6 +11,8 @@
*/
package org.eclipse.che.api.factory.server.github;
import static com.google.common.base.Strings.isNullOrEmpty;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
@ -36,6 +38,9 @@ public abstract class AbstractGithubUserDataFetcher extends AbstractGitUserDataF
public static final Set<String> DEFAULT_TOKEN_SCOPES =
ImmutableSet.of("repo", "user:email", "read:user");
private static final String NO_USERNAME_AND_EMAIL_ERROR_MESSAGE =
"User name and/or email is not found in the GitHub profile.";
/** Constructor used for testing only. */
public AbstractGithubUserDataFetcher(
String apiEndpoint,
@ -53,15 +58,27 @@ public abstract class AbstractGithubUserDataFetcher extends AbstractGitUserDataF
protected GitUserData fetchGitUserDataWithOAuthToken(OAuthToken oAuthToken)
throws ScmItemNotFoundException, ScmCommunicationException, ScmBadRequestException {
GithubUser user = githubApiClient.getUser(oAuthToken.getToken());
return new GitUserData(user.getName(), user.getEmail());
if (isNullOrEmpty(user.getName()) || isNullOrEmpty(user.getEmail())) {
throw new ScmItemNotFoundException(NO_USERNAME_AND_EMAIL_ERROR_MESSAGE);
} else {
return new GitUserData(user.getName(), user.getEmail());
}
}
@Override
protected GitUserData fetchGitUserDataWithPersonalAccessToken(
PersonalAccessToken personalAccessToken)
throws ScmItemNotFoundException, ScmCommunicationException, ScmBadRequestException {
GithubUser user = githubApiClient.getUser(personalAccessToken.getToken());
return new GitUserData(user.getName(), user.getEmail());
GithubApiClient apiClient =
githubApiClient.isConnected(personalAccessToken.getScmProviderUrl())
? githubApiClient
: new GithubApiClient(personalAccessToken.getScmProviderUrl());
GithubUser user = apiClient.getUser(personalAccessToken.getToken());
if (isNullOrEmpty(user.getName()) || isNullOrEmpty(user.getEmail())) {
throw new ScmItemNotFoundException(NO_USERNAME_AND_EMAIL_ERROR_MESSAGE);
} else {
return new GitUserData(user.getName(), user.getEmail());
}
}
protected String getLocalAuthenticateUrl() {

View File

@ -192,7 +192,7 @@ public class GithubUrl extends DefaultFactoryUrl {
return new StringJoiner("/")
.add(
isNullOrEmpty(serverUrl)
HOSTNAME.equals(serverUrl)
? "https://raw.githubusercontent.com"
: disableSubdomainIsolation
? serverUrl + "/raw"
@ -208,7 +208,8 @@ public class GithubUrl extends DefaultFactoryUrl {
@Override
public String getHostName() {
return isNullOrEmpty(serverUrl) ? HOSTNAME : serverUrl;
// TODO: rework this method to return hostname in format https://<hostname>/user/repo
return serverUrl;
}
/**
@ -218,12 +219,7 @@ public class GithubUrl extends DefaultFactoryUrl {
*/
protected String repositoryLocation() {
if (isHTTPSUrl) {
return (isNullOrEmpty(serverUrl) ? HOSTNAME : serverUrl)
+ "/"
+ this.username
+ "/"
+ this.repository
+ ".git";
return serverUrl + "/" + this.username + "/" + this.repository + ".git";
}
return "git@"
+ getHostName().substring(getHostName().indexOf("://") + 3)

View File

@ -49,6 +49,7 @@ public class GithubAuthorizingFileContentProviderTest {
.withUsername("eclipse")
.withRepository("che")
.withBranch("main")
.withServerUrl("https://github.com")
.withLatestCommit("d74923ebf968454cf13251f17df69dcd87d3b932");
FileContentProvider fileContentProvider =
@ -74,6 +75,7 @@ public class GithubAuthorizingFileContentProviderTest {
new GithubUrl("github")
.withUsername("eclipse")
.withRepository("che")
.withServerUrl("https://github.com")
.withBranch("main")
.withLatestCommit("9ac2f42ed62944d164f189afd57f14a2793a7e4b");
@ -92,7 +94,11 @@ public class GithubAuthorizingFileContentProviderTest {
public void shouldThrowNotFoundForPublicRepos() throws Exception {
String url = "https://raw.githubusercontent.com/foo/bar/branch-name/devfile.yaml";
GithubUrl githubUrl = new GithubUrl("github").withUsername("eclipse").withRepository("che");
GithubUrl githubUrl =
new GithubUrl("github")
.withUsername("eclipse")
.withRepository("che")
.withServerUrl("https://github.com");
URLFetcher urlFetcher = Mockito.mock(URLFetcher.class);
FileContentProvider fileContentProvider =
@ -109,7 +115,11 @@ public class GithubAuthorizingFileContentProviderTest {
@Test(expectedExceptions = DevfileException.class)
public void shouldThrowDevfileException() throws Exception {
String url = "https://raw.githubusercontent.com/foo/bar/branch-name/devfile.yaml";
GithubUrl githubUrl = new GithubUrl("github").withUsername("eclipse").withRepository("che");
GithubUrl githubUrl =
new GithubUrl("github")
.withUsername("eclipse")
.withRepository("che")
.withServerUrl("https://github.com");
URLFetcher urlFetcher = Mockito.mock(URLFetcher.class);
FileContentProvider fileContentProvider =
@ -128,7 +138,11 @@ public class GithubAuthorizingFileContentProviderTest {
String raw_url = "https://ghserver.com/foo/bar/branch-name/devfile.yaml";
URLFetcher urlFetcher = Mockito.mock(URLFetcher.class);
GithubUrl githubUrl = new GithubUrl("github").withUsername("eclipse").withRepository("che");
GithubUrl githubUrl =
new GithubUrl("github")
.withUsername("eclipse")
.withRepository("che")
.withServerUrl("https://github.com");
FileContentProvider fileContentProvider =
new GithubAuthorizingFileContentProvider(githubUrl, urlFetcher, personalAccessTokenManager);
var personalAccessToken = new PersonalAccessToken(raw_url, "che", "my-token");

View File

@ -163,6 +163,7 @@ public class GithubFactoryParametersResolverTest {
any(RemoteFactoryUrl.class), any(), anyMap(), anyBoolean()))
.thenReturn(Optional.empty());
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getLatestCommit(anyString(), anyString(), anyString(), any()))
.thenReturn(new GithubCommit().withSha("test-sha"));
@ -182,7 +183,7 @@ public class GithubFactoryParametersResolverTest {
// given
when(urlFactoryBuilder.buildDefaultDevfile(any()))
.thenReturn(generateDevfileFactory().getDevfile());
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getLatestCommit(anyString(), anyString(), anyString(), any()))
.thenReturn(new GithubCommit().withSha("test-sha"));
@ -205,7 +206,7 @@ public class GithubFactoryParametersResolverTest {
// given
when(urlFactoryBuilder.buildDefaultDevfile(any()))
.thenReturn(generateDevfileFactory().getDevfile());
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getLatestCommit(anyString(), anyString(), anyString(), any()))
.thenReturn(new GithubCommit().withSha("test-sha"));
@ -231,7 +232,7 @@ public class GithubFactoryParametersResolverTest {
when(urlFactoryBuilder.createFactoryFromDevfile(
any(RemoteFactoryUrl.class), any(), anyMap(), anyBoolean()))
.thenReturn(Optional.of(computedFactory));
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getLatestCommit(anyString(), anyString(), anyString(), any()))
.thenReturn(new GithubCommit().withSha("13bbd0d4605a6ed3350f7b15eb02c4d4e6f8df6e"));
@ -262,7 +263,7 @@ public class GithubFactoryParametersResolverTest {
when(urlFactoryBuilder.createFactoryFromDevfile(
any(RemoteFactoryUrl.class), any(), anyMap(), anyBoolean()))
.thenReturn(Optional.of(computedFactory));
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getLatestCommit(anyString(), anyString(), anyString(), any()))
.thenReturn(new GithubCommit().withSha("test-sha"));
@ -293,7 +294,7 @@ public class GithubFactoryParametersResolverTest {
when(urlFactoryBuilder.createFactoryFromDevfile(
any(RemoteFactoryUrl.class), any(), anyMap(), anyBoolean()))
.thenReturn(Optional.of(computedFactory));
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getLatestCommit(anyString(), anyString(), anyString(), any()))
.thenReturn(new GithubCommit().withSha("test-sha"));
@ -316,7 +317,7 @@ public class GithubFactoryParametersResolverTest {
when(urlFactoryBuilder.createFactoryFromDevfile(
any(RemoteFactoryUrl.class), any(), anyMap(), anyBoolean()))
.thenReturn(Optional.of(computedFactory));
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getLatestCommit(anyString(), anyString(), anyString(), any()))
.thenReturn(new GithubCommit().withSha("test-sha"));

View File

@ -90,6 +90,7 @@ public class GithubScmFileResolverTest {
.when(personalAccessTokenManager.getAndStore(anyString()))
.thenReturn(new PersonalAccessToken("foo", "che", "my-token"));
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getLatestCommit(anyString(), anyString(), anyString(), any()))
.thenReturn(
new GithubCommit()

View File

@ -13,8 +13,10 @@ package org.eclipse.che.api.factory.server.github;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
@ -89,7 +91,13 @@ public class GithubURLParserTest {
@Test(dataProvider = "parsingBadRepository")
public void checkParsingBadRepositoryDoNotModifiesInitialInput(String url, String repository)
throws ApiException {
// given
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
// when
GithubUrl githubUrl = githubUrlParser.parse(url);
// then
assertEquals(githubUrl.getRepository(), repository);
}
@ -189,6 +197,7 @@ public class GithubURLParserTest {
.withRef("pr-main-to-7.46.0")
.withUser(new GithubUser().withId(0).withName("eclipse").withLogin("eclipse"))
.withRepo(new GithubRepo().withName("che")));
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getPullRequest(any(), any(), any(), any())).thenReturn(pr);
GithubUrl githubUrl = githubUrlParser.parse(url);
@ -215,6 +224,7 @@ public class GithubURLParserTest {
when(personalAccessTokenManager.get(any(Subject.class), anyString()))
.thenReturn(Optional.of(personalAccessToken));
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getPullRequest(anyString(), anyString(), anyString(), anyString()))
.thenReturn(pr);
@ -239,6 +249,7 @@ public class GithubURLParserTest {
.withUser(new GithubUser().withId(0).withName("eclipse").withLogin("eclipse"))
.withRepo(new GithubRepo().withName("che")));
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getPullRequest(any(), any(), any(), any())).thenReturn(pr);
GithubUrl githubUrl = githubUrlParser.parseWithoutAuthentication(url);
@ -261,10 +272,47 @@ public class GithubURLParserTest {
when(personalAccessToken.getToken()).thenReturn("token");
when(personalAccessTokenManager.get(any(Subject.class), anyString()))
.thenReturn(Optional.of(personalAccessToken));
when(githubApiClient.isConnected(eq("https://github.com"))).thenReturn(true);
when(githubApiClient.getPullRequest(anyString(), anyString(), anyString(), anyString()))
.thenReturn(githubPullRequest);
String url = "https://github.com/eclipse/che/pull/11103";
githubUrlParser.parse(url);
}
@Test
public void shouldParseServerUr() throws Exception {
// given
String url = "https://github-server.com/user/repo";
// when
GithubUrl githubUrl = githubUrlParser.parse(url);
// then
assertEquals(githubUrl.getUsername(), "user");
assertEquals(githubUrl.getRepository(), "repo");
assertEquals(githubUrl.getHostName(), "https://github-server.com");
}
@Test
public void shouldParseServerUrWithPullRequestId() throws Exception {
// given
String url = "https://github-server.com/user/repo/pull/11103";
GithubPullRequest pr =
new GithubPullRequest()
.withState("open")
.withHead(
new GithubHead()
.withUser(new GithubUser().withId(0).withName("eclipse").withLogin("eclipse"))
.withRepo(new GithubRepo().withName("che")));
when(githubApiClient.isConnected(eq("https://github-server.com"))).thenReturn(true);
when(githubApiClient.getPullRequest(any(), any(), any(), any())).thenReturn(pr);
// when
githubUrlParser.parse(url);
// then
verify(personalAccessTokenManager, times(2))
.get(any(Subject.class), eq("https://github-server.com"));
}
}

View File

@ -39,6 +39,7 @@ public class GithubUrlTest {
@Test
public void checkDevfileLocation() throws Exception {
DevfileFilenamesProvider devfileFilenamesProvider = mock(DevfileFilenamesProvider.class);
when(githubApiClient.isConnected("https://github.com")).thenReturn(true);
/** Parser used to create the url. */
GithubURLParser githubUrlParser =
@ -67,6 +68,7 @@ public class GithubUrlTest {
@Test
public void shouldReturnDevfileLocationFromSSHUrl() throws Exception {
DevfileFilenamesProvider devfileFilenamesProvider = mock(DevfileFilenamesProvider.class);
when(githubApiClient.isConnected("https://github.com")).thenReturn(true);
/** Parser used to create the url. */
GithubURLParser githubUrlParser =
@ -139,7 +141,11 @@ public class GithubUrlTest {
public void testRawFileLocationWithDefaultBranchName() {
String file = ".che/che-theia-plugins.yaml";
GithubUrl url = new GithubUrl("github").withUsername("eclipse").withRepository("che");
GithubUrl url =
new GithubUrl("github")
.withUsername("eclipse")
.withRepository("che")
.withServerUrl("https://github.com");
assertEquals(
url.rawFileLocation(file),
@ -151,7 +157,11 @@ public class GithubUrlTest {
String file = ".che/che-theia-plugins.yaml";
GithubUrl url =
new GithubUrl("github").withUsername("eclipse").withRepository("che").withBranch("main");
new GithubUrl("github")
.withUsername("eclipse")
.withRepository("che")
.withBranch("main")
.withServerUrl("https://github.com");
assertEquals(
url.rawFileLocation(file),
@ -166,6 +176,7 @@ public class GithubUrlTest {
new GithubUrl("github")
.withUsername("eclipse")
.withRepository("che")
.withServerUrl("https://github.com")
.withBranch("main")
.withLatestCommit("c24fd44e0f7296be2e49a380fb8abe2fe4db9100");