diff --git a/plugins/google-app-engine/source/com/intellij/appengine/actions/AppEngineUploader.java b/plugins/google-app-engine/source/com/intellij/appengine/actions/AppEngineUploader.java index ea24e05f88d0..5c2a9893120b 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/actions/AppEngineUploader.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/actions/AppEngineUploader.java @@ -16,6 +16,7 @@ package com.intellij.appengine.actions; import com.intellij.CommonBundle; +import com.intellij.appengine.cloud.AppEngineAuthData; import com.intellij.appengine.cloud.AppEngineServerConfiguration; import com.intellij.appengine.descriptor.dom.AppEngineWebApp; import com.intellij.appengine.facet.AppEngineAccountDialog; @@ -37,7 +38,6 @@ import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.ui.RunnerLayoutUi; import com.intellij.execution.ui.actions.CloseAction; -import com.intellij.ide.passwordSafe.PasswordSafeException; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.DefaultActionGroup; @@ -91,19 +91,17 @@ public class AppEngineUploader { private final Artifact myArtifact; private final AppEngineFacet myAppEngineFacet; private final AppEngineSdk mySdk; - private final String myEmail; - private final String myPassword; + private final AppEngineAuthData myAuthData; private final ServerRuntimeInstance.DeploymentOperationCallback myCallback; private final LoggingHandler myLoggingHandler; - private AppEngineUploader(Project project, Artifact artifact, AppEngineFacet appEngineFacet, AppEngineSdk sdk, String email, - String password, ServerRuntimeInstance.DeploymentOperationCallback callback, @Nullable LoggingHandler loggingHandler) { + private AppEngineUploader(Project project, Artifact artifact, AppEngineFacet appEngineFacet, AppEngineSdk sdk, AppEngineAuthData authData, + ServerRuntimeInstance.DeploymentOperationCallback callback, @Nullable LoggingHandler loggingHandler) { myProject = project; myArtifact = artifact; myAppEngineFacet = appEngineFacet; mySdk = sdk; - myEmail = email; - myPassword = password; + myAuthData = authData; myCallback = callback; myLoggingHandler = loggingHandler; } @@ -154,26 +152,10 @@ public class AppEngineUploader { } } - String password = null; - String email = null; - try { - email = AppEngineAccountDialog.getStoredEmail(configuration, project); - password = AppEngineAccountDialog.getStoredPassword(project, email); - } - catch (PasswordSafeException e) { - LOG.info("Cannot load stored password: " + e.getMessage()); - LOG.info(e); - } - if (StringUtil.isEmpty(email) || StringUtil.isEmpty(password)) { - final AppEngineAccountDialog dialog = new AppEngineAccountDialog(project, configuration); - dialog.show(); - if (!dialog.isOK()) return null; + AppEngineAuthData authData = AppEngineAccountDialog.createAuthData(project, configuration); + if (authData == null) return null; - email = dialog.getEmail(); - password = dialog.getPassword(); - } - - return new AppEngineUploader(project, artifact, appEngineFacet, sdk, email, password, callback, loggingHandler); + return new AppEngineUploader(project, artifact, appEngineFacet, sdk, authData, callback, loggingHandler); } public void startUploading() { @@ -231,7 +213,14 @@ public class AppEngineUploader { } final ParametersList programParameters = parameters.getProgramParametersList(); - programParameters.add("--email=" + myEmail); + if (myAuthData.isOAuth2()) { + programParameters.add("--oauth2"); + } + else { + programParameters.add("--email=" + myAuthData.getEmail()); + programParameters.add("--passin"); + } + programParameters.add("--no_cookies"); programParameters.add("update"); programParameters.add(FileUtil.toSystemDependentName(myArtifact.getOutputPath())); @@ -281,15 +270,15 @@ public class AppEngineUploader { @Override public void onTextAvailable(ProcessEvent event, Key outputType) { - if (!myPasswordEntered && !outputType.equals(ProcessOutputTypes.SYSTEM) && event.getText().contains(myEmail)) { + if (!myAuthData.isOAuth2() && !myPasswordEntered && !outputType.equals(ProcessOutputTypes.SYSTEM) && event.getText().contains(myAuthData.getEmail())) { myPasswordEntered = true; final OutputStream processInput = myProcessHandler.getProcessInput(); if (processInput != null) { //noinspection IOResourceOpenedButNotSafelyClosed final PrintWriter input = new PrintWriter(processInput); - input.println(myPassword); + input.println(myAuthData.getPassword()); input.flush(); - String message = StringUtil.repeatSymbol('*', myPassword.length()) + "\n"; + String message = StringUtil.repeatSymbol('*', myAuthData.getPassword().length()) + "\n"; if (myConsole != null) { myConsole.print(message, ConsoleViewContentType.USER_INPUT); } diff --git a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineAuthData.java b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineAuthData.java new file mode 100644 index 000000000000..7210049b42fa --- /dev/null +++ b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineAuthData.java @@ -0,0 +1,55 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.appengine.cloud; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class AppEngineAuthData { + private final boolean myOAuth2; + private final String myEmail; + private final String myPassword; + + @NotNull + public static AppEngineAuthData oauth2() { + return new AppEngineAuthData(true, null, null); + } + + @NotNull + public static AppEngineAuthData login(@NotNull String email, @NotNull String password) { + return new AppEngineAuthData(false, email, password); + } + + private AppEngineAuthData(boolean OAuth2, String email, String password) { + myOAuth2 = OAuth2; + myEmail = email; + myPassword = password; + } + + public boolean isOAuth2() { + return myOAuth2; + } + + public String getEmail() { + return myEmail; + } + + public String getPassword() { + return myPassword; + } +} diff --git a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudConfigurable.form b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudConfigurable.form new file mode 100644 index 000000000000..e26b9e6f10f0 --- /dev/null +++ b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudConfigurable.form @@ -0,0 +1,88 @@ + +
diff --git a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudConfigurable.java b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudConfigurable.java new file mode 100644 index 000000000000..6d497e0c001b --- /dev/null +++ b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudConfigurable.java @@ -0,0 +1,133 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.appengine.cloud; + +import com.intellij.appengine.facet.AppEngineAccountDialog; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.components.JBRadioButton; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** +* @author nik +*/ +public class AppEngineCloudConfigurable implements Configurable { + private final AppEngineServerConfiguration myConfiguration; + @Nullable private final Project myProject; + private JTextField myEmailField; + private JPasswordField myPasswordField; + private JBRadioButton myPasswordLoginButton; + private JBRadioButton myOAuthLoginButton; + private JPanel myMainPanel; + private JCheckBox myRememberPasswordCheckBox; + + public AppEngineCloudConfigurable(@NotNull AppEngineServerConfiguration configuration, @Nullable Project project) { + myConfiguration = configuration; + myProject = project; + ActionListener actionListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent event) { + updateControls(); + } + }; + myPasswordLoginButton.addActionListener(actionListener); + myOAuthLoginButton.addActionListener(actionListener); + myEmailField.getDocument().addDocumentListener(new DocumentAdapter() { + @Override + protected void textChanged(DocumentEvent e) { + updateControls(); + } + }); + updateControls(); + } + + private void updateControls() { + boolean passwordLogin = myPasswordLoginButton.isSelected(); + myEmailField.setEnabled(passwordLogin); + myPasswordField.setEnabled(passwordLogin); + myRememberPasswordCheckBox.setEnabled(passwordLogin); + } + + public String getEmail() { + return StringUtil.nullize(myEmailField.getText(), true); + } + + @Nls + @Override + public String getDisplayName() { + return "Google App Engine Account"; + } + + @Nullable + @Override + public String getHelpTopic() { + return null; + } + + @Nullable + @Override + public JComponent createComponent() { + return myMainPanel; + } + + public void reset() { + String email = myConfiguration.getEmail(); + myEmailField.setText(StringUtil.notNullize(email)); + if (myConfiguration.isOAuth2()) { + myOAuthLoginButton.setSelected(true); + } + else { + myPasswordLoginButton.setSelected(true); + } + updateControls(); + } + + public void apply() { + String email = getEmail(); + myConfiguration.setEmail(email); + myConfiguration.setOAuth2(isOAuth2()); + String password = getPassword(); + if (myRememberPasswordCheckBox.isSelected() && !StringUtil.isEmpty(email) && !password.isEmpty()) { + AppEngineAccountDialog.storePassword(email, password, myProject); + } + } + + public boolean isOAuth2() { + return myOAuthLoginButton.isSelected(); + } + + public String getPassword() { + return new String(myPasswordField.getPassword()); + } + + public boolean isModified() { + return !Comparing.strEqual(getEmail(), myConfiguration.getEmail()) || myConfiguration.isOAuth2() != isOAuth2(); + } + + @Override + public void disposeUIResources() { + } +} diff --git a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java index 1c466d88284a..58c1b1559bc6 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java @@ -17,7 +17,6 @@ package com.intellij.appengine.cloud; import com.intellij.appengine.actions.AppEngineUploader; import com.intellij.appengine.util.AppEngineUtil; -import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.options.UnnamedConfigurable; import com.intellij.openapi.project.Project; @@ -30,13 +29,10 @@ import com.intellij.remoteServer.runtime.ServerTaskExecutor; import com.intellij.remoteServer.runtime.deployment.DeploymentLogManager; import com.intellij.remoteServer.runtime.deployment.DeploymentTask; import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance; -import com.intellij.util.ui.FormBuilder; import icons.GoogleAppEngineIcons; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.awt.*; import java.util.List; /** @@ -69,7 +65,7 @@ public class AppEngineCloudType extends ServerType