| 1 23 24 package org.apache.slide.security; 25 26 import java.lang.reflect.Constructor; 27 import java.lang.reflect.InvocationTargetException; 28 import java.util.ArrayList; 29 import java.util.Collections; 30 import java.util.Enumeration; 31 import java.util.HashMap; 32 import java.util.HashSet; 33 import java.util.Hashtable; 34 import java.util.Iterator; 35 import java.util.List; 36 import java.util.Map; 37 import java.util.Set; 38 import java.util.Vector; 39 import org.apache.slide.common.Namespace; 40 import org.apache.slide.common.NamespaceConfig; 41 import org.apache.slide.common.ServiceAccessException; 42 import org.apache.slide.common.SlideException; 43 import org.apache.slide.common.SlideToken; 44 import org.apache.slide.common.Uri; 45 import org.apache.slide.content.NodeProperty; 46 import org.apache.slide.content.NodeRevisionDescriptor; 47 import org.apache.slide.content.NodeRevisionDescriptors; 48 import org.apache.slide.content.NodeRevisionNumber; 49 import org.apache.slide.content.RevisionDescriptorNotFoundException; 50 import org.apache.slide.store.Store; 51 import org.apache.slide.structure.ActionNode; 52 import org.apache.slide.structure.LinkNode; 53 import org.apache.slide.structure.ObjectAlreadyExistsException; 54 import org.apache.slide.structure.ObjectNode; 55 import org.apache.slide.structure.ObjectNotFoundException; 56 import org.apache.slide.structure.SubjectNode; 57 import org.apache.slide.util.Configuration; 58 import org.apache.slide.util.XMLValue; 59 import org.apache.slide.util.logger.Logger; 60 import org.apache.slide.event.VetoException; 61 import org.apache.slide.event.EventDispatcher; 62 import org.apache.slide.event.SecurityEvent; 63 import org.jdom.JDOMException; 64 65 70 public class SecurityImpl implements Security { 71 72 private static final String LOG_CHANNEL = SecurityImpl.class.getName(); 73 private static final String PRIVILEGE_MEMBER_SET = "privilege-member-set"; 74 private static final String PRIVILEGE_NAMESPACE = "privilege-namespace"; 75 protected Logger logger; 76 77 78 81 public SecurityImpl() {} 82 83 89 public SecurityImpl(Namespace namespace, NamespaceConfig namespaceConfig) { 90 init(namespace, namespaceConfig); 91 } 92 93 public void init(Namespace namespace, NamespaceConfig namespaceConfig) { 94 this.namespace = namespace; 95 this.namespaceConfig = namespaceConfig; 96 this.rolesCache = new Hashtable(); 97 aclInheritanceType = namespaceConfig.getAclInheritanceType(); 98 logger = namespace.getLogger(); 99 } 100 101 103 104 107 protected Namespace namespace; 108 109 110 113 protected NamespaceConfig namespaceConfig; 114 115 116 120 protected Hashtable rolesCache; 121 122 protected int aclInheritanceType; 123 124 128 private Set modificationActions; 129 130 132 133 143 public void setPermissions(SlideToken token, String object, 144 Enumeration permissions) 145 throws ServiceAccessException, ObjectNotFoundException, 146 AccessDeniedException { 147 148 Uri objectUri = namespace.getUri(token, object); 149 ObjectNode objectNode = objectUri.getStore().retrieveObject(objectUri); 150 151 checkCredentials(token, objectNode, 152 namespaceConfig.getGrantPermissionAction()); 153 checkCredentials(token, objectNode, 154 namespaceConfig.getRevokePermissionAction()); 155 156 objectUri.getStore().revokePermissions(objectUri); 157 158 while (permissions.hasMoreElements()) { 159 NodePermission permission = 160 (NodePermission) permissions.nextElement(); 161 objectUri.getStore().grantPermission(objectUri, permission); 162 } 163 164 } 165 166 167 179 public void grantPermission(SlideToken token, ObjectNode object, 180 SubjectNode subject, ActionNode action) 181 throws ServiceAccessException, ObjectNotFoundException, 182 AccessDeniedException, VetoException { 183 grantPermission(token, object, subject, action, true); 184 } 185 186 187 200 public void grantPermission(SlideToken token, ObjectNode object, 201 SubjectNode subject, ActionNode action, 202 boolean inheritable) 203 throws ServiceAccessException, ObjectNotFoundException, 204 AccessDeniedException, VetoException { 205 NodePermission permission = new NodePermission(object, subject, action, 206 inheritable); 207 grantPermission(token, permission); 208 } 209 210 211 221 public void grantPermission(SlideToken token, 222 NodePermission permission) 223 throws ServiceAccessException, ObjectNotFoundException, 224 AccessDeniedException, VetoException { 225 Uri objectUri = namespace.getUri(token, permission.getObjectUri()); 226 ObjectNode object = objectUri.getStore() 227 .retrieveObject(objectUri); 228 229 Enumeration permissions = enumeratePermissions(token, object); 231 boolean alreadyPresent = false; 232 while (permissions.hasMoreElements() && !alreadyPresent) { 233 if (permission.equals(permissions.nextElement())) { 234 alreadyPresent = true; 235 } 236 } 237 238 if (!alreadyPresent) { 239 checkCredentials(token, object, 240 namespaceConfig.getGrantPermissionAction()); 241 objectUri.getStore().grantPermission(objectUri, permission); 242 } 243 244 if ( permission.isNegative() ) { 246 if ( SecurityEvent.DENY_PERMISSION.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(SecurityEvent.DENY_PERMISSION, new SecurityEvent(this, token, namespace, objectUri, permission)); 247 } else { 248 if ( SecurityEvent.GRANT_PERMISSION.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(SecurityEvent.GRANT_PERMISSION, new SecurityEvent(this, token, namespace, objectUri, permission)); 249 } 250 } 251 252 253 265 public void denyPermission(SlideToken token, ObjectNode object, 266 SubjectNode subject, ActionNode action) 267 throws ServiceAccessException, ObjectNotFoundException, 268 AccessDeniedException, VetoException { 269 denyPermission(token, object, subject, action, true); 270 } 271 272 273 286 public void denyPermission(SlideToken token, ObjectNode object, 287 SubjectNode subject, ActionNode action, 288 boolean inheritable) 289 throws ServiceAccessException, ObjectNotFoundException, 290 AccessDeniedException, VetoException { 291 NodePermission permission = new NodePermission(object, subject, action, 292 inheritable, true); 293 denyPermission(token, permission); 294 } 295 296 297 307 public void denyPermission(SlideToken token, 308 NodePermission permission) 309 throws ServiceAccessException, ObjectNotFoundException, 310 AccessDeniedException, VetoException { 311 if (!permission.isNegative()) 314 permission.setNegative(true); 315 grantPermission(token, permission); 316 } 317 318 319 331 public void revokePermission(SlideToken token, ObjectNode object, 332 SubjectNode subject, ActionNode action) 333 throws ServiceAccessException, ObjectNotFoundException, 334 AccessDeniedException, VetoException { 335 checkCredentials(token, object, namespaceConfig 337 .getRevokePermissionAction()); 338 NodePermission permission = new NodePermission(object, subject, 339 action); 340 Uri objectUri = namespace.getUri(token, object.getUri()); 341 objectUri.getStore() 342 .revokePermission(objectUri, permission); 343 344 if ( SecurityEvent.REVOKE_PERMISSION.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(SecurityEvent.REVOKE_PERMISSION, new SecurityEvent(this, token, namespace, objectUri, permission)); 346 } 347 348 349 350 360 public void revokePermission(SlideToken token, NodePermission permission) 361 throws ServiceAccessException, ObjectNotFoundException, 362 AccessDeniedException, VetoException { 363 364 Uri objectUri = namespace.getUri(token, permission.getObjectUri()); 365 ObjectNode object = objectUri.getStore().retrieveObject(objectUri); 366 367 checkCredentials(token, object, 368 namespaceConfig.getRevokePermissionAction()); 369 objectUri.getStore().revokePermission(objectUri, permission); 370 371 if ( SecurityEvent.REVOKE_PERMISSION.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(SecurityEvent.REVOKE_PERMISSION, new SecurityEvent(this, token, namespace, objectUri, permission)); 373 } 374 375 376 387 public void checkCredentials(SlideToken token, ObjectNode object, 388 ActionNode action) 389 throws ServiceAccessException, AccessDeniedException { 390 391 if (!token.isForceSecurity()) { 392 return; 393 } 394 395 try { 396 if (Configuration.useIntegratedSecurity()) { 397 Boolean permission = token.checkPermissionCache(object, action); 399 if (permission == null) { 400 try { 402 Uri objectUri = namespace.getUri(token, object.getUri()); 403 ObjectNode realObject = objectUri.getStore() 404 .retrieveObject(objectUri); 405 checkPermission(token, realObject, action); 406 token.cachePermission(object, action, true); 407 } catch (AccessDeniedException ade) { 408 token.cachePermission(object, action, false); 409 ade.fillInStackTrace(); 410 throw ade; 411 } 412 } 413 else { 414 if (!(permission.booleanValue())) { 415 throw new AccessDeniedException 416 (object.getUri(), 417 getPrincipal(token).getPath().toString(), 418 action.getUri()); 419 } 420 } 421 } 422 } catch (ObjectNotFoundException e) { 423 String subjectUri = "*** Could not determine principal ***"; 424 try { 425 subjectUri = getPrincipal(token).getPath().toString(); 426 } catch (Exception x) {} 427 throw new AccessDeniedException 428 (object.getUri(), 429 subjectUri, 430 action.getUri()); 431 } 432 } 433 434 435 447 public void checkPermission(ObjectNode object, SubjectNode subject, 448 ActionNode action) 449 throws ServiceAccessException, AccessDeniedException, 450 ObjectNotFoundException { 451 if (!hasPermission(object, subject, action)) { 452 throw new AccessDeniedException(object.getUri(), subject.getUri(), 453 action.getUri()); 454 } 455 456 determineActionsCacheInvalidation(object, action); 457 } 458 459 471 public void checkPermission(SlideToken token, ObjectNode object, ActionNode action) throws ServiceAccessException, AccessDeniedException, ObjectNotFoundException { 472 if (!hasPermission(token, object, action)) { 473 throw new AccessDeniedException(object.getUri(), getPrincipal(token).getUri(), 474 action.getUri()); 475 } 476 477 determineActionsCacheInvalidation(object, action); 478 } 479 480 481 493 public boolean hasPermission(ObjectNode object, SubjectNode subject, 494 ActionNode action) 495 throws ServiceAccessException, ObjectNotFoundException { 496 497 if (action.equals(ActionNode.DEFAULT)) { 499 return true; 500 } 501 502 boolean granted = false; 503 boolean denied = false; 504 boolean rootObjectReached = false; 505 506 ObjectNode courObject = object; 507 508 Uri subjectUri = namespace.getUri(subject.getUri()); 509 Uri actionUri = namespace.getUri(action.getUri()); 510 511 513 while (!granted && !denied && !rootObjectReached) { 514 515 Uri courUri = namespace.getUri(courObject.getUri()); 516 Enumeration permissions = courUri.getStore() 517 .enumeratePermissions(courUri); 518 519 while (permissions.hasMoreElements()) { 520 521 boolean oldGranted = granted; 522 boolean oldDenied = denied; 523 524 NodePermission permission = 525 (NodePermission) permissions.nextElement(); 526 String permissionSubject = permission.getSubjectUri(); 527 528 if (permissionSubject.equals(SubjectNode.SELF_URI)) { 529 530 boolean check; 531 check = object.getUri().equals(subjectUri.toString()); 532 if (permission.isInheritable()) { 533 String subjectUriString = subjectUri.toString(); 534 if(!subjectUriString.endsWith("/")) 535 subjectUriString = subjectUriString + "/"; 536 537 check |= object.getUri().startsWith(subjectUriString); 538 } 539 540 granted = (!permission.isNegative()) 542 && (check) 543 && (actionUri.toString() 544 .startsWith(permission.getActionUri())); 545 denied = (permission.isNegative()) 546 && (check) 547 && (actionUri.toString() 548 .startsWith(permission.getActionUri())); 549 550 } else if (permission.isInheritable() 551 || permission.getObjectUri().equals(object.getUri())) { 552 553 if (permissionSubject.startsWith("/")) { 554 555 557 String permSubj = permission.getSubjectUri(); 558 if(!permSubj.endsWith("/")) 559 permSubj = permSubj + "/"; 560 boolean match = subjectUri.toString(). 561 equals(permission.getSubjectUri()) || 562 subjectUri.toString().startsWith(permSubj); 563 match &= actionUri.toString(). 564 startsWith(permission.getActionUri()); 565 566 granted = (!permission.isNegative()) && match; 567 denied = permission.isNegative() && match; 568 569 } else if (permissionSubject.startsWith("+")) { 570 571 Uri permissionSubjectUri = 573 namespace.getUri(permissionSubject.substring(1)); 574 ObjectNode group = 575 permissionSubjectUri.getStore().retrieveObject 576 (permissionSubjectUri); 577 if (group instanceof 580 org.apache.slide.structure.GroupNode ) { 581 if (group.hasChildren()) { 582 Enumeration groupMembers = 583 group.enumerateChildren(); 584 while (groupMembers.hasMoreElements()) { 587 588 oldGranted = granted; 589 oldDenied = denied; 590 591 Uri childUri = 592 namespace.getUri 593 ((String) groupMembers.nextElement()); 594 ObjectNode childNode = 595 childUri.getStore().retrieveObject 596 (childUri); 597 String childSubjectUri = childNode 598 instanceof LinkNode ? 599 ((LinkNode) childNode) 600 .getLinkedUri() : 601 childNode.getUri() ; 602 603 String testUri; 604 if(!childSubjectUri.endsWith("/")) 605 testUri = childSubjectUri+"/"; 606 else 607 testUri = childSubjectUri; 608 609 boolean match = subjectUri.toString(). 610 equals(childSubjectUri) || 611 subjectUri.toString(). 612 startsWith(testUri); 613 match &= actionUri.toString(). 614 startsWith(permission.getActionUri()); 615 616 granted = (!permission.isNegative()) && 617 match; 618 denied = permission.isNegative() && match; 619 620 granted = granted | oldGranted; 621 denied = denied | oldDenied; 622 623 } 624 } 625 } 626 627 } else { 628 629 granted = (!permission.isNegative()) 631 && (hasRole(subject, permissionSubject)) 632 && (actionUri.toString() 633 .startsWith(permission.getActionUri())); 634 denied = (permission.isNegative()) 635 && (hasRole(subject, permissionSubject)) 636 && (actionUri.toString() 637 .startsWith(permission.getActionUri())); 638 639 } 640 641 } 642 643 granted = granted | oldGranted; 644 denied = denied | oldDenied; 645 646 } 647 648 Uri parentUri = courUri.getParentUri(); 649 650 if (parentUri != null) { 651 courObject = parentUri.getStore() 652 .retrieveObject(parentUri); 653 } else { 654 rootObjectReached = true; 655 } 656 } 657 658 if (denied) { 661 return false; 662 } 663 664 if (!granted) { 665 return false; 666 } 667 668 return true; 669 670 } 671 672 685 public boolean hasPermission(SlideToken token, ObjectNode object, ActionNode action) throws ServiceAccessException, ObjectNotFoundException { 686 Boolean cachedPermission = token.checkPermissionCache(object, action); 687 if (cachedPermission != null) { 688 return cachedPermission.booleanValue(); 689 } 690 else { 691 return hasPermission(object, (SubjectNode)getPrincipal(token), action); 692 } 693 } 694 695 696 706 public Enumeration enumeratePermissions(SlideToken token, 707 ObjectNode object) 708 throws ServiceAccessException, ObjectNotFoundException, 709 AccessDeniedException { 710 711 return enumeratePermissions(token, object, false); 712 } 713 714 715 725 public Enumeration enumeratePermissions(SlideToken token, 726 ObjectNode object, 727 boolean includeInherited) 728 throws ServiceAccessException, ObjectNotFoundException { 729 return enumeratePermissions(token, object.getUri(), includeInherited); 730 } 731 732 733 743 public Enumeration enumeratePermissions(SlideToken token, 744 String object) 745 throws ServiceAccessException, ObjectNotFoundException, 746 AccessDeniedE
|