95dcd486032a2c21c5e2bdabe23cc7e2e3362b69
[pithos-web-client] / src / gr / grnet / pithos / web / client / FilePermissionsDialog.java
1 /*\r
2  * Copyright 2011-2012 GRNET S.A. All rights reserved.\r
3  *\r
4  * Redistribution and use in source and binary forms, with or\r
5  * without modification, are permitted provided that the following\r
6  * conditions are met:\r
7  *\r
8  *   1. Redistributions of source code must retain the above\r
9  *      copyright notice, this list of conditions and the following\r
10  *      disclaimer.\r
11  *\r
12  *   2. Redistributions in binary form must reproduce the above\r
13  *      copyright notice, this list of conditions and the following\r
14  *      disclaimer in the documentation and/or other materials\r
15  *      provided with the distribution.\r
16  *\r
17  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS\r
18  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR\r
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
24  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\r
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
28  * POSSIBILITY OF SUCH DAMAGE.\r
29  *\r
30  * The views and conclusions contained in the software and\r
31  * documentation are those of the authors and should not be\r
32  * interpreted as representing official policies, either expressed\r
33  * or implied, of GRNET S.A.\r
34  */\r
35 package gr.grnet.pithos.web.client;\r
36 \r
37 import gr.grnet.pithos.web.client.foldertree.File;\r
38 import gr.grnet.pithos.web.client.foldertree.Resource;\r
39 import gr.grnet.pithos.web.client.rest.PostRequest;\r
40 \r
41 import java.util.Map;\r
42 \r
43 import com.google.gwt.core.client.GWT;\r
44 import com.google.gwt.core.client.Scheduler;\r
45 import com.google.gwt.event.dom.client.ClickEvent;\r
46 import com.google.gwt.event.dom.client.ClickHandler;\r
47 import com.google.gwt.http.client.Response;\r
48 import com.google.gwt.http.client.URL;\r
49 import com.google.gwt.resources.client.ImageResource;\r
50 import com.google.gwt.user.client.Command;\r
51 import com.google.gwt.user.client.Window;\r
52 import com.google.gwt.user.client.ui.Anchor;\r
53 import com.google.gwt.user.client.ui.Button;\r
54 import com.google.gwt.user.client.ui.CheckBox;\r
55 import com.google.gwt.user.client.ui.FocusPanel;\r
56 import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
57 import com.google.gwt.user.client.ui.HorizontalPanel;\r
58 import com.google.gwt.user.client.ui.Label;\r
59 import com.google.gwt.user.client.ui.TextBox;\r
60 import com.google.gwt.user.client.ui.VerticalPanel;\r
61 \r
62 /**\r
63  * The 'File properties' dialog box implementation.\r
64  *\r
65  */\r
66 public class FilePermissionsDialog extends AbstractPropertiesDialog {\r
67 \r
68         protected PermissionsList permList;\r
69 \r
70         protected CheckBox readForAll;\r
71 \r
72         /**\r
73          * An image bundle for this widgets images.\r
74          */\r
75         public interface Images extends MessagePanel.Images {\r
76 \r
77                 @Source("gr/grnet/pithos/resources/edit_user.png")\r
78                 ImageResource permUser();\r
79 \r
80                 @Source("gr/grnet/pithos/resources/groups22.png")\r
81                 ImageResource permGroup();\r
82 \r
83                 @Source("gr/grnet/pithos/resources/editdelete.png")\r
84                 ImageResource delete();\r
85         }\r
86 \r
87         final File file;\r
88 \r
89     Images images = GWT.create(Images.class);\r
90 \r
91         /**\r
92          * The widget's constructor.\r
93          */\r
94         public FilePermissionsDialog(Pithos _app, File _file) {\r
95         super(_app);\r
96         file = _file;\r
97 \r
98                 Anchor close = new Anchor();\r
99                 close.addStyleName("close");\r
100                 close.addClickHandler(new ClickHandler() {\r
101                         \r
102                         @Override\r
103                         public void onClick(ClickEvent event) {\r
104                                 hide();\r
105                         }\r
106                 });\r
107                 // Set the dialog's caption.\r
108                 setText("File permissions");\r
109                 setAnimationEnabled(true);\r
110                 setGlassEnabled(true);\r
111                 setStyleName("pithos-DialogBox");\r
112 \r
113                 // Outer contains inner and buttons.\r
114                 final VerticalPanel outer = new VerticalPanel();\r
115                 outer.add(close);\r
116                 final FocusPanel focusPanel = new FocusPanel(outer);\r
117                 // Inner contains generalPanel and permPanel.\r
118                 inner = new VerticalPanel();\r
119                 inner.addStyleName("inner");\r
120 \r
121         inner.add(createSharingPanel());\r
122 \r
123         outer.add(inner);\r
124 \r
125                 // Create the 'OK' button, along with a listener that hides the dialog\r
126                 // when the button is clicked.\r
127                 final Button ok = new Button("OK", new ClickHandler() {\r
128                         @Override\r
129                         public void onClick(ClickEvent event) {\r
130                                 accept();\r
131                                 closeDialog();\r
132                         }\r
133                 });\r
134                 ok.addStyleName("button");\r
135 \r
136         outer.add(ok);\r
137         outer.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER);\r
138 \r
139         focusPanel.setFocus(true);\r
140         setWidget(outer);\r
141         }\r
142 \r
143     private VerticalPanel createSharingPanel() {\r
144         VerticalPanel permPanel = new VerticalPanel();\r
145 \r
146         permList = new PermissionsList(images, file.getPermissions(), file.getOwner(), false);\r
147         permPanel.add(permList);\r
148 \r
149         HorizontalPanel permButtons = new HorizontalPanel();\r
150         Button add = new Button("Add Group", new ClickHandler() {\r
151             @Override\r
152             public void onClick(ClickEvent event) {\r
153                 PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, false);\r
154                 dlg.center();\r
155                 permList.updatePermissionTable();\r
156             }\r
157         });\r
158         add.addStyleName("button");\r
159         permButtons.add(add);\r
160         permButtons.setCellHorizontalAlignment(add, HasHorizontalAlignment.ALIGN_CENTER);\r
161 \r
162         final Button addUser = new Button("Add User", new ClickHandler() {\r
163             @Override\r
164             public void onClick(ClickEvent event) {\r
165                 PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, true);\r
166                 dlg.center();\r
167                 permList.updatePermissionTable();\r
168             }\r
169         });\r
170         addUser.addStyleName("button");\r
171         permButtons.add(addUser);\r
172         permButtons.setCellHorizontalAlignment(addUser, HasHorizontalAlignment.ALIGN_CENTER);\r
173 \r
174         permButtons.setSpacing(8);\r
175         permButtons.addStyleName("pithos-TabPanelBottom");\r
176         permPanel.add(permButtons);\r
177 \r
178         final Label readForAllNote = new Label("When this option is enabled, the file will be readable" +\r
179                     " by everyone. By checking this option, you are certifying that you have the right to " +\r
180                     "distribute this file and that it does not violate the Terms of Use.", true);\r
181         readForAllNote.setVisible(false);\r
182         readForAllNote.setStylePrimaryName("pithos-readForAllNote");\r
183 \r
184         readForAll = new CheckBox();\r
185         readForAll.setValue(file.isPublished());\r
186         readForAll.addClickHandler(new ClickHandler() {\r
187             @Override\r
188             public void onClick(ClickEvent event) {\r
189                 readForAllNote.setVisible(readForAll.getValue());\r
190             }\r
191         });\r
192 \r
193         // Only show the read for all permission if the user is the owner.\r
194         if (file.getOwner().equals(app.getUsername())) {\r
195             final HorizontalPanel permForAll = new HorizontalPanel();\r
196             permForAll.add(new Label("Public"));\r
197             permForAll.add(readForAll);\r
198             permForAll.setSpacing(8);\r
199             permForAll.addStyleName("pithos-TabPanelBottom");\r
200             permForAll.add(readForAllNote);\r
201             permPanel.add(permForAll);\r
202         }\r
203 \r
204         if (file.isPublished()) {\r
205             final HorizontalPanel pathPanel = new HorizontalPanel();\r
206             pathPanel.setWidth("100%");\r
207             pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);\r
208             pathPanel.add(new Label("Link"));\r
209             pathPanel.setSpacing(8);\r
210             pathPanel.addStyleName("pithos-TabPanelBottom");\r
211 \r
212             TextBox path = new TextBox();\r
213             path.setWidth("100%");\r
214             path.addClickHandler(new ClickHandler() {\r
215                 @Override\r
216                 public void onClick(ClickEvent event) {\r
217                     Pithos.enableIESelection();\r
218                     ((TextBox) event.getSource()).selectAll();\r
219                     Pithos.preventIESelection();\r
220                 }\r
221             });\r
222             path.setText(Window.Location.getHost() + file.getPublicUri());\r
223             path.setTitle("Use this link for sharing the file via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)");\r
224             path.setWidth("100%");\r
225             path.setReadOnly(true);\r
226             pathPanel.add(path);\r
227             permPanel.add(pathPanel);\r
228         }\r
229 \r
230         return permPanel;\r
231     }\r
232 \r
233         /**\r
234          * Accepts any change and updates the file\r
235          *\r
236          */\r
237         @Override\r
238         protected void accept() {\r
239                 final Map<String, Boolean[]> perms = (permList.hasChanges() ? permList.getPermissions() : null);\r
240 \r
241                 //only update the read for all perm if the user is the owner\r
242         Boolean published = null;\r
243                 if (readForAll.getValue() != file.isPublished())\r
244                         if (file.getOwner().equals(app.getUsername()))\r
245                 published = readForAll.getValue();\r
246         final Boolean finalPublished = published;\r
247 \r
248         updateMetaData(app.getApiPath(), app.getUsername(), file.getUri() + "?update=", finalPublished, perms);\r
249         }\r
250 \r
251         protected void updateMetaData(String api, String owner, String path, final Boolean published, final Map<String, Boolean[]> newPermissions) {\r
252         if (published != null || newPermissions != null) {\r
253             PostRequest updateFile = new PostRequest(api, owner, path) {\r
254                 @Override\r
255                 public void onSuccess(Resource result) {\r
256                     app.updateFolder(file.getParent(), true, new Command() {\r
257                                                 \r
258                                                 @Override\r
259                                                 public void execute() {\r
260                                                         app.updateMySharedRoot();\r
261                                                 }\r
262                                         });\r
263                 }\r
264 \r
265                 @Override\r
266                 public void onError(Throwable t) {\r
267                     GWT.log("", t);\r
268                                         app.setError(t);\r
269                     app.displayError("System error modifying file:" + t.getMessage());\r
270                 }\r
271 \r
272                                 @Override\r
273                                 protected void onUnauthorized(Response response) {\r
274                                         app.sessionExpired();\r
275                                 }\r
276             };\r
277             updateFile.setHeader("X-Auth-Token", app.getToken());\r
278             \r
279             if (published != null)\r
280                 updateFile.setHeader("X-Object-Public", published.toString());\r
281             if (newPermissions != null) {\r
282                 String readPermHeader = "read=";\r
283                 String writePermHeader = "write=";\r
284                 for (String u : newPermissions.keySet()) {\r
285                     Boolean[] p = newPermissions.get(u);\r
286                     if (p[0] != null && p[0])\r
287                         readPermHeader += u + ",";\r
288                     if (p[1] != null && p[1])\r
289                         writePermHeader += u + ",";\r
290                 }\r
291                 if (readPermHeader.endsWith("="))\r
292                     readPermHeader = "";\r
293                 else if (readPermHeader.endsWith(","))\r
294                     readPermHeader = readPermHeader.substring(0, readPermHeader.length() - 1);\r
295                 if (writePermHeader.endsWith("="))\r
296                     writePermHeader = "";\r
297                 else if (writePermHeader.endsWith(","))\r
298                     writePermHeader = writePermHeader.substring(0, writePermHeader.length() - 1);\r
299                 String permHeader = readPermHeader +  ((readPermHeader.length()  > 0 && writePermHeader.length() > 0) ?  ";" : "") + writePermHeader;\r
300                 if (permHeader.length() == 0)\r
301                     permHeader="~";\r
302                 else\r
303                         permHeader = URL.encodePathSegment(permHeader);\r
304                 updateFile.setHeader("X-Object-Sharing", permHeader);\r
305             }\r
306             Scheduler.get().scheduleDeferred(updateFile);\r
307         }\r
308         else\r
309             app.updateFolder(file.getParent(), true, new Command() {\r
310                                 \r
311                                 @Override\r
312                                 public void execute() {\r
313                                         if (file.isShared())\r
314                                                 app.updateMySharedRoot();\r
315                                 }\r
316                         });\r
317     }\r
318 }\r