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