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.jcr.util.NodeUtil;
40 import info.magnolia.ui.vaadin.integration.jcr.AbstractJcrNodeAdapter;
41 import info.magnolia.ui.vaadin.integration.jcr.DefaultProperty;
42 import info.magnolia.ui.vaadin.integration.jcr.JcrNewNodeAdapter;
43 import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
44
45 import javax.jcr.Node;
46 import javax.jcr.RepositoryException;
47
48 import com.vaadin.data.Item;
49 import com.vaadin.data.Property;
50 import com.vaadin.ui.AbstractOrderedLayout;
51 import com.vaadin.ui.Button;
52 import com.vaadin.ui.Component;
53 import com.vaadin.ui.CustomField;
54 import com.vaadin.ui.Field;
55 import com.vaadin.ui.HorizontalLayout;
56 import com.vaadin.ui.Label;
57 import com.vaadin.ui.NativeSelect;
58 import com.vaadin.ui.TextField;
59 import com.vaadin.ui.VerticalLayout;
60
61
62
63
64
65
66
67 public class WebAccessFieldFactory<D extends WebAccessFieldDefinition> extends AbstractAccessFieldFactory<D> {
68
69 private static final String ACL_NODE_NAME = "acl_uri";
70 private static final String PERMISSIONS_PROPERTY_NAME = "permissions";
71 private static final String PATH_PROPERTY_NAME = "path";
72
73 private final SimpleTranslator i18n;
74
75 public WebAccessFieldFactory(D definition, Item relatedFieldItem, SimpleTranslator i18n) {
76 super(definition, relatedFieldItem);
77 this.i18n = i18n;
78 }
79
80 @Override
81 protected Field<Object> createFieldComponent() {
82
83 final VerticalLayout layout = new VerticalLayout();
84 layout.setSpacing(true);
85
86 try {
87
88 final JcrNodeAdapter roleItem = (JcrNodeAdapter) item;
89 Node roleNode = roleItem.getJcrItem();
90
91 final VerticalLayout aclLayout = new VerticalLayout();
92
93 final Label emptyLabel = new Label(i18n.translate("security.web.field.noAccess"));
94
95 if (roleNode.hasNode(ACL_NODE_NAME)) {
96
97 final Node aclNode = roleNode.getNode(ACL_NODE_NAME);
98 AbstractJcrNodeAdapter aclItem = new JcrNodeAdapter(aclNode);
99 roleItem.addChild(aclItem);
100
101 for (Node entryNode : NodeUtil.getNodes(aclNode)) {
102
103 AbstractJcrNodeAdapter entryItem = new JcrNodeAdapter(entryNode);
104 aclItem.addChild(entryItem);
105
106 Component ruleRow = createRuleRow(aclLayout, entryItem, emptyLabel);
107 aclLayout.addComponent(ruleRow);
108 }
109 }
110
111 if (aclLayout.getComponentCount() == 0) {
112 aclLayout.addComponent(emptyLabel);
113 }
114
115 final HorizontalLayout buttons = new HorizontalLayout();
116 final Button addButton = new Button(i18n.translate("security.web.field.addNew"));
117 addButton.addClickListener(new Button.ClickListener() {
118
119 @Override
120 public void buttonClick(Button.ClickEvent event) {
121
122 try {
123 AbstractJcrNodeAdapter aclItem = getOrAddAclItem(roleItem, ACL_NODE_NAME);
124 JcrNewNodeAdapter newItem = addAclEntryItem(aclItem);
125 Component ruleRow = createRuleRow(aclLayout, newItem, emptyLabel);
126 aclLayout.removeComponent(emptyLabel);
127 aclLayout.addComponent(ruleRow, aclLayout.getComponentCount() - 1);
128
129 } catch (RepositoryException e) {
130 throw new RuntimeRepositoryException(e);
131 }
132 }
133 });
134 buttons.addComponent(addButton);
135 aclLayout.addComponent(buttons);
136
137 layout.addComponent(aclLayout);
138
139 } catch (RepositoryException e) {
140 throw new RuntimeRepositoryException(e);
141 }
142
143 return new CustomField<Object>() {
144
145 @Override
146 protected Component initContent() {
147 return layout;
148 }
149
150 @Override
151 public Class<?> getType() {
152 return Object.class;
153 }
154 };
155 }
156
157 private Component createRuleRow(final AbstractOrderedLayout parentContainer, final AbstractJcrNodeAdapter ruleItem, final Label emptyLabel) {
158
159 final HorizontalLayout ruleLayout = new HorizontalLayout();
160 ruleLayout.setSpacing(true);
161
162 NativeSelect accessRights = new NativeSelect();
163 accessRights.addItem(Permission.ALL);
164 accessRights.setItemCaption(Permission.ALL, i18n.translate("security.web.field.getPost"));
165 accessRights.addItem(Permission.READ);
166 accessRights.setItemCaption(Permission.READ, i18n.translate("security.web.field.get"));
167 accessRights.addItem(Permission.NONE);
168 accessRights.setItemCaption(Permission.NONE, i18n.translate("security.web.field.deny"));
169 accessRights.setNullSelectionAllowed(false);
170 accessRights.setImmediate(true);
171 accessRights.setInvalidAllowed(false);
172 accessRights.setNewItemsAllowed(false);
173 Property permissionsProperty = ruleItem.getItemProperty(PERMISSIONS_PROPERTY_NAME);
174 if (permissionsProperty == null) {
175 permissionsProperty = new DefaultProperty<Long>(Long.class, Permission.ALL);
176 ruleItem.addItemProperty(PERMISSIONS_PROPERTY_NAME, permissionsProperty);
177 }
178 accessRights.setPropertyDataSource(permissionsProperty);
179 ruleLayout.addComponent(accessRights);
180
181 TextField path = new TextField();
182 path.setWidth("375px");
183 Property pathProperty = ruleItem.getItemProperty(PATH_PROPERTY_NAME);
184 if (pathProperty == null) {
185 pathProperty = new DefaultProperty<String>(String.class, "/*");
186 ruleItem.addItemProperty(PATH_PROPERTY_NAME, pathProperty);
187 }
188 path.setPropertyDataSource(pathProperty);
189 ruleLayout.addComponent(path);
190
191 final Button deleteButton = new Button();
192 deleteButton.setHtmlContentAllowed(true);
193 deleteButton.setCaption("<span class=\"" + "icon-trash" + "\"></span>");
194 deleteButton.addStyleName("inline");
195 deleteButton.setDescription(i18n.translate("security.web.field.delete"));
196 deleteButton.addClickListener(new Button.ClickListener() {
197
198 @Override
199 public void buttonClick(Button.ClickEvent event) {
200 parentContainer.removeComponent(ruleLayout);
201 ruleItem.getParent().removeChild(ruleItem);
202 if (parentContainer.getComponentCount() == 1) {
203 parentContainer.addComponent(emptyLabel, 0);
204 }
205 }
206 });
207 ruleLayout.addComponent(deleteButton);
208
209 return ruleLayout;
210 }
211 }