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.core.Content;
37 import info.magnolia.cms.core.HierarchyManager;
38 import info.magnolia.cms.core.Path;
39 import info.magnolia.context.MgnlContext;
40 import info.magnolia.jcr.iterator.SameChildNodeTypeIterator;
41 import info.magnolia.jcr.util.NodeTypes;
42 import info.magnolia.repository.RepositoryConstants;
43
44 import javax.jcr.Node;
45 import javax.jcr.NodeIterator;
46 import javax.jcr.PathNotFoundException;
47 import javax.jcr.RepositoryException;
48 import javax.jcr.Session;
49
50 import org.apache.commons.lang.StringUtils;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54
55
56
57
58 public class MgnlRoleManager extends RepositoryBackedSecurityManager implements RoleManager {
59
60 private static final Logger log = LoggerFactory.getLogger(MgnlRoleManager.class);
61
62 @Override
63 public Role getRole(final String name) {
64 return MgnlContext.doInSystemContext(new SilentSessionOp<MgnlRole>(getRepositoryName()) {
65
66 @Override
67 public MgnlRole doExec(Session session) throws RepositoryException {
68 Node roleNode = findPrincipalNode(name, MgnlContext.getJCRSession(getRepositoryName()));
69 if (roleNode == null) {
70 log.debug("can't find role [" + name + "]");
71 return null;
72 }
73 return newRoleInstance(roleNode);
74 }
75
76 @Override
77 public String toString() {
78 return "get role " + name;
79 }
80 });
81 }
82
83 @Override
84 public Role createRole(String name) throws AccessDeniedException {
85 return createRole(null, name);
86 }
87
88
89
90
91
92
93
94 public Role createRole(final String path, final String name) throws AccessDeniedException {
95 validateRoleName(name);
96 return MgnlContext.doInSystemContext(new SilentSessionOp<MgnlRole>(getRepositoryName()) {
97
98 @Override
99 public MgnlRole doExec(Session session) throws RepositoryException {
100 String parentPath = StringUtils.defaultString(path, "/");
101 Node roleNode = session.getNode(parentPath).addNode(name, NodeTypes.Role.NAME);
102 session.save();
103 return newRoleInstance(roleNode);
104 }
105
106 @Override
107 public String toString() {
108 return "create role " + name;
109 }
110 });
111 }
112
113
114
115
116 @Deprecated
117 protected MgnlRole newRoleInstance(Content node) throws RepositoryException {
118 return newRoleInstance(node.getJCRNode());
119 }
120
121 protected MgnlRole newRoleInstance(Node node) throws RepositoryException {
122 return new MgnlRole(node.getName(), node.getIdentifier(), getACLs(node).values());
123 }
124
125
126
127
128 @Deprecated
129 protected HierarchyManager getHierarchyManager() {
130 return MgnlContext.getHierarchyManager(RepositoryConstants.USER_ROLES);
131 }
132
133 @Override
134 public void removePermission(final Role role, final String workspace, final String path, final long permission) {
135 MgnlContext.doInSystemContext(new SilentSessionOp<Object>(getRepositoryName()) {
136
137 @Override
138 public Object doExec(Session session) throws Throwable {
139 Node roleNode = session.getNodeByIdentifier(role.getId());
140 Node aclNode = getAclNode(roleNode, workspace);
141 NodeIterator children = new SameChildNodeTypeIterator(aclNode);
142 while(children.hasNext()) {
143 Node child = children.nextNode();
144 if (child.getProperty("path").getString().equals(path)) {
145 if (permission == MgnlRole.PERMISSION_ANY || child.getProperty("permissions").getLong() == permission) {
146 child.remove();
147 }
148 }
149 }
150 session.save();
151 return null;
152 }
153
154 @Override
155 public String toString() {
156 return "add permission to role " + role.getName();
157 }
158 });
159 }
160
161
162
163
164 private Node getAclNode(Node roleNode, String repository) throws RepositoryException, PathNotFoundException,
165 AccessDeniedException {
166 Node aclNode;
167 if (!roleNode.hasNode("acl_" + repository)) {
168 aclNode = roleNode.addNode("acl_" + repository, NodeTypes.ContentNode.NAME);
169 }
170 else {
171 aclNode = roleNode.getNode("acl_" + repository);
172 }
173 return aclNode;
174 }
175
176
177
178
179 private boolean existsPermission(Node aclNode, String path, long permission) throws RepositoryException {
180 NodeIterator children = aclNode.getNodes();
181 while(children.hasNext()) {
182 Node child = children.nextNode();
183 if (child.hasProperty("path") && child.getProperty("path").getString().equals(path)) {
184 if (permission == MgnlRole.PERMISSION_ANY
185 || child.getProperty("permissions").getLong() == permission) {
186 return true;
187 }
188 }
189 }
190 return false;
191 }
192
193 @Override
194 public void addPermission(final Role role, final String workspace, final String path, final long permission) {
195 MgnlContext.doInSystemContext(new SilentSessionOp<Object>(getRepositoryName()) {
196
197 @Override
198 public Object doExec(Session session) throws Throwable {
199 Node roleNode = session.getNodeByIdentifier(role.getId());
200 Node aclNode = getAclNode(roleNode, workspace);
201 if (!existsPermission(aclNode, path, permission)) {
202 String nodeName = Path.getUniqueLabel(session, aclNode.getPath(), "0");
203 Node node = aclNode.addNode(nodeName, NodeTypes.ContentNode.NAME);
204 node.setProperty("path", path);
205 node.setProperty("permissions", permission);
206 session.save();
207 }
208 return null;
209 }
210
211 @Override
212 public String toString() {
213 return "remove permission from role " + role.getName();
214 }
215 });
216 }
217
218
219
220
221
222 @Override
223 protected Node findPrincipalNode(String principalName, Session session) throws RepositoryException {
224 return findPrincipalNode(principalName, session, NodeTypes.Role.NAME);
225 }
226
227 @Override
228 protected String getRepositoryName() {
229 return RepositoryConstants.USER_ROLES;
230 }
231
232 @Override
233 public String getRoleNameById(String string) {
234 return getResourceName(string);
235 }
236
237 protected void validateRoleName(String name) throws AccessDeniedException {
238 if (StringUtils.isBlank(name)) {
239 throw new IllegalArgumentException(name + " is not a valid role name.");
240 }
241
242 Role role = Security.getRoleManager().getRole(name);
243
244 if (role != null) {
245 throw new IllegalArgumentException("Role with name " + name + " already exists.");
246 }
247 }
248 }