Support Bitbucket-server oAuth2 factory (#440)
Apply Bitbucket Server oAuth-2 configuration for the factory flow.pull/443/head
parent
7bad48cfed
commit
cb3565dbf8
|
|
@ -395,7 +395,7 @@ public class WsMasterModule extends AbstractModule {
|
|||
}
|
||||
bind(TokenValidator.class).to(NotImplementedTokenValidator.class);
|
||||
bind(ProfileDao.class).to(JpaProfileDao.class);
|
||||
bind(OAuthAPI.class).to(EmbeddedOAuthAPI.class);
|
||||
bind(OAuthAPI.class).to(EmbeddedOAuthAPI.class).asEagerSingleton();
|
||||
}
|
||||
|
||||
bind(AdminPermissionInitializer.class).asEagerSingleton();
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ che.oauth1.bitbucket.consumerkeypath=NULL
|
|||
che.oauth1.bitbucket.privatekeypath=NULL
|
||||
# Bitbucket Server URL. To work correctly with factories, the same URL
|
||||
# has to be part of `che.integration.bitbucket.server_endpoints` too.
|
||||
che.oauth1.bitbucket.endpoint=NULL
|
||||
che.oauth.bitbucket.endpoint=https://bitbucket.org
|
||||
|
||||
# Configuration of Bitbucket OAuth2 client. Used to obtain Personal access tokens.
|
||||
# Location of the file with Bitbucket client id.
|
||||
|
|
@ -172,7 +172,7 @@ che.oauth.bitbucket.tokenuri= https://bitbucket.org/site/oauth2/access_token
|
|||
|
||||
# Bitbucket OAuth redirect URIs.
|
||||
# Separate multiple values with comma, for example: URI,URI,URI
|
||||
che.oauth.bitbucket.redirecturis= http://localhost:${CHE_PORT}/api/oauth/callback
|
||||
che.oauth.bitbucket.redirecturis= https://${CHE_HOST}/api/oauth/callback
|
||||
|
||||
### Internal
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@
|
|||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.oauth-client</groupId>
|
||||
<artifactId>google-oauth-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.inject</groupId>
|
||||
<artifactId>jakarta.inject-api</artifactId>
|
||||
|
|
@ -53,7 +57,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-json</artifactId>
|
||||
<artifactId>che-core-commons-lang</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
|
|
|
|||
|
|
@ -11,33 +11,42 @@
|
|||
*/
|
||||
package org.eclipse.che.security.oauth;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
|
||||
import com.google.api.client.auth.oauth2.AuthorizationCodeRequestUrl;
|
||||
import com.google.api.client.util.store.MemoryDataStoreFactory;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.commons.json.JsonHelper;
|
||||
import org.eclipse.che.commons.json.JsonParseException;
|
||||
import org.eclipse.che.security.oauth.shared.User;
|
||||
|
||||
/** OAuth authentication for BitBucket SAAS account. */
|
||||
@Singleton
|
||||
public class BitbucketOAuthAuthenticator extends OAuthAuthenticator {
|
||||
private final String bitbucketEndpoint;
|
||||
|
||||
public BitbucketOAuthAuthenticator(
|
||||
String clientId, String clientSecret, String[] redirectUris, String authUri, String tokenUri)
|
||||
String bitbucketEndpoint,
|
||||
String clientId,
|
||||
String clientSecret,
|
||||
String[] redirectUris,
|
||||
String authUri,
|
||||
String tokenUri)
|
||||
throws IOException {
|
||||
this.bitbucketEndpoint = bitbucketEndpoint;
|
||||
configure(
|
||||
clientId, clientSecret, redirectUris, authUri, tokenUri, new MemoryDataStoreFactory());
|
||||
}
|
||||
|
||||
private static final String USER_URL = "https://api.bitbucket.org/2.0/user";
|
||||
|
||||
@Override
|
||||
public User getUser(OAuthToken accessToken) throws OAuthAuthenticationException {
|
||||
BitbucketUser user = getJson(USER_URL, accessToken.getToken(), BitbucketUser.class);
|
||||
return user;
|
||||
public String getAuthenticateUrl(URL requestUrl, List<String> scopes) {
|
||||
AuthorizationCodeRequestUrl url = flow.newAuthorizationUrl().setScopes(scopes);
|
||||
url.setState(prepareState(requestUrl));
|
||||
url.set("redirect_uri", findRedirectUrl(requestUrl));
|
||||
return url.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -50,35 +59,42 @@ public class BitbucketOAuthAuthenticator extends OAuthAuthenticator {
|
|||
final OAuthToken token = super.getToken(userId);
|
||||
// Need to check if token is valid for requests, if valid - return it to caller.
|
||||
try {
|
||||
if (token == null
|
||||
|| token.getToken() == null
|
||||
|| token.getToken().isEmpty()
|
||||
|| getJson(USER_URL, token.getToken(), BitbucketUser.class) == null) {
|
||||
if (token == null || isNullOrEmpty(token.getToken())) {
|
||||
return null;
|
||||
}
|
||||
testRequest(getTestRequestUrl(), token.getToken());
|
||||
} catch (OAuthAuthenticationException e) {
|
||||
return null;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEndpointUrl() {
|
||||
return "https://bitbucket.org";
|
||||
/**
|
||||
* Generate an API request URL, to use for a token validation.
|
||||
*
|
||||
* @return Bitbucket Cloud or Server API request URL
|
||||
*/
|
||||
private String getTestRequestUrl() {
|
||||
return "https://bitbucket.org".equals(bitbucketEndpoint)
|
||||
? "https://api.bitbucket.org/2.0/user"
|
||||
: bitbucketEndpoint + "/rest/api/1.0/application-properties";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <O> O getJson(String getUserUrl, String accessToken, Class<O> userClass)
|
||||
public String getEndpointUrl() {
|
||||
return bitbucketEndpoint;
|
||||
}
|
||||
|
||||
private void testRequest(String requestUrl, String accessToken)
|
||||
throws OAuthAuthenticationException {
|
||||
HttpURLConnection urlConnection = null;
|
||||
InputStream urlInputStream = null;
|
||||
|
||||
try {
|
||||
urlConnection = (HttpURLConnection) new URL(getUserUrl).openConnection();
|
||||
urlConnection = (HttpURLConnection) new URL(requestUrl).openConnection();
|
||||
urlConnection.setRequestProperty("Authorization", "Bearer " + accessToken);
|
||||
urlInputStream = urlConnection.getInputStream();
|
||||
return JsonHelper.fromJson(urlInputStream, userClass, null);
|
||||
} catch (JsonParseException | IOException e) {
|
||||
} catch (IOException e) {
|
||||
throw new OAuthAuthenticationException(e.getMessage(), e);
|
||||
} finally {
|
||||
if (urlInputStream != null) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -21,9 +22,7 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.security.oauth.shared.User;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
@ -38,6 +37,7 @@ public class BitbucketOAuthAuthenticatorProvider implements Provider<OAuthAuthen
|
|||
|
||||
@Inject
|
||||
public BitbucketOAuthAuthenticatorProvider(
|
||||
@Named("che.oauth.bitbucket.endpoint") String oauthEndpoint,
|
||||
@Nullable @Named("che.oauth2.bitbucket.clientid_filepath") String bitbucketClientIdPath,
|
||||
@Nullable @Named("che.oauth2.bitbucket.clientsecret_filepath")
|
||||
String bitbucketClientSecretPath,
|
||||
|
|
@ -47,7 +47,12 @@ public class BitbucketOAuthAuthenticatorProvider implements Provider<OAuthAuthen
|
|||
throws IOException {
|
||||
authenticator =
|
||||
getOAuthAuthenticator(
|
||||
bitbucketClientIdPath, bitbucketClientSecretPath, redirectUris, authUri, tokenUri);
|
||||
oauthEndpoint,
|
||||
bitbucketClientIdPath,
|
||||
bitbucketClientSecretPath,
|
||||
redirectUris,
|
||||
authUri,
|
||||
tokenUri);
|
||||
LOG.debug("{} Bitbucket OAuth Authenticator is used.", authenticator);
|
||||
}
|
||||
|
||||
|
|
@ -57,11 +62,12 @@ public class BitbucketOAuthAuthenticatorProvider implements Provider<OAuthAuthen
|
|||
}
|
||||
|
||||
private OAuthAuthenticator getOAuthAuthenticator(
|
||||
String clientIdPath,
|
||||
String clientSecretPath,
|
||||
String[] redirectUris,
|
||||
String authUri,
|
||||
String tokenUri)
|
||||
String oauthEndpoint,
|
||||
@Nullable String clientIdPath,
|
||||
@Nullable String clientSecretPath,
|
||||
@Nullable String[] redirectUris,
|
||||
@Nullable String authUri,
|
||||
@Nullable String tokenUri)
|
||||
throws IOException {
|
||||
|
||||
if (!isNullOrEmpty(clientIdPath)
|
||||
|
|
@ -70,23 +76,21 @@ public class BitbucketOAuthAuthenticatorProvider implements Provider<OAuthAuthen
|
|||
&& !isNullOrEmpty(tokenUri)
|
||||
&& Objects.nonNull(redirectUris)
|
||||
&& redirectUris.length != 0) {
|
||||
String trimmedOauthEndpoint = trimEnd(oauthEndpoint, '/');
|
||||
boolean isBitbucketCloud = trimmedOauthEndpoint.equals("https://bitbucket.org");
|
||||
authUri = isBitbucketCloud ? authUri : trimmedOauthEndpoint + "/rest/oauth2/1.0/authorize";
|
||||
tokenUri = isBitbucketCloud ? tokenUri : trimmedOauthEndpoint + "/rest/oauth2/1.0/token";
|
||||
final String clientId = Files.readString(Path.of(clientIdPath)).trim();
|
||||
final String clientSecret = Files.readString(Path.of(clientSecretPath)).trim();
|
||||
if (!isNullOrEmpty(clientId) && !isNullOrEmpty(clientSecret)) {
|
||||
return new BitbucketOAuthAuthenticator(
|
||||
clientId, clientSecret, redirectUris, authUri, tokenUri);
|
||||
trimmedOauthEndpoint, clientId, clientSecret, redirectUris, authUri, tokenUri);
|
||||
}
|
||||
}
|
||||
return new NoopOAuthAuthenticator();
|
||||
}
|
||||
|
||||
static class NoopOAuthAuthenticator extends OAuthAuthenticator {
|
||||
@Override
|
||||
public User getUser(OAuthToken accessToken) throws OAuthAuthenticationException {
|
||||
throw new OAuthAuthenticationException(
|
||||
"The fallback noop authenticator cannot be used for Bitbucket authentication. Make sure OAuth is properly configured.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOAuthProvider() {
|
||||
return "Noop";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2023 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/
|
||||
|
|
@ -35,7 +35,7 @@ public class BitbucketServerOAuthAuthenticatorProvider implements Provider<OAuth
|
|||
public BitbucketServerOAuthAuthenticatorProvider(
|
||||
@Nullable @Named("che.oauth1.bitbucket.consumerkeypath") String consumerKeyPath,
|
||||
@Nullable @Named("che.oauth1.bitbucket.privatekeypath") String privateKeyPath,
|
||||
@Nullable @Named("che.oauth1.bitbucket.endpoint") String bitbucketEndpoint,
|
||||
@Nullable @Named("che.oauth.bitbucket.endpoint") String bitbucketEndpoint,
|
||||
@Named("che.api") String apiEndpoint)
|
||||
throws IOException {
|
||||
authenticator =
|
||||
|
|
|
|||
|
|
@ -35,10 +35,6 @@
|
|||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.mail</groupId>
|
||||
<artifactId>jakarta.mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.inject</groupId>
|
||||
<artifactId>jakarta.inject-api</artifactId>
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ 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;
|
||||
import jakarta.mail.internet.InternetAddress;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
|
|
@ -24,7 +22,6 @@ import java.net.URL;
|
|||
import java.util.Base64;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.security.oauth.shared.User;
|
||||
|
||||
/** OAuth authentication for github account. */
|
||||
@Singleton
|
||||
|
|
@ -53,24 +50,6 @@ public class GitHubOAuthAuthenticator extends OAuthAuthenticator {
|
|||
clientId, clientSecret, redirectUris, authUri, tokenUri, new MemoryDataStoreFactory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser(OAuthToken accessToken) throws OAuthAuthenticationException {
|
||||
GitHubUser user = getJson(githubApiUrl + "/user", accessToken.getToken(), GitHubUser.class);
|
||||
final String email = user.getEmail();
|
||||
|
||||
if (isNullOrEmpty(email)) {
|
||||
throw new OAuthAuthenticationException(
|
||||
"Sorry, we failed to find any verified emails associated with your GitHub account."
|
||||
+ " Please, verify at least one email in your GitHub account and try to connect with GitHub again.");
|
||||
}
|
||||
try {
|
||||
new InternetAddress(email).validate();
|
||||
} catch (AddressException e) {
|
||||
throw new OAuthAuthenticationException(e.getMessage());
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getOAuthProvider() {
|
||||
return "github";
|
||||
|
|
|
|||
|
|
@ -22,9 +22,7 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.security.oauth.shared.User;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
@ -98,12 +96,6 @@ public class GitHubOAuthAuthenticatorProvider implements Provider<OAuthAuthentic
|
|||
}
|
||||
|
||||
static class NoopOAuthAuthenticator extends OAuthAuthenticator {
|
||||
@Override
|
||||
public User getUser(OAuthToken accessToken) throws OAuthAuthenticationException {
|
||||
throw new OAuthAuthenticationException(
|
||||
"The fallback noop authenticator cannot be used for GitHub authentication. Make sure OAuth is properly configured.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOAuthProvider() {
|
||||
return "Noop";
|
||||
|
|
|
|||
|
|
@ -35,10 +35,6 @@
|
|||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.mail</groupId>
|
||||
<artifactId>jakarta.mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.inject</groupId>
|
||||
<artifactId>jakarta.inject-api</artifactId>
|
||||
|
|
|
|||
|
|
@ -11,12 +11,9 @@
|
|||
*/
|
||||
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;
|
||||
import jakarta.mail.internet.InternetAddress;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
|
|
@ -28,7 +25,6 @@ import javax.inject.Singleton;
|
|||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.commons.json.JsonHelper;
|
||||
import org.eclipse.che.commons.json.JsonParseException;
|
||||
import org.eclipse.che.security.oauth.shared.User;
|
||||
|
||||
/**
|
||||
* OAuth2 authenticator for GitLab account.
|
||||
|
|
@ -57,24 +53,6 @@ public class GitLabOAuthAuthenticator extends OAuthAuthenticator {
|
|||
new MemoryDataStoreFactory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser(OAuthToken accessToken) throws OAuthAuthenticationException {
|
||||
GitLabUser user = getJson(gitlabUserEndpoint, accessToken.getToken(), GitLabUser.class);
|
||||
final String email = user.getEmail();
|
||||
|
||||
if (isNullOrEmpty(email)) {
|
||||
throw new OAuthAuthenticationException(
|
||||
"Sorry, we failed to find any verified email associated with your GitLab account."
|
||||
+ " Please, verify at least one email in your account and try to connect with GitLab again.");
|
||||
}
|
||||
try {
|
||||
new InternetAddress(email).validate();
|
||||
} catch (AddressException e) {
|
||||
throw new OAuthAuthenticationException(e.getMessage());
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOAuthProvider() {
|
||||
return "gitlab";
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.security.oauth.shared.User;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
@ -69,11 +67,6 @@ public class GitLabOAuthAuthenticatorProvider implements Provider<OAuthAuthentic
|
|||
}
|
||||
|
||||
static class NoopOAuthAuthenticator extends OAuthAuthenticator {
|
||||
@Override
|
||||
public User getUser(OAuthToken accessToken) throws OAuthAuthenticationException {
|
||||
throw new OAuthAuthenticationException(
|
||||
"The fallback noop authenticator cannot be used for GitLab authentication. Make sure OAuth is properly configured.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOAuthProvider() {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import javax.inject.Named;
|
|||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.security.oauth.shared.User;
|
||||
|
||||
/**
|
||||
* OAuth authentication for OpenShift.
|
||||
|
|
@ -58,11 +57,6 @@ public class OpenShiftOAuthAuthenticator extends OAuthAuthenticator {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser(OAuthToken accessToken) throws OAuthAuthenticationException {
|
||||
throw new OAuthAuthenticationException("not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getOAuthProvider() {
|
||||
return "openshift";
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
package org.eclipse.che.security.oauth;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.eclipse.che.commons.lang.UrlUtils.*;
|
||||
import static org.eclipse.che.commons.lang.UrlUtils.getParameter;
|
||||
|
|
@ -28,6 +29,7 @@ import java.net.URL;
|
|||
import java.util.*;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
|
|
@ -52,6 +54,7 @@ import org.slf4j.LoggerFactory;
|
|||
*
|
||||
* @author Mykhailo Kuznietsov
|
||||
*/
|
||||
@Singleton
|
||||
public class EmbeddedOAuthAPI implements OAuthAPI {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(EmbeddedOAuthAPI.class);
|
||||
|
||||
|
|
@ -61,6 +64,7 @@ public class EmbeddedOAuthAPI implements OAuthAPI {
|
|||
|
||||
@Inject protected OAuthAuthenticatorProvider providers;
|
||||
@Inject protected PersonalAccessTokenManager personalAccessTokenManager;
|
||||
private String redirectAfterLogin;
|
||||
|
||||
@Override
|
||||
public Response authenticate(
|
||||
|
|
@ -70,6 +74,7 @@ public class EmbeddedOAuthAPI implements OAuthAPI {
|
|||
String redirectAfterLogin,
|
||||
HttpServletRequest request)
|
||||
throws NotFoundException, OAuthAuthenticationException {
|
||||
this.redirectAfterLogin = redirectAfterLogin;
|
||||
OAuthAuthenticator oauth = getAuthenticator(oauthProvider);
|
||||
final String authUrl =
|
||||
oauth.getAuthenticateUrl(getRequestUrl(uriInfo), scopes == null ? emptyList() : scopes);
|
||||
|
|
@ -80,9 +85,12 @@ public class EmbeddedOAuthAPI implements OAuthAPI {
|
|||
public Response callback(UriInfo uriInfo, List<String> errorValues) throws NotFoundException {
|
||||
URL requestUrl = getRequestUrl(uriInfo);
|
||||
Map<String, List<String>> params = getQueryParametersFromState(getState(requestUrl));
|
||||
if (errorValues != null && errorValues.contains("access_denied")) {
|
||||
errorValues = errorValues == null ? uriInfo.getQueryParameters().get("error") : errorValues;
|
||||
if (!isNullOrEmpty(redirectAfterLogin)
|
||||
&& errorValues != null
|
||||
&& errorValues.contains("access_denied")) {
|
||||
return Response.temporaryRedirect(
|
||||
uriInfo.getRequestUriBuilder().replacePath(errorPage).replaceQuery(null).build())
|
||||
URI.create(redirectAfterLogin + "&error_code=access_denied"))
|
||||
.build();
|
||||
}
|
||||
final String providerName = getParameter(params, "oauth_provider");
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ import org.eclipse.che.commons.env.EnvironmentContext;
|
|||
import org.eclipse.che.commons.json.JsonHelper;
|
||||
import org.eclipse.che.commons.json.JsonParseException;
|
||||
import org.eclipse.che.security.oauth.shared.OAuthTokenProvider;
|
||||
import org.eclipse.che.security.oauth.shared.User;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
@ -223,15 +222,6 @@ public abstract class OAuthAuthenticator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user info.
|
||||
*
|
||||
* @param accessToken oauth access token
|
||||
* @return user info
|
||||
* @throws OAuthAuthenticationException if fail to get user info
|
||||
*/
|
||||
public abstract User getUser(OAuthToken accessToken) throws OAuthAuthenticationException;
|
||||
|
||||
/**
|
||||
* Get the name of OAuth provider supported by current implementation.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-auth-bitbucket</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-auth-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-core</artifactId>
|
||||
|
|
@ -120,6 +124,11 @@
|
|||
<artifactId>wiremock-jre8-standalone</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-json</artifactId>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2023 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/
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.security.oauth1;
|
||||
package org.eclipse.che.api.factory.server.bitbucket;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
|
||||
|
|
@ -23,11 +23,13 @@ import javax.inject.Named;
|
|||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketServerApiClient;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.HttpBitbucketServerApiClient;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.NoopBitbucketServerApiClient;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.commons.lang.StringUtils;
|
||||
import org.eclipse.che.inject.ConfigurationException;
|
||||
import org.eclipse.che.security.oauth.OAuthAPI;
|
||||
import org.eclipse.che.security.oauth1.NoopOAuthAuthenticator;
|
||||
import org.eclipse.che.security.oauth1.OAuthAuthenticator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
@ -37,13 +39,19 @@ public class BitbucketServerApiProvider implements Provider<BitbucketServerApiCl
|
|||
private static final Logger LOG = LoggerFactory.getLogger(BitbucketServerApiProvider.class);
|
||||
|
||||
private final BitbucketServerApiClient bitbucketServerApiClient;
|
||||
private final String apiEndpoint;
|
||||
private final OAuthAPI oAuthAPI;
|
||||
|
||||
@Inject
|
||||
public BitbucketServerApiProvider(
|
||||
@Nullable @Named("che.integration.bitbucket.server_endpoints") String bitbucketEndpoints,
|
||||
@Nullable @Named("che.oauth1.bitbucket.endpoint") String bitbucketOauth1Endpoint,
|
||||
@Named("che.oauth.bitbucket.endpoint") String bitbucketOauthEndpoint,
|
||||
@Named("che.api") String apiEndpoint,
|
||||
OAuthAPI oAuthAPI,
|
||||
Set<OAuthAuthenticator> authenticators) {
|
||||
bitbucketServerApiClient = doGet(bitbucketEndpoints, bitbucketOauth1Endpoint, authenticators);
|
||||
this.apiEndpoint = apiEndpoint;
|
||||
this.oAuthAPI = oAuthAPI;
|
||||
bitbucketServerApiClient = doGet(bitbucketEndpoints, bitbucketOauthEndpoint, authenticators);
|
||||
LOG.debug("Bitbucket server api is used {}", bitbucketServerApiClient);
|
||||
}
|
||||
|
||||
|
|
@ -52,40 +60,38 @@ public class BitbucketServerApiProvider implements Provider<BitbucketServerApiCl
|
|||
return bitbucketServerApiClient;
|
||||
}
|
||||
|
||||
private static BitbucketServerApiClient doGet(
|
||||
private BitbucketServerApiClient doGet(
|
||||
String rawBitbucketEndpoints,
|
||||
String bitbucketOauth1Endpoint,
|
||||
String bitbucketOauthEndpoint,
|
||||
Set<OAuthAuthenticator> authenticators) {
|
||||
if (isNullOrEmpty(bitbucketOauth1Endpoint) && isNullOrEmpty(rawBitbucketEndpoints)) {
|
||||
boolean isBitbucketCloud = bitbucketOauthEndpoint.equals("https://bitbucket.org");
|
||||
if (isBitbucketCloud && isNullOrEmpty(rawBitbucketEndpoints)) {
|
||||
return new NoopBitbucketServerApiClient();
|
||||
} else if (!isNullOrEmpty(bitbucketOauth1Endpoint) && isNullOrEmpty(rawBitbucketEndpoints)) {
|
||||
} else if (!isBitbucketCloud && isNullOrEmpty(rawBitbucketEndpoints)) {
|
||||
throw new ConfigurationException(
|
||||
"`che.integration.bitbucket.server_endpoints` bitbucket configuration is missing."
|
||||
+ " It should contain values from 'che.oauth1.bitbucket.endpoint'");
|
||||
} else if (isNullOrEmpty(bitbucketOauth1Endpoint) && !isNullOrEmpty(rawBitbucketEndpoints)) {
|
||||
+ " It should contain values from 'che.oauth.bitbucket.endpoint'");
|
||||
} else if (isBitbucketCloud && !isNullOrEmpty(rawBitbucketEndpoints)) {
|
||||
return new HttpBitbucketServerApiClient(
|
||||
sanitizedEndpoints(rawBitbucketEndpoints).get(0), new NoopOAuthAuthenticator());
|
||||
sanitizedEndpoints(rawBitbucketEndpoints).get(0),
|
||||
new NoopOAuthAuthenticator(),
|
||||
oAuthAPI,
|
||||
apiEndpoint);
|
||||
} else {
|
||||
bitbucketOauth1Endpoint = StringUtils.trimEnd(bitbucketOauth1Endpoint, '/');
|
||||
if (!sanitizedEndpoints(rawBitbucketEndpoints).contains(bitbucketOauth1Endpoint)) {
|
||||
bitbucketOauthEndpoint = StringUtils.trimEnd(bitbucketOauthEndpoint, '/');
|
||||
if (!sanitizedEndpoints(rawBitbucketEndpoints).contains(bitbucketOauthEndpoint)) {
|
||||
throw new ConfigurationException(
|
||||
"`che.integration.bitbucket.server_endpoints` must contain `"
|
||||
+ bitbucketOauth1Endpoint
|
||||
+ bitbucketOauthEndpoint
|
||||
+ "` value");
|
||||
} else {
|
||||
Optional<OAuthAuthenticator> authenticator =
|
||||
authenticators.stream()
|
||||
.filter(
|
||||
a ->
|
||||
a.getOAuthProvider()
|
||||
.equals(BitbucketServerOAuthAuthenticator.AUTHENTICATOR_NAME))
|
||||
.filter(a -> BitbucketServerOAuthAuthenticator.class.isAssignableFrom(a.getClass()))
|
||||
.findFirst();
|
||||
Optional<OAuthAuthenticator> authenticator = authenticators.stream().findFirst();
|
||||
if (authenticator.isEmpty()) {
|
||||
throw new ConfigurationException(
|
||||
"'che.oauth1.bitbucket.endpoint' is set but BitbucketServerOAuthAuthenticator is not deployed correctly");
|
||||
"'che.oauth.bitbucket.endpoint' is set but BitbucketServerOAuthAuthenticator is not deployed correctly");
|
||||
}
|
||||
return new HttpBitbucketServerApiClient(bitbucketOauth1Endpoint, authenticator.get());
|
||||
return new HttpBitbucketServerApiClient(
|
||||
bitbucketOauthEndpoint, authenticator.get(), oAuthAPI, apiEndpoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,6 @@ import com.google.inject.multibindings.Multibinder;
|
|||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketServerApiClient;
|
||||
import org.eclipse.che.api.factory.server.scm.GitUserDataFetcher;
|
||||
import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenFetcher;
|
||||
import org.eclipse.che.security.oauth1.BitbucketServerApiProvider;
|
||||
|
||||
public class BitbucketServerModule extends AbstractModule {
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import javax.inject.Named;
|
|||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketPersonalAccessToken;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketServerApiClient;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketUser;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.HttpBitbucketServerApiClient;
|
||||
import org.eclipse.che.api.factory.server.scm.PersonalAccessToken;
|
||||
import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenFetcher;
|
||||
import org.eclipse.che.api.factory.server.scm.exception.ScmBadRequestException;
|
||||
|
|
@ -34,6 +33,7 @@ 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.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.security.oauth.OAuthAPI;
|
||||
import org.eclipse.che.security.oauth1.NoopOAuthAuthenticator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
@ -53,12 +53,16 @@ public class BitbucketServerPersonalAccessTokenFetcher implements PersonalAccess
|
|||
ImmutableSet.of("PROJECT_WRITE", "REPO_WRITE");
|
||||
private final BitbucketServerApiClient bitbucketServerApiClient;
|
||||
private final URL apiEndpoint;
|
||||
private final OAuthAPI oAuthAPI;
|
||||
|
||||
@Inject
|
||||
public BitbucketServerPersonalAccessTokenFetcher(
|
||||
BitbucketServerApiClient bitbucketServerApiClient, @Named("che.api") URL apiEndpoint) {
|
||||
BitbucketServerApiClient bitbucketServerApiClient,
|
||||
@Named("che.api") URL apiEndpoint,
|
||||
OAuthAPI oAuthAPI) {
|
||||
this.bitbucketServerApiClient = bitbucketServerApiClient;
|
||||
this.apiEndpoint = apiEndpoint;
|
||||
this.oAuthAPI = oAuthAPI;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -109,7 +113,10 @@ public class BitbucketServerPersonalAccessTokenFetcher implements PersonalAccess
|
|||
// If BitBucket oAuth is not configured check the manually added user namespace token.
|
||||
HttpBitbucketServerApiClient apiClient =
|
||||
new HttpBitbucketServerApiClient(
|
||||
personalAccessToken.getScmProviderUrl(), new NoopOAuthAuthenticator());
|
||||
personalAccessToken.getScmProviderUrl(),
|
||||
new NoopOAuthAuthenticator(),
|
||||
oAuthAPI,
|
||||
apiEndpoint.toString());
|
||||
try {
|
||||
apiClient.getUser(personalAccessToken.getScmUserName(), personalAccessToken.getToken());
|
||||
return Optional.of(Boolean.TRUE);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import java.util.regex.Pattern;
|
|||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.HttpBitbucketServerApiClient;
|
||||
import org.eclipse.che.api.factory.server.scm.PersonalAccessToken;
|
||||
import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager;
|
||||
import org.eclipse.che.api.factory.server.scm.exception.ScmCommunicationException;
|
||||
|
|
@ -35,6 +34,7 @@ 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.lang.StringUtils;
|
||||
import org.eclipse.che.security.oauth.OAuthAPI;
|
||||
import org.eclipse.che.security.oauth1.BitbucketServerOAuthAuthenticator;
|
||||
|
||||
/**
|
||||
|
|
@ -46,6 +46,7 @@ import org.eclipse.che.security.oauth1.BitbucketServerOAuthAuthenticator;
|
|||
public class BitbucketServerURLParser {
|
||||
|
||||
private final DevfileFilenamesProvider devfileFilenamesProvider;
|
||||
private final OAuthAPI oAuthAPI;
|
||||
private final PersonalAccessTokenManager personalAccessTokenManager;
|
||||
private static final List<String> bitbucketUrlPatternTemplates =
|
||||
List.of(
|
||||
|
|
@ -60,8 +61,10 @@ public class BitbucketServerURLParser {
|
|||
public BitbucketServerURLParser(
|
||||
@Nullable @Named("che.integration.bitbucket.server_endpoints") String bitbucketEndpoints,
|
||||
DevfileFilenamesProvider devfileFilenamesProvider,
|
||||
OAuthAPI oAuthAPI,
|
||||
PersonalAccessTokenManager personalAccessTokenManager) {
|
||||
this.devfileFilenamesProvider = devfileFilenamesProvider;
|
||||
this.oAuthAPI = oAuthAPI;
|
||||
this.personalAccessTokenManager = personalAccessTokenManager;
|
||||
if (bitbucketEndpoints != null) {
|
||||
for (String bitbucketEndpoint : Splitter.on(",").split(bitbucketEndpoints)) {
|
||||
|
|
@ -106,7 +109,10 @@ public class BitbucketServerURLParser {
|
|||
try {
|
||||
HttpBitbucketServerApiClient bitbucketServerApiClient =
|
||||
new HttpBitbucketServerApiClient(
|
||||
getServerUrl(repositoryUrl), new BitbucketServerOAuthAuthenticator("", "", "", ""));
|
||||
getServerUrl(repositoryUrl),
|
||||
new BitbucketServerOAuthAuthenticator("", "", "", ""),
|
||||
oAuthAPI,
|
||||
"");
|
||||
// If the token request catches the unauthorised error, it means that the provided url
|
||||
// belongs to Bitbucket.
|
||||
bitbucketServerApiClient.getPersonalAccessToken("", 0L);
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.factory.server.bitbucket.server;
|
||||
package org.eclipse.che.api.factory.server.bitbucket;
|
||||
|
||||
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_UNAUTHORIZED;
|
||||
|
|
@ -21,7 +22,6 @@ import com.fasterxml.jackson.databind.JavaType;
|
|||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
|
|
@ -42,6 +42,17 @@ import java.util.Set;
|
|||
import java.util.concurrent.Executors;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.UnauthorizedException;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketPersonalAccessToken;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketServerApiClient;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketUser;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.Page;
|
||||
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;
|
||||
|
|
@ -50,6 +61,8 @@ import org.eclipse.che.commons.annotation.Nullable;
|
|||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.security.oauth.OAuthAPI;
|
||||
import org.eclipse.che.security.oauth1.NoopOAuthAuthenticator;
|
||||
import org.eclipse.che.security.oauth1.OAuthAuthenticationException;
|
||||
import org.eclipse.che.security.oauth1.OAuthAuthenticator;
|
||||
import org.slf4j.Logger;
|
||||
|
|
@ -67,11 +80,16 @@ public class HttpBitbucketServerApiClient implements BitbucketServerApiClient {
|
|||
private static final Duration DEFAULT_HTTP_TIMEOUT = ofSeconds(10);
|
||||
private final URI serverUri;
|
||||
private final OAuthAuthenticator authenticator;
|
||||
private final OAuthAPI oAuthAPI;
|
||||
private final String apiEndpoint;
|
||||
private final HttpClient httpClient;
|
||||
|
||||
public HttpBitbucketServerApiClient(String serverUrl, OAuthAuthenticator authenticator) {
|
||||
public HttpBitbucketServerApiClient(
|
||||
String serverUrl, OAuthAuthenticator authenticator, OAuthAPI oAuthAPI, String apiEndpoint) {
|
||||
this.serverUri = URI.create(serverUrl.endsWith("/") ? serverUrl : serverUrl + "/");
|
||||
this.authenticator = authenticator;
|
||||
this.oAuthAPI = oAuthAPI;
|
||||
this.apiEndpoint = apiEndpoint;
|
||||
this.httpClient =
|
||||
HttpClient.newBuilder()
|
||||
.executor(
|
||||
|
|
@ -219,6 +237,8 @@ public class HttpBitbucketServerApiClient implements BitbucketServerApiClient {
|
|||
public BitbucketPersonalAccessToken createPersonalAccessTokens(
|
||||
String userSlug, String tokenName, Set<String> permissions)
|
||||
throws ScmBadRequestException, ScmUnauthorizedException, ScmCommunicationException {
|
||||
BitbucketPersonalAccessToken token =
|
||||
new BitbucketPersonalAccessToken(tokenName, permissions, 90);
|
||||
URI uri = serverUri.resolve("./rest/access-tokens/1.0/users/" + userSlug);
|
||||
|
||||
try {
|
||||
|
|
@ -228,7 +248,7 @@ public class HttpBitbucketServerApiClient implements BitbucketServerApiClient {
|
|||
HttpRequest.BodyPublishers.ofString(
|
||||
OM.writeValueAsString(
|
||||
// set maximum allowed expiryDays to 90
|
||||
new BitbucketPersonalAccessToken(tokenName, permissions, 90))))
|
||||
token)))
|
||||
.headers(
|
||||
HttpHeaders.AUTHORIZATION,
|
||||
computeAuthorizationHeader("PUT", uri.toString()),
|
||||
|
|
@ -343,7 +363,7 @@ public class HttpBitbucketServerApiClient implements BitbucketServerApiClient {
|
|||
throws ScmUnauthorizedException, ScmBadRequestException, ScmCommunicationException,
|
||||
ScmItemNotFoundException {
|
||||
String suffix = api + "?start=" + start + "&limit=" + limit;
|
||||
if (!Strings.isNullOrEmpty(filter)) {
|
||||
if (!isNullOrEmpty(filter)) {
|
||||
suffix += "&filter=" + filter;
|
||||
}
|
||||
|
||||
|
|
@ -399,8 +419,30 @@ public class HttpBitbucketServerApiClient implements BitbucketServerApiClient {
|
|||
}
|
||||
}
|
||||
|
||||
private @Nullable String getToken() throws ScmUnauthorizedException {
|
||||
try {
|
||||
OAuthToken token = oAuthAPI.getToken("bitbucket");
|
||||
return token.getToken();
|
||||
} catch (NotFoundException
|
||||
| ServerException
|
||||
| ForbiddenException
|
||||
| BadRequestException
|
||||
| ConflictException e) {
|
||||
LOG.error(e.getMessage());
|
||||
return null;
|
||||
} catch (UnauthorizedException e) {
|
||||
throw buildScmUnauthorizedException();
|
||||
}
|
||||
}
|
||||
|
||||
private String computeAuthorizationHeader(String requestMethod, String requestUrl)
|
||||
throws ScmCommunicationException {
|
||||
throws ScmUnauthorizedException, ScmCommunicationException {
|
||||
if (authenticator instanceof NoopOAuthAuthenticator) {
|
||||
String token = getToken();
|
||||
if (!isNullOrEmpty(token)) {
|
||||
return "Bearer " + token;
|
||||
}
|
||||
}
|
||||
try {
|
||||
Subject subject = EnvironmentContext.getCurrent().getSubject();
|
||||
return authenticator.computeAuthorizationHeader(
|
||||
|
|
@ -413,11 +455,11 @@ public class HttpBitbucketServerApiClient implements BitbucketServerApiClient {
|
|||
private ScmUnauthorizedException buildScmUnauthorizedException() {
|
||||
return new ScmUnauthorizedException(
|
||||
EnvironmentContext.getCurrent().getSubject().getUserName()
|
||||
+ " is not authorized in "
|
||||
+ authenticator.getOAuthProvider()
|
||||
+ " OAuth1 provider",
|
||||
authenticator.getOAuthProvider(),
|
||||
"1.0",
|
||||
authenticator.getLocalAuthenticateUrl());
|
||||
+ " is not authorized in bitbucket OAuth provider",
|
||||
"bitbucket",
|
||||
authenticator instanceof NoopOAuthAuthenticator ? "2.0" : "1.0",
|
||||
authenticator instanceof NoopOAuthAuthenticator
|
||||
? apiEndpoint + "/oauth/authenticate?oauth_provider=bitbucket&scope=ADMIN_WRITE"
|
||||
: authenticator.getLocalAuthenticateUrl());
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.security.oauth1;
|
||||
package org.eclipse.che.api.factory.server.bitbucket;
|
||||
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
|
@ -19,16 +19,20 @@ import java.io.IOException;
|
|||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketServerApiClient;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.HttpBitbucketServerApiClient;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.NoopBitbucketServerApiClient;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.inject.ConfigurationException;
|
||||
import org.eclipse.che.security.oauth.OAuthAPI;
|
||||
import org.eclipse.che.security.oauth1.BitbucketServerOAuthAuthenticator;
|
||||
import org.eclipse.che.security.oauth1.OAuthAuthenticator;
|
||||
import org.mockito.Mock;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class BitbucketServerApiClientProviderTest {
|
||||
BitbucketServerOAuthAuthenticator oAuthAuthenticator;
|
||||
@Mock OAuthAPI oAuthAPI;
|
||||
|
||||
@BeforeClass
|
||||
public void setUp() {
|
||||
|
|
@ -44,6 +48,8 @@ public class BitbucketServerApiClientProviderTest {
|
|||
new BitbucketServerApiProvider(
|
||||
"https://bitbucket.server.com, https://bitbucket2.server.com",
|
||||
"https://bitbucket.server.com",
|
||||
"https://bitbucket.server.com",
|
||||
oAuthAPI,
|
||||
ImmutableSet.of(oAuthAuthenticator));
|
||||
// when
|
||||
BitbucketServerApiClient actual = bitbucketServerApiProvider.get();
|
||||
|
|
@ -59,6 +65,8 @@ public class BitbucketServerApiClientProviderTest {
|
|||
new BitbucketServerApiProvider(
|
||||
"https://bitbucket.server.com, https://bitbucket2.server.com",
|
||||
"https://bitbucket.server.com",
|
||||
"https://bitbucket.server.com",
|
||||
oAuthAPI,
|
||||
ImmutableSet.of(oAuthAuthenticator));
|
||||
// when
|
||||
BitbucketServerApiClient actual = bitbucketServerApiProvider.get();
|
||||
|
|
@ -70,13 +78,12 @@ public class BitbucketServerApiClientProviderTest {
|
|||
|
||||
@Test(dataProvider = "noopConfig")
|
||||
public void shouldProvideNoopOAuthAuthenticatorIfSomeConfigurationIsNotSet(
|
||||
@Nullable String bitbucketEndpoints,
|
||||
@Nullable String bitbucketOauth1Endpoint,
|
||||
Set<OAuthAuthenticator> authenticators)
|
||||
@Nullable String bitbucketEndpoints, Set<OAuthAuthenticator> authenticators)
|
||||
throws IOException {
|
||||
// given
|
||||
BitbucketServerApiProvider bitbucketServerApiProvider =
|
||||
new BitbucketServerApiProvider(bitbucketEndpoints, bitbucketOauth1Endpoint, authenticators);
|
||||
new BitbucketServerApiProvider(
|
||||
bitbucketEndpoints, "https://bitbucket.org", "", oAuthAPI, authenticators);
|
||||
// when
|
||||
BitbucketServerApiClient actual = bitbucketServerApiProvider.get();
|
||||
// then
|
||||
|
|
@ -86,13 +93,12 @@ public class BitbucketServerApiClientProviderTest {
|
|||
|
||||
@Test(dataProvider = "httpOnlyConfig")
|
||||
public void shouldProvideHttpAuthenticatorIfOauthConfigurationIsNotSet(
|
||||
@Nullable String bitbucketEndpoints,
|
||||
@Nullable String bitbucketOauth1Endpoint,
|
||||
Set<OAuthAuthenticator> authenticators)
|
||||
@Nullable String bitbucketEndpoints, Set<OAuthAuthenticator> authenticators)
|
||||
throws IOException {
|
||||
// given
|
||||
BitbucketServerApiProvider bitbucketServerApiProvider =
|
||||
new BitbucketServerApiProvider(bitbucketEndpoints, bitbucketOauth1Endpoint, authenticators);
|
||||
new BitbucketServerApiProvider(
|
||||
bitbucketEndpoints, "https://bitbucket.org", "", oAuthAPI, authenticators);
|
||||
// when
|
||||
BitbucketServerApiClient actual = bitbucketServerApiProvider.get();
|
||||
// then
|
||||
|
|
@ -103,19 +109,23 @@ public class BitbucketServerApiClientProviderTest {
|
|||
@Test(
|
||||
expectedExceptions = ConfigurationException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"`che.integration.bitbucket.server_endpoints` bitbucket configuration is missing. It should contain values from 'che.oauth1.bitbucket.endpoint'")
|
||||
"`che.integration.bitbucket.server_endpoints` bitbucket configuration is missing. It should contain values from 'che.oauth.bitbucket.endpoint'")
|
||||
public void shouldFailToBuildIfEndpointsAreMisconfigured() {
|
||||
// given
|
||||
// when
|
||||
BitbucketServerApiProvider bitbucketServerApiProvider =
|
||||
new BitbucketServerApiProvider(
|
||||
"", "https://bitbucket.server.com", ImmutableSet.of(oAuthAuthenticator));
|
||||
"",
|
||||
"https://bitbucket.server.com",
|
||||
"https://bitbucket.server.com",
|
||||
oAuthAPI,
|
||||
ImmutableSet.of(oAuthAuthenticator));
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = ConfigurationException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"'che.oauth1.bitbucket.endpoint' is set but BitbucketServerOAuthAuthenticator is not deployed correctly")
|
||||
"'che.oauth.bitbucket.endpoint' is set but BitbucketServerOAuthAuthenticator is not deployed correctly")
|
||||
public void shouldFailToBuildIfEndpointsAreMisconfigured2() {
|
||||
// given
|
||||
// when
|
||||
|
|
@ -123,6 +133,8 @@ public class BitbucketServerApiClientProviderTest {
|
|||
new BitbucketServerApiProvider(
|
||||
"https://bitbucket.server.com, https://bitbucket2.server.com",
|
||||
"https://bitbucket.server.com",
|
||||
"https://bitbucket.server.com",
|
||||
oAuthAPI,
|
||||
Collections.emptySet());
|
||||
}
|
||||
|
||||
|
|
@ -137,25 +149,26 @@ public class BitbucketServerApiClientProviderTest {
|
|||
new BitbucketServerApiProvider(
|
||||
"https://bitbucket3.server.com, https://bitbucket2.server.com",
|
||||
"https://bitbucket.server.com",
|
||||
"https://bitbucket.server.com",
|
||||
oAuthAPI,
|
||||
ImmutableSet.of(oAuthAuthenticator));
|
||||
}
|
||||
|
||||
@DataProvider(name = "noopConfig")
|
||||
public Object[][] noopConfig() {
|
||||
return new Object[][] {
|
||||
{null, null, null},
|
||||
{"", "", null}
|
||||
{null, null},
|
||||
{"", null}
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider(name = "httpOnlyConfig")
|
||||
public Object[][] httpOnlyConfig() {
|
||||
return new Object[][] {
|
||||
{"https://bitbucket.server.com", null, null},
|
||||
{"https://bitbucket.server.com, https://bitbucket2.server.com", null, null},
|
||||
{"https://bitbucket.server.com", null},
|
||||
{"https://bitbucket.server.com, https://bitbucket2.server.com", null},
|
||||
{
|
||||
"https://bitbucket.server.com, https://bitbucket2.server.com",
|
||||
null,
|
||||
ImmutableSet.of(oAuthAuthenticator)
|
||||
}
|
||||
};
|
||||
|
|
@ -45,6 +45,7 @@ import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
|
|||
import org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.MetadataDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.SourceDto;
|
||||
import org.eclipse.che.security.oauth.OAuthAPI;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
|
|
@ -54,6 +55,7 @@ import org.testng.annotations.Test;
|
|||
@Listeners(MockitoTestNGListener.class)
|
||||
public class BitbucketServerAuthorizingFactoryParametersResolverTest {
|
||||
|
||||
@Mock private OAuthAPI oAuthAPI;
|
||||
@Mock private URLFactoryBuilder urlFactoryBuilder;
|
||||
|
||||
@Mock private URLFetcher urlFetcher;
|
||||
|
|
@ -72,6 +74,7 @@ public class BitbucketServerAuthorizingFactoryParametersResolverTest {
|
|||
new BitbucketServerURLParser(
|
||||
"http://bitbucket.2mcl.com",
|
||||
devfileFilenamesProvider,
|
||||
oAuthAPI,
|
||||
mock(PersonalAccessTokenManager.class));
|
||||
assertNotNull(this.bitbucketURLParser);
|
||||
bitbucketServerFactoryParametersResolver =
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ package org.eclipse.che.api.factory.server.bitbucket;
|
|||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
|
|
@ -26,6 +27,13 @@ import java.net.MalformedURLException;
|
|||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.UnauthorizedException;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketPersonalAccessToken;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketServerApiClient;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketUser;
|
||||
|
|
@ -37,6 +45,7 @@ import org.eclipse.che.api.factory.server.scm.exception.ScmUnauthorizedException
|
|||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
import org.eclipse.che.security.oauth.OAuthAPI;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
|
|
@ -51,6 +60,7 @@ public class BitbucketServerPersonalAccessTokenFetcherTest {
|
|||
Subject subject;
|
||||
@Mock BitbucketServerApiClient bitbucketServerApiClient;
|
||||
@Mock PersonalAccessToken personalAccessToken;
|
||||
@Mock OAuthAPI oAuthAPI;
|
||||
BitbucketUser bitbucketUser;
|
||||
BitbucketServerPersonalAccessTokenFetcher fetcher;
|
||||
BitbucketPersonalAccessToken bitbucketPersonalAccessToken;
|
||||
|
|
@ -93,7 +103,9 @@ public class BitbucketServerPersonalAccessTokenFetcherTest {
|
|||
"3456\\<0>945//i0923i4jasoidfj934ui50",
|
||||
bitbucketUser,
|
||||
ImmutableSet.of("PROJECT_READ", "REPO_READ"));
|
||||
fetcher = new BitbucketServerPersonalAccessTokenFetcher(bitbucketServerApiClient, apiEndpoint);
|
||||
fetcher =
|
||||
new BitbucketServerPersonalAccessTokenFetcher(
|
||||
bitbucketServerApiClient, apiEndpoint, oAuthAPI);
|
||||
EnvironmentContext context = new EnvironmentContext();
|
||||
context.setSubject(subject);
|
||||
EnvironmentContext.setCurrent(context);
|
||||
|
|
@ -190,8 +202,11 @@ public class BitbucketServerPersonalAccessTokenFetcherTest {
|
|||
|
||||
@Test
|
||||
public void shouldSkipToValidateTokensWithUnknownUrls()
|
||||
throws ScmUnauthorizedException, ScmCommunicationException {
|
||||
throws ScmUnauthorizedException, ScmCommunicationException, ForbiddenException,
|
||||
ServerException, ConflictException, UnauthorizedException, NotFoundException,
|
||||
BadRequestException {
|
||||
// given
|
||||
when(oAuthAPI.getToken(eq("bitbucket"))).thenReturn(mock(OAuthToken.class));
|
||||
when(personalAccessToken.getScmProviderUrl()).thenReturn(someNotBitbucketURL);
|
||||
when(bitbucketServerApiClient.isConnected(eq(someNotBitbucketURL))).thenReturn(false);
|
||||
// when
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ package org.eclipse.che.api.factory.server.bitbucket;
|
|||
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.*;
|
||||
|
|
@ -23,6 +22,7 @@ import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager;
|
|||
import org.eclipse.che.api.factory.server.scm.exception.ScmUnauthorizedException;
|
||||
import org.eclipse.che.api.factory.server.urlfactory.DevfileFilenamesProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
|
||||
import org.eclipse.che.security.oauth.OAuthAPI;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
|
|
@ -35,6 +35,7 @@ public class BitbucketServerScmFileResolverTest {
|
|||
public static final String SCM_URL = "https://foo.bar";
|
||||
BitbucketServerURLParser bitbucketURLParser;
|
||||
|
||||
@Mock private OAuthAPI oAuthAPI;
|
||||
@Mock private URLFetcher urlFetcher;
|
||||
|
||||
@Mock private DevfileFilenamesProvider devfileFilenamesProvider;
|
||||
|
|
@ -46,7 +47,7 @@ public class BitbucketServerScmFileResolverTest {
|
|||
protected void init() {
|
||||
bitbucketURLParser =
|
||||
new BitbucketServerURLParser(
|
||||
SCM_URL, devfileFilenamesProvider, mock(PersonalAccessTokenManager.class));
|
||||
SCM_URL, devfileFilenamesProvider, oAuthAPI, personalAccessTokenManager);
|
||||
assertNotNull(this.bitbucketURLParser);
|
||||
serverScmFileResolver =
|
||||
new BitbucketServerScmFileResolver(
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import com.github.tomakehurst.wiremock.client.WireMock;
|
|||
import com.github.tomakehurst.wiremock.common.Slf4jNotifier;
|
||||
import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager;
|
||||
import org.eclipse.che.api.factory.server.urlfactory.DevfileFilenamesProvider;
|
||||
import org.eclipse.che.security.oauth.OAuthAPI;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
|
|
@ -38,6 +39,7 @@ import org.testng.annotations.Test;
|
|||
public class BitbucketServerURLParserTest {
|
||||
|
||||
@Mock private DevfileFilenamesProvider devfileFilenamesProvider;
|
||||
@Mock private OAuthAPI oAuthAPI;
|
||||
|
||||
/** Instance of component that will be tested. */
|
||||
private BitbucketServerURLParser bitbucketURLParser;
|
||||
|
|
@ -59,6 +61,7 @@ public class BitbucketServerURLParserTest {
|
|||
new BitbucketServerURLParser(
|
||||
"https://bitbucket.2mcl.com,https://bbkt.com",
|
||||
devfileFilenamesProvider,
|
||||
oAuthAPI,
|
||||
mock(PersonalAccessTokenManager.class));
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +94,7 @@ public class BitbucketServerURLParserTest {
|
|||
// given
|
||||
bitbucketURLParser =
|
||||
new BitbucketServerURLParser(
|
||||
null, devfileFilenamesProvider, mock(PersonalAccessTokenManager.class));
|
||||
null, devfileFilenamesProvider, oAuthAPI, mock(PersonalAccessTokenManager.class));
|
||||
String url = wireMockServer.url("/users/user/repos/repo");
|
||||
stubFor(
|
||||
get(urlEqualTo("/rest/access-tokens/1.0/users/0")).willReturn(aResponse().withStatus(401)));
|
||||
|
|
|
|||
|
|
@ -22,6 +22,10 @@ import static com.github.tomakehurst.wiremock.client.WireMock.unauthorized;
|
|||
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
|
||||
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
|
|
@ -34,21 +38,32 @@ import com.google.common.net.HttpHeaders;
|
|||
import jakarta.ws.rs.core.MediaType;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.UnauthorizedException;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketPersonalAccessToken;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketServerApiClient;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.BitbucketUser;
|
||||
import org.eclipse.che.api.factory.server.bitbucket.server.HttpBitbucketServerApiClient;
|
||||
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.security.oauth.OAuthAPI;
|
||||
import org.eclipse.che.security.oauth1.BitbucketServerOAuthAuthenticator;
|
||||
import org.eclipse.che.security.oauth1.NoopOAuthAuthenticator;
|
||||
import org.eclipse.che.security.oauth1.OAuthAuthenticationException;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class HttpBitbucketServerApiClientTest {
|
||||
private final String AUTHORIZATION_TOKEN =
|
||||
"OAuth oauth_consumer_key=\"key123321\", oauth_nonce=\"6c0eace252f8dcda\","
|
||||
|
|
@ -59,8 +74,13 @@ public class HttpBitbucketServerApiClientTest {
|
|||
WireMock wireMock;
|
||||
BitbucketServerApiClient bitbucketServer;
|
||||
|
||||
@Mock OAuthAPI oAuthAPI;
|
||||
String apiEndpoint;
|
||||
|
||||
@BeforeMethod
|
||||
void start() {
|
||||
oAuthAPI = mock(OAuthAPI.class);
|
||||
apiEndpoint = "apiEndpoint";
|
||||
wireMockServer =
|
||||
new WireMockServer(wireMockConfig().notifier(new Slf4jNotifier(false)).dynamicPort());
|
||||
wireMockServer.start();
|
||||
|
|
@ -76,7 +96,9 @@ public class HttpBitbucketServerApiClientTest {
|
|||
throws OAuthAuthenticationException {
|
||||
return AUTHORIZATION_TOKEN;
|
||||
}
|
||||
});
|
||||
},
|
||||
oAuthAPI,
|
||||
apiEndpoint);
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
|
|
@ -276,12 +298,44 @@ public class HttpBitbucketServerApiClientTest {
|
|||
expectedExceptionsMessageRegExp =
|
||||
"The fallback noop authenticator cannot be used for authentication. Make sure OAuth is properly configured.")
|
||||
public void shouldThrowScmCommunicationExceptionInNoOauthAuthenticator()
|
||||
throws ScmCommunicationException, ScmUnauthorizedException, ScmItemNotFoundException {
|
||||
throws ScmCommunicationException, ScmUnauthorizedException, ScmItemNotFoundException,
|
||||
ForbiddenException, ServerException, ConflictException, UnauthorizedException,
|
||||
NotFoundException, BadRequestException {
|
||||
|
||||
// given
|
||||
when(oAuthAPI.getToken(eq("bitbucket"))).thenReturn(mock(OAuthToken.class));
|
||||
HttpBitbucketServerApiClient localServer =
|
||||
new HttpBitbucketServerApiClient(wireMockServer.url("/"), new NoopOAuthAuthenticator());
|
||||
new HttpBitbucketServerApiClient(
|
||||
wireMockServer.url("/"), new NoopOAuthAuthenticator(), oAuthAPI, apiEndpoint);
|
||||
|
||||
// when
|
||||
localServer.getPersonalAccessToken("ksmster", 5L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetOauth2Token()
|
||||
throws ScmItemNotFoundException, ScmUnauthorizedException, ScmCommunicationException,
|
||||
ForbiddenException, ServerException, ConflictException, UnauthorizedException,
|
||||
NotFoundException, BadRequestException {
|
||||
// given
|
||||
OAuthToken token = mock(OAuthToken.class);
|
||||
when(token.getToken()).thenReturn("token");
|
||||
when(oAuthAPI.getToken(eq("bitbucket"))).thenReturn(token);
|
||||
bitbucketServer =
|
||||
new HttpBitbucketServerApiClient(
|
||||
wireMockServer.url("/"), new NoopOAuthAuthenticator(), oAuthAPI, apiEndpoint);
|
||||
stubFor(
|
||||
get(urlEqualTo("/rest/api/1.0/users/user"))
|
||||
.withHeader(HttpHeaders.AUTHORIZATION, equalTo("Bearer token"))
|
||||
.willReturn(
|
||||
aResponse()
|
||||
.withHeader("Content-Type", "application/json; charset=utf-8")
|
||||
.withBodyFile("bitbucket/rest/api/1.0/users/ksmster/response.json")));
|
||||
|
||||
// when
|
||||
bitbucketServer.getUser("user", null);
|
||||
|
||||
// then
|
||||
verify(oAuthAPI).getToken(eq("bitbucket"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue