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.

Reply via email to