Skip to content

Commit

Permalink
Show auth window when performing import project from private repo or …
Browse files Browse the repository at this point in the history
…use factory with private repo

Signed-off-by: Max Shaposhnik <mshaposhnik@codenvy.com>
  • Loading branch information
mshaposhnik committed Feb 22, 2016
1 parent 13f2c56 commit 9465a57
Show file tree
Hide file tree
Showing 37 changed files with 636 additions and 166 deletions.
Expand Up @@ -124,7 +124,7 @@ Pair<String, String>[] propagateEventsProvider(@Named("event.bus.url") String ev
@Named("codenvy.local.infrastructure.users")
Set<User> users() {
final Set<User> users = new HashSet<>(1);
final User user = new User().withId("codenvy")
final User user = new User().withId("che")
.withName("codenvy")
.withEmail("che@eclipse.org")
.withPassword("secret");
Expand Down
4 changes: 4 additions & 0 deletions core/che-core-git-impl-native/pom.xml
Expand Up @@ -55,6 +55,10 @@
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
Expand Down
Expand Up @@ -11,8 +11,10 @@
package org.eclipse.che.git.impl.nativegit;


import com.google.common.collect.ImmutableMap;

import org.eclipse.che.api.core.ErrorCodes;
import org.eclipse.che.api.core.UnauthorizedException;
import org.eclipse.che.api.core.rest.shared.dto.ExtendedError;
import org.eclipse.che.api.core.util.LineConsumerFactory;
import org.eclipse.che.api.git.Config;
import org.eclipse.che.api.git.CredentialsLoader;
Expand All @@ -21,6 +23,7 @@
import org.eclipse.che.api.git.GitException;
import org.eclipse.che.api.git.GitUserResolver;
import org.eclipse.che.api.git.LogPage;
import org.eclipse.che.api.git.shared.ProviderInfo;
import org.eclipse.che.api.git.UserCredential;
import org.eclipse.che.api.git.shared.AddRequest;
import org.eclipse.che.api.git.shared.Branch;
Expand Down Expand Up @@ -90,6 +93,9 @@
import java.util.List;
import java.util.regex.Pattern;

import static org.eclipse.che.api.git.shared.ProviderInfo.AUTHENTICATE_URL;
import static org.eclipse.che.api.git.shared.ProviderInfo.PROVIDER_NAME;

/**
* Native implementation of GitConnection
*
Expand Down Expand Up @@ -575,7 +581,14 @@ private void executeRemoteCommand(RemoteOperationCommand<?> command) throws GitE
if (!isOperationNeedAuth(gitEx.getMessage())) {
throw gitEx;
}
throw new UnauthorizedException(gitEx.getMessage());
ProviderInfo info = credentialsLoader.getProviderInfo(command.getRemoteUri());
if (info != null) {
throw new UnauthorizedException(gitEx.getMessage(),
ErrorCodes.UNAUTHORIZED_GIT_OPERATION,
ImmutableMap.of(PROVIDER_NAME, info.getProviderName(),
AUTHENTICATE_URL, info.getAuthenticateUrl()));
}
throw new UnauthorizedException(gitEx.getMessage(), ErrorCodes.UNAUTHORIZED_GIT_OPERATION);
}
}

Expand Down
Expand Up @@ -14,8 +14,17 @@

package org.eclipse.che.ide.util;

import org.eclipse.che.ide.commons.exception.ServerException;
import org.eclipse.che.ide.dto.DtoFactory;

import java.util.Collections;
import java.util.Map;

/** Utility class for common Exception related operations. */
public class ExceptionUtils {

private static DtoFactory dtoFactory = new DtoFactory();

public static final int MAX_CAUSE = 10;

public static String getStackTraceAsString(Throwable e) {
Expand Down Expand Up @@ -59,4 +68,38 @@ public static String getThrowableAsString(Throwable e, String newline, String in

return s.toString();
}

/**
* Returns error code of the exception if it is of type {@clink ServerException} and has error code set, or -1 otherwise.
*
* @param exception
* passed exception
* @return error code
*/
public static int getErrorCode(Throwable exception) {
if (exception instanceof ServerException) {
return ((ServerException)exception).getErrorCode();
} else if (exception instanceof org.eclipse.che.ide.websocket.rest.exceptions.ServerException) {
return ((org.eclipse.che.ide.websocket.rest.exceptions.ServerException)exception).getErrorCode();
} else {
return -1;
}
}

/**
* Returns attributes of the exception if it is of type {@clink ServerException} and has attributes set, or empty map otherwise.
*
* @param exception
* passed exception
* @return error code
*/
public static Map<String, String> getAttributes(Throwable exception) {
if (exception instanceof ServerException) {
return ((ServerException)exception).getAttributes();
} else if (exception instanceof org.eclipse.che.ide.websocket.rest.exceptions.ServerException) {
return ((org.eclipse.che.ide.websocket.rest.exceptions.ServerException)exception).getAttributes();
} else {
return Collections.emptyMap();
}
}
}
Expand Up @@ -8,7 +8,7 @@
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.ext.github.client.authenticator;
package org.eclipse.che.ide.api.oauth;

import com.google.gwt.user.client.rpc.AsyncCallback;

Expand All @@ -17,6 +17,9 @@
/**
* @author Roman Nikitenko
*/
public interface GitHubAuthenticator {
void authorize(AsyncCallback<OAuthStatus> callback);
public interface OAuth2Authenticator {

void authorize(String authenticatorUrl, AsyncCallback<OAuthStatus> callback);

String getProviderName();
}
@@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright (c) 2012-2016 Codenvy, S.A.
* 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:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.api.oauth;

/**
* Authenticators registry.
*
* @author Vitalii Parfonov
*/
public interface OAuth2AuthenticatorRegistry {

void registerAuthenticator(String providerName, OAuth2Authenticator oAuth2Authenticator);

OAuth2Authenticator getAuthenticator(String providerName);
}
@@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright (c) 2012-2016 Codenvy, S.A.
* 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:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.api.oauth;

import com.google.common.base.Joiner;
import com.google.gwt.user.client.Window;

import java.util.List;


/**
* Constructs URL's to OAUth authentication depending on current host and rest context.
*
* @author Vitalii Parfonov
*/
public class OAuth2AuthenticatorUrlProvider {

private final static String oAuthServicePath = "/oauth/authenticate";

public static String get(String restContext, String authenticatePath) {
return restContext + authenticatePath + "&redirect_after_login=" + redirect();
}


public static String get(String restContext, String providerName, String userId, List<String> scopes) {
final String scope = Joiner.on(',').join(scopes);

return restContext + oAuthServicePath + "?oauth_provider=" + providerName +
"&scope=" + scope +
"&userId=" + userId +
"&redirect_after_login=" + redirect();
}

private static String redirect() {
return Window.Location.getProtocol() + "//" + Window.Location.getHost() + "/ws/";
}



}
Expand Up @@ -292,6 +292,19 @@ public interface CoreLocalizationConstant extends Messages {
@Key("import.project.error")
String importProjectError();

/* Authorization */
@Key("authorization.dialog.title")
String authorizationDialogTitle();

@Key("authorization.dialog.text")
String authorizationDialogText();

@Key("oauth.failed.to.get.authenticator.title")
String oauthFailedToGetAuthenticatorTitle();

@Key("oauth.failed.to.get.authenticator.text")
String oauthFailedToGetAuthenticatorText();

/* Actions */
@Key("action.newFolder.title")
String actionNewFolderTitle();
Expand Down
Expand Up @@ -68,6 +68,8 @@
import org.eclipse.che.ide.api.icon.IconRegistry;
import org.eclipse.che.ide.api.keybinding.KeyBindingAgent;
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.parts.EditorPartStack;
import org.eclipse.che.ide.api.parts.PartStack;
import org.eclipse.che.ide.api.parts.PartStackUIResources;
Expand Down Expand Up @@ -96,6 +98,7 @@
import org.eclipse.che.ide.api.theme.ThemeAgent;
import org.eclipse.che.ide.client.StartUpActionsProcessor;
import org.eclipse.che.ide.icon.DefaultIconsComponent;
import org.eclipse.che.ide.oauth.DefaultOAuthAuthenticatorImpl;
import org.eclipse.che.ide.preferences.PreferencesComponent;
import org.eclipse.che.ide.projecttype.ProjectTemplatesComponent;
import org.eclipse.che.ide.projecttype.ProjectTypeComponent;
Expand All @@ -120,6 +123,7 @@
import org.eclipse.che.ide.notification.NotificationManagerImpl;
import org.eclipse.che.ide.notification.NotificationManagerView;
import org.eclipse.che.ide.notification.NotificationManagerViewImpl;
import org.eclipse.che.ide.oauth.OAuth2AuthenticatorRegistryImpl;
import org.eclipse.che.ide.part.FocusManager;
import org.eclipse.che.ide.part.PartStackPresenter;
import org.eclipse.che.ide.part.PartStackPresenter.PartStackEventHandler;
Expand Down Expand Up @@ -262,9 +266,12 @@ protected void configure() {
bind(ThemeAgent.class).to(ThemeAgentImpl.class).in(Singleton.class);
bind(FileTypeRegistry.class).to(FileTypeRegistryImpl.class).in(Singleton.class);


bind(AnalyticsEventLogger.class).to(DummyAnalyticsLoger.class).in(Singleton.class);
bind(AnalyticsEventLoggerExt.class).to(DummyAnalyticsLoger.class).in(Singleton.class);

GinMultibinder.newSetBinder(binder(), OAuth2Authenticator.class).addBinding().to(DefaultOAuthAuthenticatorImpl.class);

configureComponents();
configureProjectWizard();
configureImportWizard();
Expand Down Expand Up @@ -307,6 +314,7 @@ private void configureProjectWizard() {
bind(ProjectWizardRegistry.class).to(ProjectWizardRegistryImpl.class).in(Singleton.class);
install(new GinFactoryModuleBuilder().build(ProjectWizardFactory.class));
bind(PreSelectedProjectTypeManager.class).to(PreSelectedProjectTypeManagerImpl.class).in(Singleton.class);
bind(OAuth2AuthenticatorRegistry.class).to(OAuth2AuthenticatorRegistryImpl.class).in(Singleton.class);
}

private void configureImportWizard() {
Expand Down
Expand Up @@ -326,9 +326,12 @@ public interface ParserResource extends ClientBundle {
@Inject
private WsConnectionListener wsConnectionListener;



/** Instantiates {@link StandardComponentInitializer} an creates standard content. */
@Inject
public StandardComponentInitializer(IconRegistry iconRegistry, StandardComponentInitializer.ParserResource parserResource) {
public StandardComponentInitializer(IconRegistry iconRegistry,
StandardComponentInitializer.ParserResource parserResource) {
iconRegistry.registerIcon(new Icon(BLANK_CATEGORY + ".samples.category.icon", parserResource.samplesCategoryBlank()));
}

Expand Down
@@ -0,0 +1,83 @@
/*******************************************************************************
* Copyright (c) 2012-2016 Codenvy, S.A.
* 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:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.oauth;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;

import org.eclipse.che.ide.CoreLocalizationConstant;
import org.eclipse.che.ide.api.oauth.OAuth2Authenticator;
import org.eclipse.che.ide.ui.dialogs.CancelCallback;
import org.eclipse.che.ide.ui.dialogs.ConfirmCallback;
import org.eclipse.che.ide.ui.dialogs.DialogFactory;
import org.eclipse.che.security.oauth.JsOAuthWindow;
import org.eclipse.che.security.oauth.OAuthCallback;
import org.eclipse.che.security.oauth.OAuthStatus;

import javax.validation.constraints.NotNull;

/**
* Default implementation of authenticator, used when no provider-specific one is present.
*
* @author Max Shaposhnik
*/
public class DefaultOAuthAuthenticatorImpl implements OAuth2Authenticator, OAuthCallback {
AsyncCallback<OAuthStatus> callback;

private final DialogFactory dialogFactory;
private final CoreLocalizationConstant localizationConstant;
private String authenticationUrl;

@Inject
public DefaultOAuthAuthenticatorImpl(DialogFactory dialogFactory,
CoreLocalizationConstant localizationConstant) {
this.dialogFactory = dialogFactory;
this.localizationConstant = localizationConstant;
}

@Override
public void authorize(String authenticationUrl, @NotNull final AsyncCallback<OAuthStatus> callback) {
this.authenticationUrl = authenticationUrl;
this.callback = callback;
showDialog();
}

private void showDialog() {
dialogFactory.createConfirmDialog(localizationConstant.authorizationDialogTitle(), localizationConstant.authorizationDialogText(), new ConfirmCallback() {
@Override
public void accepted() {
showAuthWindow();
}
}, new CancelCallback() {
@Override
public void cancelled() {
callback.onSuccess(OAuthStatus.NOT_PERFORMED);
}
}).show();
}

@Override
public String getProviderName() {
return "default";
}


@Override
public void onAuthenticated(OAuthStatus authStatus) {
callback.onSuccess(authStatus);
}

private void showAuthWindow() {
JsOAuthWindow authWindow;
authWindow = new JsOAuthWindow(authenticationUrl, "error.url", 500, 980, this);
authWindow.loginWithOAuth();
}
}

0 comments on commit 9465a57

Please sign in to comment.