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.core;
35
36
37 import info.magnolia.cms.security.AccessManager;
38 import info.magnolia.cms.security.AccessManagerImpl;
39 import info.magnolia.cms.security.Permission;
40
41 import java.util.List;
42 import java.util.Map;
43
44 import javax.jcr.NamespaceException;
45 import javax.jcr.RepositoryException;
46
47 import org.apache.jackrabbit.core.SessionImpl;
48 import org.apache.jackrabbit.core.cache.GrowingLRUMap;
49 import org.apache.jackrabbit.core.id.ItemId;
50 import org.apache.jackrabbit.core.id.PropertyId;
51 import org.apache.jackrabbit.core.security.authorization.AbstractCompiledPermissions;
52 import org.apache.jackrabbit.core.security.authorization.PrivilegeManagerImpl;
53 import org.apache.jackrabbit.spi.Name;
54 import org.apache.jackrabbit.spi.Path;
55 import org.apache.jackrabbit.spi.commons.conversion.CachingPathResolver;
56 import org.apache.jackrabbit.spi.commons.conversion.IllegalNameException;
57 import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
58 import org.apache.jackrabbit.spi.commons.conversion.ParsingPathResolver;
59 import org.apache.jackrabbit.spi.commons.conversion.PathResolver;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62
63
64
65
66
67 public class DefaultACLBasedPermissions extends AbstractCompiledPermissions {
68
69 protected final AccessManager ami = new AccessManagerImpl();
70 @SuppressWarnings("unchecked")
71 protected final Map<ItemId, Boolean> readCache = new GrowingLRUMap(1024, 5000);
72 protected final Object monitor = new Object();
73 protected SessionImpl session;
74
75 private static final Logger log = LoggerFactory.getLogger(DefaultACLBasedPermissions.class);
76
77 protected final long permissionMapping[][] = {
78 {org.apache.jackrabbit.core.security.authorization.Permission.READ, Permission.READ},
79 {org.apache.jackrabbit.core.security.authorization.Permission.SET_PROPERTY, Permission.SET},
80 {org.apache.jackrabbit.core.security.authorization.Permission.ADD_NODE, Permission.ADD},
81 {org.apache.jackrabbit.core.security.authorization.Permission.REMOVE_NODE, Permission.REMOVE},
82 {org.apache.jackrabbit.core.security.authorization.Permission.REMOVE_PROPERTY, Permission.REMOVE},
83 {org.apache.jackrabbit.core.security.authorization.Permission.READ_AC, Permission.EXECUTE},
84 {org.apache.jackrabbit.core.security.authorization.Permission.MODIFY_AC, Permission.EXECUTE},
85 {org.apache.jackrabbit.core.security.authorization.Permission.NODE_TYPE_MNGMT, Permission.ADD},
86 {org.apache.jackrabbit.core.security.authorization.Permission.VERSION_MNGMT, Permission.EXECUTE},
87 {org.apache.jackrabbit.core.security.authorization.Permission.LOCK_MNGMT, Permission.EXECUTE},
88 {org.apache.jackrabbit.core.security.authorization.Permission.LIFECYCLE_MNGMT, Permission.EXECUTE},
89 {org.apache.jackrabbit.core.security.authorization.Permission.RETENTION_MNGMT, Permission.EXECUTE},
90 {org.apache.jackrabbit.core.security.authorization.Permission.MODIFY_CHILD_NODE_COLLECTION, Permission.ADD}
91 };
92
93 protected long convertJackrabbitPermissionsToMagnoliaPermissions(long jackRabbitPermissions) {
94 long magnoliaPermissions = 0;
95 for (long[] mapping : permissionMapping) {
96 long jackrabbitPermission = mapping[0];
97 long magnoliaPermission = mapping[1];
98 if ((jackRabbitPermissions & jackrabbitPermission) != 0) {
99 magnoliaPermissions = magnoliaPermissions | magnoliaPermission;
100 }
101 }
102 return magnoliaPermissions;
103 }
104
105
106
107
108
109 protected final PathResolver pathResolver = new CachingPathResolver(new ParsingPathResolver(null, new NameResolver() {
110
111 @Override
112 public Name getQName(String name) throws IllegalNameException, NamespaceException {
113 throw new UnsupportedOperationException();
114 }
115
116 @Override
117 public String getJCRName(Name name) throws NamespaceException {
118 return name.getLocalName();
119 }
120 }));
121
122 public DefaultACLBasedPermissions(List<Permission> permissions, SessionImpl systemSession, Map<?, ?> configuration) {
123
124 ami.setPermissionList(permissions);
125 this.session = systemSession;
126 }
127
128 @Override
129 public boolean canRead(Path itemPath, ItemId itemId) throws RepositoryException {
130
131 if ((itemId != null && "cafebabe-cafe-babe-cafe-babecafebabe".equals(itemId.toString())) || (itemPath != null && "/".equals(itemPath.toString()))) {
132
133 return true;
134 }
135
136 if (itemPath == null) {
137
138
139 if (!itemId.denotesNode()) {
140 itemId = ((PropertyId)itemId).getParentId();
141 }
142
143 synchronized (monitor) {
144
145 if (readCache.containsKey(itemId)) {
146 return readCache.get(itemId);
147 }
148
149 itemPath = session.getHierarchyManager().getPath(itemId);
150 boolean canRead = canRead(itemPath, itemId);
151 readCache.put(itemId, canRead);
152 return canRead;
153 }
154 }
155
156 String path = pathResolver.getJCRPath(itemPath);
157 log.debug("Read request for " + path + " :: " + itemId);
158 return ami.isGranted(path, Permission.READ);
159 }
160
161 @Override
162 protected Result buildResult(Path absPath) throws RepositoryException {
163 throw new UnsupportedOperationException();
164 }
165
166 @Override
167 public Result getResult(Path absPath) throws RepositoryException {
168 throw new UnsupportedOperationException();
169 }
170
171 @Override
172 public boolean grants(Path absPath, int permissions) throws RepositoryException {
173 long magnoliaPermissions = convertJackrabbitPermissionsToMagnoliaPermissions(permissions);
174 return ami.isGranted(pathResolver.getJCRPath(absPath), magnoliaPermissions);
175 }
176
177 @Override
178 public int getPrivileges(Path absPath) throws RepositoryException {
179 throw new UnsupportedOperationException();
180 }
181
182 @Override
183 protected Result buildRepositoryResult() throws RepositoryException {
184 throw new UnsupportedOperationException();
185 }
186
187 @Override
188 protected PrivilegeManagerImpl getPrivilegeManagerImpl() throws RepositoryException {
189 throw new UnsupportedOperationException();
190 }
191
192 }