Added support of Idenvity brokering mechanism of Keycloak for Multi-user Che
parent
a6efd2d986
commit
8ff1be36f5
|
|
@ -21,10 +21,16 @@ public class WsAgentAuthServletModule extends ServletModule {
|
|||
protected void configureServlets() {
|
||||
if (Boolean.valueOf(System.getenv("CHE_AUTH_ENABLED"))) {
|
||||
configureMultiUserMode();
|
||||
} else {
|
||||
configureSingleUserMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void configureMultiUserMode() {
|
||||
filter("/*").through(MachineLoginFilter.class);
|
||||
}
|
||||
|
||||
private void configureSingleUserMode() {
|
||||
filter("/*").through(org.eclipse.che.EnvironmentInitializationFilter.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,9 +168,6 @@ public class WsMasterModule extends AbstractModule {
|
|||
|
||||
bind(org.eclipse.che.security.oauth.OAuthAuthenticatorProvider.class)
|
||||
.to(org.eclipse.che.security.oauth.OAuthAuthenticatorProviderImpl.class);
|
||||
bind(org.eclipse.che.security.oauth.shared.OAuthTokenProvider.class)
|
||||
.to(org.eclipse.che.security.oauth.OAuthAuthenticatorTokenProvider.class);
|
||||
bind(org.eclipse.che.security.oauth.OAuthAuthenticationService.class);
|
||||
|
||||
// installers
|
||||
install(new InstallerModule());
|
||||
|
|
@ -249,6 +246,10 @@ public class WsMasterModule extends AbstractModule {
|
|||
bind(org.eclipse.che.api.user.server.CheUserCreator.class);
|
||||
|
||||
bindConstant().annotatedWith(Names.named("che.agents.auth_enabled")).to(false);
|
||||
|
||||
bind(org.eclipse.che.security.oauth.shared.OAuthTokenProvider.class)
|
||||
.to(org.eclipse.che.security.oauth.OAuthAuthenticatorTokenProvider.class);
|
||||
bind(org.eclipse.che.security.oauth.OAuthAuthenticationService.class);
|
||||
}
|
||||
|
||||
private void configureMultiUserMode() {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public class CheCorsFilter implements Filter {
|
|||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
corsFilter = new CorsFilter();
|
||||
|
||||
corsFilter.init(new CodenvyCorsFilterConfig());
|
||||
corsFilter.init(new CheCorsFilterConfig());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -64,11 +64,11 @@ public class CheCorsFilter implements Filter {
|
|||
corsFilter.destroy();
|
||||
}
|
||||
|
||||
private class CodenvyCorsFilterConfig implements FilterConfig {
|
||||
private class CheCorsFilterConfig implements FilterConfig {
|
||||
|
||||
private final Map<String, String> filterParams;
|
||||
|
||||
public CodenvyCorsFilterConfig() {
|
||||
public CheCorsFilterConfig() {
|
||||
filterParams = new HashMap<>();
|
||||
filterParams.put(PARAM_CORS_ALLOWED_ORIGINS, DEFAULT_ALLOWED_ORIGINS);
|
||||
filterParams.put(
|
||||
|
|
@ -77,6 +77,7 @@ public class CheCorsFilter implements Filter {
|
|||
PARAM_CORS_ALLOWED_HEADERS,
|
||||
"Content-Type,"
|
||||
+ "X-Requested-With,"
|
||||
+ "X-Oauth-Token,"
|
||||
+ "accept,"
|
||||
+ "Origin,"
|
||||
+ "Authorization,"
|
||||
|
|
|
|||
|
|
@ -588,6 +588,7 @@
|
|||
"enabled" : true,
|
||||
"clientAuthenticatorType" : "client-secret",
|
||||
"secret" : "b59b1baf-df65-455d-b185-fda173e29d1b",
|
||||
"defaultRoles": [ "read-token" ],
|
||||
"redirectUris" : [ ],
|
||||
"webOrigins" : [ ],
|
||||
"notBefore" : 0,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.ide.ui.dialogs.askcredentials;
|
||||
package org.eclipse.che.ide.api.auth;
|
||||
|
||||
/**
|
||||
* Credentials object for subversion operations.
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2017 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.ide.api.auth;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestCallback;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestFactory;
|
||||
import org.eclipse.che.ide.rest.DtoUnmarshallerFactory;
|
||||
|
||||
/**
|
||||
* Serves connections to OauthAuthentication service. Allows to get OAuth tokens via callback or as
|
||||
* promise.
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
* @author Max Shaposhnyk
|
||||
*/
|
||||
public class OAuthServiceClient {
|
||||
private final AsyncRequestFactory asyncRequestFactory;
|
||||
private final String restContext;
|
||||
private final DtoUnmarshallerFactory unmarshallerFactory;
|
||||
|
||||
@Inject
|
||||
public OAuthServiceClient(
|
||||
AppContext appContext,
|
||||
AsyncRequestFactory asyncRequestFactory,
|
||||
DtoUnmarshallerFactory unmarshallerFactory) {
|
||||
this.asyncRequestFactory = asyncRequestFactory;
|
||||
this.restContext = appContext.getMasterApiEndpoint() + "/oauth";
|
||||
this.unmarshallerFactory = unmarshallerFactory;
|
||||
}
|
||||
|
||||
public void getToken(String oauthProvider, AsyncRequestCallback<OAuthToken> callback) {
|
||||
asyncRequestFactory
|
||||
.createGetRequest(restContext + "/token?oauth_provider=" + oauthProvider)
|
||||
.send(callback);
|
||||
}
|
||||
|
||||
public Promise<OAuthToken> getToken(String oauthProvider) {
|
||||
return asyncRequestFactory
|
||||
.createGetRequest(restContext + "/token?oauth_provider=" + oauthProvider)
|
||||
.send(unmarshallerFactory.newUnmarshaller(OAuthToken.class));
|
||||
}
|
||||
}
|
||||
|
|
@ -60,6 +60,10 @@
|
|||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</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>
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ import org.eclipse.che.api.promises.client.PromiseError;
|
|||
import org.eclipse.che.api.promises.client.js.Promises;
|
||||
import org.eclipse.che.ide.CoreLocalizationConstant;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.auth.Credentials;
|
||||
import org.eclipse.che.ide.api.factory.model.FactoryImpl;
|
||||
import org.eclipse.che.ide.api.notification.NotificationManager;
|
||||
import org.eclipse.che.ide.api.notification.StatusNotification;
|
||||
|
|
@ -62,7 +63,6 @@ import org.eclipse.che.ide.projectimport.wizard.ProjectNotificationSubscriber;
|
|||
import org.eclipse.che.ide.resource.Path;
|
||||
import org.eclipse.che.ide.ui.dialogs.DialogFactory;
|
||||
import org.eclipse.che.ide.ui.dialogs.askcredentials.AskCredentialsDialog;
|
||||
import org.eclipse.che.ide.ui.dialogs.askcredentials.Credentials;
|
||||
import org.eclipse.che.ide.util.ExceptionUtils;
|
||||
import org.eclipse.che.ide.util.StringUtils;
|
||||
import org.eclipse.che.security.oauth.OAuthStatus;
|
||||
|
|
|
|||
|
|
@ -25,16 +25,16 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
|
|||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.Map;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.api.core.model.workspace.config.SourceStorage;
|
||||
import org.eclipse.che.api.promises.client.Function;
|
||||
import org.eclipse.che.api.promises.client.FunctionException;
|
||||
import org.eclipse.che.api.promises.client.Operation;
|
||||
import org.eclipse.che.api.promises.client.OperationException;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.api.promises.client.PromiseError;
|
||||
import org.eclipse.che.api.promises.client.callback.AsyncPromiseHelper.RequestCall;
|
||||
import org.eclipse.che.ide.CoreLocalizationConstant;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.api.oauth.OAuth2Authenticator;
|
||||
import org.eclipse.che.ide.api.oauth.OAuth2AuthenticatorRegistry;
|
||||
import org.eclipse.che.ide.api.oauth.OAuth2AuthenticatorUrlProvider;
|
||||
|
|
@ -43,8 +43,9 @@ import org.eclipse.che.ide.api.resources.Project;
|
|||
import org.eclipse.che.ide.api.wizard.Wizard.CompleteCallback;
|
||||
import org.eclipse.che.ide.projectimport.AbstractImporter;
|
||||
import org.eclipse.che.ide.resource.Path;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestCallback;
|
||||
import org.eclipse.che.ide.rest.DtoUnmarshallerFactory;
|
||||
import org.eclipse.che.ide.ui.dialogs.askcredentials.AskCredentialsDialog;
|
||||
import org.eclipse.che.ide.ui.dialogs.askcredentials.Credentials;
|
||||
import org.eclipse.che.ide.util.ExceptionUtils;
|
||||
import org.eclipse.che.security.oauth.OAuthStatus;
|
||||
|
||||
|
|
@ -59,6 +60,8 @@ public class ProjectImporter extends AbstractImporter {
|
|||
private final ProjectResolver projectResolver;
|
||||
private final AskCredentialsDialog credentialsDialog;
|
||||
private final OAuth2AuthenticatorRegistry oAuth2AuthenticatorRegistry;
|
||||
private final OAuthServiceClient oAuthServiceClient;
|
||||
private final DtoUnmarshallerFactory unmarshallerFactory;
|
||||
|
||||
@Inject
|
||||
public ProjectImporter(
|
||||
|
|
@ -67,12 +70,16 @@ public class ProjectImporter extends AbstractImporter {
|
|||
AppContext appContext,
|
||||
ProjectResolver projectResolver,
|
||||
AskCredentialsDialog credentialsDialog,
|
||||
OAuth2AuthenticatorRegistry oAuth2AuthenticatorRegistry) {
|
||||
OAuth2AuthenticatorRegistry oAuth2AuthenticatorRegistry,
|
||||
DtoUnmarshallerFactory unmarshaller,
|
||||
OAuthServiceClient oAuthServiceClient) {
|
||||
super(appContext, subscriberFactory);
|
||||
this.localizationConstant = localizationConstant;
|
||||
this.projectResolver = projectResolver;
|
||||
this.credentialsDialog = credentialsDialog;
|
||||
this.unmarshallerFactory = unmarshaller;
|
||||
this.oAuth2AuthenticatorRegistry = oAuth2AuthenticatorRegistry;
|
||||
this.oAuthServiceClient = oAuthServiceClient;
|
||||
}
|
||||
|
||||
public void importProject(final CompleteCallback callback, MutableProjectConfig projectConfig) {
|
||||
|
|
@ -88,21 +95,15 @@ public class ProjectImporter extends AbstractImporter {
|
|||
|
||||
startImport(path, projectConfig.getSource())
|
||||
.then(
|
||||
new Operation<Project>() {
|
||||
@Override
|
||||
public void apply(Project arg) throws OperationException {
|
||||
if (callback != null) {
|
||||
callback.onCompleted();
|
||||
}
|
||||
project -> {
|
||||
if (callback != null) {
|
||||
callback.onCompleted();
|
||||
}
|
||||
})
|
||||
.catchError(
|
||||
new Operation<PromiseError>() {
|
||||
@Override
|
||||
public void apply(PromiseError arg) throws OperationException {
|
||||
if (callback != null) {
|
||||
callback.onFailure(arg.getCause());
|
||||
}
|
||||
error -> {
|
||||
if (callback != null) {
|
||||
callback.onFailure(error.getCause());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -126,13 +127,9 @@ public class ProjectImporter extends AbstractImporter {
|
|||
.withBody(importConfig)
|
||||
.send()
|
||||
.thenPromise(
|
||||
new Function<Project, Promise<Project>>() {
|
||||
@Override
|
||||
public Promise<Project> apply(Project project) throws FunctionException {
|
||||
subscriber.onSuccess();
|
||||
|
||||
return projectResolver.resolve(project);
|
||||
}
|
||||
project -> {
|
||||
subscriber.onSuccess();
|
||||
return projectResolver.resolve(project);
|
||||
})
|
||||
.catchErrorPromise(
|
||||
new Function<PromiseError, Promise<Project>>() {
|
||||
|
|
@ -175,27 +172,18 @@ public class ProjectImporter extends AbstractImporter {
|
|||
credentialsDialog
|
||||
.askCredentials()
|
||||
.then(
|
||||
new Operation<Credentials>() {
|
||||
@Override
|
||||
public void apply(Credentials credentials) throws OperationException {
|
||||
sourceStorage.getParameters().put("username", credentials.getUsername());
|
||||
sourceStorage.getParameters().put("password", credentials.getPassword());
|
||||
doImport(path, sourceStorage)
|
||||
.then(
|
||||
new Operation<Project>() {
|
||||
@Override
|
||||
public void apply(Project project) throws OperationException {
|
||||
callback.onSuccess(project);
|
||||
}
|
||||
})
|
||||
.catchError(
|
||||
new Operation<PromiseError>() {
|
||||
@Override
|
||||
public void apply(PromiseError error) throws OperationException {
|
||||
callback.onFailure(error.getCause());
|
||||
}
|
||||
});
|
||||
}
|
||||
credentials -> {
|
||||
sourceStorage.getParameters().put("username", credentials.getUsername());
|
||||
sourceStorage.getParameters().put("password", credentials.getPassword());
|
||||
doImport(path, sourceStorage)
|
||||
.then(
|
||||
project -> {
|
||||
callback.onSuccess(project);
|
||||
})
|
||||
.catchError(
|
||||
error -> {
|
||||
callback.onFailure(error.getCause());
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -230,21 +218,31 @@ public class ProjectImporter extends AbstractImporter {
|
|||
@Override
|
||||
public void onSuccess(OAuthStatus result) {
|
||||
if (!result.equals(OAuthStatus.NOT_PERFORMED)) {
|
||||
doImport(path, sourceStorage)
|
||||
.then(
|
||||
new Operation<Project>() {
|
||||
@Override
|
||||
public void apply(Project project) throws OperationException {
|
||||
callback.onSuccess(project);
|
||||
}
|
||||
})
|
||||
.catchError(
|
||||
new Operation<PromiseError>() {
|
||||
@Override
|
||||
public void apply(PromiseError error) throws OperationException {
|
||||
callback.onFailure(error.getCause());
|
||||
}
|
||||
});
|
||||
oAuthServiceClient.getToken(
|
||||
providerName,
|
||||
new AsyncRequestCallback<OAuthToken>(
|
||||
unmarshallerFactory.newUnmarshaller(OAuthToken.class)) {
|
||||
@Override
|
||||
protected void onSuccess(OAuthToken result) {
|
||||
sourceStorage.getParameters().put("username", result.getToken());
|
||||
sourceStorage.getParameters().put("password", result.getToken());
|
||||
|
||||
doImport(path, sourceStorage)
|
||||
.then(
|
||||
project -> {
|
||||
callback.onSuccess(project);
|
||||
})
|
||||
.catchError(
|
||||
error -> {
|
||||
callback.onFailure(error.getCause());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFailure(Throwable exception) {
|
||||
callback.onFailure(new Exception(exception.getMessage()));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
subscriber.onFailure("Authentication cancelled");
|
||||
callback.onFailure(new IllegalStateException("Authentication cancelled"));
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ import com.google.gwt.user.client.ui.Widget;
|
|||
import com.google.inject.Inject;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.ide.CoreLocalizationConstant;
|
||||
import org.eclipse.che.ide.api.auth.Credentials;
|
||||
import org.eclipse.che.ide.ui.dialogs.askcredentials.AskCredentialsDialog;
|
||||
import org.eclipse.che.ide.ui.dialogs.askcredentials.Credentials;
|
||||
import org.eclipse.che.ide.ui.window.Window;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -21,10 +21,12 @@ import org.eclipse.che.api.promises.client.Operation;
|
|||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.ide.CoreLocalizationConstant;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.api.project.MutableProjectConfig;
|
||||
import org.eclipse.che.ide.api.resources.Container;
|
||||
import org.eclipse.che.ide.api.resources.Project;
|
||||
import org.eclipse.che.ide.api.wizard.Wizard;
|
||||
import org.eclipse.che.ide.rest.DtoUnmarshallerFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
|
@ -55,6 +57,8 @@ public class ProjectImporterTest {
|
|||
@Mock private Project.ProjectRequest importRequest;
|
||||
@Mock private Promise<Project> importPromise;
|
||||
@Mock private Project importedProject;
|
||||
@Mock private OAuthServiceClient oAuthServiceClient;
|
||||
@Mock private DtoUnmarshallerFactory unmarshallerFactory;
|
||||
|
||||
@Captor private ArgumentCaptor<Function<Project, Promise<Project>>> importProjectCaptor;
|
||||
|
||||
|
|
@ -77,7 +81,14 @@ public class ProjectImporterTest {
|
|||
|
||||
importer =
|
||||
new ProjectImporter(
|
||||
localizationConstant, subscriberFactory, appContext, resolver, null, null);
|
||||
localizationConstant,
|
||||
subscriberFactory,
|
||||
appContext,
|
||||
resolver,
|
||||
null,
|
||||
null,
|
||||
unmarshallerFactory,
|
||||
oAuthServiceClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
package org.eclipse.che.ide.ui.dialogs.askcredentials;
|
||||
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.ide.api.auth.Credentials;
|
||||
|
||||
/**
|
||||
* Dialog for retrieving credentials for operations.
|
||||
|
|
|
|||
|
|
@ -54,10 +54,18 @@
|
|||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</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>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-dto</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-model</artifactId>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import org.eclipse.che.api.core.rest.Service;
|
|||
|
||||
/**
|
||||
* Endpoint which provides keycloak public client authentication information (such as URL, realm,
|
||||
* cliend_id).
|
||||
* client_id).
|
||||
*
|
||||
* @author Max Shaposhnik (mshaposh@redhat.com)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import org.eclipse.che.api.user.server.spi.ProfileDao;
|
|||
import org.eclipse.che.multiuser.keycloak.server.KeycloakConfigurationService;
|
||||
import org.eclipse.che.multiuser.keycloak.server.KeycloakTokenValidator;
|
||||
import org.eclipse.che.multiuser.keycloak.server.dao.KeycloakProfileDao;
|
||||
import org.eclipse.che.multiuser.keycloak.server.oauth2.KeycloakOAuthAuthenticationService;
|
||||
|
||||
public class KeycloakModule extends AbstractModule {
|
||||
@Override
|
||||
|
|
@ -26,6 +27,7 @@ public class KeycloakModule extends AbstractModule {
|
|||
.to(org.eclipse.che.multiuser.keycloak.server.KeycloakHttpJsonRequestFactory.class);
|
||||
bind(TokenValidator.class).to(KeycloakTokenValidator.class);
|
||||
bind(KeycloakConfigurationService.class);
|
||||
bind(KeycloakOAuthAuthenticationService.class);
|
||||
|
||||
bind(ProfileDao.class).to(KeycloakProfileDao.class);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2017 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.keycloak.server.oauth2;
|
||||
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.AUTH_SERVER_URL_SETTING;
|
||||
import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.REALM_SETTING;
|
||||
|
||||
import io.jsonwebtoken.Jwt;
|
||||
import io.jsonwebtoken.impl.DefaultClaims;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import javax.inject.Inject;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.SecurityContext;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
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.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.core.rest.annotations.Required;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.eclipse.che.multiuser.keycloak.server.KeycloakSettings;
|
||||
|
||||
@Path("/oauth")
|
||||
public class KeycloakOAuthAuthenticationService {
|
||||
@Context UriInfo uriInfo;
|
||||
|
||||
@Context SecurityContext security;
|
||||
|
||||
private final KeycloakSettings keycloakConfiguration;
|
||||
|
||||
private final HttpJsonRequestFactory requestFactory;
|
||||
|
||||
@Inject
|
||||
public KeycloakOAuthAuthenticationService(
|
||||
KeycloakSettings keycloakConfiguration, HttpJsonRequestFactory requestFactory) {
|
||||
this.keycloakConfiguration = keycloakConfiguration;
|
||||
this.requestFactory = requestFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs local and Keycloak accounts linking
|
||||
*
|
||||
* @return typically Response that redirect user for OAuth provider site
|
||||
*/
|
||||
@GET
|
||||
@Path("authenticate")
|
||||
public Response authenticate(
|
||||
@Required @QueryParam("oauth_provider") String oauthProvider,
|
||||
@Required @QueryParam("redirect_after_login") String redirectAfterLogin,
|
||||
@Context HttpServletRequest request)
|
||||
throws ForbiddenException, BadRequestException {
|
||||
|
||||
Jwt jwtToken = (Jwt) request.getAttribute("token");
|
||||
if (jwtToken == null) {
|
||||
throw new BadRequestException("No token provided.");
|
||||
}
|
||||
DefaultClaims claims = (DefaultClaims) jwtToken.getBody();
|
||||
final String clientId = claims.getAudience();
|
||||
final String nonce = UUID.randomUUID().toString();
|
||||
final String sessionState = claims.get("session_state", String.class);
|
||||
MessageDigest md;
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
final String input = nonce + sessionState + clientId + oauthProvider;
|
||||
byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
|
||||
final String hash = Base64.getUrlEncoder().encodeToString(check);
|
||||
request.getSession().setAttribute("hash", hash); // TODO: for what?
|
||||
String accountLinkUrl =
|
||||
UriBuilder.fromUri(keycloakConfiguration.get().get(AUTH_SERVER_URL_SETTING))
|
||||
.path("/realms/{realm}/broker/{provider}/link")
|
||||
.queryParam("nonce", nonce)
|
||||
.queryParam("hash", hash)
|
||||
.queryParam("client_id", clientId)
|
||||
.queryParam("redirect_uri", redirectAfterLogin)
|
||||
.build(keycloakConfiguration.get().get(REALM_SETTING), oauthProvider)
|
||||
.toString();
|
||||
return Response.temporaryRedirect(URI.create(accountLinkUrl)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets OAuth token for user from Keycloak.
|
||||
*
|
||||
* @param oauthProvider OAuth provider name
|
||||
* @return OAuthToken
|
||||
* @throws ServerException
|
||||
*/
|
||||
@GET
|
||||
@Path("token")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public OAuthToken token(@Required @QueryParam("oauth_provider") String oauthProvider)
|
||||
throws ForbiddenException, BadRequestException, ConflictException, NotFoundException,
|
||||
ServerException, UnauthorizedException {
|
||||
|
||||
try {
|
||||
String token =
|
||||
requestFactory
|
||||
.fromUrl(
|
||||
UriBuilder.fromUri(keycloakConfiguration.get().get(AUTH_SERVER_URL_SETTING))
|
||||
.path("/realms/{realm}/broker/{provider}/token")
|
||||
.build(keycloakConfiguration.get().get(REALM_SETTING), oauthProvider)
|
||||
.toString())
|
||||
.request()
|
||||
.asString();
|
||||
Map<String, String> params = splitQuery(token);
|
||||
return DtoFactory.newDto(OAuthToken.class)
|
||||
.withToken(params.get("access_token"))
|
||||
.withScope(params.get("scope"));
|
||||
} catch (IOException e) {
|
||||
throw new ServerException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, String> splitQuery(String query) {
|
||||
Map<String, String> queryPairs = new HashMap<>();
|
||||
Arrays.stream(query.split("&"))
|
||||
.forEach(
|
||||
p -> {
|
||||
int delimiterIndex = p.indexOf("=");
|
||||
queryPairs.put(p.substring(0, delimiterIndex), p.substring(delimiterIndex + 1));
|
||||
});
|
||||
return queryPairs;
|
||||
}
|
||||
}
|
||||
|
|
@ -45,6 +45,10 @@
|
|||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</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>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2017 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.ide.ext.git.client;
|
||||
|
||||
import static org.eclipse.che.api.git.shared.ProviderInfo.PROVIDER_NAME;
|
||||
import static org.eclipse.che.ide.util.ExceptionUtils.getAttributes;
|
||||
import static org.eclipse.che.ide.util.ExceptionUtils.getErrorCode;
|
||||
|
||||
import java.util.Map;
|
||||
import org.eclipse.che.api.core.ErrorCodes;
|
||||
import org.eclipse.che.api.promises.client.Function;
|
||||
import org.eclipse.che.api.promises.client.FunctionException;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.api.promises.client.PromiseError;
|
||||
import org.eclipse.che.api.promises.client.js.Promises;
|
||||
import org.eclipse.che.ide.api.auth.Credentials;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.api.notification.NotificationManager;
|
||||
|
||||
/**
|
||||
* Base presenter class for authenticated Git operations.
|
||||
*
|
||||
* @author Max Shaposhnik (mshaposh@redhat.com)
|
||||
*/
|
||||
public class GitAuthActionPresenter {
|
||||
|
||||
protected NotificationManager notificationManager;
|
||||
protected GitLocalizationConstant locale;
|
||||
protected OAuthServiceClient oAuthServiceClient;
|
||||
|
||||
public GitAuthActionPresenter(
|
||||
NotificationManager notificationManager,
|
||||
GitLocalizationConstant locale,
|
||||
OAuthServiceClient oAuthServiceClient) {
|
||||
this.notificationManager = notificationManager;
|
||||
this.locale = locale;
|
||||
this.oAuthServiceClient = oAuthServiceClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs git operation. If this operations fails with authorization error the operation will be
|
||||
* recalled with requested credentials
|
||||
*
|
||||
* @param operation operation that might require auth
|
||||
*/
|
||||
protected <Y> Promise<Y> performOperationWithTokenRequestIfNeeded(
|
||||
final RemoteGitOperation<Y> operation) {
|
||||
return operation
|
||||
.perform(null)
|
||||
.catchErrorPromise(
|
||||
new Function<PromiseError, Promise<Y>>() {
|
||||
@Override
|
||||
public Promise<Y> apply(PromiseError error) throws FunctionException {
|
||||
if (getErrorCode(error.getCause()) == ErrorCodes.UNAUTHORIZED_GIT_OPERATION) {
|
||||
Map<String, String> attributes = getAttributes(error.getCause());
|
||||
String providerName = attributes.get(PROVIDER_NAME);
|
||||
|
||||
return oAuthServiceClient
|
||||
.getToken(providerName)
|
||||
.thenPromise(
|
||||
token ->
|
||||
Promises.resolve(new Credentials(token.getToken(), token.getToken())))
|
||||
.thenPromise(operation::perform);
|
||||
}
|
||||
return Promises.reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Remote git operation that can require credentials. */
|
||||
protected interface RemoteGitOperation<Y> {
|
||||
Promise<Y> perform(Credentials credentials);
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,7 @@ import org.eclipse.che.api.git.shared.ShowFileContentResponse;
|
|||
import org.eclipse.che.api.git.shared.Status;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.ide.api.auth.Credentials;
|
||||
import org.eclipse.che.ide.resource.Path;
|
||||
|
||||
/**
|
||||
|
|
@ -65,8 +66,14 @@ public interface GitServiceClient {
|
|||
* </ul>
|
||||
*
|
||||
* @param removeDeletedRefs if <code>true</code> then delete removed refs from local repository
|
||||
* @param credentials credentials to perform vcs authorization
|
||||
*/
|
||||
Promise<Void> fetch(Path project, String remote, List<String> refspec, boolean removeDeletedRefs);
|
||||
Promise<Void> fetch(
|
||||
Path project,
|
||||
String remote,
|
||||
List<String> refspec,
|
||||
boolean removeDeletedRefs,
|
||||
Credentials credentials);
|
||||
|
||||
/**
|
||||
* Get the list of the branches. For now, all branches cannot be returned at once, so the
|
||||
|
|
@ -191,8 +198,10 @@ public interface GitServiceClient {
|
|||
*
|
||||
* @param remote remote remote repository's name
|
||||
* @param rebase use rebase instead of merge
|
||||
* @param credentials credentials to perform vcs authorization
|
||||
*/
|
||||
Promise<PullResponse> pull(Path project, String refSpec, String remote, boolean rebase);
|
||||
Promise<PullResponse> pull(
|
||||
Path project, String refSpec, String remote, boolean rebase, Credentials credentials);
|
||||
|
||||
/**
|
||||
* Push changes from local repository to remote one (sends request over WebSocket).
|
||||
|
|
@ -203,8 +212,10 @@ public interface GitServiceClient {
|
|||
* @param force push refuses to update a remote ref that is not an ancestor of the local ref used
|
||||
* to overwrite it. If <code>true</code> disables the check. This can cause the remote
|
||||
* repository to lose commits
|
||||
* @param credentials credentials to perform vcs authorization
|
||||
*/
|
||||
Promise<PushResponse> push(Path project, List<String> refSpec, String remote, boolean force);
|
||||
Promise<PushResponse> push(
|
||||
Path project, List<String> refSpec, String remote, boolean force, Credentials credentials);
|
||||
|
||||
/**
|
||||
* Clones one remote repository to local one (over WebSocket).
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ import org.eclipse.che.api.git.shared.Status;
|
|||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.ide.MimeType;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.auth.Credentials;
|
||||
import org.eclipse.che.ide.dto.DtoFactory;
|
||||
import org.eclipse.che.ide.resource.Path;
|
||||
import org.eclipse.che.ide.rest.AsyncRequest;
|
||||
|
|
@ -213,13 +214,17 @@ public class GitServiceClientImpl implements GitServiceClient {
|
|||
|
||||
@Override
|
||||
public Promise<PushResponse> push(
|
||||
Path project, List<String> refSpec, String remote, boolean force) {
|
||||
Path project, List<String> refSpec, String remote, boolean force, Credentials credentials) {
|
||||
PushRequest pushRequest =
|
||||
dtoFactory
|
||||
.createDto(PushRequest.class)
|
||||
.withRemote(remote)
|
||||
.withRefSpec(refSpec)
|
||||
.withForce(force);
|
||||
if (credentials != null) {
|
||||
pushRequest.setUsername(credentials.getUsername());
|
||||
pushRequest.setPassword(credentials.getPassword());
|
||||
}
|
||||
String url = getWsAgentBaseUrl() + PUSH + "?projectPath=" + encodePath(project);
|
||||
return asyncRequestFactory
|
||||
.createPostRequest(url, pushRequest)
|
||||
|
|
@ -391,25 +396,38 @@ public class GitServiceClientImpl implements GitServiceClient {
|
|||
|
||||
@Override
|
||||
public Promise<Void> fetch(
|
||||
Path project, String remote, List<String> refspec, boolean removeDeletedRefs) {
|
||||
Path project,
|
||||
String remote,
|
||||
List<String> refspec,
|
||||
boolean removeDeletedRefs,
|
||||
Credentials credentials) {
|
||||
FetchRequest fetchRequest =
|
||||
dtoFactory
|
||||
.createDto(FetchRequest.class)
|
||||
.withRefSpec(refspec)
|
||||
.withRemote(remote)
|
||||
.withRemoveDeletedRefs(removeDeletedRefs);
|
||||
if (credentials != null) {
|
||||
fetchRequest.setUsername(credentials.getUsername());
|
||||
fetchRequest.setPassword(credentials.getPassword());
|
||||
}
|
||||
String url = getWsAgentBaseUrl() + FETCH + "?projectPath=" + encodePath(project);
|
||||
return asyncRequestFactory.createPostRequest(url, fetchRequest).send();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<PullResponse> pull(Path project, String refSpec, String remote, boolean rebase) {
|
||||
public Promise<PullResponse> pull(
|
||||
Path project, String refSpec, String remote, boolean rebase, Credentials credentials) {
|
||||
PullRequest pullRequest =
|
||||
dtoFactory
|
||||
.createDto(PullRequest.class)
|
||||
.withRemote(remote)
|
||||
.withRefSpec(refSpec)
|
||||
.withRebase(rebase);
|
||||
if (credentials != null) {
|
||||
pullRequest.setUsername(credentials.getUsername());
|
||||
pullRequest.setPassword(credentials.getPassword());
|
||||
}
|
||||
String url = getWsAgentBaseUrl() + PULL + "?projectPath=" + encodePath(project);
|
||||
return asyncRequestFactory
|
||||
.createPostRequest(url, pullRequest)
|
||||
|
|
|
|||
|
|
@ -31,13 +31,18 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.eclipse.che.api.core.ErrorCodes;
|
||||
import org.eclipse.che.api.git.shared.PushResponse;
|
||||
import org.eclipse.che.api.git.shared.Revision;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.auth.Credentials;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.api.notification.NotificationManager;
|
||||
import org.eclipse.che.ide.api.resources.Project;
|
||||
import org.eclipse.che.ide.commons.exception.ServerException;
|
||||
import org.eclipse.che.ide.ext.git.client.DateTimeFormatter;
|
||||
import org.eclipse.che.ide.ext.git.client.GitAuthActionPresenter;
|
||||
import org.eclipse.che.ide.ext.git.client.GitLocalizationConstant;
|
||||
import org.eclipse.che.ide.ext.git.client.GitServiceClient;
|
||||
import org.eclipse.che.ide.ext.git.client.compare.AlteredFiles;
|
||||
|
|
@ -57,7 +62,8 @@ import org.eclipse.che.ide.ui.dialogs.DialogFactory;
|
|||
* @author Igor Vinokur
|
||||
*/
|
||||
@Singleton
|
||||
public class CommitPresenter implements CommitView.ActionDelegate, SelectionCallBack {
|
||||
public class CommitPresenter extends GitAuthActionPresenter
|
||||
implements CommitView.ActionDelegate, SelectionCallBack {
|
||||
private static final String COMMIT_COMMAND_NAME = "Git commit";
|
||||
|
||||
private final SelectableChangesPanelPresenter selectableChangesPanelPresenter;
|
||||
|
|
@ -65,8 +71,6 @@ public class CommitPresenter implements CommitView.ActionDelegate, SelectionCall
|
|||
private final AppContext appContext;
|
||||
private final CommitView view;
|
||||
private final GitServiceClient service;
|
||||
private final GitLocalizationConstant constant;
|
||||
private final NotificationManager notificationManager;
|
||||
private final DateTimeFormatter dateTimeFormatter;
|
||||
private final GitOutputConsoleFactory gitOutputConsoleFactory;
|
||||
private final ProcessesPanelPresenter consolesPanelPresenter;
|
||||
|
|
@ -84,7 +88,9 @@ public class CommitPresenter implements CommitView.ActionDelegate, SelectionCall
|
|||
AppContext appContext,
|
||||
DateTimeFormatter dateTimeFormatter,
|
||||
GitOutputConsoleFactory gitOutputConsoleFactory,
|
||||
ProcessesPanelPresenter processesPanelPresenter) {
|
||||
ProcessesPanelPresenter processesPanelPresenter,
|
||||
OAuthServiceClient oAuthServiceClient) {
|
||||
super(notificationManager, constant, oAuthServiceClient);
|
||||
this.view = view;
|
||||
this.selectableChangesPanelPresenter = selectableChangesPanelPresenter;
|
||||
this.dialogFactory = dialogFactory;
|
||||
|
|
@ -94,9 +100,6 @@ public class CommitPresenter implements CommitView.ActionDelegate, SelectionCall
|
|||
this.consolesPanelPresenter = processesPanelPresenter;
|
||||
this.view.setDelegate(this);
|
||||
this.service = service;
|
||||
this.constant = constant;
|
||||
this.notificationManager = notificationManager;
|
||||
|
||||
this.view.setChangesPanelView(selectableChangesPanelPresenter.getView());
|
||||
}
|
||||
|
||||
|
|
@ -142,7 +145,7 @@ public class CommitPresenter implements CommitView.ActionDelegate, SelectionCall
|
|||
})
|
||||
.catchError(
|
||||
arg -> {
|
||||
notificationManager.notify(constant.diffFailed(), FAIL, FLOAT_MODE);
|
||||
notificationManager.notify(locale.diffFailed(), FAIL, FLOAT_MODE);
|
||||
});
|
||||
|
||||
service
|
||||
|
|
@ -150,17 +153,17 @@ public class CommitPresenter implements CommitView.ActionDelegate, SelectionCall
|
|||
.then(view::setRemoteBranchesList)
|
||||
.catchError(
|
||||
error -> {
|
||||
notificationManager.notify(constant.branchesListFailed(), FAIL, FLOAT_MODE);
|
||||
notificationManager.notify(locale.branchesListFailed(), FAIL, FLOAT_MODE);
|
||||
});
|
||||
}
|
||||
|
||||
private void showAskForAmendDialog() {
|
||||
dialogFactory
|
||||
.createConfirmDialog(
|
||||
constant.commitTitle(),
|
||||
constant.commitNothingToCommitMessageText(),
|
||||
constant.buttonYes(),
|
||||
constant.buttonNo(),
|
||||
locale.commitTitle(),
|
||||
locale.commitNothingToCommitMessageText(),
|
||||
locale.buttonYes(),
|
||||
locale.buttonNo(),
|
||||
() -> {
|
||||
view.setValueToAmendCheckBox(true);
|
||||
view.setEnablePushAfterCommitCheckBox(false);
|
||||
|
|
@ -210,7 +213,7 @@ public class CommitPresenter implements CommitView.ActionDelegate, SelectionCall
|
|||
})
|
||||
.catchError(
|
||||
error -> {
|
||||
notificationManager.notify(constant.addFailed(), FAIL, FLOAT_MODE);
|
||||
notificationManager.notify(locale.addFailed(), FAIL, FLOAT_MODE);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -228,15 +231,20 @@ public class CommitPresenter implements CommitView.ActionDelegate, SelectionCall
|
|||
String remoteBranch = view.getRemoteBranch();
|
||||
String remote = remoteBranch.split("/")[0];
|
||||
String branch = remoteBranch.split("/")[1];
|
||||
service
|
||||
.push(location, singletonList(branch), remote, false)
|
||||
performOperationWithTokenRequestIfNeeded(
|
||||
new RemoteGitOperation<PushResponse>() {
|
||||
@Override
|
||||
public Promise<PushResponse> perform(Credentials credentials) {
|
||||
return service.push(location, singletonList(branch), remote, false, credentials);
|
||||
}
|
||||
})
|
||||
.then(
|
||||
result -> {
|
||||
notificationManager.notify(constant.pushSuccess(remote), SUCCESS, FLOAT_MODE);
|
||||
notificationManager.notify(locale.pushSuccess(remote), SUCCESS, FLOAT_MODE);
|
||||
})
|
||||
.catchError(
|
||||
error -> {
|
||||
notificationManager.notify(constant.pushFail(), FAIL, FLOAT_MODE);
|
||||
notificationManager.notify(locale.pushFail(), FAIL, FLOAT_MODE);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -276,23 +284,23 @@ public class CommitPresenter implements CommitView.ActionDelegate, SelectionCall
|
|||
if (getErrorCode(error.getCause()) == ErrorCodes.INIT_COMMIT_WAS_NOT_PERFORMED) {
|
||||
dialogFactory
|
||||
.createMessageDialog(
|
||||
constant.commitTitle(), constant.initCommitWasNotPerformed(), null)
|
||||
locale.commitTitle(), locale.initCommitWasNotPerformed(), null)
|
||||
.show();
|
||||
} else {
|
||||
CommitPresenter.this.view.setMessage("");
|
||||
notificationManager.notify(constant.logFailed(), FAIL, NOT_EMERGE_MODE);
|
||||
notificationManager.notify(locale.logFailed(), FAIL, NOT_EMERGE_MODE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onCommitSuccess(@NotNull final Revision revision) {
|
||||
String date = dateTimeFormatter.getFormattedDate(revision.getCommitTime());
|
||||
String message = constant.commitMessage(revision.getId(), date);
|
||||
String message = locale.commitMessage(revision.getId(), date);
|
||||
|
||||
if ((revision.getCommitter() != null
|
||||
&& revision.getCommitter().getName() != null
|
||||
&& !revision.getCommitter().getName().isEmpty())) {
|
||||
message += " " + constant.commitUser(revision.getCommitter().getName());
|
||||
message += " " + locale.commitUser(revision.getCommitter().getName());
|
||||
}
|
||||
GitOutputConsole console = gitOutputConsoleFactory.create(COMMIT_COMMAND_NAME);
|
||||
console.print(message);
|
||||
|
|
@ -306,7 +314,7 @@ public class CommitPresenter implements CommitView.ActionDelegate, SelectionCall
|
|||
&& ((ServerException) exception).getErrorCode()
|
||||
== ErrorCodes.NO_COMMITTER_NAME_OR_EMAIL_DEFINED) {
|
||||
dialogFactory
|
||||
.createMessageDialog(constant.commitTitle(), constant.committerIdentityInfoEmpty(), null)
|
||||
.createMessageDialog(locale.commitTitle(), locale.committerIdentityInfoEmpty(), null)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
|
|
@ -314,10 +322,10 @@ public class CommitPresenter implements CommitView.ActionDelegate, SelectionCall
|
|||
String errorMessage =
|
||||
(exceptionMessage != null && !exceptionMessage.isEmpty())
|
||||
? exceptionMessage
|
||||
: constant.commitFailed();
|
||||
: locale.commitFailed();
|
||||
GitOutputConsole console = gitOutputConsoleFactory.create(COMMIT_COMMAND_NAME);
|
||||
console.printError(errorMessage);
|
||||
consolesPanelPresenter.addCommandOutput(console);
|
||||
notificationManager.notify(constant.commitFailed(), errorMessage, FAIL, FLOAT_MODE);
|
||||
notificationManager.notify(locale.commitFailed(), errorMessage, FAIL, FLOAT_MODE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,12 +26,15 @@ import javax.validation.constraints.NotNull;
|
|||
import org.eclipse.che.api.core.rest.shared.dto.ServiceError;
|
||||
import org.eclipse.che.api.git.shared.Branch;
|
||||
import org.eclipse.che.api.git.shared.BranchListMode;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.ide.api.auth.Credentials;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.api.notification.NotificationManager;
|
||||
import org.eclipse.che.ide.api.notification.StatusNotification;
|
||||
import org.eclipse.che.ide.api.resources.Project;
|
||||
import org.eclipse.che.ide.dto.DtoFactory;
|
||||
import org.eclipse.che.ide.ext.git.client.BranchSearcher;
|
||||
import org.eclipse.che.ide.ext.git.client.GitAuthActionPresenter;
|
||||
import org.eclipse.che.ide.ext.git.client.GitLocalizationConstant;
|
||||
import org.eclipse.che.ide.ext.git.client.GitServiceClient;
|
||||
import org.eclipse.che.ide.ext.git.client.outputconsole.GitOutputConsole;
|
||||
|
|
@ -45,18 +48,15 @@ import org.eclipse.che.ide.processes.panel.ProcessesPanelPresenter;
|
|||
* @author Vlad Zhukovskyi
|
||||
*/
|
||||
@Singleton
|
||||
public class FetchPresenter implements FetchView.ActionDelegate {
|
||||
public class FetchPresenter extends GitAuthActionPresenter implements FetchView.ActionDelegate {
|
||||
public static final String FETCH_COMMAND_NAME = "Git fetch";
|
||||
|
||||
private final DtoFactory dtoFactory;
|
||||
private final NotificationManager notificationManager;
|
||||
private final BranchSearcher branchSearcher;
|
||||
private final GitOutputConsoleFactory gitOutputConsoleFactory;
|
||||
private final ProcessesPanelPresenter processesPanelPresenter;
|
||||
private final FetchView view;
|
||||
private final GitServiceClient service;
|
||||
private final AppContext appContext;
|
||||
private final GitLocalizationConstant constant;
|
||||
|
||||
private Project project;
|
||||
|
||||
|
|
@ -65,12 +65,13 @@ public class FetchPresenter implements FetchView.ActionDelegate {
|
|||
DtoFactory dtoFactory,
|
||||
FetchView view,
|
||||
GitServiceClient service,
|
||||
AppContext appContext,
|
||||
GitLocalizationConstant constant,
|
||||
NotificationManager notificationManager,
|
||||
BranchSearcher branchSearcher,
|
||||
GitOutputConsoleFactory gitOutputConsoleFactory,
|
||||
ProcessesPanelPresenter processesPanelPresenter) {
|
||||
ProcessesPanelPresenter processesPanelPresenter,
|
||||
OAuthServiceClient oauthServiceClient) {
|
||||
super(notificationManager, constant, oauthServiceClient);
|
||||
this.dtoFactory = dtoFactory;
|
||||
this.view = view;
|
||||
this.branchSearcher = branchSearcher;
|
||||
|
|
@ -78,8 +79,6 @@ public class FetchPresenter implements FetchView.ActionDelegate {
|
|||
this.processesPanelPresenter = processesPanelPresenter;
|
||||
this.view.setDelegate(this);
|
||||
this.service = service;
|
||||
this.appContext = appContext;
|
||||
this.constant = constant;
|
||||
this.notificationManager = notificationManager;
|
||||
}
|
||||
|
||||
|
|
@ -108,9 +107,9 @@ public class FetchPresenter implements FetchView.ActionDelegate {
|
|||
.catchError(
|
||||
error -> {
|
||||
GitOutputConsole console = gitOutputConsoleFactory.create(FETCH_COMMAND_NAME);
|
||||
console.printError(constant.remoteListFailed());
|
||||
console.printError(locale.remoteListFailed());
|
||||
processesPanelPresenter.addCommandOutput(console);
|
||||
notificationManager.notify(constant.remoteListFailed(), FAIL, FLOAT_MODE);
|
||||
notificationManager.notify(locale.remoteListFailed(), FAIL, FLOAT_MODE);
|
||||
view.setEnableFetchButton(false);
|
||||
});
|
||||
}
|
||||
|
|
@ -142,11 +141,11 @@ public class FetchPresenter implements FetchView.ActionDelegate {
|
|||
.catchError(
|
||||
error -> {
|
||||
final String errorMessage =
|
||||
error.getMessage() != null ? error.getMessage() : constant.branchesListFailed();
|
||||
error.getMessage() != null ? error.getMessage() : locale.branchesListFailed();
|
||||
GitOutputConsole console = gitOutputConsoleFactory.create(FETCH_COMMAND_NAME);
|
||||
console.printError(errorMessage);
|
||||
processesPanelPresenter.addCommandOutput(console);
|
||||
notificationManager.notify(constant.branchesListFailed(), FAIL, FLOAT_MODE);
|
||||
notificationManager.notify(locale.branchesListFailed(), FAIL, FLOAT_MODE);
|
||||
view.setEnableFetchButton(false);
|
||||
});
|
||||
}
|
||||
|
|
@ -157,18 +156,27 @@ public class FetchPresenter implements FetchView.ActionDelegate {
|
|||
final String remoteUrl = view.getRepositoryUrl();
|
||||
|
||||
final StatusNotification notification =
|
||||
notificationManager.notify(constant.fetchProcess(), PROGRESS, FLOAT_MODE);
|
||||
notificationManager.notify(locale.fetchProcess(), PROGRESS, FLOAT_MODE);
|
||||
final GitOutputConsole console = gitOutputConsoleFactory.create(FETCH_COMMAND_NAME);
|
||||
|
||||
service
|
||||
.fetch(
|
||||
project.getLocation(), view.getRepositoryName(), getRefs(), view.isRemoveDeletedRefs())
|
||||
performOperationWithTokenRequestIfNeeded(
|
||||
new RemoteGitOperation<Void>() {
|
||||
@Override
|
||||
public Promise<Void> perform(Credentials credentials) {
|
||||
return service.fetch(
|
||||
project.getLocation(),
|
||||
view.getRepositoryName(),
|
||||
getRefs(),
|
||||
view.isRemoveDeletedRefs(),
|
||||
credentials);
|
||||
}
|
||||
})
|
||||
.then(
|
||||
ignored -> {
|
||||
console.print(constant.fetchSuccess(remoteUrl));
|
||||
console.print(locale.fetchSuccess(remoteUrl));
|
||||
processesPanelPresenter.addCommandOutput(console);
|
||||
notification.setStatus(SUCCESS);
|
||||
notification.setTitle(constant.fetchSuccess(remoteUrl));
|
||||
notification.setTitle(locale.fetchSuccess(remoteUrl));
|
||||
})
|
||||
.catchError(
|
||||
error -> {
|
||||
|
|
@ -208,16 +216,16 @@ public class FetchPresenter implements FetchView.ActionDelegate {
|
|||
String errorMessage = throwable.getMessage();
|
||||
notification.setStatus(FAIL);
|
||||
if (errorMessage == null) {
|
||||
console.printError(constant.fetchFail(remoteUrl));
|
||||
notification.setTitle(constant.fetchFail(remoteUrl));
|
||||
console.printError(locale.fetchFail(remoteUrl));
|
||||
notification.setTitle(locale.fetchFail(remoteUrl));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
errorMessage = dtoFactory.createDtoFromJson(errorMessage, ServiceError.class).getMessage();
|
||||
if (errorMessage.equals("Unable get private ssh key")) {
|
||||
console.printError(constant.messagesUnableGetSshKey());
|
||||
notification.setTitle(constant.messagesUnableGetSshKey());
|
||||
console.printError(locale.messagesUnableGetSshKey());
|
||||
notification.setTitle(locale.messagesUnableGetSshKey());
|
||||
return;
|
||||
}
|
||||
console.printError(errorMessage);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
*/
|
||||
package org.eclipse.che.ide.ext.git.client.pull;
|
||||
|
||||
import static org.eclipse.che.api.core.ErrorCodes.MERGE_CONFLICT;
|
||||
import static org.eclipse.che.api.git.shared.BranchListMode.LIST_LOCAL;
|
||||
import static org.eclipse.che.api.git.shared.BranchListMode.LIST_REMOTE;
|
||||
import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.FLOAT_MODE;
|
||||
|
|
@ -26,13 +27,17 @@ import javax.validation.constraints.NotNull;
|
|||
import org.eclipse.che.api.core.ErrorCodes;
|
||||
import org.eclipse.che.api.git.shared.Branch;
|
||||
import org.eclipse.che.api.git.shared.BranchListMode;
|
||||
import org.eclipse.che.api.git.shared.PullResponse;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.auth.Credentials;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.api.notification.Notification;
|
||||
import org.eclipse.che.ide.api.notification.NotificationManager;
|
||||
import org.eclipse.che.ide.api.notification.StatusNotification;
|
||||
import org.eclipse.che.ide.api.resources.Project;
|
||||
import org.eclipse.che.ide.ext.git.client.BranchSearcher;
|
||||
import org.eclipse.che.ide.ext.git.client.GitAuthActionPresenter;
|
||||
import org.eclipse.che.ide.ext.git.client.GitLocalizationConstant;
|
||||
import org.eclipse.che.ide.ext.git.client.GitServiceClient;
|
||||
import org.eclipse.che.ide.ext.git.client.outputconsole.GitOutputConsole;
|
||||
|
|
@ -47,16 +52,13 @@ import org.eclipse.che.ide.ui.dialogs.DialogFactory;
|
|||
* @author Vlad Zhukovskyi
|
||||
*/
|
||||
@Singleton
|
||||
public class PullPresenter implements PullView.ActionDelegate {
|
||||
public class PullPresenter extends GitAuthActionPresenter implements PullView.ActionDelegate {
|
||||
public static final String PULL_COMMAND_NAME = "Git pull";
|
||||
|
||||
private static final String GREEN_COLOR = "lightgreen";
|
||||
|
||||
private final PullView view;
|
||||
private final GitServiceClient service;
|
||||
private final GitLocalizationConstant constant;
|
||||
private final AppContext appContext;
|
||||
private final NotificationManager notificationManager;
|
||||
private final DialogFactory dialogFactory;
|
||||
private final BranchSearcher branchSearcher;
|
||||
private final GitOutputConsoleFactory gitOutputConsoleFactory;
|
||||
|
|
@ -68,13 +70,14 @@ public class PullPresenter implements PullView.ActionDelegate {
|
|||
public PullPresenter(
|
||||
PullView view,
|
||||
GitServiceClient service,
|
||||
AppContext appContext,
|
||||
GitLocalizationConstant constant,
|
||||
NotificationManager notificationManager,
|
||||
DialogFactory dialogFactory,
|
||||
BranchSearcher branchSearcher,
|
||||
GitOutputConsoleFactory gitOutputConsoleFactory,
|
||||
ProcessesPanelPresenter processesPanelPresenter) {
|
||||
ProcessesPanelPresenter processesPanelPresenter,
|
||||
OAuthServiceClient oauthServiceClient) {
|
||||
super(notificationManager, constant, oauthServiceClient);
|
||||
this.view = view;
|
||||
this.dialogFactory = dialogFactory;
|
||||
this.branchSearcher = branchSearcher;
|
||||
|
|
@ -82,8 +85,6 @@ public class PullPresenter implements PullView.ActionDelegate {
|
|||
this.consolesPanelPresenter = processesPanelPresenter;
|
||||
this.view.setDelegate(this);
|
||||
this.service = service;
|
||||
this.constant = constant;
|
||||
this.appContext = appContext;
|
||||
this.notificationManager = notificationManager;
|
||||
}
|
||||
|
||||
|
|
@ -145,29 +146,39 @@ public class PullPresenter implements PullView.ActionDelegate {
|
|||
view.close();
|
||||
|
||||
final StatusNotification notification =
|
||||
notificationManager.notify(constant.pullProcess(), PROGRESS, FLOAT_MODE);
|
||||
notificationManager.notify(locale.pullProcess(), PROGRESS, FLOAT_MODE);
|
||||
GitOutputConsole console = gitOutputConsoleFactory.create(PULL_COMMAND_NAME);
|
||||
|
||||
service
|
||||
.pull(project.getLocation(), getRefs(), view.getRepositoryName(), view.getRebase())
|
||||
performOperationWithTokenRequestIfNeeded(
|
||||
new RemoteGitOperation<PullResponse>() {
|
||||
@Override
|
||||
public Promise<PullResponse> perform(Credentials credentials) {
|
||||
return service.pull(
|
||||
project.getLocation(),
|
||||
getRefs(),
|
||||
view.getRepositoryName(),
|
||||
view.getRebase(),
|
||||
credentials);
|
||||
}
|
||||
})
|
||||
.then(
|
||||
response -> {
|
||||
GitOutputConsole console = gitOutputConsoleFactory.create(PULL_COMMAND_NAME);
|
||||
console.print(response.getCommandOutput(), GREEN_COLOR);
|
||||
consolesPanelPresenter.addCommandOutput(console);
|
||||
notification.setStatus(SUCCESS);
|
||||
if (response.getCommandOutput().contains("Already up-to-date")) {
|
||||
notification.setTitle(constant.pullUpToDate());
|
||||
notification.setTitle(locale.pullUpToDate());
|
||||
} else {
|
||||
project.synchronize();
|
||||
notification.setTitle(constant.pullSuccess(view.getRepositoryUrl()));
|
||||
notification.setTitle(locale.pullSuccess(view.getRepositoryUrl()));
|
||||
}
|
||||
})
|
||||
.catchError(
|
||||
error -> {
|
||||
notification.setStatus(FAIL);
|
||||
if (getErrorCode(error.getCause()) == ErrorCodes.MERGE_CONFLICT) {
|
||||
if (getErrorCode(error.getCause()) == MERGE_CONFLICT) {
|
||||
project.synchronize();
|
||||
}
|
||||
notification.setStatus(FAIL);
|
||||
handleError(error.getCause(), PULL_COMMAND_NAME, notification);
|
||||
});
|
||||
}
|
||||
|
|
@ -205,12 +216,12 @@ public class PullPresenter implements PullView.ActionDelegate {
|
|||
int errorCode = getErrorCode(exception);
|
||||
if (errorCode == ErrorCodes.NO_COMMITTER_NAME_OR_EMAIL_DEFINED) {
|
||||
dialogFactory
|
||||
.createMessageDialog(constant.pullTitle(), constant.committerIdentityInfoEmpty(), null)
|
||||
.createMessageDialog(locale.pullTitle(), locale.committerIdentityInfoEmpty(), null)
|
||||
.show();
|
||||
return;
|
||||
} else if (errorCode == ErrorCodes.UNABLE_GET_PRIVATE_SSH_KEY) {
|
||||
dialogFactory
|
||||
.createMessageDialog(constant.pullTitle(), constant.messagesUnableGetSshKey(), null)
|
||||
.createMessageDialog(locale.pullTitle(), locale.messagesUnableGetSshKey(), null)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
|
|
@ -219,13 +230,13 @@ public class PullPresenter implements PullView.ActionDelegate {
|
|||
if (errorMessage == null) {
|
||||
switch (commandName) {
|
||||
case REMOTE_REPO_COMMAND_NAME:
|
||||
errorMessage = constant.remoteListFailed();
|
||||
errorMessage = locale.remoteListFailed();
|
||||
break;
|
||||
case BRANCH_LIST_COMMAND_NAME:
|
||||
errorMessage = constant.branchesListFailed();
|
||||
errorMessage = locale.branchesListFailed();
|
||||
break;
|
||||
case PULL_COMMAND_NAME:
|
||||
errorMessage = constant.pullFail(view.getRepositoryUrl());
|
||||
errorMessage = locale.pullFail(view.getRepositoryUrl());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,10 @@ import javax.validation.constraints.NotNull;
|
|||
import org.eclipse.che.api.core.rest.shared.dto.ServiceError;
|
||||
import org.eclipse.che.api.git.shared.Branch;
|
||||
import org.eclipse.che.api.git.shared.BranchListMode;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.api.git.shared.PushResponse;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.ide.api.auth.Credentials;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.api.notification.NotificationManager;
|
||||
import org.eclipse.che.ide.api.notification.StatusNotification;
|
||||
import org.eclipse.che.ide.api.resources.Project;
|
||||
|
|
@ -37,6 +40,7 @@ import org.eclipse.che.ide.commons.exception.UnauthorizedException;
|
|||
import org.eclipse.che.ide.dto.DtoFactory;
|
||||
import org.eclipse.che.ide.ext.git.client.BranchFilterByRemote;
|
||||
import org.eclipse.che.ide.ext.git.client.BranchSearcher;
|
||||
import org.eclipse.che.ide.ext.git.client.GitAuthActionPresenter;
|
||||
import org.eclipse.che.ide.ext.git.client.GitLocalizationConstant;
|
||||
import org.eclipse.che.ide.ext.git.client.GitServiceClient;
|
||||
import org.eclipse.che.ide.ext.git.client.outputconsole.GitOutputConsole;
|
||||
|
|
@ -51,7 +55,8 @@ import org.eclipse.che.ide.processes.panel.ProcessesPanelPresenter;
|
|||
* @author Vlad Zhukovskyi
|
||||
*/
|
||||
@Singleton
|
||||
public class PushToRemotePresenter implements PushToRemoteView.ActionDelegate {
|
||||
public class PushToRemotePresenter extends GitAuthActionPresenter
|
||||
implements PushToRemoteView.ActionDelegate {
|
||||
public static final String PUSH_COMMAND_NAME = "Git push";
|
||||
public static final String CONFIG_COMMAND_NAME = "Git config";
|
||||
|
||||
|
|
@ -61,9 +66,6 @@ public class PushToRemotePresenter implements PushToRemoteView.ActionDelegate {
|
|||
private final BranchSearcher branchSearcher;
|
||||
private final PushToRemoteView view;
|
||||
private final GitServiceClient service;
|
||||
private final AppContext appContext;
|
||||
private final GitLocalizationConstant constant;
|
||||
private final NotificationManager notificationManager;
|
||||
private Project project;
|
||||
|
||||
@Inject
|
||||
|
|
@ -71,19 +73,19 @@ public class PushToRemotePresenter implements PushToRemoteView.ActionDelegate {
|
|||
DtoFactory dtoFactory,
|
||||
PushToRemoteView view,
|
||||
GitServiceClient service,
|
||||
AppContext appContext,
|
||||
GitLocalizationConstant constant,
|
||||
NotificationManager notificationManager,
|
||||
BranchSearcher branchSearcher,
|
||||
GitOutputConsoleFactory gitOutputConsoleFactory,
|
||||
ProcessesPanelPresenter processesPanelPresenter) {
|
||||
ProcessesPanelPresenter processesPanelPresenter,
|
||||
OAuthServiceClient oAuthServiceClient) {
|
||||
super(notificationManager, constant, oAuthServiceClient);
|
||||
this.dtoFactory = dtoFactory;
|
||||
this.branchSearcher = branchSearcher;
|
||||
this.view = view;
|
||||
this.oAuthServiceClient = oAuthServiceClient;
|
||||
this.view.setDelegate(this);
|
||||
this.service = service;
|
||||
this.appContext = appContext;
|
||||
this.constant = constant;
|
||||
this.notificationManager = notificationManager;
|
||||
this.gitOutputConsoleFactory = gitOutputConsoleFactory;
|
||||
this.processesPanelPresenter = processesPanelPresenter;
|
||||
|
|
@ -113,11 +115,11 @@ public class PushToRemotePresenter implements PushToRemoteView.ActionDelegate {
|
|||
.catchError(
|
||||
error -> {
|
||||
String errorMessage =
|
||||
error.getMessage() != null ? error.getMessage() : constant.remoteListFailed();
|
||||
error.getMessage() != null ? error.getMessage() : locale.remoteListFailed();
|
||||
GitOutputConsole console = gitOutputConsoleFactory.create(REMOTE_REPO_COMMAND_NAME);
|
||||
console.printError(errorMessage);
|
||||
processesPanelPresenter.addCommandOutput(console);
|
||||
notificationManager.notify(constant.remoteListFailed(), FAIL, FLOAT_MODE);
|
||||
notificationManager.notify(locale.remoteListFailed(), FAIL, FLOAT_MODE);
|
||||
view.setEnablePushButton(false);
|
||||
});
|
||||
}
|
||||
|
|
@ -149,11 +151,11 @@ public class PushToRemotePresenter implements PushToRemoteView.ActionDelegate {
|
|||
String errorMessage =
|
||||
exception.getMessage() != null
|
||||
? exception.getMessage()
|
||||
: constant.localBranchesListFailed();
|
||||
: locale.localBranchesListFailed();
|
||||
GitOutputConsole console = gitOutputConsoleFactory.create(BRANCH_LIST_COMMAND_NAME);
|
||||
console.printError(errorMessage);
|
||||
processesPanelPresenter.addCommandOutput(console);
|
||||
notificationManager.notify(constant.localBranchesListFailed(), FAIL, FLOAT_MODE);
|
||||
notificationManager.notify(locale.localBranchesListFailed(), FAIL, FLOAT_MODE);
|
||||
view.setEnablePushButton(false);
|
||||
}
|
||||
});
|
||||
|
|
@ -207,9 +209,9 @@ public class PushToRemotePresenter implements PushToRemoteView.ActionDelegate {
|
|||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
GitOutputConsole console = gitOutputConsoleFactory.create(CONFIG_COMMAND_NAME);
|
||||
console.printError(constant.failedGettingConfig());
|
||||
console.printError(locale.failedGettingConfig());
|
||||
processesPanelPresenter.addCommandOutput(console);
|
||||
notificationManager.notify(constant.failedGettingConfig(), FAIL, FLOAT_MODE);
|
||||
notificationManager.notify(locale.failedGettingConfig(), FAIL, FLOAT_MODE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -219,11 +221,11 @@ public class PushToRemotePresenter implements PushToRemoteView.ActionDelegate {
|
|||
String errorMessage =
|
||||
exception.getMessage() != null
|
||||
? exception.getMessage()
|
||||
: constant.remoteBranchesListFailed();
|
||||
: locale.remoteBranchesListFailed();
|
||||
GitOutputConsole console = gitOutputConsoleFactory.create(BRANCH_LIST_COMMAND_NAME);
|
||||
console.printError(errorMessage);
|
||||
processesPanelPresenter.addCommandOutput(console);
|
||||
notificationManager.notify(constant.remoteBranchesListFailed(), FAIL, FLOAT_MODE);
|
||||
notificationManager.notify(locale.remoteBranchesListFailed(), FAIL, FLOAT_MODE);
|
||||
view.setEnablePushButton(false);
|
||||
}
|
||||
});
|
||||
|
|
@ -287,21 +289,32 @@ public class PushToRemotePresenter implements PushToRemoteView.ActionDelegate {
|
|||
@Override
|
||||
public void onPushClicked() {
|
||||
final StatusNotification notification =
|
||||
notificationManager.notify(constant.pushProcess(), PROGRESS, FLOAT_MODE);
|
||||
notificationManager.notify(locale.pushProcess(), PROGRESS, FLOAT_MODE);
|
||||
|
||||
final String repository = view.getRepository();
|
||||
final GitOutputConsole console = gitOutputConsoleFactory.create(PUSH_COMMAND_NAME);
|
||||
service
|
||||
.push(project.getLocation(), getRefs(), repository, view.isForcePushSelected())
|
||||
|
||||
performOperationWithTokenRequestIfNeeded(
|
||||
new RemoteGitOperation<PushResponse>() {
|
||||
@Override
|
||||
public Promise<PushResponse> perform(Credentials credentials) {
|
||||
return service.push(
|
||||
project.getLocation(),
|
||||
getRefs(),
|
||||
repository,
|
||||
view.isForcePushSelected(),
|
||||
credentials);
|
||||
}
|
||||
})
|
||||
.then(
|
||||
response -> {
|
||||
console.print(response.getCommandOutput());
|
||||
processesPanelPresenter.addCommandOutput(console);
|
||||
notification.setStatus(SUCCESS);
|
||||
if (response.getCommandOutput().contains("Everything up-to-date")) {
|
||||
notification.setTitle(constant.pushUpToDate());
|
||||
notification.setTitle(locale.pushUpToDate());
|
||||
} else {
|
||||
notification.setTitle(constant.pushSuccess(repository));
|
||||
notification.setTitle(locale.pushSuccess(repository));
|
||||
}
|
||||
})
|
||||
.catchError(
|
||||
|
|
@ -347,25 +360,25 @@ public class PushToRemotePresenter implements PushToRemoteView.ActionDelegate {
|
|||
@NotNull Throwable throwable, StatusNotification notification, GitOutputConsole console) {
|
||||
notification.setStatus(FAIL);
|
||||
if (throwable instanceof UnauthorizedException) {
|
||||
console.printError(constant.messagesNotAuthorizedTitle());
|
||||
console.print(constant.messagesNotAuthorizedContent());
|
||||
notification.setTitle(constant.messagesNotAuthorizedTitle());
|
||||
notification.setContent(constant.messagesNotAuthorizedContent());
|
||||
console.printError(locale.messagesNotAuthorizedTitle());
|
||||
console.print(locale.messagesNotAuthorizedContent());
|
||||
notification.setTitle(locale.messagesNotAuthorizedTitle());
|
||||
notification.setContent(locale.messagesNotAuthorizedContent());
|
||||
return;
|
||||
}
|
||||
|
||||
String errorMessage = throwable.getMessage();
|
||||
if (errorMessage == null) {
|
||||
console.printError(constant.pushFail());
|
||||
notification.setTitle(constant.pushFail());
|
||||
console.printError(locale.pushFail());
|
||||
notification.setTitle(locale.pushFail());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
errorMessage = dtoFactory.createDtoFromJson(errorMessage, ServiceError.class).getMessage();
|
||||
if (errorMessage.equals("Unable get private ssh key")) {
|
||||
console.printError(constant.messagesUnableGetSshKey());
|
||||
notification.setTitle(constant.messagesUnableGetSshKey());
|
||||
console.printError(locale.messagesUnableGetSshKey());
|
||||
notification.setTitle(locale.messagesUnableGetSshKey());
|
||||
return;
|
||||
}
|
||||
console.printError(errorMessage);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import org.eclipse.che.api.git.shared.Revision;
|
|||
import org.eclipse.che.api.git.shared.Status;
|
||||
import org.eclipse.che.api.promises.client.Operation;
|
||||
import org.eclipse.che.api.promises.client.PromiseError;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.api.resources.Project;
|
||||
import org.eclipse.che.ide.api.resources.Resource;
|
||||
import org.eclipse.che.ide.commons.exception.ServerException;
|
||||
|
|
@ -61,6 +62,7 @@ public class CommitPresenterTest extends BaseTest {
|
|||
@Mock private CommitView view;
|
||||
@Mock private DateTimeFormatter dateTimeFormatter;
|
||||
@Mock private SelectableChangesPanelPresenter selectableChangesPanelPresenter;
|
||||
@Mock private OAuthServiceClient oAuthServiceClient;
|
||||
|
||||
private CommitPresenter presenter;
|
||||
|
||||
|
|
@ -80,7 +82,8 @@ public class CommitPresenterTest extends BaseTest {
|
|||
appContext,
|
||||
dateTimeFormatter,
|
||||
gitOutputConsoleFactory,
|
||||
processesPanelPresenter));
|
||||
processesPanelPresenter,
|
||||
oAuthServiceClient));
|
||||
|
||||
when(view.getCommitMessage()).thenReturn(EMPTY_TEXT);
|
||||
|
||||
|
|
@ -116,7 +119,7 @@ public class CommitPresenterTest extends BaseTest {
|
|||
.thenReturn(stringPromise);
|
||||
when(service.branchList(any(Path.class), any(BranchListMode.class)))
|
||||
.thenReturn(branchListPromise);
|
||||
when(service.push(any(Path.class), anyList(), anyString(), anyBoolean()))
|
||||
when(service.push(any(Path.class), anyList(), anyString(), anyBoolean(), null))
|
||||
.thenReturn(pushPromise);
|
||||
when(service.log(any(Path.class), eq(null), anyInt(), anyInt(), anyBoolean()))
|
||||
.thenReturn(logPromise);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import java.util.List;
|
|||
import org.eclipse.che.api.git.shared.Branch;
|
||||
import org.eclipse.che.api.git.shared.Remote;
|
||||
import org.eclipse.che.api.promises.client.Operation;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.ext.git.client.BaseTest;
|
||||
import org.eclipse.che.ide.ext.git.client.BranchSearcher;
|
||||
import org.eclipse.che.ide.resource.Path;
|
||||
|
|
@ -43,6 +44,7 @@ public class FetchPresenterTest extends BaseTest {
|
|||
@Mock private FetchView view;
|
||||
@Mock private Branch branch;
|
||||
@Mock private BranchSearcher branchSearcher;
|
||||
@Mock private OAuthServiceClient oAuthServiceClient;
|
||||
|
||||
private FetchPresenter presenter;
|
||||
|
||||
|
|
@ -55,12 +57,12 @@ public class FetchPresenterTest extends BaseTest {
|
|||
dtoFactory,
|
||||
view,
|
||||
service,
|
||||
appContext,
|
||||
constant,
|
||||
notificationManager,
|
||||
branchSearcher,
|
||||
gitOutputConsoleFactory,
|
||||
processesPanelPresenter);
|
||||
processesPanelPresenter,
|
||||
oAuthServiceClient);
|
||||
|
||||
when(service.remoteList(any(Path.class), anyString(), anyBoolean()))
|
||||
.thenReturn(remoteListPromise);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@
|
|||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</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-dto</artifactId>
|
||||
|
|
|
|||
|
|
@ -30,38 +30,47 @@ import org.eclipse.che.plugin.github.shared.GitHubUser;
|
|||
* @author Oksana Vereshchaka
|
||||
* @author Kevin Pollet
|
||||
*/
|
||||
public interface GitHubClientService {
|
||||
public interface GitHubServiceClient {
|
||||
|
||||
/**
|
||||
* Get given repository information.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param user the owner of the repository.
|
||||
* @param repository the repository name.
|
||||
*/
|
||||
Promise<GitHubRepository> getRepository(String user, String repository);
|
||||
Promise<GitHubRepository> getRepository(String oauthToken, String user, String repository);
|
||||
|
||||
/** Get list of available public and private repositories of the authorized user. */
|
||||
Promise<List<GitHubRepository>> getRepositoriesList();
|
||||
/**
|
||||
* Get list of available public and private repositories of the authorized user.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
*/
|
||||
Promise<List<GitHubRepository>> getRepositoriesList(String oauthToken);
|
||||
|
||||
/**
|
||||
* Get list of forks for given repository
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param user the owner of the repository.
|
||||
* @param repository the repository name.
|
||||
*/
|
||||
Promise<GitHubRepositoryList> getForks(String user, String repository);
|
||||
Promise<GitHubRepositoryList> getForks(
|
||||
@NotNull String oauthToken, String user, String repository);
|
||||
|
||||
/**
|
||||
* Fork the given repository for the authorized user.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param user the owner of the repository to fork.
|
||||
* @param repository the repository name.
|
||||
*/
|
||||
Promise<GitHubRepository> fork(String user, String repository);
|
||||
Promise<GitHubRepository> fork(@NotNull String oauthToken, String user, String repository);
|
||||
|
||||
/**
|
||||
* Add a comment to the issue on the given repository.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param user the owner of the repository.
|
||||
* @param repository the repository name.
|
||||
* @param issue the issue number.
|
||||
|
|
@ -69,6 +78,7 @@ public interface GitHubClientService {
|
|||
* @param callback callback called when operation is done.
|
||||
*/
|
||||
void commentIssue(
|
||||
@NotNull String oauthToken,
|
||||
@NotNull String user,
|
||||
@NotNull String repository,
|
||||
@NotNull String issue,
|
||||
|
|
@ -78,23 +88,28 @@ public interface GitHubClientService {
|
|||
/**
|
||||
* Get pull requests for given repository.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param owner the repository owner.
|
||||
* @param repository the repository name.
|
||||
*/
|
||||
Promise<GitHubPullRequestList> getPullRequests(@NotNull String owner, @NotNull String repository);
|
||||
Promise<GitHubPullRequestList> getPullRequests(
|
||||
@NotNull String oauthToken, @NotNull String owner, @NotNull String repository);
|
||||
|
||||
/**
|
||||
* Get pull requests for given repository.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param owner the repository owner.
|
||||
* @param repository the repository name.
|
||||
* @param head user and branch name in the format of user:ref-name
|
||||
*/
|
||||
Promise<GitHubPullRequestList> getPullRequests(String owner, String repository, String head);
|
||||
Promise<GitHubPullRequestList> getPullRequests(
|
||||
@NotNull String oauthToken, String owner, String repository, String head);
|
||||
|
||||
/**
|
||||
* Get a pull request by id for a given repository.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param owner the owner of the target repository
|
||||
* @param repository the target repository
|
||||
* @param pullRequestId the Id of the pull request
|
||||
|
|
@ -102,6 +117,7 @@ public interface GitHubClientService {
|
|||
* exist
|
||||
*/
|
||||
void getPullRequest(
|
||||
@NotNull String oauthToken,
|
||||
@NotNull String owner,
|
||||
@NotNull String repository,
|
||||
@NotNull String pullRequestId,
|
||||
|
|
@ -110,11 +126,13 @@ public interface GitHubClientService {
|
|||
/**
|
||||
* Create a pull request on origin repository
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param user the owner of the repository.
|
||||
* @param repository the repository name.
|
||||
* @param input the pull request information.
|
||||
*/
|
||||
Promise<GitHubPullRequest> createPullRequest(
|
||||
@NotNull String oauthToken,
|
||||
@NotNull String user,
|
||||
@NotNull String repository,
|
||||
@NotNull GitHubPullRequestCreationInput input);
|
||||
|
|
@ -122,59 +140,80 @@ public interface GitHubClientService {
|
|||
/**
|
||||
* Get the list of available public repositories for a GitHub user.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param userName the name of GitHub User
|
||||
* @param callback callback called when operation is done.
|
||||
*/
|
||||
void getRepositoriesByUser(
|
||||
String userName, @NotNull AsyncRequestCallback<GitHubRepositoryList> callback);
|
||||
@NotNull String oauthToken,
|
||||
String userName,
|
||||
@NotNull AsyncRequestCallback<GitHubRepositoryList> callback);
|
||||
|
||||
/**
|
||||
* Get the list of available repositories by GitHub organization.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param organization the name of GitHub organization.
|
||||
* @param callback callback called when operation is done.
|
||||
*/
|
||||
void getRepositoriesByOrganization(
|
||||
String organization, @NotNull AsyncRequestCallback<GitHubRepositoryList> callback);
|
||||
@NotNull String oauthToken,
|
||||
String organization,
|
||||
@NotNull AsyncRequestCallback<GitHubRepositoryList> callback);
|
||||
|
||||
/**
|
||||
* Get list of available public repositories for GitHub account.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param account the GitHub account.
|
||||
* @param callback callback called when operation is done.
|
||||
*/
|
||||
void getRepositoriesByAccount(
|
||||
String account, @NotNull AsyncRequestCallback<GitHubRepositoryList> callback);
|
||||
@NotNull String oauthToken,
|
||||
String account,
|
||||
@NotNull AsyncRequestCallback<GitHubRepositoryList> callback);
|
||||
|
||||
/**
|
||||
* Get list of collaborators of GitHub repository. For detail see GitHub REST API
|
||||
* http://developer.github.com/v3/repos/collaborators/.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param user the owner of the repository.
|
||||
* @param repository the repository name.
|
||||
* @param callback callback called when operation is done.
|
||||
*/
|
||||
void getCollaborators(
|
||||
@NotNull String oauthToken,
|
||||
@NotNull String user,
|
||||
@NotNull String repository,
|
||||
@NotNull AsyncRequestCallback<Collaborators> callback);
|
||||
|
||||
/** Get the list of the organizations, where authorized user is a member. */
|
||||
Promise<List<GitHubUser>> getOrganizations();
|
||||
/**
|
||||
* Get the list of the organizations, where authorized user is a member.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
*/
|
||||
Promise<List<GitHubUser>> getOrganizations(@NotNull String oauthToken);
|
||||
|
||||
/** Get authorized user information. */
|
||||
Promise<GitHubUser> getUserInfo();
|
||||
/**
|
||||
* Get authorized user information.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
*/
|
||||
Promise<GitHubUser> getUserInfo(@NotNull String oauthToken);
|
||||
|
||||
/**
|
||||
* Generate and upload new public key if not exist on github.com.
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param callback callback called when operation is done.
|
||||
*/
|
||||
void updatePublicKey(@NotNull AsyncRequestCallback<Void> callback);
|
||||
void updatePublicKey(@NotNull String oauthToken, @NotNull AsyncRequestCallback<Void> callback);
|
||||
|
||||
/**
|
||||
* Updates github pull request
|
||||
*
|
||||
* @param oauthToken Github OAuth authorization token
|
||||
* @param user repository owner
|
||||
* @param repository name of repository
|
||||
* @param pullRequestId pull request identifier
|
||||
|
|
@ -182,5 +221,9 @@ public interface GitHubClientService {
|
|||
* @return updated pull request
|
||||
*/
|
||||
Promise<GitHubPullRequest> updatePullRequest(
|
||||
String user, String repository, String pullRequestId, GitHubPullRequest pullRequest);
|
||||
@NotNull String oauthToken,
|
||||
String user,
|
||||
String repository,
|
||||
String pullRequestId,
|
||||
GitHubPullRequest pullRequest);
|
||||
}
|
||||
|
|
@ -33,13 +33,15 @@ import org.eclipse.che.plugin.github.shared.GitHubRepositoryList;
|
|||
import org.eclipse.che.plugin.github.shared.GitHubUser;
|
||||
|
||||
/**
|
||||
* Implementation for {@link GitHubClientService}.
|
||||
* Implementation for {@link GitHubServiceClient}.
|
||||
*
|
||||
* @author Oksana Vereshchaka
|
||||
* @author Stéphane Daviet
|
||||
*/
|
||||
@Singleton
|
||||
public class GitHubClientServiceImpl implements GitHubClientService {
|
||||
public class GitHubServiceClientImpl implements GitHubServiceClient {
|
||||
|
||||
private static final String TOKEN_HEADER_NAME = "X-Oauth-Token";
|
||||
private static final String LIST = "/list";
|
||||
private static final String LIST_ACCOUNT = "/list/account";
|
||||
private static final String LIST_ORG = "/list/org";
|
||||
|
|
@ -63,7 +65,7 @@ public class GitHubClientServiceImpl implements GitHubClientService {
|
|||
private final DtoUnmarshallerFactory dtoUnmarshallerFactory;
|
||||
|
||||
@Inject
|
||||
protected GitHubClientServiceImpl(
|
||||
protected GitHubServiceClientImpl(
|
||||
LoaderFactory loaderFactory,
|
||||
AsyncRequestFactory asyncRequestFactory,
|
||||
AppContext appContext,
|
||||
|
|
@ -79,89 +81,110 @@ public class GitHubClientServiceImpl implements GitHubClientService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Promise<GitHubRepository> getRepository(String user, String repository) {
|
||||
public Promise<GitHubRepository> getRepository(
|
||||
@NotNull String oauthToken, String user, String repository) {
|
||||
final String url = baseUrl() + REPOSITORIES + "/" + user + "/" + repository;
|
||||
return asyncRequestFactory
|
||||
.createGetRequest(url)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(dtoUnmarshallerFactory.newUnmarshaller(GitHubRepository.class));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public Promise<List<GitHubRepository>> getRepositoriesList() {
|
||||
public Promise<List<GitHubRepository>> getRepositoriesList(@NotNull String oauthToken) {
|
||||
String url = baseUrl() + LIST;
|
||||
return asyncRequestFactory
|
||||
.createGetRequest(url)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(dtoUnmarshallerFactory.newListUnmarshaller(GitHubRepository.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<GitHubRepositoryList> getForks(String user, String repository) {
|
||||
public Promise<GitHubRepositoryList> getForks(
|
||||
@NotNull String oauthToken, String user, String repository) {
|
||||
return asyncRequestFactory
|
||||
.createGetRequest(baseUrl() + FORKS + '/' + user + '/' + repository)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(dtoUnmarshallerFactory.newUnmarshaller(GitHubRepositoryList.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<GitHubRepository> fork(String user, String repository) {
|
||||
public Promise<GitHubRepository> fork(
|
||||
@NotNull String oauthToken, String user, String repository) {
|
||||
return asyncRequestFactory
|
||||
.createGetRequest(baseUrl() + CREATE_FORK + '/' + user + '/' + repository)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(dtoUnmarshallerFactory.newUnmarshaller(GitHubRepository.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commentIssue(
|
||||
@NotNull String oauthToken,
|
||||
@NotNull String user,
|
||||
@NotNull String repository,
|
||||
@NotNull String issue,
|
||||
@NotNull GitHubIssueCommentInput input,
|
||||
@NotNull AsyncRequestCallback<GitHubIssueComment> callback) {
|
||||
String url = baseUrl() + ISSUE_COMMENTS + "/" + user + "/" + repository + "/" + issue;
|
||||
asyncRequestFactory.createPostRequest(url, input).loader(loader).send(callback);
|
||||
asyncRequestFactory
|
||||
.createPostRequest(url, input)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<GitHubPullRequestList> getPullRequests(
|
||||
@NotNull String owner, @NotNull String repository) {
|
||||
@NotNull String oauthToken, @NotNull String owner, @NotNull String repository) {
|
||||
final String url = baseUrl() + PULL_REQUESTS + '/' + owner + '/' + repository;
|
||||
return asyncRequestFactory
|
||||
.createGetRequest(url)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(dtoUnmarshallerFactory.newUnmarshaller(GitHubPullRequestList.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<GitHubPullRequestList> getPullRequests(
|
||||
String owner, String repository, String head) {
|
||||
@NotNull String oauthToken, String owner, String repository, String head) {
|
||||
final String url = baseUrl() + PULL_REQUESTS + '/' + owner + '/' + repository + "?head=" + head;
|
||||
return asyncRequestFactory
|
||||
.createGetRequest(url)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(dtoUnmarshallerFactory.newUnmarshaller(GitHubPullRequestList.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPullRequest(
|
||||
@NotNull String oauthToken,
|
||||
final String owner,
|
||||
final String repository,
|
||||
final String pullRequestId,
|
||||
final AsyncRequestCallback<GitHubPullRequest> callback) {
|
||||
String url = baseUrl() + PULL_REQUESTS + "/" + owner + "/" + repository + "/" + pullRequestId;
|
||||
asyncRequestFactory.createGetRequest(url).loader(loader).send(callback);
|
||||
asyncRequestFactory
|
||||
.createGetRequest(url)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<GitHubPullRequest> createPullRequest(
|
||||
@NotNull String oauthToken,
|
||||
@NotNull String user,
|
||||
@NotNull String repository,
|
||||
@NotNull GitHubPullRequestCreationInput input) {
|
||||
final String url = baseUrl() + PULL_REQUEST + '/' + user + '/' + repository;
|
||||
return asyncRequestFactory
|
||||
.createPostRequest(url, input)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(dtoUnmarshallerFactory.newUnmarshaller(GitHubPullRequest.class));
|
||||
}
|
||||
|
|
@ -169,38 +192,51 @@ public class GitHubClientServiceImpl implements GitHubClientService {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void getRepositoriesByUser(
|
||||
String userName, @NotNull AsyncRequestCallback<GitHubRepositoryList> callback) {
|
||||
@NotNull String oauthToken,
|
||||
String userName,
|
||||
@NotNull AsyncRequestCallback<GitHubRepositoryList> callback) {
|
||||
String params = (userName != null) ? "?username=" + userName : "";
|
||||
String url = baseUrl() + LIST_USER;
|
||||
asyncRequestFactory.createGetRequest(url + params).loader(loader).send(callback);
|
||||
asyncRequestFactory
|
||||
.createGetRequest(url + params)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(callback);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void getCollaborators(
|
||||
@NotNull String oauthToken,
|
||||
@NotNull String user,
|
||||
@NotNull String repository,
|
||||
@NotNull AsyncRequestCallback<Collaborators> callback) {
|
||||
String url = baseUrl() + COLLABORATORS + "/" + user + "/" + repository;
|
||||
asyncRequestFactory.createGetRequest(url).loader(loader).send(callback);
|
||||
asyncRequestFactory
|
||||
.createGetRequest(url)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(callback);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public Promise<List<GitHubUser>> getOrganizations() {
|
||||
public Promise<List<GitHubUser>> getOrganizations(@NotNull String oauthToken) {
|
||||
String url = baseUrl() + ORGANIZATIONS;
|
||||
return asyncRequestFactory
|
||||
.createGetRequest(url)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(dtoUnmarshallerFactory.newListUnmarshaller(GitHubUser.class));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public Promise<GitHubUser> getUserInfo() {
|
||||
public Promise<GitHubUser> getUserInfo(@NotNull String oauthToken) {
|
||||
String url = baseUrl() + USER;
|
||||
return asyncRequestFactory
|
||||
.createGetRequest(url)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(dtoUnmarshallerFactory.newUnmarshaller(GitHubUser.class));
|
||||
}
|
||||
|
|
@ -208,35 +244,56 @@ public class GitHubClientServiceImpl implements GitHubClientService {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void getRepositoriesByOrganization(
|
||||
String organization, @NotNull AsyncRequestCallback<GitHubRepositoryList> callback) {
|
||||
@NotNull String oauthToken,
|
||||
String organization,
|
||||
@NotNull AsyncRequestCallback<GitHubRepositoryList> callback) {
|
||||
String params = (organization != null) ? "?organization=" + organization : "";
|
||||
String url = baseUrl() + LIST_ORG;
|
||||
asyncRequestFactory.createGetRequest(url + params).loader(loader).send(callback);
|
||||
asyncRequestFactory
|
||||
.createGetRequest(url + params)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(callback);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void getRepositoriesByAccount(
|
||||
String account, @NotNull AsyncRequestCallback<GitHubRepositoryList> callback) {
|
||||
@NotNull String oauthToken,
|
||||
String account,
|
||||
@NotNull AsyncRequestCallback<GitHubRepositoryList> callback) {
|
||||
String params = (account != null) ? "?account=" + account : "";
|
||||
String url = baseUrl() + LIST_ACCOUNT;
|
||||
asyncRequestFactory.createGetRequest(url + params).loader(loader).send(callback);
|
||||
asyncRequestFactory
|
||||
.createGetRequest(url + params)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(callback);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void updatePublicKey(@NotNull AsyncRequestCallback<Void> callback) {
|
||||
public void updatePublicKey(String oauthToken, @NotNull AsyncRequestCallback<Void> callback) {
|
||||
String url = baseUrl() + SSH_GEN;
|
||||
asyncRequestFactory.createPostRequest(url, null).loader(loader).send(callback);
|
||||
asyncRequestFactory
|
||||
.createPostRequest(url, null)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<GitHubPullRequest> updatePullRequest(
|
||||
String owner, String repository, String pullRequestId, GitHubPullRequest updateInput) {
|
||||
@NotNull String oauthToken,
|
||||
String owner,
|
||||
String repository,
|
||||
String pullRequestId,
|
||||
GitHubPullRequest updateInput) {
|
||||
final String url =
|
||||
baseUrl() + PULL_REQUEST + '/' + owner + '/' + repository + '/' + pullRequestId;
|
||||
return asyncRequestFactory
|
||||
.createRequest(RequestBuilder.PUT, url, updateInput, false)
|
||||
.header(TOKEN_HEADER_NAME, oauthToken)
|
||||
.loader(loader)
|
||||
.send(dtoUnmarshallerFactory.newUnmarshaller(GitHubPullRequest.class));
|
||||
}
|
||||
|
|
@ -18,13 +18,12 @@ import com.google.inject.Inject;
|
|||
import com.google.inject.Singleton;
|
||||
import org.eclipse.che.ide.api.ProductInfoDataProvider;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.api.notification.NotificationManager;
|
||||
import org.eclipse.che.ide.api.notification.StatusNotification;
|
||||
import org.eclipse.che.ide.commons.exception.UnauthorizedException;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestCallback;
|
||||
import org.eclipse.che.ide.ui.dialogs.CancelCallback;
|
||||
import org.eclipse.che.ide.ui.dialogs.DialogFactory;
|
||||
import org.eclipse.che.ide.ui.dialogs.confirm.ConfirmCallback;
|
||||
import org.eclipse.che.plugin.ssh.key.client.SshKeyUploader;
|
||||
import org.eclipse.che.security.oauth.JsOAuthWindow;
|
||||
import org.eclipse.che.security.oauth.OAuthCallback;
|
||||
|
|
@ -39,7 +38,7 @@ import org.eclipse.che.security.oauth.SecurityTokenProvider;
|
|||
@Singleton
|
||||
public class GitHubSshKeyUploader implements SshKeyUploader, OAuthCallback {
|
||||
|
||||
private final GitHubClientService gitHubService;
|
||||
private final GitHubServiceClient gitHubService;
|
||||
private final String baseUrl;
|
||||
private final GitHubLocalizationConstant constant;
|
||||
private final NotificationManager notificationManager;
|
||||
|
|
@ -47,19 +46,21 @@ public class GitHubSshKeyUploader implements SshKeyUploader, OAuthCallback {
|
|||
private final DialogFactory dialogFactory;
|
||||
private final AppContext appContext;
|
||||
private final SecurityTokenProvider securityTokenProvider;
|
||||
private final OAuthServiceClient oAuthServiceClient;
|
||||
|
||||
private AsyncCallback<Void> callback;
|
||||
private String userId;
|
||||
|
||||
@Inject
|
||||
public GitHubSshKeyUploader(
|
||||
GitHubClientService gitHubService,
|
||||
GitHubServiceClient gitHubService,
|
||||
GitHubLocalizationConstant constant,
|
||||
NotificationManager notificationManager,
|
||||
ProductInfoDataProvider productInfoDataProvider,
|
||||
DialogFactory dialogFactory,
|
||||
AppContext appContext,
|
||||
SecurityTokenProvider securityTokenProvider) {
|
||||
SecurityTokenProvider securityTokenProvider,
|
||||
OAuthServiceClient oAuthServiceClient) {
|
||||
this.gitHubService = gitHubService;
|
||||
this.baseUrl = appContext.getMasterApiEndpoint();
|
||||
this.constant = constant;
|
||||
|
|
@ -68,6 +69,7 @@ public class GitHubSshKeyUploader implements SshKeyUploader, OAuthCallback {
|
|||
this.dialogFactory = dialogFactory;
|
||||
this.appContext = appContext;
|
||||
this.securityTokenProvider = securityTokenProvider;
|
||||
this.oAuthServiceClient = oAuthServiceClient;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
|
|
@ -76,23 +78,32 @@ public class GitHubSshKeyUploader implements SshKeyUploader, OAuthCallback {
|
|||
this.callback = callback;
|
||||
this.userId = userId;
|
||||
|
||||
gitHubService.updatePublicKey(
|
||||
new AsyncRequestCallback<Void>() {
|
||||
@Override
|
||||
protected void onSuccess(Void o) {
|
||||
callback.onSuccess(o);
|
||||
}
|
||||
oAuthServiceClient
|
||||
.getToken("github")
|
||||
.then(
|
||||
result -> {
|
||||
gitHubService.updatePublicKey(
|
||||
result.getToken(),
|
||||
new AsyncRequestCallback<Void>() {
|
||||
@Override
|
||||
protected void onSuccess(Void o) {
|
||||
callback.onSuccess(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFailure(Throwable e) {
|
||||
if (e instanceof UnauthorizedException) {
|
||||
@Override
|
||||
protected void onFailure(Throwable e) {
|
||||
if (e instanceof UnauthorizedException) {
|
||||
oAuthLoginStart();
|
||||
return;
|
||||
}
|
||||
callback.onFailure(e);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catchError(
|
||||
error -> {
|
||||
oAuthLoginStart();
|
||||
return;
|
||||
}
|
||||
|
||||
callback.onFailure(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** Log in github */
|
||||
|
|
@ -101,18 +112,8 @@ public class GitHubSshKeyUploader implements SshKeyUploader, OAuthCallback {
|
|||
.createConfirmDialog(
|
||||
constant.authorizationDialogTitle(),
|
||||
constant.authorizationDialogText(productInfoDataProvider.getName()),
|
||||
new ConfirmCallback() {
|
||||
@Override
|
||||
public void accepted() {
|
||||
showPopUp();
|
||||
}
|
||||
},
|
||||
new CancelCallback() {
|
||||
@Override
|
||||
public void cancelled() {
|
||||
callback.onFailure(new Exception(constant.authorizationRequestRejected()));
|
||||
}
|
||||
})
|
||||
() -> showPopUp(),
|
||||
() -> callback.onFailure(new Exception(constant.authorizationRequestRejected())))
|
||||
.show();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class GitHubAuthenticatorImpl
|
|||
private final GitHubLocalizationConstant locale;
|
||||
private final String baseUrl;
|
||||
private final AppContext appContext;
|
||||
private final SecurityTokenProvider securityTokenPærovider;
|
||||
private final SecurityTokenProvider securityTokenProvider;
|
||||
private String authenticationUrl;
|
||||
|
||||
@Inject
|
||||
|
|
@ -68,11 +68,11 @@ public class GitHubAuthenticatorImpl
|
|||
GitHubLocalizationConstant locale,
|
||||
NotificationManager notificationManager,
|
||||
AppContext appContext,
|
||||
SecurityTokenProvider securityTokenPærovider) {
|
||||
SecurityTokenProvider securityTokenProvider) {
|
||||
this.registry = registry;
|
||||
this.sshServiceClient = sshServiceClient;
|
||||
this.view = view;
|
||||
this.securityTokenPærovider = securityTokenPærovider;
|
||||
this.securityTokenProvider = securityTokenProvider;
|
||||
this.view.setDelegate(this);
|
||||
this.locale = locale;
|
||||
this.baseUrl = appContext.getMasterApiEndpoint();
|
||||
|
|
@ -130,10 +130,10 @@ public class GitHubAuthenticatorImpl
|
|||
JsOAuthWindow authWindow;
|
||||
if (authenticationUrl == null) {
|
||||
authWindow =
|
||||
new JsOAuthWindow(getAuthUrl(), "error.url", 500, 980, this, securityTokenPærovider);
|
||||
new JsOAuthWindow(getAuthUrl(), "error.url", 500, 980, this, securityTokenProvider);
|
||||
} else {
|
||||
authWindow =
|
||||
new JsOAuthWindow(authenticationUrl, "error.url", 500, 980, this, securityTokenPærovider);
|
||||
new JsOAuthWindow(authenticationUrl, "error.url", 500, 980, this, securityTokenProvider);
|
||||
}
|
||||
authWindow.loginWithOAuth();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@
|
|||
*/
|
||||
package org.eclipse.che.plugin.github.ide.importer.page;
|
||||
|
||||
import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.FLOAT_MODE;
|
||||
import static org.eclipse.che.ide.api.notification.StatusNotification.Status.FAIL;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gwt.core.client.JsArrayMixed;
|
||||
|
|
@ -18,18 +21,16 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
|
|||
import com.google.gwt.user.client.ui.AcceptsOneWidget;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.eclipse.che.api.promises.client.Operation;
|
||||
import org.eclipse.che.api.promises.client.OperationException;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.api.promises.client.PromiseError;
|
||||
import org.eclipse.che.api.promises.client.js.Promises;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.api.notification.NotificationManager;
|
||||
import org.eclipse.che.ide.api.oauth.OAuth2Authenticator;
|
||||
import org.eclipse.che.ide.api.oauth.OAuth2AuthenticatorRegistry;
|
||||
import org.eclipse.che.ide.api.oauth.OAuth2AuthenticatorUrlProvider;
|
||||
|
|
@ -38,8 +39,8 @@ import org.eclipse.che.ide.api.wizard.AbstractWizardPage;
|
|||
import org.eclipse.che.ide.commons.exception.UnauthorizedException;
|
||||
import org.eclipse.che.ide.dto.DtoFactory;
|
||||
import org.eclipse.che.ide.util.NameUtils;
|
||||
import org.eclipse.che.plugin.github.ide.GitHubClientService;
|
||||
import org.eclipse.che.plugin.github.ide.GitHubLocalizationConstant;
|
||||
import org.eclipse.che.plugin.github.ide.GitHubServiceClient;
|
||||
import org.eclipse.che.plugin.github.ide.load.ProjectData;
|
||||
import org.eclipse.che.plugin.github.shared.GitHubRepository;
|
||||
import org.eclipse.che.plugin.github.shared.GitHubUser;
|
||||
|
|
@ -65,13 +66,15 @@ public class GithubImporterPagePresenter extends AbstractWizardPage<MutableProje
|
|||
private static final RegExp WHITE_SPACE = RegExp.compile("^\\s");
|
||||
|
||||
private final DtoFactory dtoFactory;
|
||||
private GitHubClientService gitHubClientService;
|
||||
private GitHubServiceClient gitHubClientService;
|
||||
private Map<String, List<GitHubRepository>> repositories;
|
||||
private GitHubLocalizationConstant locale;
|
||||
private GithubImporterPageView view;
|
||||
private final String baseUrl;
|
||||
private final AppContext appContext;
|
||||
private OAuth2Authenticator gitHubAuthenticator;
|
||||
private final OAuthServiceClient oAuthServiceClient;
|
||||
private final NotificationManager notificationManager;
|
||||
|
||||
private boolean ignoreChanges;
|
||||
|
||||
|
|
@ -79,16 +82,20 @@ public class GithubImporterPagePresenter extends AbstractWizardPage<MutableProje
|
|||
public GithubImporterPagePresenter(
|
||||
GithubImporterPageView view,
|
||||
OAuth2AuthenticatorRegistry gitHubAuthenticatorRegistry,
|
||||
GitHubClientService gitHubClientService,
|
||||
GitHubServiceClient gitHubClientService,
|
||||
DtoFactory dtoFactory,
|
||||
AppContext appContext,
|
||||
GitHubLocalizationConstant locale) {
|
||||
GitHubLocalizationConstant locale,
|
||||
OAuthServiceClient oAuthServiceClient,
|
||||
NotificationManager notificationManager) {
|
||||
this.view = view;
|
||||
this.baseUrl = appContext.getMasterApiEndpoint();
|
||||
this.appContext = appContext;
|
||||
this.gitHubAuthenticator = gitHubAuthenticatorRegistry.getAuthenticator("github");
|
||||
this.gitHubClientService = gitHubClientService;
|
||||
this.dtoFactory = dtoFactory;
|
||||
this.oAuthServiceClient = oAuthServiceClient;
|
||||
this.notificationManager = notificationManager;
|
||||
this.view.setDelegate(this);
|
||||
this.locale = locale;
|
||||
}
|
||||
|
|
@ -260,32 +267,16 @@ public class GithubImporterPagePresenter extends AbstractWizardPage<MutableProje
|
|||
private void getUserRepositoriesAndOrganizations() {
|
||||
showProcessing(true);
|
||||
|
||||
Promise<GitHubUser> userInfo = gitHubClientService.getUserInfo();
|
||||
Promise<List<GitHubUser>> organizations = gitHubClientService.getOrganizations();
|
||||
Promise<List<GitHubRepository>> allRepositories = gitHubClientService.getRepositoriesList();
|
||||
|
||||
doRequest(userInfo, organizations, allRepositories);
|
||||
}
|
||||
|
||||
protected void doRequest(
|
||||
Promise<GitHubUser> userInfo,
|
||||
Promise<List<GitHubUser>> organizations,
|
||||
Promise<List<GitHubRepository>> allRepositories) {
|
||||
Promises.all(userInfo, organizations, allRepositories)
|
||||
.then(
|
||||
new Operation<JsArrayMixed>() {
|
||||
@Override
|
||||
public void apply(JsArrayMixed arg) throws OperationException {
|
||||
onSuccessRequest(arg);
|
||||
}
|
||||
})
|
||||
.catchError(
|
||||
new Operation<PromiseError>() {
|
||||
@Override
|
||||
public void apply(PromiseError arg) throws OperationException {
|
||||
onFailRequest(arg);
|
||||
}
|
||||
});
|
||||
oAuthServiceClient
|
||||
.getToken(gitHubAuthenticator.getProviderName())
|
||||
.thenPromise(
|
||||
token ->
|
||||
Promises.all(
|
||||
gitHubClientService.getUserInfo(token.getToken()),
|
||||
gitHubClientService.getOrganizations(token.getToken()),
|
||||
gitHubClientService.getRepositoriesList(token.getToken())))
|
||||
.then(this::onSuccessRequest)
|
||||
.catchError(this::onFailRequest);
|
||||
}
|
||||
|
||||
protected void onSuccessRequest(JsArrayMixed arg) {
|
||||
|
|
@ -308,6 +299,8 @@ public class GithubImporterPagePresenter extends AbstractWizardPage<MutableProje
|
|||
showProcessing(false);
|
||||
if (arg.getCause() instanceof UnauthorizedException) {
|
||||
authorize();
|
||||
} else {
|
||||
notificationManager.notify(locale.authorizationFailed(), FAIL, FLOAT_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -365,7 +358,7 @@ public class GithubImporterPagePresenter extends AbstractWizardPage<MutableProje
|
|||
|
||||
Map<String, String> login2OrgName = getLogin2OrgName(gitHubOrganizations);
|
||||
for (String orgName : login2OrgName.values()) {
|
||||
repositories.put(orgName, new ArrayList<GitHubRepository>());
|
||||
repositories.put(orgName, new ArrayList<>());
|
||||
}
|
||||
|
||||
for (GitHubRepository gitHubRepository : gitHubRepositories) {
|
||||
|
|
@ -410,14 +403,7 @@ public class GithubImporterPagePresenter extends AbstractWizardPage<MutableProje
|
|||
projectsData.add(projectData);
|
||||
}
|
||||
|
||||
Collections.sort(
|
||||
projectsData,
|
||||
new Comparator<ProjectData>() {
|
||||
@Override
|
||||
public int compare(ProjectData o1, ProjectData o2) {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
});
|
||||
projectsData.sort(Comparator.comparing(ProjectData::getName));
|
||||
|
||||
view.setRepositories(projectsData);
|
||||
view.reset();
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import com.google.inject.Singleton;
|
|||
import org.eclipse.che.ide.api.extension.ExtensionGinModule;
|
||||
import org.eclipse.che.ide.api.oauth.OAuth2Authenticator;
|
||||
import org.eclipse.che.ide.api.project.wizard.ImportWizardRegistrar;
|
||||
import org.eclipse.che.plugin.github.ide.GitHubClientService;
|
||||
import org.eclipse.che.plugin.github.ide.GitHubClientServiceImpl;
|
||||
import org.eclipse.che.plugin.github.ide.GitHubServiceClient;
|
||||
import org.eclipse.che.plugin.github.ide.GitHubServiceClientImpl;
|
||||
import org.eclipse.che.plugin.github.ide.authenticator.GitHubAuthenticatorImpl;
|
||||
import org.eclipse.che.plugin.github.ide.importer.GitHubImportWizardRegistrar;
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ public class GitHubGinModule extends AbstractGinModule {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(GitHubClientService.class).to(GitHubClientServiceImpl.class).in(Singleton.class);
|
||||
bind(GitHubServiceClient.class).to(GitHubServiceClientImpl.class).in(Singleton.class);
|
||||
GinMultibinder.newSetBinder(binder(), OAuth2Authenticator.class)
|
||||
.addBinding()
|
||||
.to(GitHubAuthenticatorImpl.class);
|
||||
|
|
|
|||
|
|
@ -13,11 +13,9 @@ package org.eclipse.che.plugin.github.ide.importer.page;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyObject;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
|
|
@ -27,21 +25,18 @@ import static org.mockito.Mockito.verify;
|
|||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.gwt.core.client.JsArrayMixed;
|
||||
import com.google.gwt.http.client.Response;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.AcceptsOneWidget;
|
||||
import com.google.gwtmockito.GwtMockitoTestRunner;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.eclipse.che.api.project.shared.dto.ProjectImporterDescriptor;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.api.promises.client.PromiseError;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.app.CurrentUser;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.api.notification.NotificationManager;
|
||||
import org.eclipse.che.ide.api.oauth.OAuth2Authenticator;
|
||||
import org.eclipse.che.ide.api.oauth.OAuth2AuthenticatorRegistry;
|
||||
|
|
@ -49,12 +44,9 @@ import org.eclipse.che.ide.api.project.MutableProjectConfig;
|
|||
import org.eclipse.che.ide.api.wizard.Wizard;
|
||||
import org.eclipse.che.ide.commons.exception.UnauthorizedException;
|
||||
import org.eclipse.che.ide.dto.DtoFactory;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestCallback;
|
||||
import org.eclipse.che.ide.rest.DtoUnmarshallerFactory;
|
||||
import org.eclipse.che.plugin.github.ide.GitHubClientService;
|
||||
import org.eclipse.che.plugin.github.ide.GitHubLocalizationConstant;
|
||||
import org.eclipse.che.plugin.github.ide.GitHubServiceClient;
|
||||
import org.eclipse.che.plugin.github.ide.load.ProjectData;
|
||||
import org.eclipse.che.plugin.github.shared.GitHubRepository;
|
||||
import org.eclipse.che.plugin.github.shared.GitHubUser;
|
||||
import org.eclipse.che.security.oauth.OAuthStatus;
|
||||
import org.junit.Before;
|
||||
|
|
@ -64,8 +56,6 @@ import org.mockito.ArgumentCaptor;
|
|||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
/**
|
||||
* Testing {@link GithubImporterPagePresenter} functionality.
|
||||
|
|
@ -77,30 +67,20 @@ public class GithubImporterPagePresenterTest {
|
|||
|
||||
@Captor private ArgumentCaptor<AsyncCallback<OAuthStatus>> asyncCallbackCaptor;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<AsyncRequestCallback<Map<String, List<GitHubRepository>>>>
|
||||
asyncRequestCallbackRepoListCaptor;
|
||||
|
||||
@Mock private Wizard.UpdateDelegate updateDelegate;
|
||||
@Mock private DtoFactory dtoFactory;
|
||||
@Mock private GithubImporterPageView view;
|
||||
@Mock private GitHubClientService gitHubClientService;
|
||||
@Mock private DtoUnmarshallerFactory dtoUnmarshallerFactory;
|
||||
@Mock private NotificationManager notificationManager;
|
||||
@Mock private GitHubServiceClient gitHubClientService;
|
||||
@Mock private GitHubLocalizationConstant locale;
|
||||
@Mock private MutableProjectConfig dataObject;
|
||||
@Mock private MutableProjectConfig.MutableSourceStorage source;
|
||||
@Mock private Map<String, String> parameters;
|
||||
@Mock private Promise<GitHubUser> gitHubUserPromise;
|
||||
@Mock private Promise<List<GitHubUser>> gitHubOrgsPromise;
|
||||
@Mock private Promise<List<GitHubRepository>> gitHubReposPromise;
|
||||
@Mock private JsArrayMixed jsArrayMixed;
|
||||
@Mock private GitHubUser gitHubUser;
|
||||
@Mock private PromiseError promiseError;
|
||||
@Mock private Response response;
|
||||
@Mock private OAuth2Authenticator gitHubAuthenticator;
|
||||
@Mock private OAuth2AuthenticatorRegistry gitHubAuthenticatorRegistry;
|
||||
@Mock private AppContext appContext;
|
||||
@Mock private OAuthServiceClient oAuthServiceClient;
|
||||
@Mock private NotificationManager notificationManager;
|
||||
|
||||
private GithubImporterPagePresenter presenter;
|
||||
|
||||
|
|
@ -120,7 +100,9 @@ public class GithubImporterPagePresenterTest {
|
|||
gitHubClientService,
|
||||
dtoFactory,
|
||||
appContext,
|
||||
locale));
|
||||
locale,
|
||||
oAuthServiceClient,
|
||||
notificationManager));
|
||||
doReturn(Collections.singletonList(gitHubUser))
|
||||
.when(presenter)
|
||||
.toOrgList(nullable(JsArrayMixed.class));
|
||||
|
|
@ -151,68 +133,46 @@ public class GithubImporterPagePresenterTest {
|
|||
|
||||
@Test
|
||||
public void onLoadRepoClickedWhenGetUserReposIsSuccessful() throws Exception {
|
||||
doAnswer(
|
||||
new Answer() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
presenter.onSuccessRequest(jsArrayMixed);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.when(presenter)
|
||||
.doRequest(nullable(Promise.class), nullable(Promise.class), nullable(Promise.class));
|
||||
when(view.getAccountName()).thenReturn("AccountName");
|
||||
|
||||
presenter.onLoadRepoClicked();
|
||||
|
||||
verify(gitHubClientService).getRepositoriesList();
|
||||
verify(gitHubClientService).getUserInfo();
|
||||
verify(gitHubClientService).getOrganizations();
|
||||
verify(gitHubClientService).getRepositoriesList(anyString());
|
||||
verify(gitHubClientService).getUserInfo(anyString());
|
||||
verify(gitHubClientService).getOrganizations(anyString());
|
||||
|
||||
verify(view).setLoaderVisibility(eq(true));
|
||||
verify(view).setInputsEnableState(eq(false));
|
||||
verify(view).setLoaderVisibility(eq(false));
|
||||
verify(view).setInputsEnableState(eq(true));
|
||||
verify(view).setAccountNames(org.mockito.ArgumentMatchers.<Set>anyObject());
|
||||
verify(view).setAccountNames(org.mockito.ArgumentMatchers.<Set>any());
|
||||
verify(view, times(2)).showGithubPanel();
|
||||
verify(view).setRepositories(org.mockito.ArgumentMatchers.<List<ProjectData>>anyObject());
|
||||
verify(view).setRepositories(org.mockito.ArgumentMatchers.any());
|
||||
verify(view).reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onLoadRepoClickedWhenGetUserReposIsFailed() throws Exception {
|
||||
doAnswer(
|
||||
new Answer() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
presenter.onFailRequest(promiseError);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.when(presenter)
|
||||
.doRequest(nullable(Promise.class), nullable(Promise.class), nullable(Promise.class));
|
||||
|
||||
presenter.onLoadRepoClicked();
|
||||
|
||||
verify(gitHubClientService).getRepositoriesList();
|
||||
verify(gitHubClientService).getUserInfo();
|
||||
verify(gitHubClientService).getOrganizations();
|
||||
verify(gitHubClientService).getRepositoriesList(anyString());
|
||||
verify(gitHubClientService).getUserInfo(anyString());
|
||||
verify(gitHubClientService).getOrganizations(anyString());
|
||||
|
||||
verify(view).setLoaderVisibility(eq(true));
|
||||
verify(view).setInputsEnableState(eq(false));
|
||||
verify(view).setLoaderVisibility(eq(false));
|
||||
verify(view).setInputsEnableState(eq(true));
|
||||
verify(view, never()).setAccountNames((Set<String>) anyObject());
|
||||
verify(view, never()).setAccountNames(any());
|
||||
verify(view, never()).showGithubPanel();
|
||||
verify(view, never())
|
||||
.setRepositories(org.mockito.ArgumentMatchers.<List<ProjectData>>anyObject());
|
||||
verify(view, never()).setRepositories(org.mockito.ArgumentMatchers.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRepositorySelectedTest() {
|
||||
ProjectData projectData =
|
||||
new ProjectData(
|
||||
"name", "description", "type", new ArrayList<String>(), "repoUrl", "readOnlyUrl");
|
||||
"name", "description", "type", Collections.emptyList(), "repoUrl", "readOnlyUrl");
|
||||
|
||||
presenter.onRepositorySelected(projectData);
|
||||
|
||||
|
|
@ -497,23 +457,13 @@ public class GithubImporterPagePresenterTest {
|
|||
when(user.getId()).thenReturn(userId);
|
||||
|
||||
final Throwable exception = mock(UnauthorizedException.class);
|
||||
doAnswer(
|
||||
new Answer() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
presenter.onFailRequest(promiseError);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.when(presenter)
|
||||
.doRequest(nullable(Promise.class), nullable(Promise.class), nullable(Promise.class));
|
||||
doReturn(exception).when(promiseError).getCause();
|
||||
|
||||
presenter.onLoadRepoClicked();
|
||||
|
||||
verify(gitHubClientService).getRepositoriesList();
|
||||
verify(gitHubClientService).getUserInfo();
|
||||
verify(gitHubClientService).getOrganizations();
|
||||
verify(gitHubClientService).getRepositoriesList(anyString());
|
||||
verify(gitHubClientService).getUserInfo(anyString());
|
||||
verify(gitHubClientService).getOrganizations(anyString());
|
||||
|
||||
verify(gitHubAuthenticator).authenticate(anyString(), asyncCallbackCaptor.capture());
|
||||
AsyncCallback<OAuthStatus> asyncCallback = asyncCallbackCaptor.getValue();
|
||||
|
|
@ -522,32 +472,13 @@ public class GithubImporterPagePresenterTest {
|
|||
verify(view, times(2)).setLoaderVisibility(eq(true));
|
||||
verify(view, times(2)).setInputsEnableState(eq(false));
|
||||
verify(view, times(2)).setInputsEnableState(eq(true));
|
||||
verify(view, never()).setAccountNames((Set<String>) anyObject());
|
||||
verify(view, never()).setAccountNames(any());
|
||||
verify(view, never()).showGithubPanel();
|
||||
verify(view, never())
|
||||
.setRepositories(org.mockito.ArgumentMatchers.<List<ProjectData>>anyObject());
|
||||
verify(view, never()).setRepositories(org.mockito.ArgumentMatchers.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onLoadRepoClickedWhenAuthorizeIsSuccessful() throws Exception {
|
||||
doAnswer(
|
||||
new Answer() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
presenter.onFailRequest(promiseError);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.doAnswer(
|
||||
new Answer() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
presenter.onSuccessRequest(jsArrayMixed);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.when(presenter)
|
||||
.doRequest(nullable(Promise.class), nullable(Promise.class), nullable(Promise.class));
|
||||
final Throwable exception = mock(UnauthorizedException.class);
|
||||
String userId = "userId";
|
||||
CurrentUser user = mock(CurrentUser.class);
|
||||
|
|
@ -558,9 +489,9 @@ public class GithubImporterPagePresenterTest {
|
|||
|
||||
presenter.onLoadRepoClicked();
|
||||
|
||||
verify(gitHubClientService).getRepositoriesList();
|
||||
verify(gitHubClientService).getUserInfo();
|
||||
verify(gitHubClientService).getOrganizations();
|
||||
verify(gitHubClientService).getRepositoriesList(anyString());
|
||||
verify(gitHubClientService).getUserInfo(anyString());
|
||||
verify(gitHubClientService).getOrganizations(anyString());
|
||||
|
||||
verify(gitHubAuthenticator).authenticate(anyString(), asyncCallbackCaptor.capture());
|
||||
AsyncCallback<OAuthStatus> asyncCallback = asyncCallbackCaptor.getValue();
|
||||
|
|
|
|||
|
|
@ -37,10 +37,6 @@
|
|||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</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>
|
||||
|
|
|
|||
|
|
@ -10,51 +10,29 @@
|
|||
*/
|
||||
package org.eclipse.che.ide.ext.git.server.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.api.git.CredentialsProvider;
|
||||
import org.eclipse.che.api.git.UserCredential;
|
||||
import org.eclipse.che.api.git.exception.GitException;
|
||||
import org.eclipse.che.api.git.GitBasicAuthenticationCredentialsProvider;
|
||||
import org.eclipse.che.api.git.shared.ProviderInfo;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.security.oauth.shared.OAuthTokenProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** @author Sergii Kabashniuk */
|
||||
@Singleton
|
||||
public class GitHubOAuthCredentialProvider implements CredentialsProvider {
|
||||
public class GitHubOAuthCredentialProvider extends GitBasicAuthenticationCredentialsProvider {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GitHubOAuthCredentialProvider.class);
|
||||
|
||||
private static String OAUTH_PROVIDER_NAME = "github";
|
||||
private final OAuthTokenProvider oAuthTokenProvider;
|
||||
private final String authorizationServicePath;
|
||||
|
||||
@Inject
|
||||
public GitHubOAuthCredentialProvider(OAuthTokenProvider oAuthTokenProvider) {
|
||||
this.oAuthTokenProvider = oAuthTokenProvider;
|
||||
public GitHubOAuthCredentialProvider() {
|
||||
this.authorizationServicePath = "/oauth/authenticate";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserCredential getUserCredential() throws GitException {
|
||||
try {
|
||||
OAuthToken token =
|
||||
oAuthTokenProvider.getToken(
|
||||
OAUTH_PROVIDER_NAME, EnvironmentContext.getCurrent().getSubject().getUserId());
|
||||
if (token != null) {
|
||||
return new UserCredential(token.getToken(), token.getToken(), OAUTH_PROVIDER_NAME);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.warn(e.getLocalizedMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return OAUTH_PROVIDER_NAME;
|
||||
|
|
@ -72,7 +50,7 @@ public class GitHubOAuthCredentialProvider implements CredentialsProvider {
|
|||
UriBuilder.fromPath(authorizationServicePath)
|
||||
.queryParam("oauth_provider", OAUTH_PROVIDER_NAME)
|
||||
.queryParam("userId", EnvironmentContext.getCurrent().getSubject().getUserId())
|
||||
.queryParam("scope", "repo")
|
||||
.queryParam("scope", "repo,write:public_key")
|
||||
.build()
|
||||
.toString());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@
|
|||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</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-model</artifactId>
|
||||
|
|
|
|||
|
|
@ -28,8 +28,9 @@ import org.eclipse.che.api.promises.client.js.JsPromiseError;
|
|||
import org.eclipse.che.api.promises.client.js.Promises;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.app.CurrentUser;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.dto.DtoFactory;
|
||||
import org.eclipse.che.plugin.github.ide.GitHubClientService;
|
||||
import org.eclipse.che.plugin.github.ide.GitHubServiceClient;
|
||||
import org.eclipse.che.plugin.github.shared.GitHubPullRequest;
|
||||
import org.eclipse.che.plugin.github.shared.GitHubPullRequestCreationInput;
|
||||
import org.eclipse.che.plugin.github.shared.GitHubPullRequestList;
|
||||
|
|
@ -71,30 +72,34 @@ public class GitHubHostingService implements VcsHostingService {
|
|||
|
||||
private final AppContext appContext;
|
||||
private final DtoFactory dtoFactory;
|
||||
private final GitHubClientService gitHubClientService;
|
||||
private final GitHubServiceClient gitHubClientService;
|
||||
private final HostingServiceTemplates templates;
|
||||
private final String baseUrl;
|
||||
private final SecurityTokenProvider securityTokenProvider;
|
||||
private final OAuthServiceClient oAuthServiceClient;
|
||||
|
||||
@Inject
|
||||
public GitHubHostingService(
|
||||
@NotNull final AppContext appContext,
|
||||
@NotNull final DtoFactory dtoFactory,
|
||||
@NotNull final GitHubClientService gitHubClientService,
|
||||
@NotNull final GitHubServiceClient gitHubClientService,
|
||||
@NotNull final GitHubTemplates templates,
|
||||
SecurityTokenProvider securityTokenProvider) {
|
||||
SecurityTokenProvider securityTokenProvider,
|
||||
OAuthServiceClient oAuthServiceClient) {
|
||||
this.appContext = appContext;
|
||||
this.dtoFactory = dtoFactory;
|
||||
this.gitHubClientService = gitHubClientService;
|
||||
this.templates = templates;
|
||||
this.baseUrl = appContext.getMasterApiEndpoint();
|
||||
this.securityTokenProvider = securityTokenProvider;
|
||||
this.oAuthServiceClient = oAuthServiceClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<HostUser> getUserInfo() {
|
||||
return gitHubClientService
|
||||
.getUserInfo()
|
||||
return oAuthServiceClient
|
||||
.getToken(SERVICE_NAME.toLowerCase())
|
||||
.thenPromise(token -> gitHubClientService.getUserInfo(token.getToken()))
|
||||
.then(
|
||||
new Function<GitHubUser, HostUser>() {
|
||||
@Override
|
||||
|
|
@ -111,15 +116,11 @@ public class GitHubHostingService implements VcsHostingService {
|
|||
|
||||
@Override
|
||||
public Promise<Repository> getRepository(String owner, String repositoryName) {
|
||||
return gitHubClientService
|
||||
.getRepository(owner, repositoryName)
|
||||
.then(
|
||||
new Function<GitHubRepository, Repository>() {
|
||||
@Override
|
||||
public Repository apply(GitHubRepository ghRepo) throws FunctionException {
|
||||
return valueOf(ghRepo);
|
||||
}
|
||||
});
|
||||
return oAuthServiceClient
|
||||
.getToken(SERVICE_NAME.toLowerCase())
|
||||
.thenPromise(
|
||||
token -> gitHubClientService.getRepository(token.getToken(), owner, repositoryName))
|
||||
.then((Function<GitHubRepository, Repository>) this::valueOf);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
|
@ -159,8 +160,9 @@ public class GitHubHostingService implements VcsHostingService {
|
|||
|
||||
@Override
|
||||
public Promise<Repository> fork(final String owner, final String repository) {
|
||||
return gitHubClientService
|
||||
.fork(owner, repository)
|
||||
return oAuthServiceClient
|
||||
.getToken(SERVICE_NAME.toLowerCase())
|
||||
.thenPromise(token -> gitHubClientService.fork(token.getToken(), owner, repository))
|
||||
.thenPromise(
|
||||
new Function<GitHubRepository, Promise<Repository>>() {
|
||||
@Override
|
||||
|
|
@ -232,8 +234,12 @@ public class GitHubHostingService implements VcsHostingService {
|
|||
@Override
|
||||
public Promise<PullRequest> getPullRequest(
|
||||
String owner, String repository, String username, final String branchName) {
|
||||
return gitHubClientService
|
||||
.getPullRequests(owner, repository, username + ':' + branchName)
|
||||
return oAuthServiceClient
|
||||
.getToken(SERVICE_NAME.toLowerCase())
|
||||
.thenPromise(
|
||||
token ->
|
||||
gitHubClientService.getPullRequests(
|
||||
token.getToken(), owner, repository, username + ':' + branchName))
|
||||
.thenPromise(
|
||||
new Function<GitHubPullRequestList, Promise<PullRequest>>() {
|
||||
@Override
|
||||
|
|
@ -260,8 +266,10 @@ public class GitHubHostingService implements VcsHostingService {
|
|||
@NotNull final String repository,
|
||||
@NotNull final AsyncCallback<List<PullRequest>> callback) {
|
||||
|
||||
gitHubClientService
|
||||
.getPullRequests(owner, repository)
|
||||
oAuthServiceClient
|
||||
.getToken(SERVICE_NAME.toLowerCase())
|
||||
.thenPromise(
|
||||
token -> gitHubClientService.getPullRequests(token.getToken(), owner, repository))
|
||||
.then(
|
||||
result -> {
|
||||
final List<PullRequest> pullRequests = new ArrayList<>();
|
||||
|
|
@ -284,8 +292,10 @@ public class GitHubHostingService implements VcsHostingService {
|
|||
*/
|
||||
private Promise<List<PullRequest>> getPullRequests(String owner, String repository) {
|
||||
|
||||
return gitHubClientService
|
||||
.getPullRequests(owner, repository)
|
||||
return oAuthServiceClient
|
||||
.getToken(SERVICE_NAME.toLowerCase())
|
||||
.thenPromise(
|
||||
token -> gitHubClientService.getPullRequests(token.getToken(), owner, repository))
|
||||
.then(
|
||||
new Function<GitHubPullRequestList, List<PullRequest>>() {
|
||||
@Override
|
||||
|
|
@ -327,8 +337,11 @@ public class GitHubHostingService implements VcsHostingService {
|
|||
.withHead(brName)
|
||||
.withBase(baseBranchName)
|
||||
.withBody(body);
|
||||
return gitHubClientService
|
||||
.createPullRequest(owner, repository, input)
|
||||
return oAuthServiceClient
|
||||
.getToken(SERVICE_NAME.toLowerCase())
|
||||
.thenPromise(
|
||||
token ->
|
||||
gitHubClientService.createPullRequest(token.getToken(), owner, repository, input))
|
||||
.then(
|
||||
new Function<GitHubPullRequest, PullRequest>() {
|
||||
@Override
|
||||
|
|
@ -395,8 +408,9 @@ public class GitHubHostingService implements VcsHostingService {
|
|||
@NotNull final String owner,
|
||||
@NotNull final String repository,
|
||||
@NotNull final AsyncCallback<List<Repository>> callback) {
|
||||
gitHubClientService
|
||||
.getForks(owner, repository)
|
||||
oAuthServiceClient
|
||||
.getToken(SERVICE_NAME.toLowerCase())
|
||||
.thenPromise(token -> gitHubClientService.getForks(token.getToken(), owner, repository))
|
||||
.then(
|
||||
gitHubRepositoryList -> {
|
||||
final List<Repository> repositories = new ArrayList<>();
|
||||
|
|
@ -413,8 +427,9 @@ public class GitHubHostingService implements VcsHostingService {
|
|||
}
|
||||
|
||||
private Promise<List<Repository>> getForks(final String owner, final String repository) {
|
||||
return gitHubClientService
|
||||
.getForks(owner, repository)
|
||||
return oAuthServiceClient
|
||||
.getToken(SERVICE_NAME.toLowerCase())
|
||||
.thenPromise(token -> gitHubClientService.getForks(token.getToken(), owner, repository))
|
||||
.then(
|
||||
new Function<GitHubRepositoryList, List<Repository>>() {
|
||||
@Override
|
||||
|
|
@ -520,15 +535,17 @@ public class GitHubHostingService implements VcsHostingService {
|
|||
@Override
|
||||
public Promise<PullRequest> updatePullRequest(
|
||||
String owner, String repository, PullRequest pullRequest) {
|
||||
return gitHubClientService
|
||||
.updatePullRequest(owner, repository, pullRequest.getNumber(), valueOf(pullRequest))
|
||||
.then(
|
||||
new Function<GitHubPullRequest, PullRequest>() {
|
||||
@Override
|
||||
public PullRequest apply(GitHubPullRequest arg) throws FunctionException {
|
||||
return valueOf(arg);
|
||||
}
|
||||
});
|
||||
return oAuthServiceClient
|
||||
.getToken(SERVICE_NAME.toLowerCase())
|
||||
.thenPromise(
|
||||
token ->
|
||||
gitHubClientService.updatePullRequest(
|
||||
token.getToken(),
|
||||
owner,
|
||||
repository,
|
||||
pullRequest.getNumber(),
|
||||
valueOf(pullRequest)))
|
||||
.then((Function<GitHubPullRequest, PullRequest>) this::valueOf);
|
||||
}
|
||||
|
||||
private GitHubPullRequest valueOf(PullRequest pullRequest) {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@
|
|||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
|
|
@ -45,10 +49,6 @@
|
|||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</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>
|
||||
|
|
|
|||
|
|
@ -10,13 +10,9 @@
|
|||
*/
|
||||
package org.eclipse.che.plugin.github.server;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.UnauthorizedException;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.security.oauth.shared.OAuthTokenProvider;
|
||||
import org.kohsuke.github.GitHub;
|
||||
|
||||
/**
|
||||
|
|
@ -27,41 +23,17 @@ import org.kohsuke.github.GitHub;
|
|||
*/
|
||||
public class GitHubFactory {
|
||||
|
||||
private final OAuthTokenProvider oauthTokenProvider;
|
||||
|
||||
@Inject
|
||||
private GitHubFactory(OAuthTokenProvider oauthTokenProvider) {
|
||||
this.oauthTokenProvider = oauthTokenProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to GitHub API
|
||||
* Connect to GitHub API using OAuth
|
||||
*
|
||||
* @param oauthToken token for OAuth connection
|
||||
* @return connected GitHub API class
|
||||
*/
|
||||
public GitHub connect() throws ServerException, UnauthorizedException {
|
||||
public GitHub oauthConnect(String oauthToken) throws ServerException, UnauthorizedException {
|
||||
try {
|
||||
return GitHub.connectUsingOAuth(getToken());
|
||||
return GitHub.connectUsingOAuth(oauthToken);
|
||||
} catch (IOException e) {
|
||||
throw new ServerException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String getToken() throws ServerException, UnauthorizedException {
|
||||
OAuthToken token;
|
||||
try {
|
||||
token =
|
||||
oauthTokenProvider.getToken(
|
||||
"github", EnvironmentContext.getCurrent().getSubject().getUserId());
|
||||
} catch (IOException e) {
|
||||
throw new ServerException(e.getMessage());
|
||||
}
|
||||
|
||||
String oauthToken = token != null ? token.getToken() : null;
|
||||
if (oauthToken == null || oauthToken.isEmpty()) {
|
||||
throw new UnauthorizedException("User doesn't have access token to github");
|
||||
}
|
||||
|
||||
return oauthToken;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
*/
|
||||
package org.eclipse.che.plugin.github.server;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
|
@ -28,15 +28,12 @@ import java.util.regex.Pattern;
|
|||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.api.core.UnauthorizedException;
|
||||
import org.eclipse.che.api.git.GitUrlUtils;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.json.JsonHelper;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.eclipse.che.plugin.github.shared.GitHubKey;
|
||||
import org.eclipse.che.plugin.ssh.key.script.SshKeyUploader;
|
||||
import org.eclipse.che.security.oauth.shared.OAuthTokenProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
@ -47,31 +44,23 @@ public class GitHubKeyUploader implements SshKeyUploader {
|
|||
private static final Logger LOG = LoggerFactory.getLogger(GitHubKeyUploader.class);
|
||||
private static final Pattern GITHUB_URL_PATTERN = Pattern.compile(".*github\\.com.*");
|
||||
|
||||
private OAuthTokenProvider tokenProvider;
|
||||
|
||||
@Inject
|
||||
public GitHubKeyUploader(OAuthTokenProvider tokenProvider) {
|
||||
this.tokenProvider = tokenProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(String url) {
|
||||
return GitUrlUtils.isSSH(url) && GITHUB_URL_PATTERN.matcher(url).matches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadKey(String publicKey) throws IOException, UnauthorizedException {
|
||||
final OAuthToken token =
|
||||
tokenProvider.getToken("github", EnvironmentContext.getCurrent().getSubject().getUserId());
|
||||
public void uploadKey(String publicKey, String oauthToken)
|
||||
throws IOException, UnauthorizedException {
|
||||
|
||||
if (token == null || token.getToken() == null) {
|
||||
if (Strings.isNullOrEmpty(oauthToken)) {
|
||||
LOG.debug("Token not found, user need to authorize to upload key.");
|
||||
throw new UnauthorizedException("To upload SSH key you need to authorize.");
|
||||
}
|
||||
|
||||
StringBuilder answer = new StringBuilder();
|
||||
final String url =
|
||||
String.format("https://api.github.com/user/keys?access_token=%s", token.getToken());
|
||||
String.format("https://api.github.com/user/keys?access_token=%s", oauthToken);
|
||||
|
||||
final List<GitHubKey> gitHubUserPublicKeys = getUserPublicKeys(url, answer);
|
||||
for (GitHubKey gitHubUserPublicKey : gitHubUserPublicKeys) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import com.google.inject.multibindings.Multibinder;
|
|||
import org.eclipse.che.api.project.server.ProjectImporter;
|
||||
import org.eclipse.che.inject.DynaModule;
|
||||
import org.eclipse.che.plugin.github.server.GitHubDTOFactory;
|
||||
import org.eclipse.che.plugin.github.server.GitHubFactory;
|
||||
import org.eclipse.che.plugin.github.server.GitHubKeyUploader;
|
||||
import org.eclipse.che.plugin.github.server.GitHubProjectImporter;
|
||||
import org.eclipse.che.plugin.github.server.rest.GitHubService;
|
||||
|
|
@ -32,7 +31,6 @@ public class GitHubModule extends AbstractModule {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(GitHubFactory.class);
|
||||
bind(GitHubDTOFactory.class);
|
||||
|
||||
Multibinder<ProjectImporter> projectImporterMultibinder =
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.HeaderParam;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
|
|
@ -59,25 +60,42 @@ import org.slf4j.LoggerFactory;
|
|||
*/
|
||||
@Path("/github")
|
||||
public class GitHubService {
|
||||
@Inject private GitHubFactory gitHubFactory;
|
||||
|
||||
@Inject private GitHubDTOFactory gitHubDTOFactory;
|
||||
private final GitHubDTOFactory gitHubDTOFactory;
|
||||
|
||||
@Inject private GitHubKeyUploader githubKeyUploader;
|
||||
private final GitHubKeyUploader githubKeyUploader;
|
||||
|
||||
@Inject private SshServiceClient sshServiceClient;
|
||||
private final SshServiceClient sshServiceClient;
|
||||
|
||||
private final GitHubFactory gitHubFactory;
|
||||
|
||||
private static final String AUTH_HEADER_NAME = "X-Oauth-Token";
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GitHubService.class);
|
||||
|
||||
@Inject
|
||||
public GitHubService(
|
||||
GitHubDTOFactory gitHubDTOFactory,
|
||||
GitHubKeyUploader githubKeyUploader,
|
||||
SshServiceClient sshServiceClient,
|
||||
GitHubFactory gitHubFactory) {
|
||||
this.gitHubDTOFactory = gitHubDTOFactory;
|
||||
this.githubKeyUploader = githubKeyUploader;
|
||||
this.sshServiceClient = sshServiceClient;
|
||||
this.gitHubFactory = gitHubFactory;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("repositories/{user}/{repository}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public GitHubRepository getUserRepository(
|
||||
@PathParam("user") String user, @PathParam("repository") String repository)
|
||||
@PathParam("user") String user,
|
||||
@PathParam("repository") String repository,
|
||||
@HeaderParam(AUTH_HEADER_NAME) String oauthToken)
|
||||
throws ApiException {
|
||||
try {
|
||||
return gitHubDTOFactory.createRepository(
|
||||
gitHubFactory.connect().getUser(user).getRepository(repository));
|
||||
gitHubFactory.oauthConnect(oauthToken).getUser(user).getRepository(repository));
|
||||
} catch (IOException e) {
|
||||
LOG.error("Get user info error", e);
|
||||
throw new ServerException(e.getMessage());
|
||||
|
|
@ -87,11 +105,12 @@ public class GitHubService {
|
|||
@GET
|
||||
@Path("list/user")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public GitHubRepositoryList listRepositoriesByUser(@QueryParam("username") String userName)
|
||||
public GitHubRepositoryList listRepositoriesByUser(
|
||||
@QueryParam("username") String userName, @HeaderParam(AUTH_HEADER_NAME) String oauthToken)
|
||||
throws ApiException {
|
||||
try {
|
||||
return gitHubDTOFactory.createRepositoriesList(
|
||||
gitHubFactory.connect().getUser(userName).listRepositories());
|
||||
gitHubFactory.oauthConnect(oauthToken).getUser(userName).listRepositories());
|
||||
} catch (IOException e) {
|
||||
LOG.error("Get list repositories by user fail", e);
|
||||
throw new ServerException(e.getMessage());
|
||||
|
|
@ -102,10 +121,12 @@ public class GitHubService {
|
|||
@Path("list/org")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public GitHubRepositoryList listRepositoriesByOrganization(
|
||||
@QueryParam("organization") String organization) throws ApiException {
|
||||
@QueryParam("organization") String organization,
|
||||
@HeaderParam(AUTH_HEADER_NAME) String oauthToken)
|
||||
throws ApiException {
|
||||
try {
|
||||
return gitHubDTOFactory.createRepositoriesList(
|
||||
gitHubFactory.connect().getOrganization(organization).listRepositories());
|
||||
gitHubFactory.oauthConnect(oauthToken).getOrganization(organization).listRepositories());
|
||||
} catch (IOException e) {
|
||||
LOG.error("Get list repositories by organization fail", e);
|
||||
throw new ServerException(e.getMessage());
|
||||
|
|
@ -115,9 +136,10 @@ public class GitHubService {
|
|||
@GET
|
||||
@Path("list/account")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public GitHubRepositoryList listRepositoriesByAccount(@QueryParam("account") String account)
|
||||
public GitHubRepositoryList listRepositoriesByAccount(
|
||||
@QueryParam("account") String account, @HeaderParam(AUTH_HEADER_NAME) String oauthToken)
|
||||
throws ApiException {
|
||||
GitHub gitHub = gitHubFactory.connect();
|
||||
GitHub gitHub = gitHubFactory.oauthConnect(oauthToken);
|
||||
try {
|
||||
// First, try to retrieve organization repositories:
|
||||
return gitHubDTOFactory.createRepositoriesList(
|
||||
|
|
@ -137,10 +159,12 @@ public class GitHubService {
|
|||
@GET
|
||||
@Path("list")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public List<GitHubRepository> listRepositories() throws ApiException {
|
||||
public List<GitHubRepository> listRepositories(@HeaderParam(AUTH_HEADER_NAME) String oauthToken)
|
||||
throws ApiException {
|
||||
try {
|
||||
return gitHubDTOFactory
|
||||
.createRepositoriesList(gitHubFactory.connect().getMyself().listRepositories())
|
||||
.createRepositoriesList(
|
||||
gitHubFactory.oauthConnect(oauthToken).getMyself().listRepositories())
|
||||
.getRepositories();
|
||||
} catch (IOException e) {
|
||||
LOG.error("Get list repositories fail", e);
|
||||
|
|
@ -152,13 +176,15 @@ public class GitHubService {
|
|||
@Path("forks/{user}/{repository}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public GitHubRepositoryList forks(
|
||||
@PathParam("user") String user, @PathParam("repository") String repository)
|
||||
@PathParam("user") String user,
|
||||
@PathParam("repository") String repository,
|
||||
@HeaderParam(AUTH_HEADER_NAME) String oauthToken)
|
||||
throws ApiException {
|
||||
GitHubRepositoryList gitHubRepositoryList;
|
||||
try {
|
||||
gitHubRepositoryList = gitHubDTOFactory.createRepositoriesList();
|
||||
|
||||
for (GHRepository ghRepository : gitHubFactory.connect().getMyself().listRepositories()) {
|
||||
for (GHRepository ghRepository :
|
||||
gitHubFactory.oauthConnect(oauthToken).getMyself().listRepositories()) {
|
||||
if (ghRepository.isFork() && ghRepository.getName().equals(repository)) {
|
||||
gitHubRepositoryList = gitHubDTOFactory.createRepositoriesList(ghRepository);
|
||||
break;
|
||||
|
|
@ -175,11 +201,13 @@ public class GitHubService {
|
|||
@Path("createfork/{user}/{repository}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public GitHubRepository fork(
|
||||
@PathParam("user") String user, @PathParam("repository") String repository)
|
||||
@PathParam("user") String user,
|
||||
@PathParam("repository") String repository,
|
||||
@HeaderParam(AUTH_HEADER_NAME) String oauthToken)
|
||||
throws ApiException {
|
||||
try {
|
||||
return gitHubDTOFactory.createRepository(
|
||||
gitHubFactory.connect().getUser(user).getRepository(repository).fork());
|
||||
gitHubFactory.oauthConnect(oauthToken).getUser(user).getRepository(repository).fork());
|
||||
} catch (IOException e) {
|
||||
LOG.error("Fork fail", e);
|
||||
throw new ServerException(e.getMessage());
|
||||
|
|
@ -193,11 +221,12 @@ public class GitHubService {
|
|||
@PathParam("user") String user,
|
||||
@PathParam("repository") String repository,
|
||||
@PathParam("issue") String issue,
|
||||
@HeaderParam(AUTH_HEADER_NAME) String oauthToken,
|
||||
GitHubIssueCommentInput input)
|
||||
throws ApiException {
|
||||
try {
|
||||
gitHubFactory
|
||||
.connect()
|
||||
.oauthConnect(oauthToken)
|
||||
.getUser(user)
|
||||
.getRepository(repository)
|
||||
.getIssue(Integer.getInteger(issue))
|
||||
|
|
@ -214,12 +243,13 @@ public class GitHubService {
|
|||
public GitHubPullRequestList listPullRequestsByRepository(
|
||||
@PathParam("user") String user,
|
||||
@PathParam("repository") String repository,
|
||||
@QueryParam("head") String head)
|
||||
@QueryParam("head") String head,
|
||||
@HeaderParam(AUTH_HEADER_NAME) String oauthToken)
|
||||
throws ApiException {
|
||||
try {
|
||||
return gitHubDTOFactory.createPullRequestsList(
|
||||
gitHubFactory
|
||||
.connect()
|
||||
.oauthConnect(oauthToken)
|
||||
.getUser(user)
|
||||
.getRepository(repository)
|
||||
.queryPullRequests()
|
||||
|
|
@ -238,12 +268,13 @@ public class GitHubService {
|
|||
public GitHubPullRequestList getPullRequestsById(
|
||||
@PathParam("user") String user,
|
||||
@PathParam("repository") String repository,
|
||||
@PathParam("pullRequestId") String pullRequestId)
|
||||
@PathParam("pullRequestId") String pullRequestId,
|
||||
@HeaderParam(AUTH_HEADER_NAME) String oauthToken)
|
||||
throws ApiException {
|
||||
try {
|
||||
return gitHubDTOFactory.createPullRequestsList(
|
||||
gitHubFactory
|
||||
.connect()
|
||||
.oauthConnect(oauthToken)
|
||||
.getUser(user)
|
||||
.getRepository(repository)
|
||||
.getPullRequest(Integer.valueOf(pullRequestId)));
|
||||
|
|
@ -259,12 +290,13 @@ public class GitHubService {
|
|||
public GitHubPullRequest createPullRequest(
|
||||
@PathParam("user") String user,
|
||||
@PathParam("repository") String repository,
|
||||
@HeaderParam(AUTH_HEADER_NAME) String oauthToken,
|
||||
GitHubPullRequestCreationInput input)
|
||||
throws ApiException {
|
||||
try {
|
||||
GHPullRequest pullRequest =
|
||||
gitHubFactory
|
||||
.connect()
|
||||
.oauthConnect(oauthToken)
|
||||
.getUser(user)
|
||||
.getRepository(repository)
|
||||
.createPullRequest(
|
||||
|
|
@ -285,12 +317,13 @@ public class GitHubService {
|
|||
@PathParam("user") String user,
|
||||
@PathParam("repository") String repository,
|
||||
@PathParam("pullRequestId") String pullRequestId,
|
||||
@HeaderParam(AUTH_HEADER_NAME) String oauthToken,
|
||||
GitHubPullRequest pullRequest)
|
||||
throws ServerException, UnauthorizedException {
|
||||
try {
|
||||
final GHPullRequest ghPullRequest =
|
||||
gitHubFactory
|
||||
.connect()
|
||||
.oauthConnect(oauthToken)
|
||||
.getUser(user)
|
||||
.getRepository(repository)
|
||||
.getPullRequest(Integer.valueOf(pullRequestId));
|
||||
|
|
@ -311,10 +344,12 @@ public class GitHubService {
|
|||
@GET
|
||||
@Path("orgs")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public List<GitHubUser> listOrganizations() throws ApiException {
|
||||
public List<GitHubUser> listOrganizations(@HeaderParam(AUTH_HEADER_NAME) String oauthToken)
|
||||
throws ApiException {
|
||||
try {
|
||||
return gitHubDTOFactory
|
||||
.createCollaborators(gitHubFactory.connect().getMyself().getAllOrganizations())
|
||||
.createCollaborators(
|
||||
gitHubFactory.oauthConnect(oauthToken).getMyself().getAllOrganizations())
|
||||
.getCollaborators();
|
||||
} catch (IOException e) {
|
||||
LOG.error("Getting list of available organizations fail", e);
|
||||
|
|
@ -325,9 +360,10 @@ public class GitHubService {
|
|||
@GET
|
||||
@Path("user")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public GitHubUser getUserInfo() throws ApiException {
|
||||
public GitHubUser getUserInfo(@HeaderParam(AUTH_HEADER_NAME) String oauthToken)
|
||||
throws ApiException {
|
||||
try {
|
||||
return gitHubDTOFactory.createUser(gitHubFactory.connect().getMyself());
|
||||
return gitHubDTOFactory.createUser(GitHub.connectUsingOAuth(oauthToken).getMyself());
|
||||
} catch (IOException e) {
|
||||
LOG.error("Getting user info fail", e);
|
||||
throw new ServerException(e.getMessage());
|
||||
|
|
@ -338,11 +374,17 @@ public class GitHubService {
|
|||
@Path("collaborators/{user}/{repository}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Collaborators collaborators(
|
||||
@PathParam("user") String user, @PathParam("repository") String repository)
|
||||
@PathParam("user") String user,
|
||||
@PathParam("repository") String repository,
|
||||
@HeaderParam(AUTH_HEADER_NAME) String oauthToken)
|
||||
throws ApiException {
|
||||
try {
|
||||
return gitHubDTOFactory.createCollaborators(
|
||||
gitHubFactory.connect().getUser(user).getRepository(repository).getCollaborators());
|
||||
gitHubFactory
|
||||
.oauthConnect(oauthToken)
|
||||
.getUser(user)
|
||||
.getRepository(repository)
|
||||
.getCollaborators());
|
||||
} catch (IOException e) {
|
||||
LOG.error("Get collaborators fail", e);
|
||||
throw new ServerException(e.getMessage());
|
||||
|
|
@ -351,7 +393,7 @@ public class GitHubService {
|
|||
|
||||
@POST
|
||||
@Path("ssh/generate")
|
||||
public void updateSSHKey() throws ApiException {
|
||||
public void updateSSHKey(@HeaderParam(AUTH_HEADER_NAME) String oauthToken) throws ApiException {
|
||||
final String host = "github.com";
|
||||
SshPair sshPair = null;
|
||||
try {
|
||||
|
|
@ -374,7 +416,7 @@ public class GitHubService {
|
|||
|
||||
// update public key
|
||||
try {
|
||||
githubKeyUploader.uploadKey(sshPair.getPublicKey());
|
||||
githubKeyUploader.uploadKey(sshPair.getPublicKey(), oauthToken);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Upload github ssh key fail", e);
|
||||
throw new GitException(e.getMessage(), e);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@
|
|||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</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>
|
||||
|
|
|
|||
|
|
@ -11,12 +11,17 @@
|
|||
package org.eclipse.che.plugin.pullrequest.client.vcs;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.eclipse.che.api.core.ErrorCodes.UNAUTHORIZED_GIT_OPERATION;
|
||||
import static org.eclipse.che.api.git.shared.ProviderInfo.PROVIDER_NAME;
|
||||
import static org.eclipse.che.ide.util.ExceptionUtils.getAttributes;
|
||||
import static org.eclipse.che.ide.util.ExceptionUtils.getErrorCode;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.eclipse.che.api.core.model.workspace.config.ProjectConfig;
|
||||
|
|
@ -31,10 +36,13 @@ import org.eclipse.che.api.promises.client.Promise;
|
|||
import org.eclipse.che.api.promises.client.js.JsPromiseError;
|
||||
import org.eclipse.che.api.promises.client.js.Promises;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.auth.Credentials;
|
||||
import org.eclipse.che.ide.api.auth.OAuthServiceClient;
|
||||
import org.eclipse.che.ide.dto.DtoFactory;
|
||||
import org.eclipse.che.ide.ext.git.client.GitServiceClient;
|
||||
import org.eclipse.che.ide.resource.Path;
|
||||
import org.eclipse.che.ide.rest.DtoUnmarshallerFactory;
|
||||
import org.eclipse.che.ide.util.StringUtils;
|
||||
|
||||
/** Git backed implementation for {@link VcsService}. */
|
||||
@Singleton
|
||||
|
|
@ -44,16 +52,19 @@ public class GitVcsService implements VcsService {
|
|||
private final GitServiceClient service;
|
||||
private final DtoFactory dtoFactory;
|
||||
private final AppContext appContext;
|
||||
private final OAuthServiceClient oAuthServiceClient;
|
||||
|
||||
@Inject
|
||||
public GitVcsService(
|
||||
final DtoFactory dtoFactory,
|
||||
final DtoUnmarshallerFactory dtoUnmarshallerFactory,
|
||||
final GitServiceClient service,
|
||||
final AppContext appContext) {
|
||||
final AppContext appContext,
|
||||
final OAuthServiceClient oAuthServiceClient) {
|
||||
this.dtoFactory = dtoFactory;
|
||||
this.service = service;
|
||||
this.appContext = appContext;
|
||||
this.oAuthServiceClient = oAuthServiceClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -204,7 +215,38 @@ public class GitVcsService implements VcsService {
|
|||
appContext.getRootProject().getLocation(),
|
||||
Collections.singletonList(localBranchName),
|
||||
remote,
|
||||
true)
|
||||
true,
|
||||
null)
|
||||
.catchErrorPromise(
|
||||
error -> {
|
||||
if (getErrorCode(error.getCause()) != UNAUTHORIZED_GIT_OPERATION) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> attributes = getAttributes(error.getCause());
|
||||
String providerName = attributes.get(PROVIDER_NAME);
|
||||
if (!StringUtils.isNullOrEmpty(providerName)) {
|
||||
return pushBranchAuthenticated(remote, localBranchName, providerName);
|
||||
} else if (BRANCH_UP_TO_DATE_ERROR_MESSAGE.equalsIgnoreCase(error.getMessage())) {
|
||||
return Promises.reject(
|
||||
JsPromiseError.create(new BranchUpToDateException(localBranchName)));
|
||||
} else {
|
||||
return Promises.reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Promise<PushResponse> pushBranchAuthenticated(
|
||||
final String remote, final String localBranchName, final String providerName) {
|
||||
return oAuthServiceClient
|
||||
.getToken(providerName)
|
||||
.thenPromise(
|
||||
token ->
|
||||
service.push(
|
||||
appContext.getRootProject().getLocation(),
|
||||
Collections.singletonList(localBranchName),
|
||||
remote,
|
||||
true,
|
||||
new Credentials(token.getToken(), token.getToken())))
|
||||
.catchErrorPromise(
|
||||
error -> {
|
||||
if (BRANCH_UP_TO_DATE_ERROR_MESSAGE.equalsIgnoreCase(error.getMessage())) {
|
||||
|
|
|
|||
|
|
@ -42,10 +42,6 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-dto</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ package org.eclipse.che.security.oauth;
|
|||
import com.google.inject.AbstractModule;
|
||||
import org.eclipse.che.security.oauth.oauth1.RemoteOAuthAuthorizationHeaderProvider;
|
||||
import org.eclipse.che.security.oauth.shared.OAuthAuthorizationHeaderProvider;
|
||||
import org.eclipse.che.security.oauth.shared.OAuthTokenProvider;
|
||||
|
||||
/**
|
||||
* Represent single guice module that bind classes to get out tokens from workspace agent.
|
||||
|
|
@ -23,7 +22,6 @@ import org.eclipse.che.security.oauth.shared.OAuthTokenProvider;
|
|||
public class OAuthAgentModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(OAuthTokenProvider.class).to(RemoteOAuthTokenProvider.class);
|
||||
bind(OAuthAuthorizationHeaderProvider.class).to(RemoteOAuthAuthorizationHeaderProvider.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2017 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.security.oauth;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
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.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Link;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.eclipse.che.security.oauth.shared.OAuthTokenProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Allow get token from OAuth service over http.
|
||||
*
|
||||
* @author Max Shaposhnik
|
||||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
public class RemoteOAuthTokenProvider implements OAuthTokenProvider {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RemoteOAuthTokenProvider.class);
|
||||
|
||||
private final String apiEndpoint;
|
||||
|
||||
private final HttpJsonRequestFactory httpJsonRequestFactory;
|
||||
|
||||
@Inject
|
||||
public RemoteOAuthTokenProvider(
|
||||
@Named("che.api") String apiEndpoint, HttpJsonRequestFactory httpJsonRequestFactory) {
|
||||
this.apiEndpoint = apiEndpoint;
|
||||
this.httpJsonRequestFactory = httpJsonRequestFactory;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public OAuthToken getToken(String oauthProviderName, String userId) throws IOException {
|
||||
if (userId.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
UriBuilder ub =
|
||||
UriBuilder.fromUri(apiEndpoint)
|
||||
.path("/oauth/token")
|
||||
.queryParam("oauth_provider", oauthProviderName);
|
||||
Link getTokenLink =
|
||||
DtoFactory.newDto(Link.class).withHref(ub.build().toString()).withMethod("GET");
|
||||
return httpJsonRequestFactory.fromLink(getTokenLink).request().asDto(OAuthToken.class);
|
||||
} catch (NotFoundException ne) {
|
||||
LOG.warn("Token not found for user {}", userId);
|
||||
return null;
|
||||
} catch (ServerException
|
||||
| UnauthorizedException
|
||||
| ForbiddenException
|
||||
| ConflictException
|
||||
| BadRequestException e) {
|
||||
LOG.warn("Exception on token retrieval, message : {}", e.getLocalizedMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2017 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.security.oauth;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
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 java.io.IOException;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequest;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonResponse;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Link;
|
||||
import org.eclipse.che.commons.test.mockito.answer.SelfReturningAnswer;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Listeners(value = {MockitoTestNGListener.class})
|
||||
public class RemoteOAuthTokenProviderTest {
|
||||
|
||||
private HttpJsonRequest httpJsonRequest;
|
||||
|
||||
private RemoteOAuthTokenProvider tokenProvider;
|
||||
|
||||
@Mock private HttpJsonRequestFactory httpJsonRequestFactory;
|
||||
@Mock private HttpJsonResponse httpJsonResponse;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
httpJsonRequest = mock(HttpJsonRequest.class, new SelfReturningAnswer());
|
||||
when(httpJsonRequestFactory.fromLink(any())).thenReturn(httpJsonRequest);
|
||||
tokenProvider = new RemoteOAuthTokenProvider("http://dev.box.com/api", httpJsonRequestFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnToken() throws Exception {
|
||||
// given
|
||||
OAuthToken expected = DtoFactory.newDto(OAuthToken.class).withScope("scope").withToken("token");
|
||||
when(httpJsonResponse.asDto(any(Class.class))).thenReturn(expected);
|
||||
when(httpJsonRequest.request()).thenReturn(httpJsonResponse);
|
||||
// when
|
||||
OAuthToken actual = tokenProvider.getToken("google", "id");
|
||||
// then
|
||||
assertEquals(actual, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldConstructCorrectUrl() throws Exception {
|
||||
// given
|
||||
OAuthToken expected = DtoFactory.newDto(OAuthToken.class).withScope("scope").withToken("token");
|
||||
when(httpJsonResponse.asDto(any(Class.class))).thenReturn(expected);
|
||||
when(httpJsonRequest.request()).thenReturn(httpJsonResponse);
|
||||
// when
|
||||
tokenProvider.getToken("google", "id");
|
||||
// then
|
||||
ArgumentCaptor<Link> argumentCaptor = ArgumentCaptor.forClass(Link.class);
|
||||
verify(httpJsonRequestFactory).fromLink(argumentCaptor.capture());
|
||||
Link link = argumentCaptor.getValue();
|
||||
assertEquals(link.getMethod(), "GET");
|
||||
assertEquals(link.getHref(), "http://dev.box.com/api/oauth/token?oauth_provider=google");
|
||||
assertEquals(link.getParameters().size(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnNollForNotExistedProvider() throws Exception {
|
||||
// given
|
||||
when(httpJsonRequest.request()).thenReturn(httpJsonResponse);
|
||||
// when
|
||||
// then
|
||||
Assert.assertNull(tokenProvider.getToken("smoogle", "id"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnNullOnNotFoundException() throws Exception {
|
||||
// given
|
||||
when(httpJsonRequest.request()).thenThrow(NotFoundException.class);
|
||||
// when
|
||||
// then
|
||||
Assert.assertNull(tokenProvider.getToken("google", "id"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnNullOnIfUserIsEmpty() throws Exception {
|
||||
// given
|
||||
// when
|
||||
// then
|
||||
Assert.assertNull(tokenProvider.getToken("google", ""));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IOException.class)
|
||||
public void shouldThrowIoExceptionOnIoException() throws Exception {
|
||||
// given
|
||||
when(httpJsonRequest.request()).thenThrow(IOException.class);
|
||||
// when
|
||||
// then
|
||||
Assert.assertNull(tokenProvider.getToken("google", "id"));
|
||||
}
|
||||
}
|
||||
|
|
@ -11,13 +11,10 @@
|
|||
package org.eclipse.che.plugin.ssh.key.script;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import org.eclipse.che.api.core.ErrorCodes;
|
||||
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.core.rest.shared.dto.ExtendedError;
|
||||
import org.eclipse.che.api.ssh.shared.model.SshPair;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
|
|
@ -72,29 +69,6 @@ public class SshKeyProviderImpl implements SshKeyProvider {
|
|||
.withMessage("Unable get private ssh key")
|
||||
.withErrorCode(ErrorCodes.UNABLE_GET_PRIVATE_SSH_KEY));
|
||||
}
|
||||
|
||||
final String publicKey = pair.getPublicKey();
|
||||
if (publicKey != null) {
|
||||
final Optional<SshKeyUploader> optionalKeyUploader =
|
||||
sshKeyUploaders.stream().filter(keyUploader -> keyUploader.match(url)).findFirst();
|
||||
if (optionalKeyUploader.isPresent()) {
|
||||
final SshKeyUploader uploader = optionalKeyUploader.get();
|
||||
try {
|
||||
uploader.uploadKey(publicKey);
|
||||
} catch (IOException e) {
|
||||
throw new ServerException(e.getMessage(), e);
|
||||
} catch (UnauthorizedException e) {
|
||||
// action might fail without uploaded public SSH key.
|
||||
LOG.warn(
|
||||
String.format(
|
||||
"Unable upload public SSH key with %s", uploader.getClass().getSimpleName()),
|
||||
e);
|
||||
}
|
||||
} else {
|
||||
// action might fail without uploaded public SSH key.
|
||||
LOG.warn(String.format("Not found ssh key uploader for %s", host));
|
||||
}
|
||||
}
|
||||
return privateKey.getBytes();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public interface SshKeyUploader {
|
|||
* @throws IOException if an i/o error occurs
|
||||
* @throws UnauthorizedException if user is not authorized to access SSH key storage
|
||||
*/
|
||||
void uploadKey(String publicKey) throws IOException, UnauthorizedException;
|
||||
void uploadKey(String publicKey, String oauthToken) throws IOException, UnauthorizedException;
|
||||
|
||||
/**
|
||||
* Check if specified url matched to use current upload provider.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2017 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.inject.Singleton;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
|
||||
/**
|
||||
* Sets dummy subject into {@link EnvironmentContext}
|
||||
*
|
||||
* @author Max Shaposhnik (mshaposh@redhat.com)
|
||||
*/
|
||||
@Singleton
|
||||
public class EnvironmentInitializationFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {}
|
||||
|
||||
@Override
|
||||
public final void doFilter(
|
||||
ServletRequest request, ServletResponse response, FilterChain filterChain)
|
||||
throws IOException, ServletException {
|
||||
Subject subject = new SubjectImpl("che", "che", "dummy_token", false);
|
||||
final EnvironmentContext environmentContext = EnvironmentContext.getCurrent();
|
||||
try {
|
||||
environmentContext.setSubject(subject);
|
||||
filterChain.doFilter(request, response);
|
||||
} finally {
|
||||
EnvironmentContext.reset();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2017 Red Hat, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertNotEquals;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/** @author Max Shaposhnik (mshaposh@redhat.com) */
|
||||
@Listeners(value = {MockitoTestNGListener.class})
|
||||
public class EnvironmentInitializationFilterTest {
|
||||
|
||||
@Mock private FilterChain chain;
|
||||
|
||||
@Mock private HttpServletRequest request;
|
||||
|
||||
@Mock private HttpServletResponse response;
|
||||
|
||||
@InjectMocks private EnvironmentInitializationFilter filter;
|
||||
|
||||
@Test
|
||||
public void shouldSkipRequestToProject() throws Exception {
|
||||
// given
|
||||
when(request.getMethod()).thenReturn("GET");
|
||||
when(request.getRequestURI()).thenReturn("/ws/ws-id");
|
||||
|
||||
EnvironmentContext context = spy(EnvironmentContext.getCurrent());
|
||||
EnvironmentContext.setCurrent(context);
|
||||
|
||||
// when
|
||||
filter.doFilter(request, response, chain);
|
||||
|
||||
// then
|
||||
verify(chain).doFilter(eq(request), eq(response));
|
||||
verify(context).setSubject(eq(new SubjectImpl("che", "che", "dummy_token", false)));
|
||||
// after reset
|
||||
assertNotEquals(EnvironmentContext.getCurrent(), context);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue