Revision: 3796
Author: [email protected]
Date: Wed Jul 28 08:41:01 2010
Log: NEW - bug 2889: Changing password doesn't work
http://trillian.sqlpower.ca/bugzilla/show_bug.cgi?id=2889

The root cause was the rest tag was not added to the change password server request. Part of the problem was the request was nested in several anonymous classes in the UserEditorPanel.

The request is now made in the ArchitectClientSideSession along with the rest of the server requests so they are contained in one place. In the future we may want to refactor the static server request methods to a utility class.
http://code.google.com/p/power-architect/source/detail?r=3796

Modified:
/trunk/src/main/java/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java /trunk/src/main/java/ca/sqlpower/architect/enterprise/JSONResponseHandler.java /trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/SecurityPanel.java /trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/UserEditorPanel.java

=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java Tue Jul 27 09:04:00 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java Wed Jul 28 08:41:01 2010
@@ -6,6 +6,8 @@
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -20,6 +22,7 @@
 import javax.swing.event.UndoableEditEvent;
 import javax.swing.event.UndoableEditListener;

+import org.apache.commons.codec.binary.Hex;
 import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
 import org.apache.http.auth.AuthScope;
@@ -34,6 +37,7 @@
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.entity.FileEntity;
+import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.BasicCookieStore;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.message.BasicNameValuePair;
@@ -81,6 +85,7 @@
 import ca.sqlpower.swingui.event.SessionLifecycleEvent;
 import ca.sqlpower.swingui.event.SessionLifecycleListener;
 import ca.sqlpower.util.SQLPowerUtils;
+import ca.sqlpower.util.UserPrompterFactory;
 import ca.sqlpower.util.UserPrompter.UserPromptOptions;
 import ca.sqlpower.util.UserPrompter.UserPromptResponse;

@@ -485,6 +490,73 @@
         }

        }
+
+    /**
+ * This method can update any users password on the server given the correct + * old password and done by a user with the privileges to change the user's
+     * password.
+     *
+     * @param session
+ * The client session that has the correct server information to
+     *            post requests to the server.
+     * @param username
+     *            The user name of the user to update.
+     * @param oldPassword
+ * The old password of the user to validate that the password can
+     *            be updated correctly.
+     * @param newPassword
+     *            The new password to update to.
+     * @param upf
+ * A user prompter to display message and error information to
+     *            the user as necessary.
+     */
+ public static void updateUserPassword(ArchitectClientSideSession session, String username,
+               String oldPassword, String newPassword, UserPrompterFactory 
upf) {
+ SPServerInfo serviceInfo = session.getProjectLocation().getServiceInfo();
+
+ HttpClient client = ArchitectClientSideSession.createHttpClient(serviceInfo);
+
+        MessageDigest digester;
+        try {
+            digester = MessageDigest.getInstance("SHA-256");
+        } catch (NoSuchAlgorithmException ex) {
+            throw new RuntimeException(ex);
+        }
+
+        try {
+            JSONObject json = new JSONObject();
+            json.put("username", username);
+ json.put("oldPassword", new String(Hex.encodeHex(digester.digest(oldPassword.getBytes())))); + json.put("newPassword", new String(Hex.encodeHex(digester.digest(newPassword.getBytes()))));
+
+            URI serverURI = new URI("http", null,
+                    serviceInfo.getServerAddress(),
+                    serviceInfo.getPort(),
+ serviceInfo.getPath() + "/" + REST_TAG + "/project/system/change_password",
+                    null, null);
+            HttpPost postRequest = new HttpPost(serverURI);
+            postRequest.setEntity(new StringEntity(json.toString()));
+            postRequest.setHeader("Content-Type", "application/json");
+            HttpUriRequest request = postRequest;
+            client.execute(request, new JSONResponseHandler());
+        } catch (AccessDeniedException ex) {
+            logger.warn("Failed password change", ex);
+ upf.createUserPrompter("The password you have entered is incorrect.",
+                    UserPromptType.MESSAGE,
+                    UserPromptOptions.OK,
+                    UserPromptResponse.OK,
+                    "OK", "OK").promptUser("");
+        } catch (Exception ex) {
+            logger.warn("Failed password change", ex);
+            upf.createUserPrompter(
+ "Could not change the password due to the following: " +
+                    ex.getMessage() + " See logs for more details.",
+                    UserPromptType.MESSAGE,
+                    UserPromptOptions.OK,
+                    UserPromptResponse.OK,
+                    "OK", "OK").promptUser("");
+        }
+       }

