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.cms.security;
35
36 import info.magnolia.cms.beans.config.ContentRepository;
37 import info.magnolia.cms.core.Content;
38 import info.magnolia.cms.core.HierarchyManager;
39 import info.magnolia.cms.core.ItemType;
40 import info.magnolia.cms.core.NodeData;
41 import info.magnolia.cms.core.Path;
42 import info.magnolia.cms.util.NodeDataUtil;
43 import org.apache.commons.lang.StringUtils;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 import javax.jcr.ItemNotFoundException;
48 import javax.jcr.PathNotFoundException;
49 import javax.jcr.RepositoryException;
50 import java.util.Collection;
51
52
53
54
55
56 public class MgnlGroup implements Group {
57 private static final Logger log = LoggerFactory.getLogger(MgnlGroup.class);
58
59
60
61
62 private static final String NODE_ROLES = "roles";
63
64 private static final String NODE_GROUPS = "groups";
65
66
67
68
69 private final Content groupNode;
70
71
72
73
74 protected MgnlGroup(Content groupNode) {
75 this.groupNode = groupNode;
76 }
77
78
79
80
81
82 public String getName() {
83 return getGroupNode().getName();
84 }
85
86
87
88
89
90
91
92 public void addRole(String roleName) throws UnsupportedOperationException, AccessDeniedException {
93 this.add(roleName, NODE_ROLES);
94 }
95
96
97
98
99
100
101
102 public void addGroup(String groupName) throws UnsupportedOperationException, AccessDeniedException {
103 this.add(groupName, NODE_GROUPS);
104 }
105
106
107
108
109
110
111
112 public void removeRole(String roleName) throws UnsupportedOperationException, AccessDeniedException {
113 this.remove(roleName, NODE_ROLES);
114 }
115
116
117
118
119
120
121
122 public void removeGroup(String groupName) throws UnsupportedOperationException, AccessDeniedException {
123 this.remove(groupName, NODE_GROUPS);
124 }
125
126
127
128
129
130
131
132 public boolean hasRole(String roleName) throws UnsupportedOperationException, AccessDeniedException {
133 return this.hasAny(roleName, NODE_ROLES);
134 }
135
136 public String getProperty(String propertyName) {
137 return NodeDataUtil.getString(getGroupNode(), propertyName, null);
138 }
139
140 public void setProperty(String propertyName, String value) {
141 try {
142 NodeDataUtil.getOrCreateAndSet(getGroupNode(), propertyName, value);
143 getGroupNode().save();
144 } catch (RepositoryException e) {
145 throw new RuntimeException(e);
146 }
147 }
148
149 public Collection<String> getRoles() {
150 return MgnlSecurityUtil.collectPropertyNames(getGroupNode(), "roles", ContentRepository.USER_ROLES, false);
151 }
152
153 public Collection<String> getGroups() {
154 return MgnlSecurityUtil.collectPropertyNames(getGroupNode(), "groups", ContentRepository.USER_GROUPS, false);
155 }
156
157 public Collection<String> getAllGroups() {
158 return MgnlSecurityUtil.collectPropertyNames(getGroupNode(), "groups", ContentRepository.USER_GROUPS, true);
159 }
160
161
162
163
164
165
166 private boolean hasAny(String name, String nodeName) {
167 try {
168 final String hmName;
169 if (StringUtils.equalsIgnoreCase(nodeName, NODE_ROLES)) {
170 hmName = ContentRepository.USER_ROLES;
171 }
172 else {
173 hmName = ContentRepository.USER_GROUPS;
174 }
175 final HierarchyManager hm = MgnlSecurityUtil.getSystemHierarchyManager(hmName);
176
177 Content node = getGroupNode().getContent(nodeName);
178 for (NodeData nodeData : node.getNodeDataCollection()) {
179
180 try {
181 if (hm.getContentByUUID(nodeData.getString()).getName().equalsIgnoreCase(name)) {
182 return true;
183 }
184 }
185 catch (ItemNotFoundException e) {
186 log.debug("[{}] does not exist in the {} repository", name, hmName);
187 }
188 catch (IllegalArgumentException e) {
189 log.debug(nodeData.getHandle() + " has invalid value");
190 }
191 }
192 }
193 catch (RepositoryException e) {
194 log.debug(e.getMessage(), e);
195 }
196 return false;
197 }
198
199
200
201
202
203
204 private void remove(String name, String nodeName) {
205 try {
206 final String hmName;
207 if (StringUtils.equalsIgnoreCase(nodeName, NODE_ROLES)) {
208 hmName = ContentRepository.USER_ROLES;
209 }
210 else {
211 hmName = ContentRepository.USER_GROUPS;
212 }
213 final HierarchyManager hm = MgnlSecurityUtil.getContextHierarchyManager(hmName);
214 Content node = getGroupNode().getContent(nodeName);
215
216 for (NodeData nodeData: node.getNodeDataCollection()) {
217
218 try {
219 if (hm.getContentByUUID(nodeData.getString()).getName().equalsIgnoreCase(name)) {
220 nodeData.delete();
221 }
222 }
223 catch (ItemNotFoundException e) {
224 log.debug("[{}] does not exist in the {} repository", name, hmName);
225 }
226 catch (IllegalArgumentException e) {
227 log.debug(nodeData.getHandle() + " has invalid value");
228 }
229 }
230 getGroupNode().save();
231 }
232 catch (RepositoryException e) {
233 log.error("failed to remove " + name + " from group [" + this.getName() + "]", e);
234 }
235 }
236
237
238
239
240 private void add(String name, String nodeName) {
241 try {
242 final Content groupNode = getGroupNode();
243 final String hmName;
244 if (StringUtils.equalsIgnoreCase(nodeName, NODE_ROLES)) {
245 hmName = ContentRepository.USER_ROLES;
246 } else {
247 hmName = ContentRepository.USER_GROUPS;
248 }
249
250 final HierarchyManager hm = MgnlSecurityUtil.getContextHierarchyManager(hmName);
251
252 if (!this.hasAny(name, nodeName)) {
253 if (!groupNode.hasContent(nodeName)) {
254 groupNode.createContent(nodeName, ItemType.CONTENTNODE);
255 }
256 Content node = groupNode.getContent(nodeName);
257
258 try {
259 String value = hm.getContent("/" + name).getUUID();
260
261 final HierarchyManager sysHM = MgnlSecurityUtil.getSystemHierarchyManager(ContentRepository.USER_GROUPS);
262 final String newName = Path.getUniqueLabel(sysHM, node.getHandle(), "0");
263 node.createNodeData(newName).setValue(value);
264 groupNode.save();
265 }
266 catch (PathNotFoundException e) {
267 log.debug("[{}] does not exist in the {} repository", name, hmName);
268 }
269 }
270 }
271 catch (RepositoryException e) {
272 log.error("failed to add " + name + " to group [" + this.getName() + "]", e);
273 }
274 }
275
276 public Content getGroupNode() {
277 return groupNode;
278 }
279 }