diff --git a/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties b/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties index 313f352bc2..5a17acc3cd 100644 --- a/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties +++ b/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties @@ -204,6 +204,10 @@ che.oauth.github.authuri= https://github.com/login/oauth/authorize # GitHub OAuth token URI. che.oauth.github.tokenuri= https://github.com/login/oauth/access_token +# GitHub server address. +# Prerequisite: OAuth 2 integration is configured on the GitHub server. +che.integration.github.oauth_endpoint=NULL + # GitHub OAuth redirect URIs. # Separate multiple values with comma, for example: URI,URI,URI che.oauth.github.redirecturis= http://localhost:${CHE_PORT}/api/oauth/callback diff --git a/multiuser/keycloak/che-multiuser-keycloak-token-provider/src/main/java/org/eclipse/che/multiuser/keycloak/token/provider/oauth/OpenShiftGitHubOAuthAuthenticator.java b/multiuser/keycloak/che-multiuser-keycloak-token-provider/src/main/java/org/eclipse/che/multiuser/keycloak/token/provider/oauth/OpenShiftGitHubOAuthAuthenticator.java index 723e3ee260..dff56b9af7 100644 --- a/multiuser/keycloak/che-multiuser-keycloak-token-provider/src/main/java/org/eclipse/che/multiuser/keycloak/token/provider/oauth/OpenShiftGitHubOAuthAuthenticator.java +++ b/multiuser/keycloak/che-multiuser-keycloak-token-provider/src/main/java/org/eclipse/che/multiuser/keycloak/token/provider/oauth/OpenShiftGitHubOAuthAuthenticator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 Red Hat, Inc. + * Copyright (c) 2012-2022 Red Hat, Inc. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -33,7 +33,7 @@ public class OpenShiftGitHubOAuthAuthenticator extends GitHubOAuthAuthenticator @Nullable @Named("che.oauth.github.tokenuri") String tokenUri) throws IOException { - super("NULL", "NULL", redirectUris, authUri, tokenUri); + super("NULL", "NULL", redirectUris, null, authUri, tokenUri); if (!isNullOrEmpty(authUri) && !isNullOrEmpty(tokenUri) diff --git a/wsmaster/che-core-api-auth-github/pom.xml b/wsmaster/che-core-api-auth-github/pom.xml index 681a1a7f36..5868e24fb4 100644 --- a/wsmaster/che-core-api-auth-github/pom.xml +++ b/wsmaster/che-core-api-auth-github/pom.xml @@ -59,6 +59,10 @@ org.eclipse.che.core che-core-commons-inject + + org.eclipse.che.core + che-core-commons-lang + org.slf4j slf4j-api diff --git a/wsmaster/che-core-api-auth-github/src/main/java/org/eclipse/che/security/oauth/GitHubOAuthAuthenticator.java b/wsmaster/che-core-api-auth-github/src/main/java/org/eclipse/che/security/oauth/GitHubOAuthAuthenticator.java index 8f7354846b..ea60fac5d4 100644 --- a/wsmaster/che-core-api-auth-github/src/main/java/org/eclipse/che/security/oauth/GitHubOAuthAuthenticator.java +++ b/wsmaster/che-core-api-auth-github/src/main/java/org/eclipse/che/security/oauth/GitHubOAuthAuthenticator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2021 Red Hat, Inc. + * Copyright (c) 2012-2022 Red Hat, Inc. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -12,6 +12,7 @@ package org.eclipse.che.security.oauth; import static com.google.common.base.Strings.isNullOrEmpty; +import static org.eclipse.che.commons.lang.StringUtils.trimEnd; import com.google.api.client.util.store.MemoryDataStoreFactory; import jakarta.mail.internet.AddressException; @@ -24,17 +25,27 @@ import org.eclipse.che.security.oauth.shared.User; /** OAuth authentication for github account. */ @Singleton public class GitHubOAuthAuthenticator extends OAuthAuthenticator { + private final String userRequestUrl; + public GitHubOAuthAuthenticator( - String clientId, String clientSecret, String[] redirectUris, String authUri, String tokenUri) + String clientId, + String clientSecret, + String[] redirectUris, + String authEndpoint, + String authUri, + String tokenUri) throws IOException { + userRequestUrl = + isNullOrEmpty(authEndpoint) || trimEnd(authEndpoint, '/').equals("https://github.com") + ? "https://api.github.com/user" + : trimEnd(authEndpoint, '/') + "/api/v3/user"; configure( clientId, clientSecret, redirectUris, authUri, tokenUri, new MemoryDataStoreFactory()); } @Override public User getUser(OAuthToken accessToken) throws OAuthAuthenticationException { - GitHubUser user = - getJson("https://api.github.com/user", accessToken.getToken(), GitHubUser.class); + GitHubUser user = getJson(userRequestUrl, accessToken.getToken(), GitHubUser.class); final String email = user.getEmail(); if (isNullOrEmpty(email)) { @@ -65,7 +76,7 @@ public class GitHubOAuthAuthenticator extends OAuthAuthenticator { if (token == null || token.getToken() == null || token.getToken().isEmpty() - || getJson("https://api.github.com/user", token.getToken(), GitHubUser.class) == null) { + || getJson(userRequestUrl, token.getToken(), GitHubUser.class) == null) { return null; } } catch (OAuthAuthenticationException e) { diff --git a/wsmaster/che-core-api-auth-github/src/main/java/org/eclipse/che/security/oauth/GitHubOAuthAuthenticatorProvider.java b/wsmaster/che-core-api-auth-github/src/main/java/org/eclipse/che/security/oauth/GitHubOAuthAuthenticatorProvider.java index c975fdd219..f7379c1a15 100644 --- a/wsmaster/che-core-api-auth-github/src/main/java/org/eclipse/che/security/oauth/GitHubOAuthAuthenticatorProvider.java +++ b/wsmaster/che-core-api-auth-github/src/main/java/org/eclipse/che/security/oauth/GitHubOAuthAuthenticatorProvider.java @@ -12,6 +12,7 @@ package org.eclipse.che.security.oauth; import static com.google.common.base.Strings.isNullOrEmpty; +import static org.eclipse.che.commons.lang.StringUtils.trimEnd; import java.io.IOException; import java.nio.file.Files; @@ -42,12 +43,18 @@ public class GitHubOAuthAuthenticatorProvider implements Providerorg.eclipse.che.core che-core-api-workspace-shared + + org.eclipse.che.core + che-core-commons-annotations + org.eclipse.che.core che-core-commons-lang diff --git a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubApiClient.java b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubApiClient.java index 03e08988a5..dd9db3b322 100644 --- a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubApiClient.java +++ b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubApiClient.java @@ -11,11 +11,13 @@ */ package org.eclipse.che.api.factory.server.github; +import static com.google.common.base.Strings.isNullOrEmpty; import static java.net.HttpURLConnection.HTTP_BAD_REQUEST; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import static java.net.HttpURLConnection.HTTP_NO_CONTENT; import static java.net.HttpURLConnection.HTTP_OK; import static java.time.Duration.ofSeconds; +import static org.eclipse.che.commons.lang.StringUtils.trimEnd; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Charsets; @@ -37,6 +39,7 @@ import java.util.function.Function; import org.eclipse.che.api.factory.server.scm.exception.ScmBadRequestException; import org.eclipse.che.api.factory.server.scm.exception.ScmCommunicationException; import org.eclipse.che.api.factory.server.scm.exception.ScmItemNotFoundException; +import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,11 +49,8 @@ public class GithubApiClient { private static final Logger LOG = LoggerFactory.getLogger(GithubApiClient.class); - /** GitHub API endpoint URL. */ - public static final String GITHUB_API_SERVER = "https://api.github.com"; - /** GitHub endpoint URL. */ - public static final String GITHUB_SERVER = "https://github.com"; + public static final String GITHUB_SAAS_ENDPOINT = "https://github.com"; /** GitHub HTTP header containing OAuth scopes. */ public static final String GITHUB_OAUTH_SCOPES_HEADER = "X-OAuth-Scopes"; @@ -62,19 +62,16 @@ public class GithubApiClient { private static final Duration DEFAULT_HTTP_TIMEOUT = ofSeconds(10); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - /** Default constructor, binds http client to https://api.github.com */ - public GithubApiClient() { - this(GITHUB_API_SERVER); - } - - /** - * Used for URL injection in testing. - * - * @param apiServerUrl the GitHub API url - */ - GithubApiClient(final String apiServerUrl) { - this.apiServerUrl = URI.create(apiServerUrl); - this.scmServerUrl = URI.create(GITHUB_SERVER); + /** Default constructor, binds http client to GitHub API url */ + public GithubApiClient(@Nullable String serverUrl) { + String trimmedServerUrl = !isNullOrEmpty(serverUrl) ? trimEnd(serverUrl, '/') : null; + this.apiServerUrl = + URI.create( + isNullOrEmpty(trimmedServerUrl) || trimmedServerUrl.equals(GITHUB_SAAS_ENDPOINT) + ? "https://api.github.com/" + : trimmedServerUrl + "/api/v3/"); + this.scmServerUrl = + URI.create(isNullOrEmpty(trimmedServerUrl) ? GITHUB_SAAS_ENDPOINT : trimmedServerUrl); this.httpClient = HttpClient.newBuilder() .executor( @@ -101,7 +98,7 @@ public class GithubApiClient { */ public GithubUser getUser(String authenticationToken) throws ScmItemNotFoundException, ScmCommunicationException, ScmBadRequestException { - final URI uri = apiServerUrl.resolve("/user"); + final URI uri = apiServerUrl.resolve("./user"); HttpRequest request = buildGithubApiRequest(uri, authenticationToken); LOG.trace("executeRequest={}", request); return executeRequest( @@ -120,7 +117,7 @@ public class GithubApiClient { String id, String username, String repoName, String authenticationToken) throws ScmItemNotFoundException, ScmCommunicationException, ScmBadRequestException { final URI uri = - apiServerUrl.resolve(String.format("/repos/%1s/%2s/pulls/%3s", username, repoName, id)); + apiServerUrl.resolve(String.format("./repos/%1s/%2s/pulls/%3s", username, repoName, id)); HttpRequest request = buildGithubApiRequest(uri, authenticationToken); LOG.trace("executeRequest={}", request); return executeRequest( @@ -149,7 +146,7 @@ public class GithubApiClient { */ public String[] getTokenScopes(String authenticationToken) throws ScmItemNotFoundException, ScmCommunicationException, ScmBadRequestException { - final URI uri = apiServerUrl.resolve("/user"); + final URI uri = apiServerUrl.resolve("./user"); HttpRequest request = buildGithubApiRequest(uri, authenticationToken); LOG.trace("executeRequest={}", request); return executeRequest( @@ -213,6 +210,6 @@ public class GithubApiClient { * @return If the provided url is recognized by the current client */ public boolean isConnected(String scmServerUrl) { - return this.scmServerUrl.equals(URI.create(scmServerUrl)); + return this.scmServerUrl.equals(URI.create(trimEnd(scmServerUrl, '/'))); } } diff --git a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubPersonalAccessTokenFetcher.java b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubPersonalAccessTokenFetcher.java index 37316bf843..b8e218cf72 100644 --- a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubPersonalAccessTokenFetcher.java +++ b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubPersonalAccessTokenFetcher.java @@ -34,6 +34,7 @@ import org.eclipse.che.api.factory.server.scm.exception.ScmCommunicationExceptio import org.eclipse.che.api.factory.server.scm.exception.ScmItemNotFoundException; import org.eclipse.che.api.factory.server.scm.exception.ScmUnauthorizedException; import org.eclipse.che.api.factory.server.scm.exception.UnknownScmProviderException; +import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.commons.lang.NameGenerator; import org.eclipse.che.commons.subject.Subject; import org.eclipse.che.security.oauth.OAuthAPI; @@ -117,8 +118,11 @@ public class GithubPersonalAccessTokenFetcher implements PersonalAccessTokenFetc .build(); @Inject - public GithubPersonalAccessTokenFetcher(@Named("che.api") String apiEndpoint, OAuthAPI oAuthAPI) { - this(apiEndpoint, oAuthAPI, new GithubApiClient()); + public GithubPersonalAccessTokenFetcher( + @Named("che.api") String apiEndpoint, + @Nullable @Named("che.integration.github.oauth_endpoint") String oauthEndpoint, + OAuthAPI oAuthAPI) { + this(apiEndpoint, oAuthAPI, new GithubApiClient(oauthEndpoint)); } /** @@ -161,7 +165,7 @@ public class GithubPersonalAccessTokenFetcher implements PersonalAccessTokenFetc if (valid.isEmpty()) { throw new ScmCommunicationException( "Unable to verify if current token is a valid GitHub token. Token's scm-url needs to be '" - + GithubApiClient.GITHUB_SERVER + + GithubApiClient.GITHUB_SAAS_ENDPOINT + "' and was '" + token.getScmProviderUrl() + "'"); diff --git a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubURLParser.java b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubURLParser.java index f768db5136..79a4f56132 100644 --- a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubURLParser.java +++ b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubURLParser.java @@ -11,13 +11,19 @@ */ package org.eclipse.che.api.factory.server.github; +import static com.google.common.base.Strings.isNullOrEmpty; +import static java.lang.String.format; +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; +import static org.eclipse.che.commons.lang.StringUtils.trimEnd; import jakarta.validation.constraints.NotNull; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.inject.Inject; +import javax.inject.Named; import javax.inject.Singleton; import org.eclipse.che.api.core.ApiException; import org.eclipse.che.api.factory.server.scm.PersonalAccessToken; @@ -30,6 +36,7 @@ import org.eclipse.che.api.factory.server.scm.exception.ScmUnauthorizedException import org.eclipse.che.api.factory.server.scm.exception.UnknownScmProviderException; import org.eclipse.che.api.factory.server.scm.exception.UnsatisfiedScmPreconditionException; import org.eclipse.che.api.factory.server.urlfactory.DevfileFilenamesProvider; +import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.commons.env.EnvironmentContext; import org.eclipse.che.commons.subject.Subject; import org.slf4j.Logger; @@ -47,27 +54,42 @@ public class GithubURLParser { 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; @Inject public GithubURLParser( PersonalAccessTokenManager tokenManager, DevfileFilenamesProvider devfileFilenamesProvider, - GithubApiClient apiClient) { - this.tokenManager = tokenManager; - this.devfileFilenamesProvider = devfileFilenamesProvider; - this.apiClient = apiClient; + @Nullable @Named("che.integration.github.oauth_endpoint") String oauthEndpoint) { + this(tokenManager, devfileFilenamesProvider, new GithubApiClient(oauthEndpoint), oauthEndpoint); } - /** - * Regexp to find repository details (repository name, project name and branch and subfolder) - * Examples of valid URLs are in the test class. - */ - protected static final Pattern GITHUB_PATTERN = - Pattern.compile( - "^(?:http)(?:s)?(?:\\:\\/\\/)github.com/(?[^/]++)/(?[^/]++)((/)|(?:/tree/(?[^/]++)(?:/(?.*))?)|(/pull/(?[^/]++)))?$"); + /** Constructor used for testing only. */ + GithubURLParser( + PersonalAccessTokenManager tokenManager, + DevfileFilenamesProvider devfileFilenamesProvider, + GithubApiClient githubApiClient, + String oauthEndpoint) { + this.tokenManager = tokenManager; + this.devfileFilenamesProvider = devfileFilenamesProvider; + this.apiClient = githubApiClient; + this.oauthEndpoint = oauthEndpoint; + String endpoint = + isNullOrEmpty(oauthEndpoint) ? GITHUB_SAAS_ENDPOINT : trimEnd(oauthEndpoint, '/'); + this.githubPattern = + compile( + format( + "^%s/(?[^/]++)/(?[^/]++)((/)|(?:/tree/(?[^/]++)(?:/(?.*))?)|(/pull/(?[^/]++)))?$", + endpoint)); + } public boolean isValid(@NotNull String url) { - return GITHUB_PATTERN.matcher(url).matches(); + return githubPattern.matcher(url).matches(); } public GithubUrl parseWithoutAuthentication(String url) throws ApiException { @@ -80,14 +102,18 @@ public class GithubURLParser { private GithubUrl parse(String url, boolean authenticationRequired) throws ApiException { // Apply github url to the regexp - Matcher matcher = GITHUB_PATTERN.matcher(url); + Matcher matcher = githubPattern.matcher(url); if (!matcher.matches()) { throw new IllegalArgumentException( - String.format( + format( "The given github url %s is not a valid URL github url. It should start with https://github.com//", url)); } + String serverUrl = + isNullOrEmpty(oauthEndpoint) || trimEnd(oauthEndpoint, '/').equals(GITHUB_SAAS_ENDPOINT) + ? null + : trimEnd(oauthEndpoint, '/'); String repoUser = matcher.group("repoUser"); String repoName = matcher.group("repoName"); if (repoName.matches("^[\\w-][\\w.-]*?\\.git$")) { @@ -98,7 +124,8 @@ public class GithubURLParser { String pullRequestId = matcher.group("pullRequestId"); if (pullRequestId != null) { try { - String githubEndpoint = "https://github.com"; + String githubEndpoint = + isNullOrEmpty(oauthEndpoint) ? GITHUB_SAAS_ENDPOINT : trimEnd(oauthEndpoint, '/'); Subject subject = EnvironmentContext.getCurrent().getSubject(); PersonalAccessToken personalAccessToken = null; Optional tokenOptional = tokenManager.get(subject, githubEndpoint); @@ -114,7 +141,7 @@ public class GithubURLParser { String prState = pullRequest.getState(); if (!"open".equalsIgnoreCase(prState)) { throw new IllegalArgumentException( - String.format( + format( "The given Pull Request url %s is not Opened, (found %s), thus it can't be opened as branch may have been removed.", url, prState)); } @@ -139,6 +166,7 @@ public class GithubURLParser { return new GithubUrl() .withUsername(repoUser) .withRepository(repoName) + .withServerUrl(serverUrl) .withBranch(branchName) .withSubfolder(matcher.group("subFolder")) .withDevfileFilenames(devfileFilenamesProvider.getConfiguredDevfileFilenames()); diff --git a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUrl.java b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUrl.java index 730fdf9c56..1dbb142f20 100644 --- a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUrl.java +++ b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUrl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2021 Red Hat, Inc. + * Copyright (c) 2012-2022 Red Hat, Inc. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -12,8 +12,8 @@ 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 com.google.common.base.Strings; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -47,6 +47,8 @@ public class GithubUrl implements RemoteFactoryUrl { /** Subfolder if any */ private String subfolder; + private String serverUrl; + /** Devfile filenames list */ private final List devfileFilenames = new ArrayList<>(); @@ -110,7 +112,7 @@ public class GithubUrl implements RemoteFactoryUrl { } protected GithubUrl withBranch(String branch) { - if (!Strings.isNullOrEmpty(branch)) { + if (!isNullOrEmpty(branch)) { this.branch = branch; } return this; @@ -136,6 +138,11 @@ public class GithubUrl implements RemoteFactoryUrl { return this; } + public GithubUrl withServerUrl(String serverUrl) { + this.serverUrl = serverUrl; + return this; + } + /** * Provides list of configured devfile filenames with locations * @@ -167,7 +174,7 @@ public class GithubUrl implements RemoteFactoryUrl { */ public String rawFileLocation(String fileName) { return new StringJoiner("/") - .add("https://raw.githubusercontent.com") + .add(isNullOrEmpty(serverUrl) ? "https://raw.githubusercontent.com" : serverUrl + "/raw") .add(username) .add(repository) .add(firstNonNull(branch, "HEAD")) @@ -177,7 +184,7 @@ public class GithubUrl implements RemoteFactoryUrl { @Override public String getHostName() { - return HOSTNAME; + return isNullOrEmpty(serverUrl) ? HOSTNAME : serverUrl; } /** @@ -186,6 +193,11 @@ public class GithubUrl implements RemoteFactoryUrl { * @return location of the repository. */ protected String repositoryLocation() { - return HOSTNAME + "/" + this.username + "/" + this.repository + ".git"; + return (isNullOrEmpty(serverUrl) ? HOSTNAME : serverUrl) + + "/" + + this.username + + "/" + + this.repository + + ".git"; } } diff --git a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUserDataFetcher.java b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUserDataFetcher.java index 1315f65fad..0f657dc6ff 100644 --- a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUserDataFetcher.java +++ b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUserDataFetcher.java @@ -29,6 +29,7 @@ import org.eclipse.che.api.factory.server.scm.exception.ScmBadRequestException; import org.eclipse.che.api.factory.server.scm.exception.ScmCommunicationException; import org.eclipse.che.api.factory.server.scm.exception.ScmItemNotFoundException; import org.eclipse.che.api.factory.server.scm.exception.ScmUnauthorizedException; +import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.commons.env.EnvironmentContext; import org.eclipse.che.commons.subject.Subject; import org.eclipse.che.security.oauth.OAuthAPI; @@ -49,8 +50,11 @@ public class GithubUserDataFetcher implements GitUserDataFetcher { ImmutableSet.of("repo", "user:email", "read:user"); @Inject - public GithubUserDataFetcher(@Named("che.api") String apiEndpoint, OAuthAPI oAuthAPI) { - this(apiEndpoint, oAuthAPI, new GithubApiClient()); + public GithubUserDataFetcher( + @Named("che.api") String apiEndpoint, + @Nullable @Named("che.integration.github.oauth_endpoint") String oauthEndpoint, + OAuthAPI oAuthAPI) { + this(apiEndpoint, oAuthAPI, new GithubApiClient(oauthEndpoint)); } /** Constructor used for testing only. */ diff --git a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubApiClientTest.java b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubApiClientTest.java index e82648b319..0738f4b14a 100644 --- a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubApiClientTest.java +++ b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubApiClientTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2021 Red Hat, Inc. + * Copyright (c) 2012-2022 Red Hat, Inc. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -58,7 +58,7 @@ public class GithubApiClientTest { @Test public void testGetUser() throws Exception { stubFor( - get(urlEqualTo("/user")) + get(urlEqualTo("/api/v3/user")) .withHeader(HttpHeaders.AUTHORIZATION, equalTo("token token1")) .willReturn( aResponse() @@ -81,7 +81,7 @@ public class GithubApiClientTest { @Test public void testGetTokenScopes() throws Exception { stubFor( - get(urlEqualTo("/user")) + get(urlEqualTo("/api/v3/user")) .withHeader(HttpHeaders.AUTHORIZATION, equalTo("token token1")) .willReturn( aResponse() @@ -99,7 +99,7 @@ public class GithubApiClientTest { @Test public void testGetTokenScopesWithNoScopeHeader() throws Exception { stubFor( - get(urlEqualTo("/user")) + get(urlEqualTo("/api/v3/user")) .withHeader(HttpHeaders.AUTHORIZATION, equalTo("token token1")) .willReturn( aResponse() @@ -119,7 +119,7 @@ public class GithubApiClientTest { @Test public void testGetTokenScopesWithNoScope() throws Exception { stubFor( - get(urlEqualTo("/user")) + get(urlEqualTo("/api/v3/user")) .withHeader(HttpHeaders.AUTHORIZATION, equalTo("token token1")) .willReturn( aResponse() @@ -144,6 +144,6 @@ public class GithubApiClientTest { @Test public void shouldReturnTrueWhenConnectedToGithub() { - assertTrue(client.isConnected("https://github.com")); + assertTrue(client.isConnected(wireMockServer.url("/"))); } } diff --git a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubFactoryParametersResolverTest.java b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubFactoryParametersResolverTest.java index 286da3e590..f4f7f2b8fb 100644 --- a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubFactoryParametersResolverTest.java +++ b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubFactoryParametersResolverTest.java @@ -21,7 +21,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -102,8 +101,7 @@ public class GithubFactoryParametersResolverTest { @BeforeMethod protected void init() { githubUrlParser = - new GithubURLParser( - personalAccessTokenManager, devfileFilenamesProvider, mock(GithubApiClient.class)); + new GithubURLParser(personalAccessTokenManager, devfileFilenamesProvider, null); assertNotNull(this.githubUrlParser); githubFactoryParametersResolver = new GithubFactoryParametersResolver( diff --git a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubGitUserDataFetcherTest.java b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubGitUserDataFetcherTest.java index d4d3fe77f8..62256ae832 100644 --- a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubGitUserDataFetcherTest.java +++ b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubGitUserDataFetcherTest.java @@ -59,7 +59,7 @@ public class GithubGitUserDataFetcherTest { new GithubUserDataFetcher( "http://che.api", oAuthAPI, new GithubApiClient(wireMockServer.url("/"))); stubFor( - get(urlEqualTo("/user")) + get(urlEqualTo("/api/v3/user")) .withHeader(HttpHeaders.AUTHORIZATION, equalTo("token " + githubOauthToken)) .willReturn( aResponse() diff --git a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubPersonalAccessTokenFetcherTest.java b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubPersonalAccessTokenFetcherTest.java index df0a3fb660..5cf0d83e74 100644 --- a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubPersonalAccessTokenFetcherTest.java +++ b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubPersonalAccessTokenFetcherTest.java @@ -143,7 +143,7 @@ public class GithubPersonalAccessTokenFetcherTest { when(oAuthAPI.getToken(anyString())).thenReturn(oAuthToken); stubFor( - get(urlEqualTo("/user")) + get(urlEqualTo("/api/v3/user")) .withHeader(HttpHeaders.AUTHORIZATION, equalTo("token " + githubOauthToken)) .willReturn( aResponse() @@ -151,7 +151,7 @@ public class GithubPersonalAccessTokenFetcherTest { .withHeader(GithubApiClient.GITHUB_OAUTH_SCOPES_HEADER, "") .withBodyFile("github/rest/user/response.json"))); - githubPATFetcher.fetchPersonalAccessToken(subject, GithubApiClient.GITHUB_SERVER); + githubPATFetcher.fetchPersonalAccessToken(subject, wireMockServer.url("/")); } @Test( @@ -161,7 +161,7 @@ public class GithubPersonalAccessTokenFetcherTest { Subject subject = new SubjectImpl("Username", "id1", "token", false); when(oAuthAPI.getToken(anyString())).thenThrow(UnauthorizedException.class); - githubPATFetcher.fetchPersonalAccessToken(subject, GithubApiClient.GITHUB_SERVER); + githubPATFetcher.fetchPersonalAccessToken(subject, wireMockServer.url("/")); } @Test @@ -171,7 +171,7 @@ public class GithubPersonalAccessTokenFetcherTest { when(oAuthAPI.getToken(anyString())).thenReturn(oAuthToken); stubFor( - get(urlEqualTo("/user")) + get(urlEqualTo("/api/v3/user")) .withHeader(HttpHeaders.AUTHORIZATION, equalTo("token " + githubOauthToken)) .willReturn( aResponse() @@ -182,14 +182,14 @@ public class GithubPersonalAccessTokenFetcherTest { .withBodyFile("github/rest/user/response.json"))); PersonalAccessToken token = - githubPATFetcher.fetchPersonalAccessToken(subject, GithubApiClient.GITHUB_SERVER); + githubPATFetcher.fetchPersonalAccessToken(subject, wireMockServer.url("/")); assertNotNull(token); } @Test public void shouldValidatePersonalToken() throws Exception { stubFor( - get(urlEqualTo("/user")) + get(urlEqualTo("/api/v3/user")) .withHeader(HttpHeaders.AUTHORIZATION, equalTo("token " + githubOauthToken)) .willReturn( aResponse() @@ -201,7 +201,7 @@ public class GithubPersonalAccessTokenFetcherTest { PersonalAccessToken token = new PersonalAccessToken( - "https://github.com", + wireMockServer.url("/"), "cheUser", "username", "123456789", @@ -215,7 +215,7 @@ public class GithubPersonalAccessTokenFetcherTest { @Test public void shouldValidateOauthToken() throws Exception { stubFor( - get(urlEqualTo("/user")) + get(urlEqualTo("/api/v3/user")) .withHeader(HttpHeaders.AUTHORIZATION, equalTo("token " + githubOauthToken)) .willReturn( aResponse() @@ -227,7 +227,7 @@ public class GithubPersonalAccessTokenFetcherTest { PersonalAccessToken token = new PersonalAccessToken( - "https://github.com", + wireMockServer.url("/"), "cheUser", "username", "123456789", @@ -240,11 +240,11 @@ public class GithubPersonalAccessTokenFetcherTest { @Test public void shouldNotValidateExpiredOauthToken() throws Exception { - stubFor(get(urlEqualTo("/user")).willReturn(aResponse().withStatus(HTTP_FORBIDDEN))); + stubFor(get(urlEqualTo("/api/v3/user")).willReturn(aResponse().withStatus(HTTP_FORBIDDEN))); PersonalAccessToken token = new PersonalAccessToken( - "https://github.com", + wireMockServer.url("/"), "cheUser", "username", "123456789", diff --git a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubScmFileResolverTest.java b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubScmFileResolverTest.java index b7e8017396..ff4efdab16 100644 --- a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubScmFileResolverTest.java +++ b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubScmFileResolverTest.java @@ -13,7 +13,6 @@ package org.eclipse.che.api.factory.server.github; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.testng.Assert.*; @@ -45,8 +44,7 @@ public class GithubScmFileResolverTest { @BeforeMethod protected void init() { githubURLParser = - new GithubURLParser( - personalAccessTokenManager, devfileFilenamesProvider, mock(GithubApiClient.class)); + new GithubURLParser(personalAccessTokenManager, devfileFilenamesProvider, null); assertNotNull(this.githubURLParser); githubScmFileResolver = new GithubScmFileResolver( @@ -65,7 +63,7 @@ public class GithubScmFileResolverTest { @Test public void checkValidAcceptUrl() { // should be accepted - assertTrue(githubScmFileResolver.accept("http://github.com/test/repo.git")); + assertTrue(githubScmFileResolver.accept("https://github.com/test/repo.git")); } @Test @@ -77,7 +75,8 @@ public class GithubScmFileResolverTest { when(personalAccessTokenManager.fetchAndSave(any(), anyString())) .thenReturn(personalAccessToken); - String content = githubScmFileResolver.fileContent("http://github.com/test/repo.git", filename); + String content = + githubScmFileResolver.fileContent("https://github.com/test/repo.git", filename); assertEquals(content, rawContent); }