1 23 package org.apache.slide.security; 24 25 import java.util.Enumeration ; 26 import java.util.List ; 27 import java.util.Vector ; 28 import org.apache.slide.common.Namespace; 29 import org.apache.slide.common.NamespaceConfig; 30 import org.apache.slide.common.ServiceAccessException; 31 import org.apache.slide.common.SlideToken; 32 import org.apache.slide.common.Uri; 33 import org.apache.slide.content.NodeProperty; 34 import org.apache.slide.content.NodeRevisionDescriptor; 35 import org.apache.slide.content.NodeRevisionNumber; 36 import org.apache.slide.content.RevisionDescriptorNotFoundException; 37 import org.apache.slide.structure.ActionNode; 38 import org.apache.slide.structure.ObjectNode; 39 import org.apache.slide.structure.ObjectNotFoundException; 40 import org.apache.slide.structure.SubjectNode; 41 import org.apache.slide.util.XMLValue; 42 import org.apache.slide.util.logger.Logger; 43 import org.jdom.JDOMException; 44 45 50 public class ACLSecurityImpl extends SecurityImpl { 51 52 private static final String LOG_CHANNEL = ACLSecurityImpl.class.getName(); 53 private static final Vector EMPTY_VECTOR = new Vector (); 54 55 59 public ACLSecurityImpl() { 60 super(); 61 } 62 63 69 public ACLSecurityImpl(Namespace namespace, NamespaceConfig namespaceConfig) { 70 super(namespace, namespaceConfig); 71 } 72 73 79 public void init(Namespace namespace, NamespaceConfig namespaceConfig) { 80 super.init(namespace, namespaceConfig); 81 } 82 83 95 public boolean hasPermission(ObjectNode object, SubjectNode subject, 96 ActionNode action) 97 throws ServiceAccessException, ObjectNotFoundException { 98 99 throw new UnsupportedOperationException ( 100 "Please use alternate signature: " 101 +"hasPermission(SlideToken token, ObjectNode object, ActionNode action)"); 102 } 103 104 117 public boolean hasPermission(SlideToken token, ObjectNode objectNode, ActionNode actionNode) 118 throws ServiceAccessException, ObjectNotFoundException { 119 120 if (logger.isEnabled(LOG_CHANNEL, Logger.DEBUG)) { 122 try { 123 logger.log("@@@ check object="+objectNode+", subject="+getPrincipal(token)+", action="+actionNode, LOG_CHANNEL, Logger.DEBUG); 124 } catch (ObjectNotFoundException onfe) { 125 } 127 } 128 if (actionNode == namespaceConfig.getDefaultAction()) { 130 return true; 131 } 132 133 Enumeration permissions = enumeratePermissions(token, objectNode, true); 134 return evaluateAcl(token, objectNode, actionNode, permissions); 135 } 136 137 public boolean hasRole(SlideToken token, String role) throws ServiceAccessException, ObjectNotFoundException { 138 return hasRole(token, (SubjectNode)getPrincipal(token), role); 139 } 140 141 public boolean hasRole(SlideToken token, SubjectNode subjectNode, String role) throws ServiceAccessException, ObjectNotFoundException { 143 SubjectNode roleNode = null; 144 if (namespaceConfig.getRolesPath() != null && namespaceConfig.getRolesPath().length() != 0) { 145 roleNode = SubjectNode.getSubjectNode(namespaceConfig.getRolesPath()+"/"+role); 146 } 147 if (roleNode != null && matchPrincipal(token, subjectNode, roleNode)) { 148 return true; 149 } 150 else { 151 SubjectNode groupNode = null; 153 if (namespaceConfig.getGroupsPath() != null && namespaceConfig.getGroupsPath().length() != 0) { 154 groupNode = SubjectNode.getSubjectNode(namespaceConfig.getGroupsPath()+"/"+role); 155 } 156 return (groupNode != null && matchPrincipal(token, subjectNode, groupNode)); 157 } 158 } 159 160 public boolean hasRole(ObjectNode object, String role) throws ServiceAccessException, ObjectNotFoundException { 162 throw new UnsupportedOperationException ("Please use alternate signature: hasRole(SlideToken token, String role)"); 163 } 164 165 public Enumeration getRoles(SlideToken token) throws ServiceAccessException, ObjectNotFoundException { 167 return getRoles(token, (SubjectNode)getPrincipal(token)); 168 } 169 170 179 public Enumeration getRoles(SlideToken token, SubjectNode subjectNode) throws ServiceAccessException, ObjectNotFoundException { 180 Uri subjectUri = namespace.getUri(token, subjectNode.getUri()); 182 subjectUri.getStore().retrieveObject(subjectUri); 183 184 Vector result = new Vector (); 185 Uri rolesUri = null; 186 ObjectNode rolesNode = null; 187 if (namespaceConfig.getRolesPath() != null && namespaceConfig.getRolesPath().length() != 0) { 188 rolesUri = namespace.getUri(token, namespaceConfig.getRolesPath()); 189 try { 190 rolesNode = rolesUri.getStore().retrieveObject(rolesUri); 191 } catch (ObjectNotFoundException e) {} 192 if (rolesNode != null) { 193 Enumeration rolesEnum = rolesNode.enumerateBindings(); 194 while (rolesEnum.hasMoreElements()) { 195 ObjectNode.Binding b = (ObjectNode.Binding)rolesEnum.nextElement(); 196 String role = b.getName(); 197 if (hasRole(token, subjectNode, role)) { 198 result.add(role); 199 } 200 } 201 } 202 } 203 Uri groupsUri = null; 204 ObjectNode groupsNode = null; 205 if (namespaceConfig.getGroupsPath() != null && namespaceConfig.getGroupsPath().length() != 0) { 206 groupsUri = namespace.getUri(token, namespaceConfig.getGroupsPath()); 207 groupsNode = groupsUri.getStore().retrieveObject(groupsUri); 208 if (groupsNode != null) { 209 Enumeration groupsEnum = groupsNode.enumerateBindings(); 210 while (groupsEnum.hasMoreElements()) { 211 ObjectNode.Binding b = (ObjectNode.Binding)groupsEnum.nextElement(); 212 String group = b.getName(); 213 if (hasRole(token, subjectNode, group)) { 214 result.add(group); 215 } 216 } 217 } 218 } 219 return result.elements(); 220 } 221 222 231 public Enumeration getGroupMembership(SlideToken token, SubjectNode subjectNode) throws ServiceAccessException, ObjectNotFoundException { 232 Uri subjectUri = namespace.getUri(token, subjectNode.getUri()); 234 subjectUri.getStore().retrieveObject(subjectUri); 235 236 Vector result = new Vector (); 237 Uri rolesUri = null; 238 ObjectNode rolesNode = null; 239 if (namespaceConfig.getRolesPath() != null && namespaceConfig.getRolesPath().length() != 0) { 240 rolesUri = namespace.getUri(token, namespaceConfig.getRolesPath()); 241 try { 242 rolesNode = rolesUri.getStore().retrieveObject(rolesUri); 243 } catch (ObjectNotFoundException e) {} 244 if (rolesNode != null) { 245 Enumeration rolesEnum = rolesNode.enumerateBindings(); 246 while (rolesEnum.hasMoreElements()) { 247 ObjectNode.Binding b = (ObjectNode.Binding)rolesEnum.nextElement(); 248 String role = b.getName(); 249 Uri roleUri = namespace.getUri(token, namespaceConfig.getRolesPath()+"/"+role); 250 try { 251 NodeRevisionDescriptor nrd = 252 roleUri.getStore().retrieveRevisionDescriptor(roleUri, new NodeRevisionNumber()); 253 NodeProperty membersetProp = nrd.getProperty("group-member-set"); 254 if (membersetProp != null && membersetProp.getValue() != null) { 255 XMLValue xmlVal = new XMLValue((String )membersetProp.getValue()); 256 List memberNodes = xmlVal.getHrefNodes(); 257 if (memberNodes.contains(subjectNode)) { 258 result.add(roleUri.toString()); 259 } 260 } 261 } catch (RevisionDescriptorNotFoundException e) { 262 } catch (JDOMException e) {} 263 } 264 } 265 } 266 Uri groupsUri = null; 267 ObjectNode groupsNode = null; 268 if (namespaceConfig.getGroupsPath() != null && namespaceConfig.getGroupsPath().length() != 0) { 269 groupsUri = namespace.getUri(token, namespaceConfig.getGroupsPath()); 270 try { 271 groupsNode = groupsUri.getStore().retrieveObject(groupsUri); 272 } catch (ObjectNotFoundException e) {} 273 if (groupsNode != null) { 274 Enumeration rolesEnum = groupsNode.enumerateBindings(); 275 while (rolesEnum.hasMoreElements()) { 276 ObjectNode.Binding b = (ObjectNode.Binding)rolesEnum.nextElement(); 277 String group = b.getName(); 278 Uri roleUri = namespace.getUri(token, namespaceConfig.getGroupsPath()+"/"+group); 279 try { 280 NodeRevisionDescriptor nrd = 281 roleUri.getStore().retrieveRevisionDescriptor(roleUri, new NodeRevisionNumber()); 282 NodeProperty membersetProp = nrd.getProperty("group-member-set"); 283 if (membersetProp != null && membersetProp.getValue() != null) { 284 XMLValue xmlVal = new XMLValue((String )membersetProp.getValue()); 285 List memberNodes = xmlVal.getHrefNodes(); 286 if (memberNodes.contains(subjectNode)) { 287 result.add(roleUri.toString()); 288 } 289 } 290 } catch (RevisionDescriptorNotFoundException e) { 291 } catch (JDOMException e) {} 292 } 293 } 294 } 295 return result.elements(); 296 } 297 298 public Enumeration getRoles(ObjectNode object) { 300 return EMPTY_VECTOR.elements(); 301 } 302 303 306 private boolean evaluateAcl(SlideToken token, ObjectNode objectNode, ActionNode actionNode, Enumeration permissions) throws ServiceAccessException, ObjectNotFoundException { 307 boolean result = false; 308 SubjectNode subjectNode = (SubjectNode)getPrincipal(token); 309 while (permissions.hasMoreElements()) { 310 NodePermission permission = (NodePermission)permissions.nextElement(); 311 if (match(token, objectNode, subjectNode, actionNode, permission)) { 312 result = !permission.isNegative(); 313 break; 314 } 315 } 316 return result; 317 } 318 319 private boolean match(SlideToken token, ObjectNode objectNode, SubjectNode subjectNode, ActionNode actionNode, NodePermission permission) throws ServiceAccessException { 320 boolean result = true; 321 result = matchAction(token, actionNode, permission.getActionNode()) && matchSubject(token, objectNode, subjectNode, permission.getSubjectNode()); 322 if (logger.isEnabled(LOG_CHANNEL, Logger.DEBUG)) { 324 logger.log(" permission="+permission+", match="+result, LOG_CHANNEL, Logger.DEBUG); 325 } 326 return result; 327 } 328 329 private boolean matchSubject(SlideToken token, ObjectNode objectNode, SubjectNode checkSubject, SubjectNode permSubject) throws ServiceAccessException { 330 if (permSubject.equals(SubjectNode.ALL)) { 331 return true; 332 } 333 else if (permSubject.equals(SubjectNode.AUTHENTICATED)) { 334 return !checkSubject.equals(SubjectNode.UNAUTHENTICATED); 335 } 336 else if (permSubject.equals(SubjectNode.UNAUTHENTICATED)) { 337 return checkSubject.equals(SubjectNode.UNAUTHENTICATED); 338 } 339 else if (permSubject.equals(SubjectNode.OWNER)) { 340 return matchOwner(token, objectNode, checkSubject); 341 } 342 else if (permSubject.equals(SubjectNode.SELF)) { 343 return matchPrincipal(token, checkSubject, (SubjectNode)objectNode); 344 } 345 else { 346 return matchPrincipal(token, checkSubject, permSubject); 347 } 348 } 349 350 private boolean matchOwner(SlideToken token, ObjectNode objectNode, SubjectNode checkSubject) throws ServiceAccessException { 351 Uri objectUri = namespace.getUri(token, objectNode.getUri()); 352 try { 353 NodeRevisionDescriptor nrd = 354 objectUri.getStore().retrieveRevisionDescriptor(objectUri, new NodeRevisionNumber()); 355 NodeProperty ownerProp = nrd.getProperty("owner"); 356 if (ownerProp != null && ownerProp.getValue() != null) { 357 String usersPath = namespace.getConfig().getUsersPath(); 358 SubjectNode ownerSubject = SubjectNode.getSubjectNode(usersPath+"/"+ownerProp.getValue()); 359 return ownerSubject.equals(checkSubject); 360 } 361 else { 362 return false; 363 } 364 } 365 catch (RevisionDescriptorNotFoundException e) { 366 return false; 367 } 368 catch (ServiceAccessException e) { 369 throw e; 370 } 371 } 372 } 373 374 375 376 377 | Popular Tags |