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