public void persistRevisionFromServer(int revisionNo, SPJSONMessageDecoder targetDecoder) throws IOException, URISyntaxException, SPPersistenceException, IllegalArgumentException {
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/enterprise/JSONResponseHandler.java Fri Apr 23 14:24:33 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/enterprise/JSONResponseHandler.java Wed Jul 28 08:41:01 2010
@@ -24,11 +24,14 @@

 import org.apache.http.HttpResponse;
 import org.apache.http.client.ResponseHandler;
+import org.apache.log4j.Logger;
 import org.json.JSONArray;
 import org.json.JSONObject;
 import org.springframework.security.AccessDeniedException;

 public class JSONResponseHandler implements ResponseHandler<JSONMessage> {
+
+ private static final Logger logger = Logger.getLogger(JSONResponseHandler.class);

     /*
      * Unsuccessful responses should have information sent in a header,
@@ -60,6 +63,13 @@
     }

     public JSONMessage handleResponse(String json, int status) {
+        if (status == 500) {
+            logger.error("Internal server error: " + json);
+ throw new RuntimeException("Internal Server Error. See logs for more details.");
+        } else if (status == 404) {
+ throw new RuntimeException("Server resource is not available.");
+        }
+
         try {
             JSONObject message = new JSONObject(json);

=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/SecurityPanel.java Thu Jul 8 07:47:42 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/SecurityPanel.java Wed Jul 28 08:41:01 2010
@@ -256,7 +256,7 @@
         if (groupOrUser instanceof Group) {
groupOrUserEditPanel = new GroupEditorPanel((Group) groupOrUser, username, closeAction);
         } else if (groupOrUser instanceof User) {
- groupOrUserEditPanel = new UserEditorPanel((User) groupOrUser, username, closeAction, dialog, session); + groupOrUserEditPanel = new UserEditorPanel((User) groupOrUser, username, closeAction, session);
         } else {
throw new IllegalStateException("Argument must be instance of Group or User");
         }
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/UserEditorPanel.java Wed Jul 28 07:26:33 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/UserEditorPanel.java Wed Jul 28 08:41:01 2010
@@ -19,12 +19,9 @@

 package ca.sqlpower.architect.swingui.enterprise;

-import java.awt.Dialog;
 import java.awt.Dimension;
+import java.awt.Window;
 import java.awt.event.ActionEvent;
-import java.net.URI;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.List;

@@ -41,30 +38,19 @@
 import javax.swing.JPasswordField;
 import javax.swing.JScrollPane;
 import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
 import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;

-import org.apache.commons.codec.binary.Hex;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.entity.StringEntity;
-import org.json.JSONObject;
-
 import ca.sqlpower.architect.ArchitectSession;
 import ca.sqlpower.architect.enterprise.ArchitectClientSideSession;
-import ca.sqlpower.architect.enterprise.JSONResponseHandler;
 import ca.sqlpower.architect.swingui.ArchitectSwingProject;
import ca.sqlpower.architect.swingui.action.enterprise.RefreshProjectAction;
 import ca.sqlpower.enterprise.client.Grant;
 import ca.sqlpower.enterprise.client.Group;
 import ca.sqlpower.enterprise.client.GroupMember;
-import ca.sqlpower.enterprise.client.SPServerInfo;
 import ca.sqlpower.enterprise.client.User;
 import ca.sqlpower.swingui.DataEntryPanel;
-import ca.sqlpower.util.UserPrompter.UserPromptOptions;
-import ca.sqlpower.util.UserPrompter.UserPromptResponse;
-import ca.sqlpower.util.UserPrompterFactory.UserPromptType;

 import com.jgoodies.forms.builder.ButtonBarBuilder2;
 import com.jgoodies.forms.builder.DefaultFormBuilder;
@@ -154,6 +140,63 @@
             closeAction.actionPerformed(e);
         }
     };
+
+    /**
+ * This action is used to change the password of a user by creating a new
+     * dialog for the prompt.
+     */
+ private final Action changePasswordAction = new AbstractAction("Change Password") {
+        public void actionPerformed(ActionEvent e) {
+
+            Window parentWindow = SwingUtilities.getWindowAncestor(panel);
+            final JDialog dialog = new JDialog(parentWindow);
+
+            final JTextField oldPasswordField = new JPasswordField(21);
+            final JTextField newPasswordField = new JPasswordField(21);
+            final JTextField newPasswordFiled2 = new JPasswordField(21);
+
+            CellConstraints cc = new CellConstraints();
+ DefaultFormBuilder dialogBuilder = new DefaultFormBuilder(new FormLayout( + "pref:grow", "pref, pref, pref, pref, pref, pref, pref")); + dialogBuilder.add(new JLabel("Enter your old password"), cc.xy(1, 1));
+            dialogBuilder.add(oldPasswordField, cc.xy(1, 2));
+ dialogBuilder.add(new JLabel("Enter your new password"), cc.xy(1, 3));
+            dialogBuilder.add(newPasswordField, cc.xy(1, 4));
+ dialogBuilder.add(new JLabel("Confirm your password"), cc.xy(1, 5));
+            dialogBuilder.add(newPasswordFiled2, cc.xy(1, 6));
+
+ ButtonBarBuilder2 bbb = ButtonBarBuilder2.createLeftToRightBuilder();
+            bbb.addGlue();
+            bbb.addButton(new JButton(new AbstractAction("OK") {
+                public void actionPerformed(ActionEvent e) {
+ if (newPasswordField.getText().equals(newPasswordFiled2.getText())) {
+                        String username = user.getUsername();
+                        String oldPassword = oldPasswordField.getText();
+                        String newPassword = newPasswordField.getText();
+ ArchitectClientSideSession clientSession = ((ArchitectClientSideSession) securityWorkspace.getSession()); + ArchitectClientSideSession.updateUserPassword(clientSession, username, oldPassword, newPassword, session);
+                        dialog.dispose();
+                    } else {
+ JOptionPane.showMessageDialog(getPanel(), "The passwords you entered were not the same");
+                    }
+                }
+            }));
+            bbb.addRelatedGap();
+            bbb.addButton(new JButton(new AbstractAction("Cancel") {
+                public void actionPerformed(ActionEvent e) {
+                    dialog.dispose();
+                }
+            }));
+            bbb.setDefaultButtonBarGapBorder();
+
+            dialogBuilder.add(bbb.getPanel(), cc.xy(1, 7));
+            dialogBuilder.setDefaultDialogBorder();
+            dialog.setContentPane(dialogBuilder.getPanel());
+            dialog.pack();
+            dialog.setLocationRelativeTo(parentWindow);
+            dialog.setVisible(true);
+        }
+    };

     private boolean hasUnsavedChanges = false;

@@ -163,8 +206,11 @@
public void removeUpdate(DocumentEvent e) { hasUnsavedChanges = true; }
     };

- public UserEditorPanel(User baseUser, String username, Action closeAction, final Dialog d, final ArchitectSession session) {
+    private final ArchitectSession session;
+
+ public UserEditorPanel(User baseUser, String username, Action closeAction, final ArchitectSession session) {
         this.user = baseUser;
+        this.session = session;
         this.securityWorkspace = (ArchitectSwingProject) user.getParent();
         this.username = username;
         this.closeAction = closeAction;
@@ -230,87 +276,7 @@
         upperPanelBuilder.add(emailLabel, cc.xy(1, 4));
         upperPanelBuilder.add(emailField, cc.xy(3, 4));

- passwordButton = new JButton(new AbstractAction("Change Password") {
-            public void actionPerformed(ActionEvent e) {
-
-                final JDialog dialog = new JDialog(d);
-
-                final JTextField oldPasswordField = new JPasswordField(21);
-                final JTextField newPasswordField = new JPasswordField(21);
- final JTextField newPasswordFiled2 = new JPasswordField(21);
-
-                CellConstraints cc = new CellConstraints();
- DefaultFormBuilder dialogBuilder = new DefaultFormBuilder(new FormLayout( - "pref:grow", "pref, pref, pref, pref, pref, pref, pref")); - dialogBuilder.add(new JLabel("Enter your old password"), cc.xy(1, 1));
-                dialogBuilder.add(oldPasswordField, cc.xy(1, 2));
- dialogBuilder.add(new JLabel("Enter your new password"), cc.xy(1, 3));
-                dialogBuilder.add(newPasswordField, cc.xy(1, 4));
- dialogBuilder.add(new JLabel("Confirm your password"), cc.xy(1, 5));
-                dialogBuilder.add(newPasswordFiled2, cc.xy(1, 6));
-
- ButtonBarBuilder2 bbb = ButtonBarBuilder2.createLeftToRightBuilder();
-                bbb.addGlue();
-                bbb.addButton(new JButton(new AbstractAction("OK") {
-                    public void actionPerformed(ActionEvent e) {
- if (newPasswordField.getText().equals(newPasswordFiled2.getText())) { - SPServerInfo serviceInfo = ((ArchitectClientSideSession) securityWorkspace.getSession())
-                            .getProjectLocation().getServiceInfo();
-
- HttpClient client = ArchitectClientSideSession.createHttpClient(serviceInfo);
-
-                            MessageDigest digester;
-                            try {
- digester = MessageDigest.getInstance("SHA-256");
-                            } catch (NoSuchAlgorithmException e1) {
-                                throw new RuntimeException(e1);
-                            }
-
-                            try {
-                                JSONObject json = new JSONObject();
-                                json.put("username", user.getUsername());
- json.put("oldPassword", new String(Hex.encodeHex(digester.digest(oldPasswordField.getText().getBytes())))); - json.put("newPassword", new String(Hex.encodeHex(digester.digest(newPasswordField.getText().getBytes()))));
-
-                                URI serverURI = new URI("http", null,
-                                        serviceInfo.getServerAddress(),
-                                        serviceInfo.getPort(),
- serviceInfo.getPath() + "/project/system/change_password",
-                                        null, null);
- HttpPost postRequest = new HttpPost(serverURI); - postRequest.setEntity(new StringEntity(json.toString())); - postRequest.setHeader("Content-Type", "application/json");
-                                HttpUriRequest request = postRequest;
- client.execute(request, new JSONResponseHandler());
-                                dialog.dispose();
-                            } catch (Exception x) {
- session.createUserPrompter("The password you have entered is incorrect.",
-                                        UserPromptType.MESSAGE,
-                                        UserPromptOptions.OK,
-                                        UserPromptResponse.OK,
-                                        "OK", "OK").promptUser("");
-                            }
-                        } else {
- JOptionPane.showMessageDialog(getPanel(), "The passwords you entered were not the same");
-                        }
-                    }
-                }));
-                bbb.addRelatedGap();
-                bbb.addButton(new JButton(new AbstractAction("Cancel") {
-                    public void actionPerformed(ActionEvent e) {
-                        dialog.dispose();
-                    }
-                }));
-                bbb.setDefaultButtonBarGapBorder();
-
-                dialogBuilder.add(bbb.getPanel(), cc.xy(1, 7));
-                dialogBuilder.setDefaultDialogBorder();
-                dialog.setContentPane(dialogBuilder.getPanel());
-                dialog.pack();
-                dialog.setLocationRelativeTo(d);
-                dialog.setVisible(true);
-            }
-        });
+        passwordButton =  new JButton(changePasswordAction);

ButtonBarBuilder2 passwordBuilder = ButtonBarBuilder2.createLeftToRightBuilder();
         passwordBuilder.addGlue();

Reply via email to