1 19 package org.openharmonise.rm.security.authorization; 20 21 import java.util.*; 22 import java.util.logging.*; 23 24 import org.openharmonise.commons.cache.*; 25 import org.openharmonise.commons.dsi.AbstractDataStoreInterface; 26 import org.openharmonise.rm.DataAccessException; 27 import org.openharmonise.rm.factory.*; 28 import org.openharmonise.rm.metadata.*; 29 import org.openharmonise.rm.resources.*; 30 import org.openharmonise.rm.resources.lifecycle.*; 31 import org.openharmonise.rm.resources.metadata.properties.*; 32 import org.openharmonise.rm.resources.metadata.values.Value; 33 import org.openharmonise.rm.resources.users.User; 34 35 36 44 public class AuthorizationValidator implements EditEventListener, CacheListener { 45 public static final String ATTRIB_IS_VIEWABLE = "isViewable"; 46 public static final String PROP_ROLE = "ROLE"; 47 public static final String COMMAND_VIEW = "View"; 48 public static final String BROWSE_ROLE = "BROWSER"; 49 private static CachePointer m_role_ptr = null; 50 private static CachePointer m_view_ptr = null; 51 52 private static AuthorizationValidator m_instance = null; 53 54 private static Map m_object_security_cache = new Hashtable(); 55 56 private static Map m_instance_security_cache = 57 Collections.synchronizedMap(new Hashtable()); 58 59 62 private static final Logger m_logger = Logger.getLogger(AuthorizationValidator.class.getName()); 63 64 68 private AuthorizationValidator() { 69 } 70 71 76 public static AuthorizationValidator getInstance() { 77 if (m_instance == null) { 78 m_instance = new AuthorizationValidator(); 79 } 80 81 return m_instance; 82 } 83 84 93 public static boolean isVisible(User usr, AbstractProfiledObject pobj) 94 throws AuthorizationException { 95 return isCommandAvailable(usr, pobj, COMMAND_VIEW); 96 } 97 98 107 public static boolean isCommandAvailable( 108 User usr, 109 Class objClass, 110 String sCommand) 111 throws AuthorizationException { 112 boolean bIsAvail = false; 113 114 if (objClass != null) { 115 116 if (isSuperUser(usr) == true) { 117 bIsAvail = true; 118 } else { 119 120 Profile usrProf = null; 121 122 try { 123 usrProf = 124 usr.getProfile(AuthorityProfile.SECURITY_PROFILE_NAME); 125 } catch (DataAccessException e) { 126 throw new AuthorizationException( 127 "Error occured accessing user's security profile:", 128 e); 129 } 130 131 if (usrProf != null) { 132 try { 133 ChildObjectPropertyInstance roleInst = 134 ( 135 ChildObjectPropertyInstance) usrProf 136 .getPropertyInstance( 137 PROP_ROLE); 138 139 if (roleInst != null) { 140 Value roleVal = (Value) roleInst.getValue(); 141 142 bIsAvail = isCommandAvailableToObject(roleVal, 143 objClass, 144 sCommand); 145 } 146 } catch (DataAccessException e) { 147 throw new AuthorizationException( 148 "Data access exception:", 149 e); 150 } catch (InvalidPropertyInstanceException e) { 151 throw new AuthorizationException(e.getLocalizedMessage(), e); 152 } 153 } 154 } 155 156 if(m_logger.isLoggable(Level.FINE)) { 157 m_logger.logp(Level.FINE, AuthorizationValidator.class.getName(), "isCommandAvailable", "Validating availablity of " + sCommand + " to " + objClass.getName() + " for user " + usr.getId() + " - " + bIsAvail); 158 } 159 } 160 161 return bIsAvail; 162 } 163 164 173 public static boolean isCommandAvailable( 174 User usr, 175 AbstractEditableObject edObj, 176 String sCommand) 177 throws AuthorizationException { 178 boolean bIsAvail = false; 179 180 if (edObj != null && usr != null) { 181 182 if (isSuperUser(usr) == true) { 183 bIsAvail = true; 184 } else { 185 186 Profile usrProf = null; 187 188 try { 189 usrProf = 190 usr.getProfile(AuthorityProfile.SECURITY_PROFILE_NAME); 191 } catch (DataAccessException e) { 192 throw new AuthorizationException( 193 "Error occured accessing user's security profile:", 194 e); 195 } 196 197 if (usrProf != null) { 198 try { 199 ChildObjectPropertyInstance roleInst = 200 ( 201 ChildObjectPropertyInstance) usrProf 202 .getPropertyInstance( 203 PROP_ROLE); 204 205 if (roleInst != null) { 206 Value roleVal = (Value) roleInst.getValue(); 207 208 if (isCommandAvailableToObject(roleVal, 209 edObj.getClass(), 210 sCommand) 211 == true) { 212 if (edObj instanceof AbstractProfiledObject && edObj.exists() == true) { 213 bIsAvail = 214 isCommandAvailableToInstance( 215 roleVal, 216 (AbstractProfiledObject) edObj, 217 sCommand); 218 } else { 219 bIsAvail = true; 220 } 221 } 222 } 223 } catch (DataAccessException e) { 224 throw new AuthorizationException( 225 "Data access exception:", 226 e); 227 } catch (InvalidPropertyInstanceException e) { 228 throw new AuthorizationException(e.getLocalizedMessage(), e); 229 } 230 } 231 } 232 233 if(m_logger.isLoggable(Level.FINE)) { 234 m_logger.logp(Level.FINE, AuthorizationValidator.class.getName(), "isCommandAvailable", "Validating availablity of " + sCommand + " to " + edObj.getClass().getName() + " " + edObj.getId() + " for user " + usr.getId() + " - " + bIsAvail); 235 } 236 } 237 238 return bIsAvail; 239 } 240 241 249 public static void mergeSecurityProfiles( 250 Profile primaryProfile, 251 Profile referenceProfile) 252 throws AuthorizationException { 253 254 List primPropInsts = null; 255 try { 256 primPropInsts = primaryProfile.getPropertyInstances(); 257 } catch (DataAccessException e) { 258 throw new AuthorizationException( 259 "Error occured accessing property instances",e); 260 } 261 262 Iterator iter = primPropInsts.iterator(); 263 264 while (iter.hasNext()) { 269 AbstractPropertyInstance propInst = 270 (AbstractPropertyInstance) iter.next(); 271 AbstractPropertyInstance refPropInst = null; 272 Property prop = null; 273 274 try { 275 prop = propInst.getProperty(); 276 277 refPropInst = referenceProfile.getPropertyInstance(prop); 278 } catch (DataAccessException e) { 279 throw new AuthorizationException( 280 "Error occured getting property instance",e); 281 } catch (InvalidPropertyInstanceException e) { 282 throw new AuthorizationException( 283 "Error occured getting property instance",e); 284 } 285 286 if (refPropInst == null) { 287 try { 288 primaryProfile.removeProperty(prop); 289 } catch (ProfileException e) { 290 throw new AuthorizationException( 291 "Error occured removing prop inst",e); 292 } 293 } else { 294 List refVals = refPropInst.getValues(); 295 List instVals = propInst.getValues(); 296 297 Iterator valIter = instVals.iterator(); 298 299 while (valIter.hasNext()) { 300 Object val = iter.next(); 301 302 if (instVals.contains(val) == false) { 303 propInst.removeValue(val); 304 } 305 } 306 } 307 } 308 309 } 310 311 317 static public boolean isSuperUser(User usr) throws AuthorizationException { 318 boolean bIsSuper = false; 319 320 if (usr != null) { 321 try { 322 bIsSuper = usr.isSuper(); 323 } catch (DataAccessException e) { 324 throw new AuthorizationException( 325 "Error occured accessing property instance", 326 e); 327 } 328 } 329 330 return bIsSuper; 331 } 332 333 340 public static List getSecurityProperties(AbstractDataStoreInterface dsi) 341 throws DataAccessException { 342 List rbs_props = new ArrayList(); 343 344 try { 345 346 if(m_role_ptr == null) { 347 Property role = 348 PropertyFactory.getPropertyFromName( 349 dsi, 350 AuthorizationValidator.PROP_ROLE); 351 if(role != null) { 352 m_role_ptr = CacheHandler.getInstance(dsi).getCachePointer(role); 353 } 354 355 } 356 357 rbs_props.add(m_role_ptr.getObject()); 358 359 } catch (HarmoniseFactoryException e) { 360 throw new DataAccessException(e.getLocalizedMessage(), e); 361 } catch (CacheException e) { 362 throw new DataAccessException(e.getLocalizedMessage(), e); 363 } 364 365 return rbs_props; 366 } 367 368 371 public void workflowObjectSaved(EditEvent event) { 372 374 } 375 376 379 public void workflowObjectStatusChanged(EditEvent event) { 380 Editable editObj = event.getResult(); 381 Editable srcObj = (Editable) event.getSource(); 382 handleObjectChanged(editObj); 383 } 384 385 388 public void workflowObjectArchived(EditEvent event) { 389 Editable editObj = event.getResult(); 390 Editable srcObj = (Editable) event.getSource(); 391 handleObjectChanged(editObj); 392 393 } 394 395 398 public void workflowObjectReactivated(EditEvent event) { 399 401 } 402 403 406 public void workflowObjectLocked(EditEvent event) { 407 409 } 410 411 414 public void workflowObjectUnlocked(EditEvent event) { 415 417 } 418 419 422 423 434 static private boolean isCommandAvailableToObject( 435 Value roleVal, 436 Class edClass, 437 String sCommand) 438 throws DataAccessException { 439 boolean bIsAvail = false; 440 441 if (roleVal != null) { 442 443 String sObjClassname = edClass.getName(); 444 445 String sObjName = 446 sObjClassname.substring(sObjClassname.lastIndexOf(".") + 1); 447 448 String cacheKey = getCacheKey(roleVal.getName(), sCommand, edClass); 449 450 Boolean boolIsAvail = 451 (Boolean ) m_object_security_cache.get(cacheKey); 452 453 if (boolIsAvail == null) { 454 455 Profile valProf = roleVal.getProfile(); 456 457 if (valProf != null) { 458 459 try { 460 ChildObjectPropertyInstance objInst = 461 ( 462 ChildObjectPropertyInstance) valProf 463 .getPropertyInstance( 464 sObjName); 465 466 if (objInst != null) { 467 468 List allowedCommands = objInst.getValues(); 469 Value val = null; 470 471 for (Iterator iter = allowedCommands.iterator(); 474 iter.hasNext(); 475 ) { 476 val = (Value) iter.next(); 477 479 if (val.getName().equals(sCommand) == true) { 481 bIsAvail = true; 482 483 break; 485 } 486 } 487 } 488 } catch (InvalidPropertyInstanceException e) { 489 throw new DataAccessException( 490 e.getLocalizedMessage(), 491 e); 492 } 493 } 494 495 roleVal.addEditEventListener(AuthorizationValidator.getInstance()); 496 497 m_object_security_cache.put(cacheKey, new Boolean (bIsAvail)); 498 } else { 499 bIsAvail = boolIsAvail.booleanValue(); 500 } 501 } 502 503 return bIsAvail; 504 } 505 506 515 static private boolean isCommandAvailableToInstance( 516 Value roleVal, 517 AbstractProfiledObject profObj, 518 String sCommand) 519 throws DataAccessException { 520 boolean bIsAvail = false; 521 Profile objProf = null; 522 523 String cacheKey = getCacheKey(roleVal.getName(), sCommand, profObj); 524 525 Boolean boolIsAvail = (Boolean ) m_instance_security_cache.get(cacheKey); 526 527 if (boolIsAvail == null) { 528 529 objProf = profObj.getProfile(AuthorityProfile.SECURITY_PROFILE_NAME); 530 531 if (objProf != null) { 532 533 try { 534 AbstractPropertyInstance cmndInst = 535 objProf.getPropertyInstance(sCommand); 536 537 if (cmndInst != null) { 538 539 List cmndRoleVals = cmndInst.getValues(); 540 541 if (cmndRoleVals.contains(roleVal) == true) { 544 bIsAvail = true; 545 } 546 } else { 547 bIsAvail = true; 550 } 551 } catch (InvalidPropertyInstanceException e) { 552 throw new DataAccessException(e.getLocalizedMessage(), e); 553 } 554 555 if (bIsAvail == true) { 556 if (profObj instanceof AbstractChildObject) { 557 AbstractChildObject child = 558 (AbstractChildObject) profObj; 559 560 AbstractParentObject parent = child.getRealParent(); 561 562 if (parent != null) { 563 bIsAvail = 564 isCommandAvailableToInstance( 565 roleVal, 566 parent, 567 sCommand); 568 } 569 } 570 } 571 } else { 572 bIsAvail = true; 573 } 574 m_instance_security_cache.put(cacheKey, new Boolean (bIsAvail)); 575 576 profObj.addEditEventListener(AuthorizationValidator.getInstance()); 578 579 } else { 580 bIsAvail = boolIsAvail.booleanValue(); 581 } 582 583 return bIsAvail; 584 } 585 586 596 private static String getCacheKey( 597 String roleName, 598 String sCommand, 599 AbstractProfiledObject profObj) 600 throws DataAccessException { 601 StringBuffer sbuf = new StringBuffer (); 602 603 sbuf.append(profObj.getClass().getName()); 604 605 if (profObj instanceof AbstractChildObject) { 606 AbstractChildObject child = (AbstractChildObject) profObj; 607 608 sbuf.append(child.getFullPath()); 609 } else { 610 sbuf.append(profObj.getName()); 611 } 612 613 sbuf.append(roleName).append(sCommand); 614 615 return sbuf.toString(); 616 } 617 618 627 private static String getCacheKey( 628 String roleName, 629 String sCommand, 630 Class clss) 631 throws DataAccessException { 632 StringBuffer sbuf = new StringBuffer (); 633 634 sbuf.append(roleName).append(sCommand).append(clss.getName()); 635 636 return sbuf.toString(); 637 } 638 639 646 private void removeFromInstanceSecurityCache(AbstractProfiledObject profObj) 647 throws DataAccessException { 648 Set keys = m_instance_security_cache.keySet(); 649 650 StringBuffer sbuf = new StringBuffer (); 651 sbuf.append(profObj.getClass().getName()); 652 653 if (profObj instanceof AbstractChildObject) { 654 AbstractChildObject child = (AbstractChildObject) profObj; 655 sbuf.append(child.getFullPath()); 656 } else { 657 sbuf.append(profObj.getName()); 658 } 659 660 String cacheKeyPrefix = sbuf.toString(); 661 String sKey = null; 662 boolean bKeyFound = false; 663 664 for (Iterator iter = keys.iterator(); 665 iter.hasNext() && bKeyFound == false; 666 ) { 667 sKey = (String ) iter.next(); 668 669 if (sKey.startsWith(cacheKeyPrefix) == true) { 670 bKeyFound = true; 671 } 672 } 673 674 if (bKeyFound == true) { 675 m_instance_security_cache.remove(sKey); 676 } 677 } 678 679 private void removeFromObjectSecurityCache(Value roleVal) throws DataAccessException { 680 String roleName = roleVal.getName(); 681 682 Iterator iter = m_object_security_cache.keySet().iterator(); 683 List keysToRemove = new ArrayList(); 684 685 while (iter.hasNext()) { 686 String sKey = (String ) iter.next(); 687 if(sKey.startsWith(roleName)) { 688 keysToRemove.add(sKey); 689 } 690 } 691 692 for (iter = keysToRemove.iterator(); iter.hasNext();) { 693 String sKeyToRemove = (String ) iter.next(); 694 m_object_security_cache.remove(sKeyToRemove); 695 } 696 697 } 698 699 705 public static boolean isBrowser(User usr) throws AuthorizationException { 706 boolean bIsBrowse = false; 707 708 if (usr != null) { 709 try { 710 Profile prof = 711 usr.getProfile(AuthorityProfile.SECURITY_PROFILE_NAME); 712 713 if (prof != null) { 714 AbstractPropertyInstance roleInst = 715 prof.getPropertyInstance(PROP_ROLE); 716 717 if (roleInst != null) { 718 Value roleValue = (Value) roleInst.getValue(); 719 720 if (roleValue != null 721 && roleValue.getName().equals(BROWSE_ROLE) == true) { 722 bIsBrowse = true; 723 } 724 } 725 726 } 727 } catch (DataAccessException e) { 728 throw new AuthorizationException( 729 "Error occured accessing property instance", 730 e); 731 } catch (InvalidPropertyInstanceException e) { 732 throw new AuthorizationException(e.getLocalizedMessage(), e); 733 } 734 } 735 736 return bIsBrowse; 737 } 738 739 public static List getUserRoles(User usr) throws InvalidPropertyInstanceException, DataAccessException { 740 List roles = null; 741 742 Profile security = usr.getProfile(AuthorityProfile.SECURITY_PROFILE_NAME); 743 744 ChildObjectPropertyInstance roleInst = (ChildObjectPropertyInstance) security.getPropertyInstance(AuthorizationValidator.PROP_ROLE); 745 746 if(roleInst != null) { 747 roles = roleInst.getValues(); 748 } else { 749 roles = new ArrayList(); 750 } 751 752 753 return roles; 754 } 755 756 759 public void objectRemovedFromCache(CacheableObject obj) { 760 handleObjectChanged(obj); 761 } 762 763 768 private void handleObjectChanged(Object obj) { 769 if (obj instanceof AbstractProfiledObject) { 770 AbstractProfiledObject profObj = (AbstractProfiledObject) obj; 771 try { 772 if (profObj.getStatus() == Status.APPROVED) { 773 774 removeFromInstanceSecurityCache(profObj); 775 776 } 777 } catch (DataAccessException e) { 778 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 779 780 782 m_instance_security_cache.clear(); 783 } 784 } 785 786 if(obj instanceof Value) { 787 try { 788 removeFromObjectSecurityCache((Value)obj); 790 } catch (DataAccessException e) { 791 m_object_security_cache.clear(); 793 } 794 } 795 } 796 } | Popular Tags |