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.validator;
35
36 import static info.magnolia.security.app.util.AccessControlPropertyUtil.*;
37
38 import info.magnolia.cms.security.Permission;
39 import info.magnolia.cms.security.PrincipalUtil;
40 import info.magnolia.cms.security.auth.ACL;
41 import info.magnolia.cms.security.operations.AccessDefinition;
42 import info.magnolia.context.MgnlContext;
43 import info.magnolia.security.app.dialog.field.WorkspaceAccessControlList;
44
45 import java.security.AccessControlException;
46 import java.text.MessageFormat;
47 import java.util.Set;
48
49 import javax.jcr.RepositoryException;
50
51 import org.apache.commons.lang3.StringUtils;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import com.vaadin.v7.data.validator.AbstractValidator;
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 public class WorkspaceAccessControlValidator extends AbstractValidator<WorkspaceAccessControlList.Entry> {
73 private static final Logger log = LoggerFactory.getLogger(WorkspaceAccessControlValidator.class);
74 private final String originalErrorMessage;
75 private String workspace;
76
77 public WorkspaceAccessControlValidator(String workspace, String errorMessage) {
78 super(errorMessage);
79 this.workspace = workspace;
80 this.originalErrorMessage = errorMessage;
81 }
82
83 @Override
84 public Class<WorkspaceAccessControlList.Entry> getType() {
85 return WorkspaceAccessControlList.Entry.class;
86 }
87
88 @Override
89 protected boolean isValidValue(WorkspaceAccessControlList.Entry entry) {
90 boolean isValid = true;
91
92 if (MgnlContext.getUser().hasRole(AccessDefinition.DEFAULT_SUPERUSER_ROLE)) {
93 return true;
94 }
95
96
97 WorkspaceAccessControlList.Entry entryItem = entry;
98 String path = entryItem.getPath();
99 long accessType = entryItem.getAccessType();
100 long permissions = entryItem.getPermissions();
101
102 if (accessType < WorkspaceAccessControlList.ACCESS_TYPE_NODE || accessType > WorkspaceAccessControlList.ACCESS_TYPE_NODE_AND_CHILDREN) {
103 throw new IllegalArgumentException("Access type should be one of ACCESS_TYPE_NODE (1), ACCESS_TYPE_CHILDREN (2) or ACCESS_TYPE_NODE_AND_CHILDREN (3)");
104 }
105
106 try {
107 if (!isCurrentUserEntitledToGrantRights(workspace, path, accessType, permissions)) {
108 isValid = !isValid;
109 }
110 } catch (AccessControlException e) {
111 isValid = !isValid;
112 } catch (RepositoryException e) {
113 log.error("Could not validate current user permissions: ", e);
114 isValid = !isValid;
115 }
116
117 if (!isValid) {
118 setErrorMessage(MessageFormat.format(originalErrorMessage, permissions, path, accessType));
119 }
120
121 return isValid;
122 }
123
124
125
126
127
128 private boolean isCurrentUserEntitledToGrantRights(String workspaceName, String path, long accessType, long permissions) throws RepositoryException {
129
130 if (permissions == Permission.NONE) {
131 permissions = Permission.READ;
132 }
133
134 ACL acl = PrincipalUtil.findAccessControlList(MgnlContext.getSubject(), workspaceName);
135 if (acl == null) {
136 return false;
137 }
138
139 String selectedPath = stripWildcardsFromPath(path);
140
141
142 if ((accessType & WorkspaceAccessControlList.ACCESS_TYPE_NODE) == WorkspaceAccessControlList.ACCESS_TYPE_NODE) {
143 Permission nodePerm = findBestMatchingPermissions(acl.getList(), selectedPath);
144 if (nodePerm == null || !granted(nodePerm, permissions)) {
145 return false;
146 }
147 }
148
149
150 if ((accessType & WorkspaceAccessControlList.ACCESS_TYPE_CHILDREN) == WorkspaceAccessControlList.ACCESS_TYPE_CHILDREN) {
151
152 String suffixForChildren = selectedPath.equals("/") ? "*" : "/*";
153 String childPath = selectedPath + suffixForChildren;
154
155
156 Set<Permission> violatedPerms = findViolatedPermissions(acl.getList(), childPath, permissions);
157 if (!violatedPerms.isEmpty()) {
158 return false;
159 }
160
161 Permission childPerm = findBestMatchingPermissions(acl.getList(), childPath);
162
163 if (childPerm == null || !granted(childPerm, permissions) || !StringUtils.endsWith(childPerm.getPattern().getPatternString(), "/*")) {
164 return false;
165 }
166 }
167
168 return true;
169 }
170
171 private String stripWildcardsFromPath(String path) {
172 path = StringUtils.stripEnd(path, "/*");
173 if (StringUtils.isBlank(path)) {
174 path = "/";
175 }
176 return path;
177 }
178
179 private boolean granted(Permission permissionsGranted, long permissionsNeeded) {
180 return (permissionsGranted.getPermissions() & permissionsNeeded) == permissionsNeeded;
181 }
182 }