1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.admininterface.dialogs;
35
36 import info.magnolia.cms.core.Content;
37 import info.magnolia.cms.gui.control.Button;
38 import info.magnolia.cms.gui.control.Edit;
39 import info.magnolia.cms.gui.control.Hidden;
40 import info.magnolia.cms.gui.control.Select;
41 import info.magnolia.cms.gui.dialog.DialogBox;
42 import info.magnolia.cms.gui.dialog.DialogButton;
43 import info.magnolia.cms.gui.dialog.DialogFactory;
44 import info.magnolia.cms.gui.misc.CssConstants;
45 import info.magnolia.cms.i18n.Messages;
46 import info.magnolia.cms.i18n.MessagesManager;
47 import info.magnolia.cms.util.ContentUtil;
48 import info.magnolia.module.admininterface.AdminInterfaceModule;
49 import info.magnolia.module.admininterface.config.AclTypeConfiguration;
50 import info.magnolia.module.admininterface.config.PermissionConfiguration;
51 import info.magnolia.module.admininterface.config.RepositoryConfiguration;
52 import info.magnolia.module.admininterface.config.SecurityConfiguration;
53 import info.magnolia.repository.RepositoryConstants;
54
55 import java.io.IOException;
56 import java.io.PrintWriter;
57 import java.io.Writer;
58 import java.util.Iterator;
59
60 import javax.jcr.RepositoryException;
61 import javax.servlet.http.HttpServletRequest;
62 import javax.servlet.http.HttpServletResponse;
63
64 import org.apache.commons.collections.map.ListOrderedMap;
65 import org.apache.commons.lang.StringUtils;
66
67
68
69
70
71
72 public class ACLSDialogControl extends DialogBox {
73
74 private static final String CSS_ACL_DIV = "aclDynamicTable";
75
76 private SecurityConfiguration securityConf = AdminInterfaceModule.getInstance().getSecurityConfiguration();
77
78 private static String getHtmlRowInner(String dynamicTable, RepositoryConfiguration repoConf) {
79 boolean small = true;
80 Messages msgs = MessagesManager.getMessages();
81
82 Select accessRight = new Select() {
83
84 @Override
85 public String getName() {
86 return super.getName().replace("'", "'");
87 }
88 };
89
90 accessRight.setSaveInfo(false);
91 accessRight.setName("'+prefix+'AccessRight");
92 accessRight.setCssClass("mgnlDialogControlSelect");
93
94 for (Iterator<PermissionConfiguration> iter = repoConf.getPermissions().iterator(); iter.hasNext();) {
95 PermissionConfiguration permission = iter.next();
96 accessRight.setOptions(escapeJs(permission.getI18nLabel()), Long.toString(permission.getValue()));
97 }
98
99 accessRight.setValue("' + object.accessRight + '");
100
101 Select accessType = new Select(){
102
103 @Override
104 public String getName() {
105 return super.getName().replace("'", "'");
106 }
107 };
108 accessType.setSaveInfo(false);
109 accessType.setName("'+prefix+'AccessType");
110 accessType.setCssClass("mgnlDialogControlSelect");
111
112 for (Iterator<AclTypeConfiguration> iter = repoConf.getAclTypes().iterator(); iter.hasNext();) {
113 AclTypeConfiguration patternType = iter.next();
114 accessType.setOptions(escapeJs(patternType.getI18nLabel()), String.valueOf(patternType.getType()));
115 }
116
117 accessType.setValue("' + object.accessType + '");
118
119 Edit path = new Edit(){
120
121 @Override
122 public String getName() {
123 return super.getName().replace("'", "'");
124 }
125 };
126 path.setSaveInfo(false);
127 path.setName("'+prefix+'Path");
128 path.setValue("'+object.path+'");
129 path.setCssClass(CssConstants.CSSCLASS_EDIT);
130 path.setCssStyles("width", "100%");
131
132 Button choose = null;
133 if(repoConf.isChooseButton()){
134 choose = new Button();
135 choose.setLabel(escapeJs(msgs.get("buttons.choose")));
136 choose.setOnclick("aclChoose(\\''+prefix+'\\',\\'" + repoConf.getName() + "\\');");
137 choose.setSmall(small);
138 }
139
140 Button delete = new Button();
141 delete.setLabel(escapeJs(msgs.get("buttons.delete")));
142 delete.setOnclick(dynamicTable + ".del('+index+');");
143 delete.setSmall(small);
144
145 StringBuilder html = new StringBuilder();
146
147
148 html.append("<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\"><tr>");
149 html.append("<td width=\"1\" class=\"" + CssConstants.CSSCLASS_EDITWITHBUTTON + "\">").append(accessRight.getHtml()).append("</td>");
150 html.append("<td width=\"1\" class=\"mgnlDialogBoxInput\"></td>");
151
152
153 if(!repoConf.getAclTypes().isEmpty()){
154 html.append("<td width=\"1\" class=\"" + CssConstants.CSSCLASS_EDITWITHBUTTON + "\">").append(accessType.getHtml()).append("</td>");
155 html.append("<td width=\"1\"></td>");
156 }
157 else {
158 html.append("<input type=\"hidden\" id=\"' + prefix + 'AccessType\" name=\"' + prefix + 'AccessType\" value=\"sub\"/>");
159 }
160
161 html.append("<td width=\"100%\"class=\"" + CssConstants.CSSCLASS_EDITWITHBUTTON + "\">").append(path.getHtml()).append("</td>");
162 html.append("<td width=\"1\"></td>");
163
164 if (choose != null) {
165 html.append("<td width=\"1\" class=\"" + CssConstants.CSSCLASS_EDITWITHBUTTON + "\">").append(choose.getHtml()).append("</td>");
166 html.append("<td width=\"1\"></td>");
167 }
168
169 html.append("<td width=\"1\" class=\"" + CssConstants.CSSCLASS_EDITWITHBUTTON + "\">").append(delete.getHtml()).append("</td>");
170 html.append("</tr></table>");
171
172 return html.toString();
173 }
174
175 @Override
176 public void drawHtml(Writer w) throws IOException {
177 PrintWriter out = (PrintWriter) w;
178 this.drawHtmlPre(out);
179 renderACLS(out);
180 this.drawHtmlPost(out);
181
182 }
183
184 protected void renderACLS(PrintWriter out) throws IOException {
185 Messages msgs = MessagesManager.getMessages();
186 Content role = getStorageNode();
187 HttpServletRequest request = this.getRequest();
188 HttpServletResponse response = this.getResponse();
189
190
191 Select repositorySelect = getRepositorySelect();
192
193 out.print(repositorySelect.getHtml());
194 out.print("<p><p/>");
195
196
197 for (Iterator<RepositoryConfiguration> iter = securityConf.getVisibleRepositories().iterator(); iter.hasNext();) {
198 RepositoryConfiguration repositoryConf = iter.next();
199 try {
200 writeRepositoryTable(request, response, msgs, out, role, repositoryConf);
201 }
202 catch (RepositoryException e) {
203 throw new RuntimeException("can't list ", e);
204 }
205 }
206
207
208 out.println("<script type=\"text/javascript\">aclChangeRepository('website');</script>");
209 }
210
211
212
213
214
215
216
217
218 protected void writeRepositoryTable(HttpServletRequest request, HttpServletResponse response, Messages msgs,
219 PrintWriter out, Content role, RepositoryConfiguration repoConf) throws RepositoryException, IOException {
220 String tableName = "acl" + repoConf.getName() + "Table";
221 String dynamicTableName = "acl" + repoConf.getName() + "DynamicTable";
222 String hiddenFieldName = "acl" + repoConf.getName() + "List";
223
224 out.println("<div id=\"acl" + repoConf.getName() + "Div\" class=\"" + CSS_ACL_DIV + "\">");
225 out.println(new Hidden(hiddenFieldName, StringUtils.EMPTY, false).getHtml());
226
227
228 out.println("<table id=\""
229 + tableName
230 + "\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\"><tr><td></td></tr></table>");
231
232
233 out.println("<table width=\"100%\">");
234 DialogButton add = DialogFactory.getDialogButtonInstance(request, response, null, null);
235 add.setBoxType(DialogBox.BOXTYPE_1COL);
236 add.setConfig("buttonLabel", msgs.get("buttons.add"));
237 add.setConfig("onclick", dynamicTableName + ".addNew();");
238 add.drawHtml(out);
239 out.println("</table>");
240
241 out.println("</div>");
242
243 out.println("<script type=\"text/javascript\">");
244
245 out.println("aclRepositories[aclRepositories.length]= '" + repoConf.getName() + "';");
246
247
248 out.println("function acl" + repoConf.getName() + "RenderFunction(cell, prefix, index, object)");
249 out.println("{");
250
251
252 out.println("mgnlDebug('acl" + repoConf.getName() + "RenderFunction: prefix = ' + prefix, 'acl', object)");
253 out.println("cell.innerHTML= '" + getHtmlRowInner(dynamicTableName, repoConf) + "';\n");
254 out.println("document.getElementById(prefix + 'AccessType').value = object.accessType;\n");
255 out.println("document.getElementById(prefix + 'AccessRight').value = object.accessRight;\n");
256
257 out.println("}");
258
259
260 out.println(dynamicTableName + " = new MgnlDynamicTable('"
261 + tableName
262 + "',document.getElementById('mgnlFormMain')."
263 + hiddenFieldName
264 + ", aclGetNewPermissionObject, aclGetPermissionObject, acl"
265 + repoConf.getName()
266 + "RenderFunction, null);");
267
268
269
270 addExistingAclToTable(out, role, dynamicTableName, repoConf);
271
272 out.println("</script>");
273 }
274
275
276
277
278
279 private void addExistingAclToTable(PrintWriter out, Content role, String dynamicTableName,
280 RepositoryConfiguration repoConf) {
281
282 ACLS acls = new ACLS();
283
284 Content aclsNode = ContentUtil.getContent(role, "acl_" + repoConf.getName());
285 if (aclsNode == null || aclsNode.getChildren().size() == 0) {
286 out.println(dynamicTableName + ".addNew();");
287 return;
288 }
289
290 Iterator it = aclsNode.getChildren().iterator();
291 while (it.hasNext()) {
292 Content c = (Content) it.next();
293 String path = c.getNodeData("path").getString();
294 String accessRight = c.getNodeData("permissions").getString();
295 acls.register(path, Integer.valueOf(accessRight).intValue(), repoConf);
296 }
297
298 for (Iterator<ACL> iter = acls.values().iterator(); iter.hasNext();) {
299 ACL acl = iter.next();
300 out.println(dynamicTableName + ".add({accessRight:"
301 + acl.accessRight
302 + ",accessType:'"
303 + acl.type
304 + "',path:'"
305 + acl.path
306 + "'});");
307 }
308 }
309
310 private Select getRepositorySelect() {
311 Select repositorySelect = new Select();
312 repositorySelect.setName("aclRepository");
313 repositorySelect.setCssClass("mgnlDialogControlSelect");
314 repositorySelect.setEvent("onchange", "aclChangeRepository(this.value)");
315 repositorySelect.setSaveInfo(false);
316 repositorySelect.setValue(RepositoryConstants.WEBSITE);
317
318 for (Iterator<RepositoryConfiguration> iter = securityConf.getVisibleRepositories().iterator(); iter.hasNext();) {
319 RepositoryConfiguration repoConf = iter.next();
320 repositorySelect.setOptions(repoConf.getI18nLabel(), repoConf.getName());
321 }
322 return repositorySelect;
323 }
324
325 private static String escapeJs(String value) {
326 return StringUtils.replace(value, "'", "\\'");
327 }
328
329
330
331
332
333
334 protected class ACL {
335
336 int type = 0;
337
338 String path;
339
340 int accessRight;
341
342 void registerEntry(String path) {
343 if ("/*".equals(path)) {
344 type = AclTypeConfiguration.TYPE_ALL;
345 }
346 else if (path.endsWith("/*")) {
347 type = type | AclTypeConfiguration.TYPE_SUBS;
348 }
349 else {
350 type = type | AclTypeConfiguration.TYPE_THIS;
351 }
352 }
353 }
354
355
356
357
358
359 protected class ACLS extends ListOrderedMap {
360
361
362
363
364
365
366 void register(String path, int accessRight, RepositoryConfiguration repoConf) {
367 String cleanPath = repoConf.toViewPattern(path);
368
369 String key = cleanPath + ":" + accessRight;
370 if (!this.containsKey(key)) {
371 ACL acl = new ACL();
372 acl.path = cleanPath;
373 acl.accessRight = accessRight;
374 this.put(key, acl);
375 }
376 ((ACL) this.get(key)).registerEntry(path);
377 }
378 }
379
380 }