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.security.app.dialog.field;
35
36 import info.magnolia.cms.security.Permission;
37 import info.magnolia.i18nsystem.SimpleTranslator;
38 import info.magnolia.jcr.RuntimeRepositoryException;
39 import info.magnolia.objectfactory.ComponentProvider;
40 import info.magnolia.objectfactory.Components;
41 import info.magnolia.security.app.dialog.field.AccessControlListField.NewEntryHandler;
42 import info.magnolia.security.app.dialog.field.validator.WorkspaceAccessControlValidator;
43 import info.magnolia.ui.api.app.ChooseDialogCallback;
44 import info.magnolia.ui.api.context.UiContext;
45 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
46 import info.magnolia.ui.contentapp.choosedialog.ChooseDialogComponentProviderUtil;
47 import info.magnolia.ui.contentapp.field.WorkbenchFieldDefinition;
48 import info.magnolia.ui.dialog.choosedialog.ChooseDialogPresenter;
49 import info.magnolia.ui.dialog.choosedialog.ChooseDialogView;
50 import info.magnolia.ui.dialog.definition.ConfiguredChooseDialogDefinition;
51 import info.magnolia.ui.vaadin.integration.contentconnector.ConfiguredJcrContentConnectorDefinition;
52 import info.magnolia.ui.vaadin.integration.contentconnector.ConfiguredNodeTypeDefinition;
53 import info.magnolia.ui.vaadin.integration.contentconnector.NodeTypeDefinition;
54 import info.magnolia.ui.vaadin.integration.jcr.AbstractJcrNodeAdapter;
55 import info.magnolia.ui.vaadin.integration.jcr.JcrItemId;
56 import info.magnolia.ui.vaadin.integration.jcr.JcrItemUtil;
57 import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
58 import info.magnolia.ui.vaadin.integration.jcr.ModelConstants;
59 import info.magnolia.ui.workbench.column.definition.ColumnDefinition;
60 import info.magnolia.ui.workbench.column.definition.PropertyColumnDefinition;
61 import info.magnolia.ui.workbench.definition.ConfiguredWorkbenchDefinition;
62 import info.magnolia.ui.workbench.definition.ContentPresenterDefinition;
63 import info.magnolia.ui.workbench.definition.WorkbenchDefinition;
64 import info.magnolia.ui.workbench.tree.TreePresenterDefinition;
65
66 import java.util.ArrayList;
67 import java.util.List;
68 import java.util.Map;
69
70 import javax.inject.Inject;
71 import javax.jcr.Node;
72 import javax.jcr.RepositoryException;
73
74 import org.apache.commons.lang3.StringUtils;
75 import org.apache.jackrabbit.JcrConstants;
76 import org.slf4j.Logger;
77 import org.slf4j.LoggerFactory;
78
79 import com.google.common.collect.ImmutableMap;
80 import com.vaadin.data.Item;
81 import com.vaadin.data.Property;
82 import com.vaadin.data.util.ObjectProperty;
83 import com.vaadin.ui.AbstractOrderedLayout;
84 import com.vaadin.ui.Button;
85 import com.vaadin.ui.Component;
86 import com.vaadin.ui.Field;
87 import com.vaadin.ui.HorizontalLayout;
88 import com.vaadin.ui.Label;
89 import com.vaadin.ui.NativeSelect;
90 import com.vaadin.ui.TextField;
91
92
93
94
95
96
97
98
99
100
101
102 public class WorkspaceAccessFieldFactory extends AbstractAccessFieldFactory<WorkspaceAccessFieldDefinition, AccessControlList> {
103
104 private static final Logger log = LoggerFactory.getLogger(WorkspaceAccessFieldFactory.class);
105
106
107
108
109 @Deprecated
110 public static final String INTERMEDIARY_FORMAT_PROPERTY_NAME = "__intermediary_format";
111
112
113
114
115 @Deprecated
116 public static final String ACCESS_TYPE_PROPERTY_NAME = WorkspaceAccessControlList.ACCESS_TYPE_PROPERTY_NAME;
117
118 private final UiContext uiContext;
119 private final SimpleTranslator i18n;
120 private final ComponentProvider componentProvider;
121
122 private final String workspace;
123 private final String aclName;
124
125 @Inject
126 public WorkspaceAccessFieldFactory(WorkspaceAccessFieldDefinition definition, Item relatedFieldItem, UiContext uiContext, I18NAuthoringSupport i18nAuthoringSupport, ChooseDialogPresenter workbenchChooseDialogPresenter, SimpleTranslator i18n, ComponentProvider componentProvider) {
127 super(definition, relatedFieldItem, uiContext, i18nAuthoringSupport);
128 this.uiContext = uiContext;
129 this.i18n = i18n;
130 this.componentProvider = componentProvider;
131
132 workspace = definition.getWorkspace();
133 aclName = "acl_" + workspace;
134 }
135
136
137
138
139 @Deprecated
140 public WorkspaceAccessFieldFactory(WorkspaceAccessFieldDefinition definition, Item relatedFieldItem, UiContext uiContext, ChooseDialogPresenter workbenchChooseDialogPresenter, SimpleTranslator i18n, ComponentProvider componentProvider) {
141 this(definition, relatedFieldItem, uiContext, componentProvider.getComponent(I18NAuthoringSupport.class), workbenchChooseDialogPresenter, i18n, componentProvider);
142 }
143
144
145
146
147 @Deprecated
148 public WorkspaceAccessFieldFactory(WorkspaceAccessFieldDefinition definition, Item relatedFieldItem, UiContext uiContext, ChooseDialogPresenter workbenchChooseDialogPresenter, SimpleTranslator i18n) {
149 this(definition, relatedFieldItem, uiContext, Components.getComponent(I18NAuthoringSupport.class), workbenchChooseDialogPresenter, i18n, Components.getComponentProvider());
150 }
151
152 @Override
153 protected Field<AccessControlList> createFieldComponent() {
154 final Map<Long, String> permissionItems = ImmutableMap.of(
155 Permission.ALL, i18n.translate("security.workspace.field.readWrite"),
156 Permission.READ, i18n.translate("security.workspace.field.readOnly"),
157 Permission.NONE, i18n.translate("security.workspace.field.denyAccess"));
158
159 final Map<Long, String> accessTypeItems = ImmutableMap.of(
160 WorkspaceAccessControlList.ACCESS_TYPE_NODE, i18n.translate("security.workspace.field.selected"),
161 WorkspaceAccessControlList.ACCESS_TYPE_CHILDREN, i18n.translate("security.workspace.field.subnodes"),
162 WorkspaceAccessControlList.ACCESS_TYPE_NODE_AND_CHILDREN, i18n.translate("security.workspace.field.selectedSubnodes"));
163
164 final String chooseCaption = i18n.translate("security.workspace.field.choose");
165
166 AccessControlListField aclField = new AccessControlListField(permissionItems, new NewEntryHandler() {
167 @Override
168 public AccessControlList.Entry createEntry() {
169 return new WorkspaceAccessControlList.Entry(Permission.ALL, WorkspaceAccessControlList.ACCESS_TYPE_NODE_AND_CHILDREN, "");
170 }
171 });
172
173 final AccessControlField.PathChooserHandler pathChooserHandler = new AccessControlField.PathChooserHandler() {
174 @Override
175 public void openChooser(final Property<String> pathProperty) {
176 openChooseDialog(pathProperty.getValue(), new ChooseDialogCallback() {
177 @Override
178 public void onItemChosen(String actionName, Object value) {
179 try {
180 String newPath = value instanceof JcrItemId ? JcrItemUtil.getJcrItem((JcrItemId) value).getPath() : "/";
181 pathProperty.setValue(newPath);
182 } catch (RepositoryException e) {
183 log.error("Failed to read chosen node", e);
184 }
185 }
186
187 @Override
188 public void onCancel() {
189 }
190 });
191 }
192 };
193
194 aclField.setEntryFieldFactory(new AccessControlListField.EntryFieldFactory() {
195 @Override
196 public Field<AccessControlList.Entry> createField(AccessControlList.Entry entry) {
197 AccessControlField entryField = new AccessControlField(permissionItems, accessTypeItems);
198 entryField.setPropertyDataSource(new ObjectProperty<>(entry));
199 entryField.setPathChooserHandler(pathChooserHandler);
200 entryField.setChooseButtonCaption(chooseCaption);
201 entryField.addValidator(new WorkspaceAccessControlValidator(definition.getWorkspace(), i18n.translate("security-app.role.acls.errorMessage")));
202 return entryField;
203 }
204 });
205 aclField.setAddButtonCaption(i18n.translate("security.workspace.field.addButton"));
206 aclField.setRemoveButtonCaption(i18n.translate("security.workspace.field.delete"));
207 aclField.setEmptyPlaceholderCaption(i18n.translate("security.workspace.field.noAccess"));
208
209 return aclField;
210 }
211
212 @Override
213 protected Property<AccessControlList> initializeProperty() {
214
215 JcrNodeAdapter roleItem = (JcrNodeAdapter) item;
216 AccessControlList<WorkspaceAccessControlList.Entry> acl = new WorkspaceAccessControlList();
217 roleItem.addItemProperty(aclName, new ObjectProperty<>(acl));
218
219 if (!(roleItem.isNew())) {
220 try {
221 Node roleNode = roleItem.getJcrItem();
222 if (roleNode.hasNode(aclName)) {
223 final Node aclNode = roleNode.getNode(aclName);
224 acl.readEntries(aclNode);
225
226 }
227 } catch (RepositoryException e) {
228 throw new RuntimeRepositoryException(e);
229 }
230 }
231
232 return new ObjectProperty<AccessControlList>(acl);
233 }
234
235
236
237
238 @Deprecated
239 protected Component createRuleRow(final AbstractOrderedLayout parentContainer, final AbstractJcrNodeAdapter ruleItem, final Label emptyLabel) {
240
241 final HorizontalLayout ruleLayout = new HorizontalLayout();
242 ruleLayout.setSpacing(true);
243 ruleLayout.setWidth("100%");
244
245 NativeSelect accessRights = new NativeSelect();
246 accessRights.setNullSelectionAllowed(false);
247 accessRights.setImmediate(true);
248 accessRights.setInvalidAllowed(false);
249 accessRights.setNewItemsAllowed(false);
250 accessRights.addItem(Permission.ALL);
251 accessRights.setItemCaption(Permission.ALL, i18n.translate("security.workspace.field.readWrite"));
252 accessRights.addItem(Permission.READ);
253 accessRights.setItemCaption(Permission.READ, i18n.translate("security.workspace.field.readOnly"));
254 accessRights.addItem(Permission.NONE);
255 accessRights.setItemCaption(Permission.NONE, i18n.translate("security.workspace.field.denyAccess"));
256 accessRights.setPropertyDataSource(ruleItem.getItemProperty(AccessControlList.PERMISSIONS_PROPERTY_NAME));
257 ruleLayout.addComponent(accessRights);
258
259 NativeSelect accessType = new NativeSelect();
260 accessType.setNullSelectionAllowed(false);
261 accessType.setImmediate(true);
262 accessType.setInvalidAllowed(false);
263 accessType.setNewItemsAllowed(false);
264 accessType.setWidth("150px");
265 accessType.addItem(WorkspaceAccessControlList.ACCESS_TYPE_NODE);
266 accessType.setItemCaption(WorkspaceAccessControlList.ACCESS_TYPE_NODE, i18n.translate("security.workspace.field.selected"));
267 accessType.addItem(WorkspaceAccessControlList.ACCESS_TYPE_CHILDREN);
268 accessType.setItemCaption(WorkspaceAccessControlList.ACCESS_TYPE_CHILDREN, i18n.translate("security.workspace.field.subnodes"));
269 accessType.addItem(WorkspaceAccessControlList.ACCESS_TYPE_NODE_AND_CHILDREN);
270 accessType.setItemCaption(WorkspaceAccessControlList.ACCESS_TYPE_NODE_AND_CHILDREN, i18n.translate("security.workspace.field.selectedSubnodes"));
271 Property accessTypeProperty = ruleItem.getItemProperty(ACCESS_TYPE_PROPERTY_NAME);
272 accessType.setPropertyDataSource(accessTypeProperty);
273 ruleLayout.addComponent(accessType);
274
275 final TextField path = new TextField();
276 path.setWidth("100%");
277 path.setPropertyDataSource(ruleItem.getItemProperty(AccessControlList.PATH_PROPERTY_NAME));
278 ruleLayout.addComponent(path);
279 ruleLayout.setExpandRatio(path, 1.0f);
280
281 Button chooseButton = new Button(i18n.translate("security.workspace.field.choose"));
282 chooseButton.addClickListener(new Button.ClickListener() {
283
284 @Override
285 public void buttonClick(Button.ClickEvent event) {
286 openChooseDialog(path);
287 }
288 });
289 ruleLayout.addComponent(chooseButton);
290
291 Button deleteButton = new Button();
292 deleteButton.setHtmlContentAllowed(true);
293 deleteButton.setCaption("<span class=\"" + "icon-trash" + "\"></span>");
294 deleteButton.addStyleName("inline");
295 deleteButton.setDescription(i18n.translate("security.workspace.field.delete"));
296 deleteButton.addClickListener(new Button.ClickListener() {
297
298 @Override
299 public void buttonClick(Button.ClickEvent event) {
300 parentContainer.removeComponent(ruleLayout);
301 ruleItem.getParent().removeChild(ruleItem);
302 if (parentContainer.getComponentCount() == 1) {
303 parentContainer.addComponent(emptyLabel, 0);
304 }
305 }
306 });
307 ruleLayout.addComponent(deleteButton);
308
309 return ruleLayout;
310 }
311
312
313
314
315 @Deprecated
316 protected void openChooseDialog(final TextField textField) {
317 openChooseDialog(textField.getValue(), new ChooseDialogCallback() {
318 @Override
319 public void onItemChosen(String actionName, Object value) {
320 try {
321 if (value instanceof JcrItemId) {
322 JcrItemId jcrItemId = (JcrItemId) value;
323 textField.setValue(JcrItemUtil.getJcrItem(jcrItemId).getPath());
324 } else {
325 textField.setValue("/");
326 }
327 } catch (RepositoryException e) {
328 log.error("Failed to read chosen node", e);
329 }
330 }
331
332 @Override
333 public void onCancel() {
334 }
335 });
336 }
337
338 protected void openChooseDialog(String initialItemId, ChooseDialogCallback callback) {
339 final ConfiguredChooseDialogDefinition def = new ConfiguredChooseDialogDefinition();
340 final ConfiguredJcrContentConnectorDefinition contentConnectorDefinition = new ConfiguredJcrContentConnectorDefinition();
341 contentConnectorDefinition.setWorkspace(getFieldDefinition().getWorkspace());
342 contentConnectorDefinition.setRootPath("/");
343 contentConnectorDefinition.setDefaultOrder(ModelConstants.JCR_NAME);
344
345 contentConnectorDefinition.setNodeTypes(resolveNodeTypes());
346 def.setContentConnector(contentConnectorDefinition);
347
348 final WorkbenchDefinition wbDef = resolveWorkbenchDefinition();
349 final WorkbenchFieldDefinition fieldDef = new WorkbenchFieldDefinition();
350 fieldDef.setWorkbench(wbDef);
351 def.setField(fieldDef);
352
353
354 ComponentProvider chooseDialogComponentProvider = ChooseDialogComponentProviderUtil.createChooseDialogComponentProvider(def, componentProvider);
355 ChooseDialogPresenter workbenchChooseDialogPresenter = chooseDialogComponentProvider.newInstance(def.getPresenterClass(), chooseDialogComponentProvider);
356
357 ChooseDialogView chooseDialogView = workbenchChooseDialogPresenter.start(callback, def, uiContext, initialItemId);
358 chooseDialogView.setCaption(StringUtils.capitalize(getFieldDefinition().getWorkspace()));
359 }
360
361 protected WorkbenchDefinition resolveWorkbenchDefinition() {
362
363 if (getFieldDefinition().getWorkbench() != null) {
364 return getFieldDefinition().getWorkbench();
365 }
366
367 ConfiguredWorkbenchDefinition workbenchDefinition = new ConfiguredWorkbenchDefinition();
368 workbenchDefinition.setDialogWorkbench(true);
369 workbenchDefinition.setEditable(false);
370
371
372 ArrayList<ContentPresenterDefinition> contentViews = new ArrayList<>();
373 TreePresenterDefinition treeView = new TreePresenterDefinition();
374 ArrayList<ColumnDefinition> columns = new ArrayList<>();
375 PropertyColumnDefinition column = new PropertyColumnDefinition();
376 column.setEditable(false);
377 column.setDisplayInChooseDialog(true);
378 column.setLabel(i18n.translate("security.workspace.field.nodeName"));
379 column.setPropertyName(ModelConstants.JCR_NAME);
380 column.setName(ModelConstants.JCR_NAME);
381 columns.add(column);
382 treeView.setColumns(columns);
383 contentViews.add(treeView);
384 workbenchDefinition.setContentViews(contentViews);
385
386 return workbenchDefinition;
387 }
388
389 private List<NodeTypeDefinition> resolveNodeTypes() {
390
391 if (getFieldDefinition().getNodeTypes() != null) {
392 return getFieldDefinition().getNodeTypes();
393 }
394
395 ArrayList<NodeTypeDefinition> nodeTypes = new ArrayList<>();
396 ConfiguredNodeTypeDefinition nodeType = new ConfiguredNodeTypeDefinition();
397 nodeType.setName(JcrConstants.NT_BASE);
398 nodeType.setIcon("icon-folder");
399 nodeTypes.add(nodeType);
400
401 return nodeTypes;
402 }
403 }