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.AccessControlList;
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 public class WebAccessControlValidator extends AbstractValidator<AccessControlList.Entry> {
72 private static final Logger log = LoggerFactory.getLogger(WebAccessControlValidator.class);
73 private final String originalErrorMessage;
74
75 public WebAccessControlValidator(String errorMessage) {
76 super(errorMessage);
77 this.originalErrorMessage = errorMessage;
78 }
79
80 @Override
81 public Class<AccessControlList.Entry> getType() {
82 return AccessControlList.Entry.class;
83 }
84
85 @Override
86 protected boolean isValidValue(AccessControlList.Entry entry) {
87 boolean isValid = true;
88
89 if (MgnlContext.getUser().hasRole(AccessDefinition.DEFAULT_SUPERUSER_ROLE)) {
90 return true;
91 }
92
93 String path = entry.getPath();
94 long permissions = entry.getPermissions();
95
96 try {
97 if (!isCurrentUserEntitledToGrantUriRights(path, permissions)) {
98 isValid = !isValid;
99 }
100 } catch (AccessControlException e) {
101 isValid = !isValid;
102 } catch (RepositoryException e) {
103 log.error("Could not validate current user permissions: ", e);
104 isValid = !isValid;
105 }
106
107 if (!isValid) {
108 setErrorMessage(MessageFormat.format(originalErrorMessage, permissions, path));
109 }
110
111 return isValid;
112 }
113
114
115
116
117 private boolean isCurrentUserEntitledToGrantUriRights(String path, long permissions) throws RepositoryException {
118
119 if (permissions == Permission.NONE) {
120 permissions = Permission.READ;
121 }
122
123 ACL acl = PrincipalUtil.findAccessControlList(MgnlContext.getSubject(), "uri");
124 if (acl == null) {
125 return false;
126 }
127
128
129 String basePath = stripWildcardsFromPath(path);
130 Permission pathPerm = findBestMatchingPermissions(acl.getList(), basePath);
131 if (pathPerm == null || !granted(pathPerm, permissions)) {
132 return false;
133 }
134
135
136 if (path.endsWith("*")) {
137
138
139 Set<Permission> violatedPerms = findViolatedPermissions(acl.getList(), path, permissions);
140 if (!violatedPerms.isEmpty()) {
141 return false;
142 }
143
144 Permission childPerm = findBestMatchingPermissions(acl.getList(), path);
145
146 if (childPerm == null || !granted(childPerm, permissions) || !StringUtils.endsWith(childPerm.getPattern().getPatternString(), "*")) {
147 return false;
148 }
149 }
150
151 return true;
152 }
153
154 private String stripWildcardsFromPath(String path) {
155 path = StringUtils.stripEnd(path, "/*");
156 if (StringUtils.isBlank(path)) {
157 path = "/";
158 }
159 return path;
160 }
161
162 private boolean granted(Permission permissionsGranted, long permissionsNeeded) {
163 return (permissionsGranted.getPermissions() & permissionsNeeded) == permissionsNeeded;
164 }
165 }