aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEmil Ivov <emcho@jitsi.org>2012-08-07 18:32:13 +0000
committerEmil Ivov <emcho@jitsi.org>2012-08-07 18:32:13 +0000
commitab1a357d8cb3e05d205a26c5bfe8a7e3fbd11978 (patch)
tree1fb81e9b39745bc1bd66b0178d155f622139caf2 /src
parent20a28fa8c210a665f6a5fc4ef37ab12fe70a1ba8 (diff)
downloadjitsi-ab1a357d8cb3e05d205a26c5bfe8a7e3fbd11978.zip
jitsi-ab1a357d8cb3e05d205a26c5bfe8a7e3fbd11978.tar.gz
jitsi-ab1a357d8cb3e05d205a26c5bfe8a7e3fbd11978.tar.bz2
Adds password modification from within Jitsi for XMPP accounts that allow it. Contributed by Boris Grozev.
Diffstat (limited to 'src')
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OperationSetChangePasswordJabberImpl.java73
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java5
-rw-r--r--src/net/java/sip/communicator/plugin/jabberaccregwizz/AccountPanel.java322
-rw-r--r--src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationForm.java22
-rw-r--r--src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationWizard.java12
-rw-r--r--src/net/java/sip/communicator/service/protocol/OperationSetChangePassword.java26
6 files changed, 458 insertions, 2 deletions
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetChangePasswordJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetChangePasswordJabberImpl.java
new file mode 100644
index 0000000..82b89d5
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetChangePasswordJabberImpl.java
@@ -0,0 +1,73 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.protocol.jabber;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+import org.jivesoftware.smack.*;
+
+/**
+ * A jabber implementation of the password change operation set.
+ *
+ * @author Boris Grozev
+ */
+public class OperationSetChangePasswordJabberImpl
+ implements OperationSetChangePassword
+{
+ /**
+ * The <tt>ProtocolProviderService</tt> whose password we'll change.
+ */
+ private ProtocolProviderServiceJabberImpl protocolProvider;
+
+ /**
+ * The logger used by <tt>OperationSetChangePasswordJabberImpl</tt>.
+ */
+ private static final Logger logger =
+ Logger.getLogger(OperationSetChangePasswordJabberImpl.class);
+
+ /**
+ * Sets the object protocolProvider to the one given.
+ * @param protocolProvider the protocolProvider to use.
+ */
+ OperationSetChangePasswordJabberImpl (
+ ProtocolProviderServiceJabberImpl protocolProvider)
+ {
+ this.protocolProvider = protocolProvider;
+ }
+
+ /**
+ * Changes the jabber account password of protocolProvider to newPass.
+ * @param newPass the new password.
+ * @throws IllegalStateException if the account is not registered.
+ * @throws OperationFailedException if the server does not support password
+ * changes.
+ */
+ public void changePassword(String newPass)
+ throws IllegalStateException, OperationFailedException
+ {
+ org.jivesoftware.smack.AccountManager accountManager
+ = new org.jivesoftware.smack.AccountManager(
+ protocolProvider.getConnection());
+
+ try
+ {
+ accountManager.changePassword(newPass);
+ }
+ catch (XMPPException e)
+ {
+ if(logger.isInfoEnabled())
+ {
+ logger.info("Tried to change jabber password, but the server "
+ + "does not support inband password changes", e);
+ }
+
+ throw new OperationFailedException("In-band password changes not"
+ + " supported",
+ OperationFailedException.NOT_SUPPORTED_OPERATION,
+ e);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
index d6947d7..c2d0865 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
@@ -1794,6 +1794,11 @@ public class ProtocolProviderServiceJabberImpl
supportedFeatures.add(MessageCorrectionExtension.NAMESPACE);
addSupportedOperationSet(OperationSetMessageCorrection.class,
basicInstantMessaging);
+
+ OperationSetChangePassword opsetChangePassword
+ = new OperationSetChangePasswordJabberImpl(this);
+ addSupportedOperationSet(OperationSetChangePassword.class,
+ opsetChangePassword);
isInitialized = true;
}
diff --git a/src/net/java/sip/communicator/plugin/jabberaccregwizz/AccountPanel.java b/src/net/java/sip/communicator/plugin/jabberaccregwizz/AccountPanel.java
index 264e875..0bcac3a 100644
--- a/src/net/java/sip/communicator/plugin/jabberaccregwizz/AccountPanel.java
+++ b/src/net/java/sip/communicator/plugin/jabberaccregwizz/AccountPanel.java
@@ -14,6 +14,7 @@ import javax.swing.event.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
+import net.java.sip.communicator.service.protocol.*;
/**
* @author Yana Stamcheva
*/
@@ -48,6 +49,18 @@ public class AccountPanel
private final JCheckBox rememberPassBox = new SIPCommCheckBox(Resources
.getString("service.gui.REMEMBER_PASSWORD"));
+ /**
+ * Panel to hold the "change password" button
+ */
+ private final JPanel changePasswordPanel = new TransparentPanel();
+
+ /**
+ * "Change password" button
+ */
+ private final JButton changePasswordButton
+ = new JButton(Resources.getString(
+ "plugin.jabberaccregwizz.CHANGE_PASSWORD"));
+
private final JabberAccountRegistrationForm parentForm;
private final JRadioButton existingAccountButton;
@@ -128,8 +141,19 @@ public class AccountPanel
userIDPassPanel.add(southPanel, BorderLayout.SOUTH);
this.add(mainPanel, BorderLayout.NORTH);
+
+ changePasswordButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ ChangePasswordDialog changePasswordDialog
+ = new ChangePasswordDialog();
+ }
+ });
+ changePasswordPanel.add(changePasswordButton, BorderLayout.CENTER);
+ //show it only if needed (when modifying an account)
+ changePasswordPanel.setVisible(false);
+ this.add(changePasswordPanel);
+
}
-
/**
* Creates a register choice panel.
* @return the created component
@@ -473,4 +497,300 @@ public class AccountPanel
return registerButton;
}
+ /**
+ * Shows or hides the "change password" button
+ */
+ public void showChangePasswordButton()
+ {
+ changePasswordPanel.setVisible(true);
+ }
+
+ /**
+ * A "change password" dialog.
+ */
+ private class ChangePasswordDialog extends SIPCommDialog
+ {
+ /**
+ * The main panel
+ */
+ private final JPanel mainPanel = new JPanel(new BorderLayout());
+
+ /**
+ * A pane for showing messages (info or errors)
+ */
+ private final JEditorPane messagePane = new JEditorPane();
+
+ /**
+ * Panel for the text fields
+ */
+ TransparentPanel valuesPanel
+ = new TransparentPanel(new GridLayout(0, 1));
+
+ /**
+ * The password field
+ */
+ private final JPasswordField passField1 = new JPasswordField();
+
+ /**
+ * The confirm password field
+ */
+ private final JPasswordField passField2 = new JPasswordField();
+
+ /**
+ * Panel for the "ok" and "cancel" buttons
+ */
+ private final TransparentPanel buttonsPanel
+ = new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));
+
+ /**
+ * The "OK" button
+ */
+ private final JButton okButton
+ = new JButton(Resources.getString("service.gui.OK"));
+
+ /**
+ * The "cancel" button
+ */
+ private final JButton cancelButton
+ = new JButton(Resources.getString("service.gui.CANCEL"));
+
+ /**
+ * Panel for the labels
+ */
+ private final TransparentPanel labelsPanel
+ = new TransparentPanel(new GridLayout(0, 1));
+
+ /**
+ * The "new password" label
+ */
+ private final JLabel passLabel1 = new JLabel(Resources.
+ getString("plugin.jabberaccregwizz.NEW_PASSWORD"));
+
+ /**
+ * The "confirm password" label
+ */
+ private final JLabel passLabel2 = new JLabel(Resources.
+ getString("plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM"));
+
+
+ /**
+ * Creates a full dialog (sets all the fields and buttons)
+ */
+ public ChangePasswordDialog()
+ {
+ //don't save size and location
+ super(false);
+
+ setTitle(Resources.
+ getString("plugin.jabberaccregwizz.CHANGE_PASSWORD"));
+
+ messagePane.setOpaque(false);
+ messagePane.setForeground(Color.RED);
+ messagePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 15, 0));
+ messagePane.setEditable(false);
+ mainPanel.add(messagePane, BorderLayout.NORTH);
+ loadMessage(Resources.getString(
+ "plugin.jabberaccregwizz.ENTER_NEW_PASSWORD"));
+
+ labelsPanel.add(passLabel1);
+ labelsPanel.add(passLabel2);
+
+ passField1.setColumns(15);
+ passField2.setColumns(15);
+ valuesPanel.add(passField1);
+ valuesPanel.add(passField2);
+
+ okButton.addActionListener(okButtonListener);
+ cancelButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e){
+ dispose();
+ }
+ });
+
+ buttonsPanel.add(okButton);
+ buttonsPanel.add(cancelButton);
+ getRootPane().setDefaultButton(okButton);
+
+ mainPanel.add(labelsPanel, BorderLayout.WEST);
+ mainPanel.add(valuesPanel, BorderLayout.CENTER);
+ mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
+
+ mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+ getContentPane().add(mainPanel, BorderLayout.NORTH);
+ setModal(true);
+ setVisible(true);
+ pack();
+ }
+
+ /**
+ * This is the ActionListener for the "ok" button.
+ */
+ private final ActionListener okButtonListener = new ActionListener(){
+ /**
+ * Action for the "ok" button. This contains most of the logic for
+ * the dialog:
+ * It checks the fields, whether the account is logged in, tries to
+ * change the password and displays messages in the message pane
+ */
+ public void actionPerformed(ActionEvent e) {
+ String newPass1 = new String(passField1.getPassword());
+ String newPass2 = new String(passField2.getPassword());
+
+ ProtocolProviderService protocolProvider =
+ parentForm.getWizard().getProtocolProvider();
+
+ if (protocolProvider == null) {
+ //we shouldn't get here, because this dialog only shows
+ //when editing an existing account
+ logger.warn("protocolProvider is null in change"
+ + " password dialog");
+ loadMessage("Could not change password");
+ hideCancelAndFields();
+ okButton.removeActionListener(okButtonListener);
+ okButton.addActionListener(new ActionListener(){
+ public void actionPerformed(ActionEvent e)
+ {
+ dispose();
+ }
+ });
+ }
+ else if (!protocolProvider.isRegistered()) {
+ //editing an account, which is not logged in
+ loadMessage(Resources.getString(
+ "plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN"));
+ }
+ else if (!newPass1.equals(newPass2)) {
+ loadMessage(Resources.getString(
+ "plugin.jabberaccregwizz.NOT_SAME_PASSWORD"));
+ }
+ else if (newPass1.length() <= 0) {
+ loadMessage(Resources.getString(
+ "plugin.jabberaccregwizz.PASSWORD_EMPTY"));
+ }
+ else if (protocolProvider.getTransportProtocol()
+ != TransportProtocol.TLS) {
+ //XEP-077 advices agains changing password unless
+ //the underlying stream is encrypted
+ loadMessage(Resources.getString(
+ "plugin.jabberaccregwizz.TLS_REQUIRED"));
+ }
+ else //try to change
+ {
+ if (logger.isInfoEnabled()) {
+ logger.info("Trying to change password for jabber"
+ + " account "
+ + protocolProvider.
+ getAccountID().getAccountAddress());
+ }
+
+ OperationSetChangePassword opset =
+ protocolProvider.getOperationSet(
+ OperationSetChangePassword.class);
+ try {
+ opset.changePassword(newPass1);
+ loadMessage(Resources.getString(
+ "plugin.jabberaccregwizz.PASSWORD_CHANGED"));
+
+ /**
+ * If the old password was stored, update it with the
+ * new one. If the old password was not stored, leave it
+ * like it is.
+ */
+ if (isRememberPassword())
+ {
+ try
+ {
+ if(logger.isInfoEnabled())
+ logger.info("Storing new password for"
+ + " account " + protocolProvider.
+ getAccountID().getAccountAddress());
+
+ storeNewPassword(newPass1);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ //If we get here its a bug, and showing a
+ //message like this might be unappropriate. But
+ //the user would want to know about it!
+ logger.warn("Failed to store password for"
+ + " account " + protocolProvider.
+ getAccountID().getAccountAddress(),
+ ex);
+ loadMessage(Resources.getString(
+ "plugin.jabberaccregwizz."
+ + "PASSWORD_NOT_STORED"));
+ }
+
+ //now update the password field in AccountPanel,
+ //because it still has the old pass and if the user
+ //completes the wizard it will store it.
+ passField.setText(newPass1);
+ }
+
+ hideCancelAndFields();
+ okButton.removeActionListener(this);
+ okButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ dispose();
+ }
+ });
+ }
+ catch (IllegalStateException ex) {
+ //we already checked for this, but if the connection
+ //has since been lost smack will throw this
+ loadMessage(Resources.getString(
+ "plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN"));
+ }
+ catch (OperationFailedException ex) {
+ loadMessage(Resources.getString(
+ "plugin.jabberaccregwizz."
+ + "SERVER_NOT_SUPPORT_PASSWORD_CHANGE"));
+ }
+ }
+ }
+ };
+
+
+ /**
+ * Loads the given message into the message pane.
+ * @param message The message to load
+ */
+ private void loadMessage(String message)
+ {
+ messagePane.setText(message);
+ mainPanel.revalidate();
+ mainPanel.repaint();
+ pack();
+ }
+
+ /**
+ * Leaves only the message pane and the "ok" button visible
+ * XXX: a more appropriate name?
+ */
+ public void hideCancelAndFields()
+ {
+ cancelButton.setVisible(false);
+ passField1.setVisible(false);
+ passField2.setVisible(false);
+ passLabel1.setVisible(false);
+ passLabel2.setVisible(false);
+ pack();
+ }
+
+ /**
+ * Stores the new password in the account configuration
+ * @param newPass The new password
+ * @throws IllegalArgumentException on failure (from
+ * ProtocolProviderFactory.storePassword)
+ */
+ void storeNewPassword(String newPass) throws IllegalArgumentException
+ {
+ AccountID accountID = parentForm.getWizard().getProtocolProvider().
+ getAccountID();
+ ProtocolProviderFactory protocolProviderFactory =
+ JabberAccRegWizzActivator.getJabberProtocolProviderFactory();
+
+ protocolProviderFactory.storePassword(accountID, newPass);
+ }
+ }
}
diff --git a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationForm.java b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationForm.java
index 9baba50..6008dc8 100644
--- a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationForm.java
+++ b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationForm.java
@@ -365,10 +365,21 @@ public class JabberAccountRegistrationForm
accountPanel.setPassword(password);
accountPanel.setRememberPassword(true);
}
-
+
String serverAddress
= accountProperties.get(ProtocolProviderFactory.SERVER_ADDRESS);
+ //The idea here is to not show the "change password" button for
+ //GTalk and Facebook acounts, or accounts in gmail, since we know
+ //they don't support inband password changes.
+ //This is probably a bad way to achieve it...
+ if ( !serverAddress.equals("gmail.com")
+ && !serverAddress.equals("talk.google.com")
+ && !serverAddress.equals("chat.facebook.com"))
+ {
+ accountPanel.showChangePasswordButton();
+ }
+
connectionPanel.setServerAddress(serverAddress);
String serverPort
@@ -699,4 +710,13 @@ public class JabberAccountRegistrationForm
return password;
}
+
+ /**
+ * Returns the wizard that created the form
+ * @return The form wizard
+ */
+ public JabberAccountRegistrationWizard getWizard()
+ {
+ return wizard;
+ }
}
diff --git a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationWizard.java
index 4126865..093b361 100644
--- a/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationWizard.java
+++ b/src/net/java/sip/communicator/plugin/jabberaccregwizz/JabberAccountRegistrationWizard.java
@@ -749,4 +749,16 @@ public class JabberAccountRegistrationWizard
{
return null;
}
+
+ /**
+ * Return the wizard's protocolProvider, if the wizard modifies an
+ * account, null if it creates a new one
+ * @return the wizard's protocolProvider
+ */
+ public ProtocolProviderService getProtocolProvider()
+ {
+ if(isModification())
+ return protocolProvider;
+ return null;
+ }
}
diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetChangePassword.java b/src/net/java/sip/communicator/service/protocol/OperationSetChangePassword.java
new file mode 100644
index 0000000..0efda6a
--- /dev/null
+++ b/src/net/java/sip/communicator/service/protocol/OperationSetChangePassword.java
@@ -0,0 +1,26 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.service.protocol;
+
+/**
+ * An operation set that allows "inband" change of the account password
+ *
+ * @author Boris Grozev
+ */
+public interface OperationSetChangePassword
+ extends OperationSet
+{
+ /**
+ * Changes the account password to newPass
+ *
+ * @param newPass the new password.
+ * @throws IllegalStateException if the account is not registered.
+ * @throws OperationFailedException if the change failed for another reason.
+ */
+ public void changePassword(String newPass)
+ throws IllegalStateException, OperationFailedException;
+}