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();