Revision: 3433
Author: ferguson.sebastian
Date: Tue Apr 6 10:20:51 2010
Log: Unauthorized access now displays user friendly dialogs.
http://code.google.com/p/power-architect/source/detail?r=3433
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/enterprise/NetworkConflictResolver.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectFrame.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectSwingSessionContextImpl.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/action/RemoveServerProjectAction.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/PrivilegesEditorPanel.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/ProjectSecurityPanel.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/ServerProjectsManagerPanel.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/UserEditorPanel.java
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java
Mon Mar 29 14:08:45 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java
Tue Apr 6 10:20:51 2010
@@ -8,6 +8,7 @@
import java.net.URISyntaxException;
import java.text.ParseException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -32,7 +33,6 @@
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.BasicCookieStore;
-import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
@@ -43,6 +43,7 @@
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import org.springframework.security.AccessDeniedException;
import ca.sqlpower.architect.ArchitectProject;
import ca.sqlpower.architect.ArchitectSession;
@@ -282,6 +283,9 @@
return
getSecuritySessions().get(getProjectLocation().getServiceInfo().getServerAddress()).getWorkspace();
}
+ public ArchitectClientSideSession getSystemSession() {
+ return
getSecuritySessions().get(getProjectLocation().getServiceInfo().getServerAddress());
+ }
@Override
public void runInForeground(Runnable runner) {
@@ -312,7 +316,7 @@
// -
- public static List<ProjectLocation> getWorkspaceNames(SPServerInfo
serviceInfo)
+ public static List<ProjectLocation> getWorkspaceNames(SPServerInfo
serviceInfo, ArchitectSession session)
throws IOException, URISyntaxException, JSONException {
HttpClient httpClient = createHttpClient(serviceInfo);
try {
@@ -328,6 +332,14 @@
serviceInfo));
}
return workspaces;
+ } catch (AccessDeniedException e) {
+ session.createUserPrompter("You do not have sufficient privileges
to perform that action.\n" +
+ "Please hit the refresh button to re-synchonize with
the server.",
+ UserPromptType.MESSAGE,
+ UserPromptOptions.OK,
+ UserPromptResponse.OK,
+ "OK", "OK").promptUser("");
+ return Collections.emptyList();
} finally {
httpClient.getConnectionManager().shutdown();
}
@@ -355,7 +367,7 @@
}
- public static ProjectLocation createNewServerSession(SPServerInfo
serviceInfo, String name)
+ public static ProjectLocation createNewServerSession(SPServerInfo
serviceInfo, String name, ArchitectSession session)
throws URISyntaxException, ClientProtocolException, IOException,
JSONException {
HttpClient httpClient = createHttpClient(serviceInfo);
@@ -367,6 +379,13 @@
response.getString("uuid"),
response.getString("name"),
serviceInfo);
+ } catch (AccessDeniedException e) {
+ session.createUserPrompter("You do not have sufficient privileges
to create a new workspace.",
+ UserPromptType.MESSAGE,
+ UserPromptOptions.OK,
+ UserPromptResponse.OK,
+ "OK", "OK").promptUser("");
+ return null;
} finally {
httpClient.getConnectionManager().shutdown();
}
@@ -493,15 +512,20 @@
return transactions;
}
- public static void deleteServerWorkspace(ProjectLocation projectLocation)
throws URISyntaxException, ClientProtocolException, IOException {
+ public static void deleteServerWorkspace(ProjectLocation projectLocation,
ArchitectSession session) throws URISyntaxException,
ClientProtocolException, IOException {
SPServerInfo serviceInfo = projectLocation.getServiceInfo();
HttpClient httpClient = createHttpClient(serviceInfo);
try {
executeServerRequest(httpClient,
projectLocation.getServiceInfo(),
"/jcr/" + projectLocation.getUUID() + "/delete",
- new BasicResponseHandler());
-
+ new JSONResponseHandler());
+ } catch (AccessDeniedException e) {
+ session.createUserPrompter("You do not have sufficient privileges
to delete the selected workspace.",
+ UserPromptType.MESSAGE,
+ UserPromptOptions.OK,
+ UserPromptResponse.OK,
+ "OK", "OK").promptUser("");
} finally {
httpClient.getConnectionManager().shutdown();
}
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/enterprise/JSONResponseHandler.java
Wed Mar 24 07:30:37 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/enterprise/JSONResponseHandler.java
Tue Apr 6 10:20:51 2010
@@ -26,6 +26,7 @@
import org.apache.http.client.ResponseHandler;
import org.json.JSONArray;
import org.json.JSONObject;
+import org.springframework.security.AccessDeniedException;
public class JSONResponseHandler implements ResponseHandler<JSONMessage> {
@@ -36,7 +37,11 @@
public JSONMessage handleResponse(HttpResponse response) {
try {
-
+
+ if (response.getStatusLine().getStatusCode() == 401) {
+ throw new AccessDeniedException("Access Denied");
+ }
+
BufferedReader reader = new BufferedReader(
new
InputStreamReader(response.getEntity().getContent()));
StringBuffer buffer = new StringBuffer();
@@ -46,6 +51,8 @@
buffer.append(line).append("\n");
}
return handleResponse(buffer.toString());
+ } catch (AccessDeniedException e) {
+ throw e;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
@@ -73,9 +80,9 @@
for (int i = 0; i < stackTraceStrings.length();
i++) {
stackTraceMessage.append("\n").append(stackTraceStrings.get(i));
}
-
+
throw new Exception(stackTraceMessage.toString());
-
+
} else {
// This exception represents a(n epic)
client-server miscommunication
throw new Exception("Unable to parse response ");
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java
Thu Apr 1 12:24:42 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java
Tue Apr 6 10:20:51 2010
@@ -32,7 +32,9 @@
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
-
+import org.springframework.security.AccessDeniedException;
+
+import ca.sqlpower.architect.ArchitectSession;
import ca.sqlpower.dao.MessageSender;
import ca.sqlpower.dao.PersistedObjectEntry;
import ca.sqlpower.dao.PersistedPropertiesEntry;
@@ -46,8 +48,10 @@
import ca.sqlpower.dao.json.SPJSONMessageDecoder;
import ca.sqlpower.dao.session.SessionPersisterSuperConverter;
import ca.sqlpower.object.SPObject;
-import ca.sqlpower.util.SPSession;
import ca.sqlpower.util.SQLPowerUtils;
+import ca.sqlpower.util.UserPrompter.UserPromptOptions;
+import ca.sqlpower.util.UserPrompter.UserPromptResponse;
+import ca.sqlpower.util.UserPrompterFactory.UserPromptType;
import com.enterprisedt.util.debug.Logger;
import com.google.common.collect.LinkedListMultimap;
@@ -61,7 +65,8 @@
private SPPersisterListener listener;
private SessionPersisterSuperConverter converter;
- private final SPSession session;
+ private ArchitectSession session;
+ private ArchitectSession promptSession;
private int currentRevision = 0;
@@ -98,7 +103,7 @@
SPJSONMessageDecoder jsonDecoder,
HttpClient inboundHttpClient,
HttpClient outboundHttpClient,
- SPSession session)
+ ArchitectSession session)
{
super("updater-" + projectLocation.getUUID());
@@ -110,6 +115,14 @@
contextRelativePath = "/project/" + projectLocation.getUUID();
}
+
+ public void setPromptSession(ArchitectSession promptSession) {
+ this.promptSession = promptSession;
+ }
+
+ public ArchitectSession getPromptSession() {
+ return promptSession;
+ }
public void setListener(SPPersisterListener listener) {
this.listener = listener;
@@ -133,8 +146,30 @@
} else {
postingJSON.set(true);
}
- // Try to send json message ...
- JSONMessage response = postJsonArray(messageBuffer.toString());
+ // Try to send json message ...
+ JSONMessage response = null;
+ try {
+ response = postJsonArray(messageBuffer.toString());
+ } catch (AccessDeniedException e) {
+ List<UpdateListener> listenersToRemove = new
ArrayList<UpdateListener>();
+ for (UpdateListener listener : updateListeners) {
+ if
(listener.updateException(NetworkConflictResolver.this)) {
+ listenersToRemove.add(listener);
+ }
+ }
+ updateListeners.removeAll(listenersToRemove);
+ if (promptSession != null) {
+ promptSession.createUserPrompter("You do not have
sufficient privileges to perform that action.\n" +
+ "Please hit the refresh button to synchonize with
the server.",
+ UserPromptType.MESSAGE,
+ UserPromptOptions.OK,
+ UserPromptResponse.OK,
+ "OK", "OK").promptUser("");
+ } else {
+ throw e;
+ }
+ return;
+ }
if (response.isSuccessful()) {
// Sent json message without conflict.
try {
@@ -239,10 +274,28 @@
if (!postingJSON.get()) {
decodeMessage(json.getString("data"),
json.getInt("currentRevision"));
}
+ } catch (AccessDeniedException ade) {
+ interrupt();
+ List<UpdateListener> listenersToRemove =
new ArrayList<UpdateListener>();
+ for (UpdateListener listener :
updateListeners) {
+ if
(listener.updateException(NetworkConflictResolver.this)) {
+ listenersToRemove.add(listener);
+ }
+ }
+
updateListeners.removeAll(listenersToRemove);
+ if (promptSession != null) {
+ promptSession.createUserPrompter("You
do not have sufficient privileges to perform that action.\n" +
+ "Please hit the refresh button
to synchonize with the server.",
+ UserPromptType.MESSAGE,
+ UserPromptOptions.OK,
+ UserPromptResponse.OK,
+ "OK", "OK").promptUser("");
+ } else {
+ throw ade;
+ }
} catch (Exception e) {
// TODO: Discard corrupt workspace and
start again from scratch.
interrupt();
-
List<UpdateListener> listenersToRemove =
new ArrayList<UpdateListener>();
for (UpdateListener listener :
updateListeners) {
if
(listener.updateException(NetworkConflictResolver.this)) {
@@ -250,7 +303,6 @@
}
}
updateListeners.removeAll(listenersToRemove);
-
throw new RuntimeException("Update from
server failed! Unable to decode the message: ", e);
} finally {
synchronized (NetworkConflictResolver.this)
{
@@ -415,6 +467,8 @@
postRequest.setHeader("Content-Type", "application/json");
HttpUriRequest request = postRequest;
return outboundHttpClient.execute(request, new
JSONResponseHandler());
+ } catch (AccessDeniedException ade) {
+ throw new AccessDeniedException("Access Denied");
} catch (Exception ex) {
throw new RuntimeException("Unable to post json to server: " +
jsonArray + "\n"+ ex.getMessage());
}
@@ -433,6 +487,8 @@
"oldRevisionNo=" + currentRevision, null);
HttpUriRequest request = new HttpGet(uri);
return client.execute(request, new JSONResponseHandler());
+ } catch (AccessDeniedException ade) {
+ throw new AccessDeniedException("Access Denied");
} catch (Exception ex) {
throw new RuntimeException("Unable to get json from server: "
+ ex.getMessage());
}
@@ -441,6 +497,10 @@
public int getRevision() {
return currentRevision;
}
+
+ public void setSession(ArchitectSession session) {
+ this.session = session;
+ }
public void addListener(UpdateListener listener) {
updateListeners.add(listener);
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectFrame.java
Mon Apr 5 16:15:43 2010
+++ /trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectFrame.java
Tue Apr 6 10:20:51 2010
@@ -256,7 +256,7 @@
// }
}
};
- ServerProjectsManagerPanel spm = new
ServerProjectsManagerPanel(si, session.getContext(),
+ ServerProjectsManagerPanel spm = new
ServerProjectsManagerPanel(si, session, session.getContext(),
ArchitectFrame.this, closeAction);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setContentPane(spm.getPanel());
@@ -275,7 +275,7 @@
public void actionPerformed(ActionEvent e) {
String msg = "Unable to connect to server";
try {
- List l =
ArchitectClientSideSession.getWorkspaceNames(sim.getSelectedServer());
+ List l =
ArchitectClientSideSession.getWorkspaceNames(sim.getSelectedServer(),
session);
if (l != null) {
msg = "Successfuly connected to server";
}
@@ -306,7 +306,7 @@
}
};
- ServerProjectsManagerPanel spm = new
ServerProjectsManagerPanel(session.getContext(),
+ ServerProjectsManagerPanel spm = new
ServerProjectsManagerPanel(session, session.getContext(),
ArchitectFrame.this, closeAction);
d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
d.setContentPane(spm.getPanel());
@@ -328,6 +328,7 @@
}
};
+ ((ArchitectClientSideSession) ((ArchitectSwingSessionImpl)
session).getDelegateSession()).getSystemSession().getUpdater().setPromptSession(session);
SecurityPanel spm = new
SecurityPanel(((ArchitectClientSideSession) ((ArchitectSwingSessionImpl)
session).getDelegateSession()).getProjectLocation().getServiceInfo(),
closeAction, d);
d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
d.setContentPane(spm.getSplitPane());
@@ -349,6 +350,7 @@
}
};
+ ((ArchitectClientSideSession) ((ArchitectSwingSessionImpl)
session).getDelegateSession()).getSystemSession().getUpdater().setPromptSession(session);
ProjectSecurityPanel spm = new
ProjectSecurityPanel(((ArchitectClientSideSession)
((ArchitectSwingSessionImpl)
session).getDelegateSession()).getSystemWorkspace(),
session.getWorkspace(),
ArchitectProject.class.getName(), ((ArchitectClientSideSession)
((ArchitectSwingSessionImpl)
session).getDelegateSession()).getProjectLocation().getServiceInfo().getUsername(),
closeAction);
d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectSwingSessionContextImpl.java
Thu Apr 1 12:24:42 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectSwingSessionContextImpl.java
Tue Apr 6 10:20:51 2010
@@ -221,6 +221,8 @@
final ArchitectClientSideSession clientSession = new
ArchitectClientSideSession(this, projectLocation.getName(),
projectLocation);
final ArchitectSwingSessionImpl swingSession = new
ArchitectSwingSessionImpl(this, clientSession);
+ clientSession.getUpdater().setPromptSession(swingSession);
+
clientSession.getUpdater().addListener(new
NetworkConflictResolver.UpdateListener() {
public void preUpdatePerformed(NetworkConflictResolver
resolver) {
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/swingui/action/RemoveServerProjectAction.java
Mon Feb 8 14:05:30 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/swingui/action/RemoveServerProjectAction.java
Tue Apr 6 10:20:51 2010
@@ -5,20 +5,23 @@
import javax.swing.AbstractAction;
+import ca.sqlpower.architect.ArchitectSession;
import ca.sqlpower.architect.enterprise.ArchitectClientSideSession;
import ca.sqlpower.architect.enterprise.ProjectLocation;
public class RemoveServerProjectAction extends AbstractAction {
private final ProjectLocation location;
-
- public RemoveServerProjectAction (ProjectLocation location) {
+ private final ArchitectSession session;
+
+ public RemoveServerProjectAction (ProjectLocation location,
ArchitectSession session) {
this.location = location;
+ this.session = session;
}
public void actionPerformed(ActionEvent e) {
try {
-
ArchitectClientSideSession.deleteServerWorkspace(location);
+
ArchitectClientSideSession.deleteServerWorkspace(location, session);
} catch (Exception ex) {
throw new RuntimeException("A problem has occured while deleting the a
workspace", ex);
}
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/PrivilegesEditorPanel.java
Mon Apr 5 14:24:45 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/PrivilegesEditorPanel.java
Tue Apr 6 10:20:51 2010
@@ -188,6 +188,7 @@
((Group) groupOrUser).addGrant(newGrant);
}
securityWorkspace.commit();
+ grant = newGrant;
}
}
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/ProjectSecurityPanel.java
Mon Apr 5 14:24:45 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/ProjectSecurityPanel.java
Tue Apr 6 10:20:51 2010
@@ -87,7 +87,7 @@
this.username = username;
this.closeAction = closeAction;
- panelLabel = new JLabel("Permissions for '" + (subject != null?
subject.getName() : type) + "'");
+ panelLabel = new JLabel("Permissions for '" + (subject != null?
subject.getName() : type.substring(type.lastIndexOf(".") + 1)) + "'");
panelLabel.setFont(new Font(panelLabel.getFont().getFontName(),
Font.BOLD, panelLabel.getFont().getSize() + 1));
panel = new JPanel();
@@ -123,6 +123,7 @@
closeAction.actionPerformed(e);
}
});
+
JButton cancelButton = new JButton(new AbstractAction("Cancel") {
public void actionPerformed(ActionEvent e) {
userModel.discardChanges();
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/ServerProjectsManagerPanel.java
Thu Apr 1 12:24:42 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/ServerProjectsManagerPanel.java
Tue Apr 6 10:20:51 2010
@@ -59,6 +59,7 @@
private final Component dialogOwner;
private final ArchitectSessionContext context;
+ private final ArchitectSession session;
private final JPanel panel;
private final Action closeAction;
@@ -80,7 +81,7 @@
if (name != null) {
try {
-
ArchitectClientSideSession.createNewServerSession(getSelectedServerInfo(),
name);
+
ArchitectClientSideSession.createNewServerSession(getSelectedServerInfo(),
name, session);
} catch (Exception ex) {
throw new RuntimeException("Unable to create new
project", ex);
}
@@ -191,7 +192,7 @@
if (obj instanceof ProjectLocation) {
ProjectLocation location =
(ProjectLocation) obj;
try {
-
ArchitectClientSideSession.deleteServerWorkspace(location);
+
ArchitectClientSideSession.deleteServerWorkspace(location, session);
} catch (Exception ex) {
throw new RuntimeException("Unable to
delete project", ex);
}
@@ -210,12 +211,14 @@
public ServerProjectsManagerPanel(
SPServerInfo serverInfo,
+ ArchitectSession session,
ArchitectSessionContext context,
Component dialogOwner,
Action closeAction)
{
this.serverInfo = serverInfo;
this.dialogOwner = dialogOwner;
+ this.session = session;
this.context = context;
this.closeAction = closeAction;
@@ -259,10 +262,12 @@
}
public ServerProjectsManagerPanel(
+ ArchitectSession session,
ArchitectSessionContext context,
Component dialogOwner,
Action closeAction)
{
+ this.session = session;
this.dialogOwner = dialogOwner;
this.context = context;
this.closeAction = closeAction;
@@ -369,7 +374,7 @@
((ArchitectSwingSessionContextImpl)
context).createSecuritySession(serviceInfo);
// Sorts the project locations alphabetically
- List<ProjectLocation> projects =
ArchitectClientSideSession.getWorkspaceNames(serviceInfo);
+ List<ProjectLocation> projects =
ArchitectClientSideSession.getWorkspaceNames(serviceInfo, session);
Collections.sort(projects, new
Comparator<ProjectLocation>() {
public int compare(ProjectLocation proj1,
ProjectLocation proj2) {
return
proj1.getName().toUpperCase().compareTo(proj2.getName().toUpperCase());
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/UserEditorPanel.java
Mon Apr 5 14:24:45 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/swingui/enterprise/UserEditorPanel.java
Tue Apr 6 10:20:51 2010
@@ -373,6 +373,7 @@
}
boolean disableModifyUser = true;
+ boolean disableModifyGroups = true;
for (Grant g : grantsForUser) {
if ((g.getSubject() != null &&
g.getSubject().equals(user.getUUID()))
@@ -381,6 +382,12 @@
disableModifyUser = false;
}
}
+
+ if (g.getType() != null &&
g.getType().equals(Group.class.getName())) {
+ if (g.isModifyPrivilege()) {
+ disableModifyGroups = false;
+ }
+ }
}
if (disableModifyUser) {
@@ -388,6 +395,13 @@
fullnameField.setEnabled(false);
emailField.setEnabled(false);
}
+
+ if (disableModifyGroups) {
+ addAction.setEnabled(false);
+ removeAction.setEnabled(false);
+ currentGroupsList.setEnabled(false);
+ availableGroupsList.setEnabled(false);
+ }
}
public void discardChanges() {
--
To unsubscribe, reply using "remove me" as the subject.