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 static info.magnolia.cms.security.SecurityConstants.*;
37
38 import info.magnolia.context.MgnlContext;
39 import info.magnolia.jcr.iterator.FilteringPropertyIterator;
40 import info.magnolia.jcr.util.NodeTypes;
41 import info.magnolia.jcr.util.NodeUtil;
42 import info.magnolia.repository.RepositoryConstants;
43
44 import java.util.ArrayList;
45 import java.util.Collection;
46 import java.util.Collections;
47 import java.util.HashSet;
48 import java.util.Iterator;
49 import java.util.List;
50
51 import javax.jcr.ItemNotFoundException;
52 import javax.jcr.Node;
53 import javax.jcr.NodeIterator;
54 import javax.jcr.Property;
55 import javax.jcr.PropertyIterator;
56 import javax.jcr.RepositoryException;
57 import javax.jcr.Session;
58
59 import org.apache.commons.lang.StringUtils;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62
63
64
65
66
67 public class MgnlGroupManager extends RepositoryBackedSecurityManager implements GroupManager {
68
69 private static final Logger log = LoggerFactory.getLogger(MgnlGroupManager.class);
70
71 @Override
72 public Group createGroup(final String name) throws AccessDeniedException {
73 return createGroup(null, name);
74 }
75
76
77
78
79
80
81
82 public Group createGroup(final String path, final String name) throws AccessDeniedException {
83 validateGroupName(name);
84 return MgnlContext.doInSystemContext(new SilentSessionOp<MgnlGroup>(getRepositoryName()) {
85
86 @Override
87 public MgnlGroup doExec(Session session) throws RepositoryException {
88 String parentPath = StringUtils.defaultString(path, "/");
89 Node groupNode = session.getNode(parentPath).addNode(name, NodeTypes.Group.NAME);
90 session.save();
91 return new MgnlGroup(groupNode.getIdentifier(), groupNode.getName(), Collections.EMPTY_LIST, Collections.EMPTY_LIST);
92 }
93
94 @Override
95 public String toString() {
96 return "create group " + name;
97 }
98 });
99 }
100
101 @Override
102 public Group getGroup(final String name) throws AccessDeniedException {
103 return MgnlContext.doInSystemContext(new SilentSessionOp<Group>(getRepositoryName()) {
104
105 @Override
106 public Group doExec(Session session) throws RepositoryException {
107 Node privilegedGroupNode = findPrincipalNode(name, session);
108 if (privilegedGroupNode == null) {
109 return null;
110 }
111 return newGroupInstance(privilegedGroupNode);
112 }
113
114 @Override
115 public String toString() {
116 return "get group " + name;
117 }
118 });
119 }
120
121 @Override
122 public Collection<Group> getAllGroups() {
123 return MgnlContext.doInSystemContext(new SilentSessionOp<Collection<Group>>(getRepositoryName()) {
124
125 @Override
126 public Collection<Group> doExec(Session session) throws RepositoryException {
127 List<Group> groups = new ArrayList<Group>();
128 Node rootNode = session.getNode("/");
129 findAllGroupsInFolder(rootNode, groups);
130 return groups;
131 }
132
133 @Override
134 public String toString() {
135 return "get all groups";
136 }
137
138 });
139 }
140
141 @Override
142 public Collection<String> getAllGroups(final String name) {
143 return MgnlContext.doInSystemContext(new SilentSessionOp<Collection<String>>(getRepositoryName()) {
144
145 List<String> groups;
146
147 @Override
148 public Collection<String> doExec(Session session) throws RepositoryException {
149 Group group = getGroup(name);
150 if(group == null){
151 return null;
152 }
153 groups = new ArrayList<String>();
154 collectGroups(group);
155
156 return groups;
157 }
158
159 private void collectGroups(Group group) throws AccessDeniedException{
160 for (Iterator iter = group.getGroups().iterator(); iter.hasNext();){
161 Group subGroup = getGroup((String) iter.next());
162 if(subGroup != null && !groups.contains(subGroup.getName())){
163 groups.add(subGroup.getName());
164 collectGroups(subGroup);
165 }
166 }
167 }
168
169 @Override
170 public String toString() {
171 return "get all groups";
172 }
173 });
174 }
175
176 protected Group newGroupInstance(Node node) throws RepositoryException {
177
178 Collection<String> groups = new HashSet<String>();
179 if (node.hasNode(NODE_GROUPS)) {
180 for (PropertyIterator iter = new FilteringPropertyIterator(node.getNode(NODE_GROUPS).getProperties(), NodeUtil.ALL_PROPERTIES_EXCEPT_JCR_AND_MGNL_FILTER); iter.hasNext();) {
181 Property subgroup = iter.nextProperty();
182 String resources = getResourceName(subgroup.getString());
183 if(resources != null){
184 groups.add(resources);
185 }
186 }
187 }
188 Collection<String> roles = new HashSet<String>();
189 if (node.hasNode(NODE_ROLES)) {
190 RoleManager roleMan = SecuritySupport.Factory.getInstance().getRoleManager();
191 for (PropertyIterator iter = new FilteringPropertyIterator(node.getNode(NODE_ROLES).getProperties(), NodeUtil.ALL_PROPERTIES_EXCEPT_JCR_AND_MGNL_FILTER); iter.hasNext();) {
192 Property role = iter.nextProperty();
193 try {
194 String roleName = roleMan.getRoleNameById(role.getString());
195 if (roleName != null) {
196 roles.add(roleName);
197 }
198 } catch (ItemNotFoundException e) {
199 log.warn("assigned role " + role.getString() + " doesn't exist.");
200 }
201 }
202 }
203 MgnlGroup group = new MgnlGroup(node.getIdentifier(), node.getName(), groups, roles);
204 return group;
205 }
206
207
208
209
210
211 @Override
212 protected Node findPrincipalNode(String principalName, Session session) throws RepositoryException {
213 return findPrincipalNode(principalName, session, NodeTypes.Group.NAME);
214 }
215
216 @Override
217 protected String getRepositoryName() {
218 return RepositoryConstants.USER_GROUPS;
219 }
220
221 @Override
222 public Group addRole(Group group, String roleName) throws AccessDeniedException {
223 try {
224 add(group.getName(), roleName, NODE_ROLES);
225 } catch (PrincipalNotFoundException e) {
226
227 return null;
228 }
229 return getGroup(group.getName());
230 }
231
232 @Override
233 public Group addGroup(Group group, String groupName) throws AccessDeniedException {
234 try {
235 add(group.getName(), groupName, NODE_GROUPS);
236 } catch (PrincipalNotFoundException e) {
237
238 return null;
239 }
240 return getGroup(groupName);
241 }
242
243
244
245
246
247
248 protected void findAllGroupsInFolder(Node node, Collection<Group> groups) throws RepositoryException {
249 NodeIterator nodesIter = node.getNodes();
250 Collection<Node> nodes = new HashSet<Node>();
251 Collection<Node> folders = new HashSet<Node>();
252 while (nodesIter.hasNext()) {
253 Node newNode = (Node) nodesIter.next();
254 if (newNode.isNodeType(NodeTypes.Group.NAME)) {
255 nodes.add(newNode);
256 } else if (newNode.isNodeType(NodeTypes.Folder.NAME)) {
257 folders.add(newNode);
258 }
259 }
260
261 if (!nodes.isEmpty()) {
262 for (Node groupNode : nodes) {
263 groups.add(newGroupInstance(groupNode));
264 }
265 }
266 if (!folders.isEmpty()) {
267 for (Node folder : folders) {
268 findAllGroupsInFolder(folder, groups);
269 }
270 }
271 }
272
273 protected void validateGroupName(String name) throws AccessDeniedException {
274 if (StringUtils.isBlank(name)) {
275 throw new IllegalArgumentException(name + " is not a valid group name.");
276 }
277
278 Group group = Security.getGroupManager().getGroup(name);
279
280 if (group != null) {
281 throw new IllegalArgumentException("Group with name " + name + " already exists.");
282 }
283 }
284 }