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.Iterator ; 34 import java.util.List ; 35 import java.util.Map ; 36 import java.util.Set ; 37 import java.util.Vector ; 38 import org.apache.slide.common.Namespace; 39 import org.apache.slide.common.NamespaceConfig; 40 import org.apache.slide.common.ServiceAccessException; 41 import org.apache.slide.common.SlideException; 42 import org.apache.slide.common.SlideToken; 43 import org.apache.slide.common.SlideTokenWrapper; 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.NodeRevisionNumber; 48 import org.apache.slide.content.RevisionDescriptorNotFoundException; 49 import org.apache.slide.store.Store; 50 import org.apache.slide.structure.ActionNode; 51 import org.apache.slide.structure.LinkNode; 52 import org.apache.slide.structure.ObjectAlreadyExistsException; 53 import org.apache.slide.structure.ObjectNode; 54 import org.apache.slide.structure.ObjectNotFoundException; 55 import org.apache.slide.structure.SubjectNode; 56 import org.apache.slide.util.Configuration; 57 import org.apache.slide.util.XMLValue; 58 import org.apache.slide.util.logger.Logger; 59 import org.jdom.JDOMException; 60 import org.jahia.services.webdav.stores.UserLinkNode; 61 import org.jahia.services.webdav.stores.JahiaGroupNode; 62 import org.jahia.services.usermanager.JahiaGroupManagerService; 63 import org.jahia.services.usermanager.JahiaUserManagerService; 64 import org.jahia.services.usermanager.JahiaGroup; 65 import org.jahia.services.usermanager.JahiaUser; 66 import org.jahia.services.sites.JahiaSite; 67 import org.jahia.registries.ServicesRegistry; 68 import org.jahia.exceptions.JahiaException; 69 70 76 public class JahiaWebdavSecurity extends SecurityImpl { 77 78 private static final String LOG_CHANNEL = SecurityImpl.class.getName(); 79 80 private static final String actions[] = {"/actions/read","/actions/write","/actions/manage"}; 81 82 85 public JahiaWebdavSecurity() {} 86 87 93 public JahiaWebdavSecurity(Namespace namespace, NamespaceConfig namespaceConfig) { 94 init(namespace, namespaceConfig); 95 } 96 97 public void init(Namespace namespace, NamespaceConfig namespaceConfig) { 98 super.init(namespace, namespaceConfig); 99 loadActionsCache(namespace, namespaceConfig); 100 } 101 102 104 108 private Map actionAggregation; private Map actionAggregationClosure; 111 113 114 124 public void setPermissions(SlideToken token, String object, 125 Enumeration permissions) 126 throws ServiceAccessException, ObjectNotFoundException, 127 AccessDeniedException { 128 129 Uri objectUri = namespace.getUri(token, object); 130 ObjectNode objectNode = objectUri.getStore().retrieveObject(objectUri); 131 132 checkCredentials(token, objectNode, 133 namespaceConfig.getGrantPermissionAction()); 134 checkCredentials(token, objectNode, 135 namespaceConfig.getRevokePermissionAction()); 136 137 objectUri.getStore().revokePermissions(objectUri); 138 139 while (permissions.hasMoreElements()) { 140 NodePermission permission = 141 (NodePermission) permissions.nextElement(); 142 mapRoles(permission); 143 objectUri.getStore().grantPermission(objectUri, permission); 144 } 145 146 } 147 148 149 161 public void grantPermission(SlideToken token, ObjectNode object, 162 SubjectNode subject, ActionNode action) 163 throws ServiceAccessException, ObjectNotFoundException, 164 AccessDeniedException { 165 grantPermission(token, object, subject, action, true); 166 } 167 168 169 182 public void grantPermission(SlideToken token, ObjectNode object, 183 SubjectNode subject, ActionNode action, 184 boolean inheritable) 185 throws ServiceAccessException, ObjectNotFoundException, 186 AccessDeniedException { 187 NodePermission permission = new NodePermission(object, subject, action, 188 inheritable); 189 grantPermission(token, permission); 190 } 191 192 193 203 public void grantPermission(SlideToken token, 204 NodePermission permission) 205 throws ServiceAccessException, ObjectNotFoundException, 206 AccessDeniedException { 207 Uri objectUri = namespace.getUri(token, permission.getObjectUri()); 208 ObjectNode object = objectUri.getStore() 209 .retrieveObject(objectUri); 210 211 checkCredentials(token, object, 212 namespaceConfig.getGrantPermissionAction()); 213 214 mapRoles(permission); 215 216 Enumeration permissions = enumeratePermissions(token, object); 218 boolean alreadyPresent = false; 219 while (permissions.hasMoreElements()) { 220 NodePermission currentPermission = (NodePermission) permissions.nextElement(); 221 if ((currentPermission.objectUri.equals(permission.getObjectUri())) 222 && (currentPermission.subjectUri.equals(permission.getSubjectUri())) 223 && (currentPermission.actionUri.equals(permission.getActionUri()))) { 224 if (currentPermission.negative == permission.negative) { 225 alreadyPresent = true; 226 } else { 227 objectUri.getStore().revokePermission(objectUri, currentPermission); 228 } 229 break; 230 } 231 } 232 233 if (!alreadyPresent) { 234 objectUri.getStore().grantPermission(objectUri, permission); 235 } 236 } 237 238 239 240 252 public void denyPermission(SlideToken token, ObjectNode object, 253 SubjectNode subject, ActionNode action) 254 throws ServiceAccessException, ObjectNotFoundException, 255 AccessDeniedException { 256 denyPermission(token, object, subject, action, true); 257 } 258 259 260 273 public void denyPermission(SlideToken token, ObjectNode object, 274 SubjectNode subject, ActionNode action, 275 boolean inheritable) 276 throws ServiceAccessException, ObjectNotFoundException, 277 AccessDeniedException { 278 NodePermission permission = new NodePermission(object, subject, action, 279 inheritable, true); 280 denyPermission(token, permission); 281 } 282 283 284 294 public void denyPermission(SlideToken token, 295 NodePermission permission) 296 throws ServiceAccessException, ObjectNotFoundException, 297 AccessDeniedException { 298 if (!permission.isNegative()) 301 permission.setNegative(true); 302 grantPermission(token, permission); 303 } 304 305 306 318 public void revokePermission(SlideToken token, ObjectNode object, 319 SubjectNode subject, ActionNode action) 320 throws ServiceAccessException, ObjectNotFoundException, 321 AccessDeniedException { 322 checkCredentials(token, object, namespaceConfig 324 .getRevokePermissionAction()); 325 NodePermission permission = new NodePermission(object, subject, 326 action); 327 328 mapRoles(permission); 329 330 Uri objectUri = namespace.getUri(token, object.getUri()); 331 objectUri.getStore() 332 .revokePermission(objectUri, permission); 333 } 334 335 336 337 347 public void revokePermission(SlideToken token, NodePermission permission) 348 throws ServiceAccessException, ObjectNotFoundException, 349 AccessDeniedException { 350 351 Uri objectUri = namespace.getUri(token, permission.getObjectUri()); 352 ObjectNode object = objectUri.getStore().retrieveObject(objectUri); 353 354 mapRoles(permission); 355 356 checkCredentials(token, object, 357 namespaceConfig.getRevokePermissionAction()); 358 objectUri.getStore().revokePermission(objectUri, permission); 359 } 360 361 362 373 public void checkCredentials(SlideToken token, ObjectNode object, 374 ActionNode action) 375 throws ServiceAccessException, AccessDeniedException { 376 377 if (!token.isForceSecurity()) { 378 return; 379 } 380 else if (token.isForceStoreEnlistment()) { 381 token = new SlideTokenWrapper(token); } 383 384 try { 385 if (Configuration.useIntegratedSecurity()) { 386 Boolean permission = token.checkPermissionCache(object, action); 388 389 if (permission == null) { 390 try { 392 Uri objectUri = namespace.getUri(token, object.getUri()); 393 ObjectNode realObject = objectUri.getStore() 394 .retrieveObject(objectUri); 395 checkPermission(token, realObject, action); 396 token.cachePermission(object, action, true); 397 } catch (AccessDeniedException ade) { 398 token.cachePermission(object, action, false); 399 ade.fillInStackTrace(); 400 throw ade; 401 } 402 } 403 else { 404 if (!(permission.booleanValue())) { 405 throw new AccessDeniedException 406 (object.getUri(), 407 getPrincipal(token).getPath().toString(), 408 action.getUri()); 409 } 410 } 411 } 412 } catch (ObjectNotFoundException e) { 413 String subjectUri = "*** Could not determine principal ***"; 414 try { 415 subjectUri = getPrincipal(token).getPath().toString(); 416 } catch (Exception x) {} 417 throw new AccessDeniedException 418 (object.getUri(), 419 subjectUri, 420 action.getUri()); 421 } 422 } 423 424 425 437 public void checkPermission(ObjectNode object, SubjectNode subject, 438 ActionNode action) 439 throws ServiceAccessException, AccessDeniedException, 440 ObjectNotFoundException { 441 442 if (!hasPermission(object, subject, action)) { 443 throw new AccessDeniedException(object.getUri(), subject.getUri(), 444 action.getUri()); 445 } 446 447 } 448 449 461 public void checkPermission(SlideToken token, ObjectNode object, ActionNode action) throws ServiceAccessException, AccessDeniedException, ObjectNotFoundException { 462 463 if (!hasPermission(token, object, action)) { 464 throw new AccessDeniedException(object.getUri(), getPrincipal(token).getUri(), 465 action.getUri()); 466 } 467 } 468 469 470 482 public boolean hasPermission(ObjectNode object, SubjectNode subject, 483 ActionNode action) 484 throws ServiceAccessException, ObjectNotFoundException { 485 return hasPermission(object,subject,action, null); 486 } 487 488 500 private boolean hasPermission(ObjectNode object, SubjectNode subject, 501 ActionNode action, SlideToken token) 502 throws ServiceAccessException, ObjectNotFoundException { 503 504 if (action == ActionNode.DEFAULT) { 506 return true; 507 } 508 509 boolean granted = false; 510 boolean denied = false; 511 boolean rootObjectReached = false; 512 513 514 if (hasRole(subject, "root")) { 515 return true; 516 } 517 518 ObjectNode courObject = object; 519 520 Uri subjectUri = namespace.getUri(token, subject.getUri()); 521 Uri actionUri = namespace.getUri(token, action.getUri()); 522 523 525 Vector deniedSubjects = new Vector (); 526 527 JahiaSite s = null; 528 try { 529 s = ServicesRegistry.getInstance().getJahiaSitesService().getSiteByKey(namespace.getName()); 530 } catch (JahiaException e) { 531 throw new ServiceAccessException(null,e); 532 } 533 String [] strings = subjectUri.toString().split("/"); 534 String uname; 535 if (strings.length < 3) { 536 uname = JahiaUserManagerService.GUEST_USERNAME; 537 } else { 538 uname = strings[2]; 539 } 540 JahiaUser u = ServicesRegistry.getInstance().getJahiaUserManagerService().lookupUser(s.getID(), uname); 541 542 while (!granted && !rootObjectReached) { 543 544 Uri courUri = namespace.getUri(token, courObject.getUri()); 545 Enumeration permissions = null; 546 try { 547 permissions = courUri.getStore() 548 .enumeratePermissions(courUri); 549 } catch (ServiceAccessException e) { 550 Uri parentUri = courUri.getParentUri(); 551 552 if (parentUri != null) { 553 courObject = parentUri.getStore() 554 .retrieveObject(parentUri); 555 } else { 556 rootObjectReached = true; 557 } 558 559 continue; 560 } 561 562 563 while (!granted && permissions.hasMoreElements()) { 564 565 NodePermission permission = 566 (NodePermission) permissions.nextElement(); 567 String permissionSubject = permission.getSubjectUri(); 568 569 if (!deniedSubjects.contains(permissionSubject)) { 570 if (permissionSubject == SubjectNode.SELF_URI) { 571 572 boolean check; 573 check = object.getUri().equals(subjectUri.toString()); 574 if (permission.isInheritable()) { 575 String subjectUriString = subjectUri.toString(); 576 if(!subjectUriString.endsWith("/")) 577 subjectUriString = subjectUriString + "/"; 578 579 check |= object.getUri().startsWith(subjectUriString); 580 } 581 582 granted = (!permission.isNegative()) 584 && (check) 585 && (actionUri.toString() 586 .startsWith(permission.getActionUri())); 587 denied = (permission.isNegative()) 588 && (check) 589 && (actionUri.toString() 590 .startsWith(permission.getActionUri())); 591 592 } else if (permission.isInheritable() 593 || permission.getObjectUri().equals(object.getUri())) { 594 595 if (permissionSubject.startsWith("/")) { 596 597 599 String permSubj = permission.getSubjectUri(); 600 if(!permSubj.endsWith("/")) 601 permSubj = permSubj + "/"; 602 boolean match = subjectUri.toString(). 603 equals(permission.getSubjectUri()) || 604 subjectUri.toString().startsWith(permSubj); 605 match &= actionUri.toString(). 606 startsWith(permission.getActionUri()); 607 608 granted = (!permission.isNegative()) && match; 609 denied = permission.isNegative() && match; 610 611 } else if (permissionSubject.startsWith("+")) { 612 613 Uri permissionSubjectUri = 615 namespace.getUri(token, permissionSubject.substring(1)); 616 ObjectNode group = 617 permissionSubjectUri.getStore().retrieveObject 618 (permissionSubjectUri); 619 if (group instanceof JahiaGroupNode ) { 622 JahiaGroup g = ServicesRegistry.getInstance().getJahiaGroupManagerService().lookupGroup(s.getID(), group.toString().split("/")[2]); 623 boolean match = g.isMember(u); 624 625 match &= actionUri.toString(). 626 startsWith(permission.getActionUri()); 627 628 granted = (!permission.isNegative()) && 629 match; 630 denied = permission.isNegative() && match; 631 } 632 } else { 633 634 granted = (!permission.isNegative()) 636 && (hasRole(subject, permissionSubject)) 637 && (actionUri.toString() 638 .startsWith(permission.getActionUri())); 639 denied = (permission.isNegative()) 640 && (hasRole(subject, permissionSubject)) 641 && (actionUri.toString() 642 .startsWith(permission.getActionUri())); 643 644 } 645 } 646 647 648 if (denied) deniedSubjects.add(permissionSubject); 649 } 650 } 651 652 Uri parentUri = courUri.getParentUri(); 653 654 if (parentUri != null) { 655 courObject = parentUri.getStore() 656 .retrieveObject(parentUri); 657 } else { 658 rootObjectReached = true; 659 } 660 } 661 662 663 if (granted) { 665 return true; 666 } 667 668 return false; 669 } 670 671 684 public boolean hasPermission(SlideToken token, ObjectNode object, ActionNode action) throws ServiceAccessException, ObjectNotFoundException { 685 Boolean cachedPermission = token.checkPermissionCache(object, action); 686 if (cachedPermission != null) { 687 return cachedPermission.booleanValue(); 688 } 689 else { 690 return hasPermission(object, (SubjectNode)getPrincipal(token), action, token); 691 } 692 } 693 694 695 705 public Enumeration enumeratePermissions(SlideToken token, 706 ObjectNode object) 707 throws ServiceAccessException, ObjectNotFoundException, 708 AccessDeniedException { 709 710 return enumeratePermissions(token, object, false); 711 } 712 713 714 724 public Enumeration enumeratePermissions(SlideToken token, 725 ObjectNode object, 726 boolean includeInherited) 727 throws ServiceAccessException, ObjectNotFoundException { 728 return enumeratePermissions(token, object.getUri(), includeInherited); 729 } 730 731 732 742 public Enumeration enumeratePermissions(SlideToken token, 743 String object) 744 throws ServiceAccessException, ObjectNotFoundException, 745 AccessDeniedException { 746 747 return enumeratePermissions(token, object, false); 748 } 749 750 751 761 public Enumeration enumeratePermissions(SlideToken token, 762 String object, 763 boolean includeInherited) 764 throws ServiceAccessException, ObjectNotFoundException { 765 766 Uri objectUri = namespace.getUri(token, object); 767 if (!includeInherited) { 768 return objectUri.getStore().enumeratePermissions(objectUri); 769 } 770 else { 771 ObjectNode objectNode = objectUri.getStore().retrieveObject(objectUri); 772 Iterator i = retrieveAclSourceNodes(token, objectNode).iterator(); 773 Vector permissions = new Vector (); 774 while (i.hasNext()) { 775 ObjectNode oNode = (ObjectNode)i.next(); 776 Uri oUri = namespace.getUri(token, oNode.getUri()); 777 Enumeration permEnum = oUri.getStore().enumeratePermissions(oUri); 778 while (permEnum.hasMoreElements()) { 779 NodePermission perm = (NodePermission)permEnum.nextElement(); 780 if (object.equals(oNode.getUri())) { 781 permissions.add(perm); 782 } 783 else if (perm.isInheritable()) { 784 perm.setInheritedFrom(oNode.getUri()); 785 permissions.add(perm); 786 } 787 } 788 } 789 return permissions.elements(); 790 } 791 } 792 793 794 806 public List retrieveAclSourceNodes(SlideToken token, ObjectNode object) 807 throws ServiceAccessException, ObjectNotFoundException { 808 809 List result = new ArrayList (); 810 if (token.isForceStoreEnlistment()) { 811 token = new SlideTokenWrapper(token); 813 } 814 815 Uri uri; 816 switch (aclInheritanceType) { 817 case NamespaceConfig.ACL_INHERIT_TYPE_NONE: 818 uri = namespace.getUri(token, object.getUri()); 819 result.add( uri.getStore().retrieveObject(uri) ); 820 break; 821 case NamespaceConfig.ACL_INHERIT_TYPE_ROOT: 822 uri = namespace.getUri(token, object.getUri()); 823 Uri rootUri = namespace.getUri(token, uri.getScope().toString()); 824 result.add( uri.getStore().retrieveObject(uri) ); 825 result.add( rootUri.getStore().retrieveObject(rootUri) ); 826 break; 827 case NamespaceConfig.ACL_INHERIT_TYPE_PATH: 828 uri = namespace.getUri(token, object.getUri()); 829 Enumeration enumeration = uri.getScopes(); 830 while (enumeration.hasMoreElements()) { 831 Uri element = namespace.getUri(token, (String )enumeration.nextElement(), false); 832 ObjectNode objectNode = element.getStore().retrieveObject(element); 833 result.add(objectNode); 834 } 835 break; 836 case NamespaceConfig.ACL_INHERIT_TYPE_FULL: 837 break; 839 default: 840 break; 841 } 842 843 return result; 844 } 845 846 855 public boolean hasRole(SlideToken token, String role) 856 throws ServiceAccessException, ObjectNotFoundException { 857 858 ObjectNode subject = getPrincipal(token); 859 860 return hasRole(subject, role); 861 862 } 863 864 865 874 public boolean hasRole(ObjectNode object, String role) 875 throws ServiceAccessException, ObjectNotFoundException { 876 877 if (role.equals(NamespaceConfig.NOBODY) || role.equals("all")) 878 return true; 879 String associatedRole = namespaceConfig.getRoleMapping(role); 880 if ((associatedRole != null) 881 && (associatedRole.equals(NamespaceConfig.NOBODY) || role.equals("all"))) 882 return true; 883 884 Class roleClass = (Class ) rolesCache.get(role); 885 if ((roleClass == null) && (associatedRole != null)) { 886 roleClass = (Class ) rolesCache.get(associatedRole); 887 if (roleClass == null) { 888 try { 889 roleClass = Class.forName(associatedRole); 890 rolesCache.put(role, roleClass); 891 rolesCache.put(associatedRole, roleClass); 892 } catch (ClassNotFoundException ex) { 893 } 894 } 895 } 896 if (roleClass == null) { 897 try { 898 roleClass = Class.forName(role); 899 rolesCache.put(role, roleClass); 900 } catch (ClassNotFoundException e) { 901 } 902 } 903 if (roleClass == null) { 904 return false; 905 } 906 907 if (roleClass.isInstance(object)) 908 return true; 909 910 return false; 911 912 } 913 914 915 920 public Enumeration getRoles(ObjectNode object) { 921 922 Vector result = new Vector (); 923 result.addElement(NamespaceConfig.NOBODY); 924 result.addElement("all"); 925 926 Class currentObjectClass = object.getClass(); 927 928 while (!currentObjectClass.equals(ObjectNode.class)) { 929 930 Class [] interfaces = currentObjectClass.getInterfaces(); 931 for (int i = 0; i < interfaces.length; i++) { 932 String className = interfaces[i].getName(); 933 String associatedName = 934 namespaceConfig.getRoleMapping(className); 935 if (associatedName != null) 936 result.addElement(associatedName); 937 else 938 result.addElement(className); 939 } 940 941 currentObjectClass = currentObjectClass.getSuperclass(); 942 if (currentObjectClass == null) { 943 throw new IllegalStateException ("Invalid node"); 945 } 946 947 } 948 949 return result.elements(); 950 951 } 952 953 954 959 public Enumeration getRoles(SlideToken token) 960 throws ServiceAccessException, ObjectNotFoundException { 961 return getRoles(getPrincipal(token)); 962 } 963 964 public Enumeration getRoles(SlideToken token, SubjectNode subjectNode) 965 throws ServiceAccessException, ObjectNotFoundException { 966 return getRoles(subjectNode); 967 } 968 969 977 public ObjectNode getPrincipal(SlideToken token) 978 throws ServiceAccessException, ObjectNotFoundException { 979 980 String user = 981 token.getCredentialsToken().getPublicCredentials(); 982 if ((user == null) || user.equals("") || user.equals("/")) { 983 return SubjectNode.UNAUTHENTICATED; 984 } 985 986 Uri subjectUri = namespace.getUri 987 (token, namespaceConfig.getUsersPath()+"/"+user); 988 989 try { 990 return subjectUri.getStore().retrieveObject(subjectUri); 991 } catch (ObjectNotFoundException e) { 992 if (!namespaceConfig.isAutoCreateUsers()) { 993 throw e; 994 } 995 else { 996 try { 997 Uri parentUri = subjectUri.getParentUri(); 998 ObjectNode parent = 999 subjectUri.getStore().retrieveObject(parentUri); 1000 Enumeration childrenEnum = parent.enumerateChildren(); 1001 Enumeration linksEnum = parent.enumerateLinks(); 1002 Vector children = new Vector (); 1003 while (childrenEnum.hasMoreElements()) { 1004 children.addElement(childrenEnum.nextElement()); 1005 } 1006 children.addElement(subjectUri.toString()); 1007 Vector links = new Vector (); 1008 while (linksEnum.hasMoreElements()) { 1009 links.addElement(linksEnum.nextElement()); 1010 } 1011 1012 Class objectClass = Class.forName 1014 (namespaceConfig.getAutoCreateUsersRole()); 1015 Class [] types = { String .class }; 1016 Object [] args = { subjectUri.toString() }; 1017 Constructor constructor = 1018 objectClass.getConstructor(types); 1019 ObjectNode object = 1020 (ObjectNode) constructor.newInstance(args); 1021 subjectUri.getStore().createObject(subjectUri, object); 1022 1023 Class [] types2 = 1024 { String .class, Vector .class, Vector .class }; 1025 Object [] args2 = { parentUri.toString(), children, links }; 1026 constructor = parent.getClass().getConstructor(types2); 1027 object = (ObjectNode) constructor.newInstance(args2); 1028 parentUri.getStore().storeObject(parentUri, object); 1029 } catch (ClassNotFoundException ex) { 1030 throw new ObjectNotFoundException(subjectUri); 1032 } catch (NoSuchMethodException ex) { 1033 throw new ObjectNotFoundException(subjectUri); 1035 } catch (InstantiationException ex) { 1036 throw new ObjectNotFoundException(subjectUri); 1038 } catch (InvocationTargetException ex) { 1039 throw new ObjectNotFoundException(subjectUri); 1041 } catch (IllegalAccessException ex) { 1042 throw new ObjectNotFoundException(subjectUri); 1044 } catch (ObjectAlreadyExistsException ex) { 1045 e.printStackTrace(); 1047 throw new ObjectNotFoundException(subjectUri); 1048 } 1049 return subjectUri.getStore().retrieveObject(subjectUri); 1050 } 1051 } 1052 } 1053 1054 private void loadActionsCache(Namespace namespace, NamespaceConfig namespaceConfig) { 1055 try { 1056 actionAggregation = new HashMap (); 1057 actionAggregationClosure = new HashMap (); 1058 String actionsPath = namespaceConfig.getActionsPath(); 1059 Uri actionsPathUri = namespace.getUri(actionsPath); 1060 ObjectNode actionsPathNode = actionsPathUri.getStore().retrieveObject(actionsPathUri); 1061 Enumeration actions = actionsPathNode.enumerateChildren(); 1062 while (actions.hasMoreElements()) { 1063 ActionNode aNode = ActionNode.getActionNode((String )actions.nextElement()); 1064 Set directAggregates = getActionAggregates(aNode); 1065 actionAggregation.put(aNode, directAggregates); 1066 Set aClosure = new HashSet (); 1067 aClosure.add(aNode); 1068 aClosure.addAll(directAggregates); 1069 actionAggregationClosure.put(aNode, aClosure); 1070 } 1071 Iterator keys = actionAggregationClosure.keySet().iterator(); 1072 while (keys.hasNext()) { 1073 ActionNode aNode = (ActionNode)keys.next(); 1074 Set aClosure = (Set )actionAggregationClosure.get(aNode); 1075 actionAggregationClosure.put(aNode, buildClosure(aClosure)); 1076 } 1077 if (logger.isEnabled(LOG_CHANNEL, Logger.INFO)) { 1079 logger.log("Action aggregations loaded successfully", LOG_CHANNEL, Logger.INFO); 1080 } 1081 if (logger.isEnabled(LOG_CHANNEL, Logger.DEBUG)) { 1082 logger.log("\n@@@ Actions aggregations", LOG_CHANNEL, Logger.DEBUG); 1083 Iterator i = actionAggregation.entrySet().iterator(); 1084 while (i.hasNext()) { 1085 logger.log(" "+i.next(), LOG_CHANNEL, Logger.DEBUG); 1086 } 1087 logger.log("\n@@@ Action aggregations (transitive closure)", LOG_CHANNEL, Logger.DEBUG); 1088 i = actionAggregationClosure.entrySet().iterator(); 1089 while (i.hasNext()) { 1090 logger.log(" "+i.next(), LOG_CHANNEL, Logger.DEBUG); 1091 } 1092 } 1093 } 1094 catch (Throwable e) { 1095 actionAggregation = null; 1096 actionAggregationClosure = null; 1097 } 1098 } 1099 1100 private Set buildClosure(Set aClosure) { 1101 Set result = new HashSet (aClosure); 1102 int size = 0; 1103 while (result.size() > size) { 1104 size = result.size(); 1105 Set newResult = new HashSet (); 1106 Iterator i = result.iterator(); 1107 while (i.hasNext()) { 1108 newResult.addAll((Set )actionAggregationClosure.get(i.next())); 1109 } 1110 result = newResult; 1111 } 1112 return result; 1113 } 1114 1115 1123 private Set getActionAggregates(ActionNode aNode) throws SlideException, JDOMException { 1124 Set result = new HashSet (); 1125 Uri aNodeUri = namespace.getUri(aNode.getUri()); 1126 NodeRevisionDescriptor aNrd = aNodeUri.getStore().retrieveRevisionDescriptor(aNodeUri, new NodeRevisionNumber()); 1127 NodeProperty membersProp = aNrd.getProperty("privilege-member-set"); 1128 if (membersProp != null && membersProp.getValue() != null) { 1129 XMLValue membersVal; 1130 if (membersProp.getValue() instanceof XMLValue) { 1131 membersVal = (XMLValue)membersProp.getValue(); 1132 } 1133 else { 1134 membersVal = new XMLValue((String )membersProp.getValue()); 1135 } 1136 Iterator mUris = membersVal.getHrefStrings().iterator(); 1137 while (mUris.hasNext()) { 1138 result.add(ActionNode.getActionNode((String )mUris.next())); 1139 } 1140 } 1141 return result; 1142 } 1143 1144 1154 public boolean matchAction(SlideToken token, ActionNode checkAction, ActionNode permAction) throws ServiceAccessException { 1155 if (permAction == ActionNode.ALL) { 1156 return true; 1157 } 1158 else { 1159 if (actionAggregationClosure != null) { 1160 Set permActionSet = (Set )actionAggregationClosure.get(permAction); 1161 if (permActionSet == null) { 1162 logger.log("Unknown action " + permAction.getUri() , LOG_CHANNEL, Logger.WARNING); 1163 return false; 1164 } else { 1165 return permActionSet.contains(checkAction); 1166 } 1167 } 1168 else { 1169 Uri u = namespace.getUri(token, checkAction.getUri()); 1170 Store s = u.getStore(); 1171 throw new ServiceAccessException(s, "Actions cache not loaded"); 1172 } 1173 } 1174 } 1175 1176 1189 public boolean matchPrincipal(SlideToken token, SubjectNode checkSubject, SubjectNode matchSubject) throws ServiceAccessException { 1190 Boolean b = token.checkMatchPrincipalCache(checkSubject, matchSubject); 1191 if (b != null) { 1192 return b.booleanValue(); 1193 } 1194 else { 1195 boolean match = matchPrincipal(token, checkSubject, matchSubject, namespaceConfig.getNestedRolesMaxDepth()); 1196 token.cacheMatchPrincipal(checkSubject, matchSubject, match); 1197 return match; 1198 } 1199 } 1200 1201 1214 public boolean matchPrincipal(SlideToken token, SubjectNode checkSubject, SubjectNode matchSubject, int level) throws ServiceAccessException { 1215 if (matchSubject.equals(checkSubject)) { 1216 return true; 1217 } 1218 else { 1219 Uri groupUri = namespace.getUri(token, matchSubject.getUri()); 1220 try { 1221 NodeRevisionDescriptor nrd = 1222 groupUri.getStore().retrieveRevisionDescriptor(groupUri, new NodeRevisionNumber()); 1223 NodeProperty membersetProp = nrd.getProperty("group-member-set"); 1224 if (membersetProp != null && membersetProp.getValue() != null) { 1225 XMLValue xmlVal = new XMLValue((String )membersetProp.getValue()); 1226 List memberNodes = xmlVal.getHrefNodes(); 1227 if (memberNodes.contains(checkSubject)) { 1228 return true; 1229 } 1230 else if (level > 0) { 1231 int nextLevel = level - 1; 1232 boolean match = false; 1233 Iterator i = memberNodes.iterator(); 1234 while (!match && i.hasNext()) { 1235 SubjectNode nextMatchNode = (SubjectNode)i.next(); 1236 if (namespaceConfig.isRole(nextMatchNode.getUri()) 1237 || namespaceConfig.isGroup(nextMatchNode.getUri())) { 1238 1239 match = matchPrincipal(token, checkSubject, nextMatchNode, nextLevel); 1240 } 1241 } 1242 return match; 1243 } 1244 else { 1245 return false; 1246 } 1247 } 1248 else { 1249 return false; 1250 } 1251 } 1252 catch (RevisionDescriptorNotFoundException e) { 1253 return false; 1254 } 1255 catch (ServiceAccessException e) { 1256 throw e; 1257 } 1258 catch (JDOMException e) { 1259 e.printStackTrace(); 1260 return false; 1261 } 1262 } 1263 } 1264 1265 1269 public Map getActionAggregation() { 1270 return Collections.unmodifiableMap(actionAggregation); 1271 } 1272 1273 private void mapRoles(NodePermission permission) { 1274 String subject = permission.getSubjectUri(); 1275 if (("+/groups/"+JahiaGroupManagerService.GUEST_GROUPNAME+"/members").equals(subject)) { 1277 subject = "all"; 1278 } else if (("+/groups/"+JahiaGroupManagerService.ADMINISTRATORS_GROUPNAME+"/members").equals(subject)) { 1279 subject = "root"; 1280 } else if (("+/groups/"+JahiaGroupManagerService.USERS_GROUPNAME+"/members").equals(subject)) { 1281 subject = "authenticated"; 1282 } else if (("/users/"+JahiaUserManagerService.GUEST_USERNAME).equals(subject)) { 1283 subject = "unauthenticated"; 1284 } 1285 permission.setSubject(subject); 1286 } 1287 1288} | Popular Tags |