diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCredentialsPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCredentialsPanel.form new file mode 100644 index 000000000000..d19ca613e0d4 --- /dev/null +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCredentialsPanel.form @@ -0,0 +1,174 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCredentialsPanel.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCredentialsPanel.java new file mode 100644 index 000000000000..155ae8951dc9 --- /dev/null +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCredentialsPanel.java @@ -0,0 +1,243 @@ +/* + * Copyright 2000-2016 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 org.jetbrains.plugins.github.ui; + +import com.intellij.ide.BrowserUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.HyperlinkAdapter; +import com.intellij.ui.components.JBLabel; +import com.intellij.util.ui.JBUI; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.github.api.GithubApiUtil; +import org.jetbrains.plugins.github.api.data.GithubUser; +import org.jetbrains.plugins.github.exceptions.GithubAuthenticationException; +import org.jetbrains.plugins.github.util.*; +import org.jetbrains.plugins.github.util.GithubAuthData.AuthType; + +import javax.swing.*; +import javax.swing.event.HyperlinkEvent; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.io.IOException; + +public class GithubCredentialsPanel extends JPanel { + private static final Logger LOG = GithubUtil.LOG; + + private JTextField myHostTextField; + private JTextField myLoginTextField; + private JPasswordField myPasswordField; + private JPasswordField myTokenField; + + private ComboBox myAuthTypeComboBox; + private JButton myCreateTokenButton; + private JButton myTestButton; + + private JBLabel myAuthTypeLabel; + private JTextPane mySignupTextField; + private JPanel myPane; + private JPanel myCardPanel; + + public GithubCredentialsPanel(@NotNull Project project) { + super(new BorderLayout()); + add(myPane, BorderLayout.CENTER); + + mySignupTextField.setText("Do not have an account at github.com? Sign up"); + mySignupTextField.setBackground(UIUtil.TRANSPARENT_COLOR); + mySignupTextField.setCursor(new Cursor(Cursor.HAND_CURSOR)); + mySignupTextField.setMargin(JBUI.insetsTop(5)); + mySignupTextField.addHyperlinkListener(new HyperlinkAdapter() { + @Override + protected void hyperlinkActivated(HyperlinkEvent e) { + BrowserUtil.browse(e.getURL()); + } + }); + + myAuthTypeLabel.setBorder(JBUI.Borders.emptyLeft(10)); + myAuthTypeComboBox.addItem(Layout.TOKEN); + myAuthTypeComboBox.addItem(Layout.PASSWORD); + + + myTestButton.addActionListener(e -> testAuthData(project)); + myCreateTokenButton.addActionListener(e -> generateToken(project)); + + myAuthTypeComboBox.addItemListener(e -> { + if (e.getStateChange() == ItemEvent.SELECTED) { + Layout item = (Layout)e.getItem(); + CardLayout cardLayout = (CardLayout)myCardPanel.getLayout(); + cardLayout.show(myCardPanel, item.getCard()); + } + }); + } + + @NotNull + public String getHost() { + return myHostTextField.getText().trim(); + } + + @NotNull + public String getLogin() { + return myLoginTextField.getText().trim(); + } + + @NotNull + private String getPassword() { + return String.valueOf(myPasswordField.getPassword()); + } + + @NotNull + private String getToken() { + return String.valueOf(myTokenField.getPassword()); + } + + @NotNull + public AuthType getAuthType() { + Layout selected = (Layout)myAuthTypeComboBox.getSelectedItem(); + if (selected == Layout.PASSWORD) return AuthType.BASIC; + if (selected == Layout.TOKEN) return AuthType.TOKEN; + LOG.error("GithubSettingsPanel: illegal selection - " + selected); + return AuthType.TOKEN; + } + + @NotNull + public GithubAuthData getAuthData() { + AuthType type = getAuthType(); + switch (type) { + case BASIC: + return GithubAuthData.createBasicAuth(getHost(), getLogin(), getPassword()); + case TOKEN: + return GithubAuthData.createTokenAuth(getHost(), StringUtil.trim(getToken())); + default: + throw new IllegalStateException(); + } + } + + public void setHost(@NotNull String host) { + myHostTextField.setText(host); + } + + public void setLogin(@Nullable String login) { + myLoginTextField.setText(login); + } + + public void setPassword(@NotNull String password) { + myPasswordField.setText(password); + } + + public void setToken(@NotNull String token) { + myTokenField.setText(token); + } + + public void setAuthType(@NotNull GithubAuthData.AuthType type) { + if (type == GithubAuthData.AuthType.BASIC) { + myAuthTypeComboBox.setSelectedItem(Layout.PASSWORD); + } + else { + myAuthTypeComboBox.setSelectedItem(Layout.TOKEN); + } + } + + public void setAuthData(@NotNull GithubAuthData authData) { + AuthType type = authData.getAuthType(); + setAuthType(type); + setHost(authData.getHost()); + if (type == AuthType.BASIC) { + GithubAuthData.BasicAuth basicAuth = authData.getBasicAuth(); + assert basicAuth != null; + setLogin(basicAuth.getLogin()); + setPassword(basicAuth.getPassword()); + } + if (type == AuthType.TOKEN) { + GithubAuthData.TokenAuth tokenAuth = authData.getTokenAuth(); + assert tokenAuth != null; + setToken(tokenAuth.getToken()); + } + } + + public void lockAuthType(@NotNull AuthType type) { + setAuthType(type); + myAuthTypeComboBox.setEnabled(false); + } + + public void lockHost(@NotNull String host) { + setHost(host); + myHostTextField.setEnabled(false); + } + + public void setTestButtonVisible(boolean visible) { + myTestButton.setVisible(visible); + } + + + private void testAuthData(@NotNull Project project) { + try { + GithubAuthData auth = getAuthData(); + GithubUser user = GithubUtil.computeValueInModalIO(project, "Access to GitHub", indicator -> + GithubUtil.checkAuthData(project, new GithubAuthDataHolder(auth), indicator)); + + if (AuthType.TOKEN.equals(auth.getAuthType())) { + GithubNotifications.showInfoDialog(myPane, "Success", "Connection successful for user " + user.getLogin()); + } + else { + GithubNotifications.showInfoDialog(myPane, "Success", "Connection successful"); + } + } + catch (GithubAuthenticationException ex) { + GithubNotifications.showErrorDialog(myPane, "Login Failure", "Can't login using given credentials: ", ex); + } + catch (IOException ex) { + GithubNotifications.showErrorDialog(myPane, "Login Failure", "Can't login: ", ex); + } + } + + private void generateToken(@NotNull Project project) { + try { + String newToken = GithubUtil.computeValueInModalIO(project, "Access to GitHub", indicator -> + GithubUtil.runTask(project, GithubAuthDataHolder.createFromSettings(), indicator, AuthLevel.basicOnetime(getHost()), connection -> + GithubApiUtil.getMasterToken(connection, "IntelliJ plugin"))); + myTokenField.setText(newToken); + } + catch (IOException ex) { + GithubNotifications.showErrorDialog(myPane, "Can't Create API Token", ex); + } + } + + + private enum Layout { + PASSWORD("Password"), + TOKEN("Token"); + + @NotNull private final String myCard; + + Layout(@NotNull String card) { + myCard = card; + } + + @NotNull + public String getCard() { + return myCard; + } + + @Override + public String toString() { + return myCard; + } + } +} diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java index 79f750d9fb42..919ab592afd6 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java @@ -9,46 +9,36 @@ import org.jetbrains.plugins.github.util.*; import javax.swing.*; import java.io.IOException; -/** - * @author oleg - * @date 10/20/10 - */ public class GithubLoginDialog extends DialogWrapper { - private static final Logger LOG = GithubUtil.LOG; - private final GithubLoginPanel myGithubLoginPanel; - private final GithubSettings mySettings; + private final GithubCredentialsPanel myCredentialsPanel; @NotNull private final Project myProject; @NotNull private final AuthLevel myAuthLevel; - protected GithubAuthData myAuthData; + private GithubAuthData myAuthData; + private boolean mySavePassword; - public GithubLoginDialog(@NotNull final Project project, @NotNull GithubAuthData oldAuthData, @NotNull AuthLevel authLevel) { + public GithubLoginDialog(@NotNull Project project, @NotNull GithubAuthData oldAuthData, @NotNull AuthLevel authLevel) { super(project, true); myProject = project; myAuthLevel = authLevel; - myGithubLoginPanel = new GithubLoginPanel(this); + myCredentialsPanel = new GithubCredentialsPanel(project); + myCredentialsPanel.setTestButtonVisible(false); - myGithubLoginPanel.setHost(oldAuthData.getHost()); - myGithubLoginPanel.setAuthType(oldAuthData.getAuthType()); + myCredentialsPanel.setHost(oldAuthData.getHost()); + myCredentialsPanel.setAuthType(oldAuthData.getAuthType()); GithubAuthData.BasicAuth basicAuth = oldAuthData.getBasicAuth(); if (basicAuth != null) { - myGithubLoginPanel.setLogin(basicAuth.getLogin()); + myCredentialsPanel.setLogin(basicAuth.getLogin()); } - mySettings = GithubSettings.getInstance(); - if (mySettings.isSavePasswordMakesSense() && !authLevel.isOnetime()) { - myGithubLoginPanel.setSavePasswordSelected(mySettings.isSavePassword()); - } - else { - myGithubLoginPanel.setSavePasswordVisibleEnabled(false); - } + if (authLevel.getHost() != null) myCredentialsPanel.lockHost(authLevel.getHost()); + if (authLevel.getAuthType() != null) myCredentialsPanel.lockAuthType(authLevel.getAuthType()); - if (authLevel.getHost() != null) myGithubLoginPanel.lockHost(authLevel.getHost()); - if (authLevel.getAuthType() != null) myGithubLoginPanel.lockAuthType(authLevel.getAuthType()); + if (!authLevel.isOnetime()) setDoNotAskOption(new MyRememberPasswordOption()); setTitle("Login to GitHub"); setOKButtonText("Login"); @@ -62,7 +52,7 @@ public class GithubLoginDialog extends DialogWrapper { @Override protected JComponent createCenterPanel() { - return myGithubLoginPanel.getPanel(); + return myCredentialsPanel; } @Override @@ -70,23 +60,15 @@ public class GithubLoginDialog extends DialogWrapper { return "login_to_github"; } - @Override - public JComponent getPreferredFocusedComponent() { - return myGithubLoginPanel.getPreferableFocusComponent(); - } - @Override protected void doOKAction() { - final GithubAuthDataHolder authHolder = new GithubAuthDataHolder(myGithubLoginPanel.getAuthData()); + GithubAuthDataHolder authHolder = new GithubAuthDataHolder(myCredentialsPanel.getAuthData()); try { GithubUtil.computeValueInModalIO(myProject, "Access to GitHub", indicator -> GithubUtil.checkAuthData(myProject, authHolder, indicator)); myAuthData = authHolder.getAuthData(); - if (mySettings.isSavePasswordMakesSense()) { - mySettings.setSavePassword(myGithubLoginPanel.isSavePasswordSelected()); - } super.doOKAction(); } catch (IOException e) { @@ -96,7 +78,7 @@ public class GithubLoginDialog extends DialogWrapper { } public boolean isSavePasswordSelected() { - return myGithubLoginPanel.isSavePasswordSelected(); + return mySavePassword; } @NotNull @@ -107,7 +89,32 @@ public class GithubLoginDialog extends DialogWrapper { return myAuthData; } - public void clearErrors() { - setErrorText(null); + private class MyRememberPasswordOption implements DoNotAskOption { + @Override + public boolean isToBeShown() { + return !GithubSettings.getInstance().isSavePassword(); + } + + @Override + public void setToBeShown(boolean toBeShown, int exitCode) { + mySavePassword = !toBeShown; + GithubSettings.getInstance().setSavePassword(!toBeShown); + } + + @Override + public boolean canBeHidden() { + return GithubSettings.getInstance().isSavePasswordMakesSense(); + } + + @Override + public boolean shouldSaveOptionsOnCancel() { + return false; + } + + @NotNull + @Override + public String getDoNotShowMessage() { + return "Save credentials"; + } } } \ No newline at end of file diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.form deleted file mode 100644 index 4b806c28872f..000000000000 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.form +++ /dev/null @@ -1,109 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.java deleted file mode 100644 index 4ee158756213..000000000000 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2000-2016 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 org.jetbrains.plugins.github.ui; - -import com.intellij.ide.BrowserUtil; -import com.intellij.openapi.ui.ComboBox; -import com.intellij.ui.DocumentAdapter; -import com.intellij.ui.HyperlinkAdapter; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.ui.JBUI; -import com.intellij.util.ui.UIUtil; -import com.intellij.util.ui.table.ComponentsListFocusTraversalPolicy; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.github.util.GithubAuthData; -import org.jetbrains.plugins.github.util.GithubUtil; - -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.HyperlinkEvent; -import java.awt.*; -import java.awt.event.ItemEvent; -import java.util.ArrayList; -import java.util.List; - -/** - * @author oleg - * @date 10/20/10 - */ -public class GithubLoginPanel { - private JPanel myPane; - private JTextField myHostTextField; - private JTextField myLoginTextField; - private JPasswordField myPasswordField; - private JTextPane mySignupTextField; - private JCheckBox mySavePasswordCheckBox; - private ComboBox myAuthTypeComboBox; - private JLabel myPasswordLabel; - private JLabel myLoginLabel; - - private final static String AUTH_PASSWORD = "Password"; - private final static String AUTH_TOKEN = "Token"; - - public GithubLoginPanel(final GithubLoginDialog dialog) { - DocumentListener listener = new DocumentAdapter() { - @Override - protected void textChanged(DocumentEvent e) { - dialog.clearErrors(); - } - }; - myLoginTextField.getDocument().addDocumentListener(listener); - myPasswordField.getDocument().addDocumentListener(listener); - mySignupTextField.setText("Do not have an account at github.com? Sign up."); - mySignupTextField.setMargin(JBUI.insetsTop(5)); - mySignupTextField.addHyperlinkListener(new HyperlinkAdapter() { - @Override - protected void hyperlinkActivated(final HyperlinkEvent e) { - BrowserUtil.browse(e.getURL()); - } - }); - mySignupTextField.setBackground(UIUtil.TRANSPARENT_COLOR); - mySignupTextField.setCursor(new Cursor(Cursor.HAND_CURSOR)); - - myAuthTypeComboBox.addItem(AUTH_PASSWORD); - myAuthTypeComboBox.addItem(AUTH_TOKEN); - - myAuthTypeComboBox.addItemListener(e -> { - if (e.getStateChange() == ItemEvent.SELECTED) { - String item = e.getItem().toString(); - if (AUTH_PASSWORD.equals(item)) { - myPasswordLabel.setText("Password:"); - mySavePasswordCheckBox.setText("Save password"); - myLoginLabel.setVisible(true); - myLoginTextField.setVisible(true); - } - else if (AUTH_TOKEN.equals(item)) { - myPasswordLabel.setText("Token:"); - mySavePasswordCheckBox.setText("Save token"); - myLoginLabel.setVisible(false); - myLoginTextField.setVisible(false); - } - if (dialog.isShowing()) { - dialog.pack(); - } - } - }); - - List order = new ArrayList(); - order.add(myHostTextField); - order.add(myAuthTypeComboBox); - order.add(mySavePasswordCheckBox); - order.add(myLoginTextField); - order.add(myPasswordField); - myPane.setFocusTraversalPolicyProvider(true); - myPane.setFocusTraversalPolicy(new MyFocusTraversalPolicy(order)); - } - - public JComponent getPanel() { - return myPane; - } - - public void setHost(@NotNull String host) { - myHostTextField.setText(host); - } - - public void setLogin(@Nullable String login) { - myLoginTextField.setText(login); - } - - public void setAuthType(@NotNull GithubAuthData.AuthType type) { - switch (type) { - case BASIC: - myAuthTypeComboBox.setSelectedItem(AUTH_PASSWORD); - break; - case TOKEN: - myAuthTypeComboBox.setSelectedItem(AUTH_TOKEN); - break; - case ANONYMOUS: - myAuthTypeComboBox.setSelectedItem(AUTH_PASSWORD); - } - } - - public void lockAuthType(@NotNull GithubAuthData.AuthType type) { - setAuthType(type); - myAuthTypeComboBox.setEnabled(false); - } - - public void lockHost(@NotNull String host) { - setHost(host); - myHostTextField.setEnabled(false); - } - - public void setSavePasswordSelected(boolean savePassword) { - mySavePasswordCheckBox.setSelected(savePassword); - } - - public void setSavePasswordVisibleEnabled(boolean visible) { - mySavePasswordCheckBox.setVisible(visible); - mySavePasswordCheckBox.setEnabled(visible); - } - - @NotNull - public String getHost() { - return myHostTextField.getText().trim(); - } - - @NotNull - public String getLogin() { - return myLoginTextField.getText().trim(); - } - - @NotNull - private String getPassword() { - return String.valueOf(myPasswordField.getPassword()); - } - - public boolean isSavePasswordSelected() { - return mySavePasswordCheckBox.isSelected(); - } - - public JComponent getPreferableFocusComponent() { - return myLoginTextField.isVisible() ? myLoginTextField : myPasswordField; - } - - @NotNull - public GithubAuthData getAuthData() { - Object selected = myAuthTypeComboBox.getSelectedItem(); - if (AUTH_PASSWORD.equals(selected)) return GithubAuthData.createBasicAuth(getHost(), getLogin(), getPassword()); - if (AUTH_TOKEN.equals(selected)) return GithubAuthData.createTokenAuth(getHost(), getPassword()); - GithubUtil.LOG.error("GithubLoginPanel illegal selection: anonymous AuthData created", selected.toString()); - return GithubAuthData.createAnonymous(getHost()); - } - - private static class MyFocusTraversalPolicy extends ComponentsListFocusTraversalPolicy { - @NotNull private List myOrder; - - private MyFocusTraversalPolicy(@NotNull List order) { - myOrder = order; - } - - @NotNull - @Override - protected List getOrderedComponents() { - return ContainerUtil.filter(myOrder, component -> component.isVisible() && component.isEnabled()); - } - } -} - diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form index 426d23371ef7..d06c61119b08 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form @@ -1,6 +1,6 @@
- + @@ -11,171 +11,20 @@ - + - + - - - - - - - + + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -184,7 +33,7 @@ - + @@ -224,7 +73,7 @@ - + diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java index bd5627877be1..0c09bec8d814 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java @@ -15,233 +15,45 @@ */ package org.jetbrains.plugins.github.ui; -import com.intellij.ide.BrowserUtil; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.ui.DocumentAdapter; -import com.intellij.ui.HyperlinkAdapter; import com.intellij.ui.components.JBCheckBox; -import com.intellij.ui.components.JBLabel; -import com.intellij.util.ui.JBUI; +import gnu.trove.Equality; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.github.api.GithubApiUtil; -import org.jetbrains.plugins.github.api.data.GithubUser; -import org.jetbrains.plugins.github.exceptions.GithubAuthenticationException; -import org.jetbrains.plugins.github.util.*; +import org.jetbrains.plugins.github.util.GithubAuthData; +import org.jetbrains.plugins.github.util.GithubSettings; import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.HyperlinkEvent; -import javax.swing.text.Document; -import javax.swing.text.PlainDocument; -import java.awt.*; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.awt.event.ItemEvent; -import java.io.IOException; -/** - * @author oleg - * @date 10/20/10 - */ public class GithubSettingsPanel { - private static final String DEFAULT_PASSWORD_TEXT = "************"; - private final static String AUTH_PASSWORD = "Password"; - private final static String AUTH_TOKEN = "Token"; - - private static final Logger LOG = GithubUtil.LOG; - private final GithubSettings mySettings; - private JTextField myLoginTextField; - private JPasswordField myPasswordField; - private JPasswordField myTokenField; // look at createUIComponents() to understand - private JTextPane mySignupTextField; private JPanel myPane; - private JButton myTestButton; - private JTextField myHostTextField; - private ComboBox myAuthTypeComboBox; - private JPanel myCardPanel; - private JBLabel myAuthTypeLabel; private JSpinner myTimeoutSpinner; - private JButton myCreateTokenButton; private JBCheckBox myCloneUsingSshCheckBox; - - private boolean myCredentialsModified; + private GithubCredentialsPanel myCredentialsPanel; public GithubSettingsPanel() { mySettings = GithubSettings.getInstance(); - mySignupTextField.addHyperlinkListener(new HyperlinkAdapter() { - @Override - protected void hyperlinkActivated(final HyperlinkEvent e) { - BrowserUtil.browse(e.getURL()); - } - }); - mySignupTextField.setText("Do not have an account at github.com? " + "Sign up" + ""); - mySignupTextField.setBackground(myPane.getBackground()); - mySignupTextField.setCursor(new Cursor(Cursor.HAND_CURSOR)); - myAuthTypeLabel.setBorder(JBUI.Borders.emptyLeft(10)); - myAuthTypeComboBox.addItem(AUTH_PASSWORD); - myAuthTypeComboBox.addItem(AUTH_TOKEN); - - final Project project = ProjectManager.getInstance().getDefaultProject(); - - myTestButton.addActionListener(e -> { - try { - final GithubAuthData auth = getAuthData(); - GithubUser user = GithubUtil.computeValueInModalIO(project, "Access to GitHub", indicator -> - GithubUtil.checkAuthData(project, new GithubAuthDataHolder(auth), indicator)); - - if (GithubAuthData.AuthType.TOKEN.equals(getAuthType())) { - GithubNotifications.showInfoDialog(myPane, "Success", "Connection successful for user " + user.getLogin()); - } - else { - GithubNotifications.showInfoDialog(myPane, "Success", "Connection successful"); - } - } - catch (GithubAuthenticationException ex) { - GithubNotifications.showErrorDialog(myPane, "Login Failure", "Can't login using given credentials: ", ex); - } - catch (IOException ex) { - GithubNotifications.showErrorDialog(myPane, "Login Failure", "Can't login: ", ex); - } - }); - - myCreateTokenButton.addActionListener(e -> { - try { - String newToken = GithubUtil.computeValueInModalIO(project, "Access to GitHub", indicator -> - GithubUtil.runTask(project, GithubAuthDataHolder.createFromSettings(), indicator, AuthLevel.basicOnetime(getHost()), connection -> - GithubApiUtil.getMasterToken(connection, "IntelliJ plugin"))); - myPasswordField.setText(newToken); - } - catch (IOException ex) { - GithubNotifications.showErrorDialog(myPane, "Can't Create API Token", ex); - } - }); - - myPasswordField.getDocument().addDocumentListener(new DocumentAdapter() { - @Override - protected void textChanged(DocumentEvent e) { - myCredentialsModified = true; - } - }); - - DocumentListener passwordEraser = new DocumentAdapter() { - @Override - protected void textChanged(DocumentEvent e) { - if (!myCredentialsModified) { - erasePassword(); - } - } - }; - myHostTextField.getDocument().addDocumentListener(passwordEraser); - myLoginTextField.getDocument().addDocumentListener(passwordEraser); - - myPasswordField.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - if (!myCredentialsModified && !getPassword().isEmpty()) { - erasePassword(); - } - } - - @Override - public void focusLost(FocusEvent e) { - } - }); - - myAuthTypeComboBox.addItemListener(e -> { - if (e.getStateChange() == ItemEvent.SELECTED) { - String item = e.getItem().toString(); - if (AUTH_PASSWORD.equals(item)) { - ((CardLayout)myCardPanel.getLayout()).show(myCardPanel, AUTH_PASSWORD); - } - else if (AUTH_TOKEN.equals(item)) { - ((CardLayout)myCardPanel.getLayout()).show(myCardPanel, AUTH_TOKEN); - } - erasePassword(); - } - }); reset(); } - private void erasePassword() { - setPassword(""); - myCredentialsModified = true; - } - public JComponent getPanel() { return myPane; } - @NotNull - public String getHost() { - return myHostTextField.getText().trim(); - } - - @NotNull - public String getLogin() { - return myLoginTextField.getText().trim(); - } - - public void setHost(@NotNull final String host) { - myHostTextField.setText(host); - } - - public void setLogin(@Nullable final String login) { - myLoginTextField.setText(login); - } - - @NotNull - private String getPassword() { - return String.valueOf(myPasswordField.getPassword()); - } - - private void setPassword(@NotNull final String password) { - // Show password as blank if password is empty - myPasswordField.setText(StringUtil.isEmpty(password) ? null : password); - } - - @NotNull - public GithubAuthData.AuthType getAuthType() { - Object selected = myAuthTypeComboBox.getSelectedItem(); - if (AUTH_PASSWORD.equals(selected)) return GithubAuthData.AuthType.BASIC; - if (AUTH_TOKEN.equals(selected)) return GithubAuthData.AuthType.TOKEN; - LOG.error("GithubSettingsPanel: illegal selection: basic AuthType returned", selected.toString()); - return GithubAuthData.AuthType.BASIC; - } - - public void setAuthType(@NotNull final GithubAuthData.AuthType type) { - switch (type) { - case BASIC: - myAuthTypeComboBox.setSelectedItem(AUTH_PASSWORD); - break; - case TOKEN: - myAuthTypeComboBox.setSelectedItem(AUTH_TOKEN); - break; - case ANONYMOUS: - default: - myAuthTypeComboBox.setSelectedItem(AUTH_PASSWORD); - } - } - @NotNull public GithubAuthData getAuthData() { - if (!myCredentialsModified) { - return mySettings.getAuthData(); + GithubAuthData authData = myCredentialsPanel.getAuthData(); + if (authData.getBasicAuth() != null && StringUtil.isEmptyOrSpaces(authData.getBasicAuth().getLogin()) || + authData.getTokenAuth() != null && StringUtil.isEmptyOrSpaces(authData.getTokenAuth().getToken())) { + return GithubAuthData.createAnonymous(myCredentialsPanel.getHost()); } - Object selected = myAuthTypeComboBox.getSelectedItem(); - if (AUTH_PASSWORD.equals(selected)) return GithubAuthData.createBasicAuth(getHost(), getLogin(), getPassword()); - if (AUTH_TOKEN.equals(selected)) return GithubAuthData.createTokenAuth(getHost(), StringUtil.trim(getPassword())); - LOG.error("GithubSettingsPanel: illegal selection: anonymous AuthData created", selected.toString()); - return GithubAuthData.createAnonymous(getHost()); + + return authData; } public void setConnectionTimeout(int timeout) { @@ -253,40 +65,45 @@ public class GithubSettingsPanel { } public void reset() { - setHost(mySettings.getHost()); - setLogin(mySettings.getLogin()); - setPassword(mySettings.isAuthConfigured() ? DEFAULT_PASSWORD_TEXT : ""); - setAuthType(mySettings.getAuthType()); + myCredentialsPanel.setAuthData(mySettings.getAuthData()); + setConnectionTimeout(mySettings.getConnectionTimeout()); myCloneUsingSshCheckBox.setSelected(mySettings.isCloneGitUsingSsh()); - resetCredentialsModification(); } public void apply() { - if (myCredentialsModified) { + if (!equal(mySettings.getAuthData(), getAuthData())) { mySettings.setAuthData(getAuthData(), true); } mySettings.setConnectionTimeout(getConnectionTimeout()); mySettings.setCloneGitUsingSsh(myCloneUsingSshCheckBox.isSelected()); - resetCredentialsModification(); } public boolean isModified() { - return myCredentialsModified || - !Comparing.equal(mySettings.getHost(), getHost()) || + return !equal(mySettings.getAuthData(), getAuthData()) || !Comparing.equal(mySettings.getConnectionTimeout(), getConnectionTimeout()) || !Comparing.equal(mySettings.isCloneGitUsingSsh(), myCloneUsingSshCheckBox.isSelected()); } - public void resetCredentialsModification() { - myCredentialsModified = false; + private void createUIComponents() { + myCredentialsPanel = new GithubCredentialsPanel(ProjectManager.getInstance().getDefaultProject()); + myTimeoutSpinner = new JSpinner(new SpinnerNumberModel(5000, 0, 60000, 500)); } - private void createUIComponents() { - Document doc = new PlainDocument(); - myPasswordField = new JPasswordField(doc, null, 0); - myTokenField = new JPasswordField(doc, null, 0); - myTimeoutSpinner = - new JSpinner(new SpinnerNumberModel(Integer.valueOf(5000), Integer.valueOf(0), Integer.valueOf(60000), Integer.valueOf(500))); + private static boolean equal(@NotNull GithubAuthData data1, @NotNull GithubAuthData data2) { + return Comparing.equal(data1.getHost(), data2.getHost()) && + Comparing.equal(data1.getAuthType(), data2.getAuthType()) && + equal(data1.getBasicAuth(), data2.getBasicAuth(), + (auth1, auth2) -> Comparing.equal(auth1.getLogin(), auth2.getLogin()) && + Comparing.equal(auth1.getPassword(), auth2.getPassword())) && + equal(data1.getTokenAuth(), data2.getTokenAuth(), + (auth1, auth2) -> Comparing.equal(auth1.getToken(), auth2.getToken())); + } + + private static boolean equal(@Nullable T o1, @Nullable T o2, @NotNull Equality notNullEquality) { + if (o1 == o2) return true; + if (o1 == null) return false; + if (o2 == null) return false; + return notNullEquality.equals(o1, o2); } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.java index e27e3de74bfb..f256a93072d2 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.java +++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.java @@ -18,7 +18,6 @@ package org.jetbrains.plugins.github.util; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.github.api.GithubApiUtil; /** * Container for authentication data: @@ -58,7 +57,7 @@ public class GithubAuthData { } public static GithubAuthData createAnonymous() { - return createAnonymous(GithubApiUtil.DEFAULT_GITHUB_HOST); + return createAnonymous(GithubSettings.getInstance().getHost()); } public static GithubAuthData createAnonymous(@NotNull String host) { diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java index 41f4ced21158..ad1999ca934f 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java +++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubSettings.java @@ -196,7 +196,7 @@ public class GithubSettings implements PersistentStateComponent