1 18 19 package org.objectweb.jac.aspects.user; 20 21 import java.util.Collection ; 22 import java.util.HashMap ; 23 import java.util.Hashtable ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.Map ; 27 import java.util.Vector ; 28 import org.aopalliance.intercept.ConstructorInvocation; 29 import org.aopalliance.intercept.MethodInvocation; 30 import org.apache.log4j.Logger; 31 import org.objectweb.jac.aspects.authentication.AuthenticationAC; 32 import org.objectweb.jac.aspects.gui.DisplayContext; 33 import org.objectweb.jac.aspects.gui.GuiAC; 34 import org.objectweb.jac.core.ACManager; 35 import org.objectweb.jac.core.AspectComponent; 36 import org.objectweb.jac.core.Collaboration; 37 import org.objectweb.jac.core.Interaction; 38 import org.objectweb.jac.core.NameRepository; 39 import org.objectweb.jac.core.ObjectRepository; 40 import org.objectweb.jac.core.Wrappee; 41 import org.objectweb.jac.core.Wrapper; 42 import org.objectweb.jac.core.rtti.AttributeController; 43 import org.objectweb.jac.core.rtti.ClassItem; 44 import org.objectweb.jac.core.rtti.ClassRepository; 45 import org.objectweb.jac.core.rtti.CollectionItem; 46 import org.objectweb.jac.core.rtti.FieldItem; 47 import org.objectweb.jac.core.rtti.MemberItem; 48 import org.objectweb.jac.core.rtti.MetaItem; 49 import org.objectweb.jac.core.rtti.MethodItem; 50 import org.objectweb.jac.util.ObjectArray; 51 52 77 78 public class UserAC 79 extends AspectComponent 80 implements UserConf, AttributeController 81 { 82 public static final Logger logger = Logger.getLogger("user"); 83 public static final Logger loggerAuth = Logger.getLogger("auth"); 84 public static final Logger loggerProfile = Logger.getLogger("profile"); 85 public static final Logger loggerFilter = Logger.getLogger("profile.filter"); 86 87 public static final String USER = "UserAC.USER"; 88 public static final String CONTEXTUAL_PROFILE = "UserAC.CONTEXTUAL_PROFILE"; 89 public static final String HABILITATION = "UserAC.HABILITATION"; 90 public static final String FILTER = "UserAC.FILTER"; 92 96 97 public UserAC() { 98 blockKeywords = new String [] { "profile" }; 99 try { 100 MetaItem.registerAccessController(this); 101 } catch (RuntimeException e) { 102 e.printStackTrace(); 103 } 104 } 105 106 public void setContextualProfile(ClassItem cl, 107 String field, 108 String profile) 109 { 110 loggerProfile.debug( 111 "defined contextual profile: " + field + " <--> " + profile); 112 cl.getField(field).setAttribute(CONTEXTUAL_PROFILE, profile); 113 } 114 115 122 123 public static void addContextualProfiledUser( 124 Object substance, 125 Object user, 126 Profile profile) { 127 128 Collection c = 129 ClassRepository.get().getClass(substance).getTaggedMembers( 130 CONTEXTUAL_PROFILE, 131 profile.getName()); 132 133 loggerProfile.debug("found contextual profiles for: " + c); 134 Iterator it = c.iterator(); 135 while (it.hasNext()) { 136 MemberItem member = (MemberItem) it.next(); 137 try { 138 if (member instanceof CollectionItem) { 139 ((CollectionItem) member).addThroughAdder(substance, user); 140 } else if (member instanceof FieldItem) { 141 ((FieldItem) member).setThroughWriter(substance, user); 142 } 143 } catch (Exception e) { 144 logger.error( 145 "Failed to set field "+ substance + "." + member 146 + " with " + user 147 , e); 148 } 149 } 150 } 151 152 public Profile getProfileFromUser(Object user) { 153 return (Profile) profileField.getThroughAccessor(user); 154 } 155 156 public void setProfileToUser(Object user, Profile profile) { 157 try { 158 profileField.setThroughWriter(user, profile); 159 } catch (Exception e) { 160 logger.error( 161 "Failed to set profile of user (" 162 + user + "." + profileField + ") with " + profile, 163 e); 164 } 165 } 166 167 177 178 protected List getProfiles(String authuser, Object substance) { 179 Vector profiles = new Vector (); 180 Object user = getUserFromLogin(authuser); 181 Profile profile = getProfileFromUser(user); 182 if (profile != null) 183 profiles.add(profile); 184 if (substance != null) { 185 Object owner = getOwner(substance); 186 if (owner == user || owner == null) { 190 profile = userManager.getProfile("owner"); 191 if (profile != null) 192 profiles.add(profile); 193 } 194 195 Collection fs = 197 ClassRepository.get().getClass(substance).getTaggedFields( 198 CONTEXTUAL_PROFILE, 199 false); 200 if (fs.size() > 0) { 201 Iterator it = fs.iterator(); 202 while (it.hasNext()) { 203 FieldItem field = (FieldItem) it.next(); 204 if ((field instanceof CollectionItem 205 && ((CollectionItem) field).getActualCollection( 206 substance).contains( 207 user)) 208 || (field.isReference() 209 && field.getThroughAccessor(substance) == user)) { 210 profile = 211 userManager.getProfile( 212 (String ) field.getAttribute( 213 CONTEXTUAL_PROFILE)); 214 if (profile != null) 215 profiles.add(profile); 216 } 217 } 218 } 219 } 220 221 loggerProfile.debug("Profiles=" + profiles); 222 return profiles; 223 } 224 225 Hashtable usersCache = new Hashtable (); 226 227 232 public void invalidateCache() { 233 usersCache.clear(); 234 } 235 236 static class BooleanThreadLocal extends ThreadLocal { 237 protected Object initialValue() { 238 return Boolean.FALSE; 239 } 240 } 241 242 private BooleanThreadLocal inHabilitation = new BooleanThreadLocal(); 243 244 261 262 public Object controlAttribute( 263 Object substance, 264 MetaItem item, 265 String attrName, 266 Object value) 267 { 268 loggerProfile.debug( 269 "controlAttribute(" + item + "," + attrName + "," + value + ")"); 270 if (inHabilitation.equals(Boolean.TRUE)) { 272 return value; 273 } 274 String authuser = (String ) attr(AuthenticationAC.USER); 275 if (authuser == null) { 276 loggerProfile.debug( 277 "user not defined, no access check for " 278 + item + "." + attrName); 279 return value; 280 } 281 282 loggerProfile.debug("1"); 283 284 ClassItem cli = null; 285 if (substance != null) 286 cli = ClassRepository.get().getClass(substance); 287 MethodItem classHabilitation = null; 288 if (cli != null) 289 classHabilitation = (MethodItem) cli.getAttribute(HABILITATION); 290 if (classHabilitation == null) 291 classHabilitation = habilitation; 292 if (classHabilitation != null) { 293 loggerProfile.debug("Calling habilitation " + classHabilitation); 294 Object savedInhabilitation = inHabilitation.get(); 295 try { 296 inHabilitation.set(Boolean.TRUE); 297 if (attrName.equals(GuiAC.VISIBLE) 298 || attrName.equals(GuiAC.EDITABLE) 299 || attrName.equals(GuiAC.ADDABLE) 300 || attrName.equals(GuiAC.REMOVABLE)) { 301 value = 302 classHabilitation.invokeStatic( 303 new Object [] { 304 substance, 305 item, 306 getUserFromLogin(authuser), 307 attrName }); 308 } 309 } finally { 310 inHabilitation.set(savedInhabilitation); 311 } 312 return value; 313 } 314 315 loggerProfile.debug("3"); 316 317 Map userCache = (HashMap ) usersCache.get(authuser); 318 if (userCache == null) { 319 userCache = new HashMap (); 320 usersCache.put(authuser, userCache); 321 } 322 ObjectArray key = 323 new ObjectArray(new Object [] { substance, item, attrName }); 324 if (userCache.containsKey(key)) { 326 331 return userCache.get(key); 332 } 333 334 if (attrName.equals(GuiAC.VISIBLE)) { 335 Collection profiles = getProfiles(authuser, substance); 336 if (profiles.isEmpty()) { 337 ; 338 } else if (!Profile.isReadable(profiles, item)) { 339 loggerProfile.debug( 340 "overriding " + attrName + " for " + item + " -> FALSE"); 341 value = Boolean.FALSE; 342 } else if ( 344 item instanceof MethodItem && ((MethodItem) item).isAdder()) { 345 CollectionItem[] addedColls = 346 ((MethodItem) item).getAddedCollections(); 347 for (int i = 0; i < addedColls.length; i++) { 348 if (!Profile.isAddable(profiles, addedColls[i])) { 349 loggerProfile.debug( 350 "overriding " + attrName 351 + " for " + item + " -> FALSE"); 352 value = Boolean.FALSE; 353 break; 354 } 355 } 356 } else if ( 358 item instanceof MethodItem 359 && ((MethodItem) item).isRemover()) { 360 CollectionItem[] removedColls = 361 ((MethodItem) item).getRemovedCollections(); 362 for (int i = 0; i < removedColls.length; i++) { 363 if (!Profile.isRemovable(profiles, removedColls[i])) { 364 loggerProfile.debug( 365 "overriding " + attrName 366 + " for " + item + " -> FALSE"); 367 value = Boolean.FALSE; 368 break; 369 } 370 } 371 } 372 } else if (attrName.equals(GuiAC.EDITABLE)) { 373 Collection profiles = getProfiles(authuser, substance); 374 if (profiles.isEmpty()) { 375 ; 376 } else if (!Profile.isWritable(profiles, item)) { 377 loggerProfile.debug( 378 "overriding " + attrName + " for " + item + " -> FALSE"); 379 value = Boolean.FALSE; 380 } 381 } else if (attrName.equals(GuiAC.ADDABLE)) { 382 Collection profiles = getProfiles(authuser, substance); 383 if (profiles.isEmpty()) { 384 ; 385 } else if (!Profile.isAddable(profiles, item)) { 386 loggerProfile.debug( 387 "overriding " + attrName + " for " + item + " -> FALSE"); 388 value = Boolean.FALSE; 389 } 390 } else if (attrName.equals(GuiAC.REMOVABLE)) { 391 Collection profiles = getProfiles(authuser, substance); 392 if (profiles.isEmpty()) { 393 ; 394 } else if (!Profile.isRemovable(profiles, item)) { 395 loggerProfile.debug( 396 "overriding " + attrName + " for " + item + " -> FALSE"); 397 value = Boolean.FALSE; 398 } 399 } else if (attrName.equals(GuiAC.CREATABLE)) { 400 Collection profiles = getProfiles(authuser, substance); 401 if (profiles.isEmpty()) { 402 ; 403 } else if (!Profile.isCreatable(profiles, item)) { 404 loggerProfile.debug( 405 "overriding " + attrName + " for " + item + " -> FALSE"); 406 value = Boolean.FALSE; 407 } 408 } 409 userCache.put(key, value); 410 return value; 411 } 412 413 417 418 public Object getCurrentUser() { 419 String authuser = 420 (String ) Collaboration.get().getAttribute(AuthenticationAC.USER); 421 if (authuser != null) { 422 return getUserFromLogin(authuser); 423 } 424 return null; 425 } 426 427 428 Hashtable cachedUsers = new Hashtable (); 429 430 438 439 public Object getUserFromLogin(String login) { 440 Object user = null; 441 user = cachedUsers.get(login); 442 if (user == null) { 443 Collection users = ObjectRepository.getObjects(userClass); 444 Iterator i = users.iterator(); 445 while (i.hasNext()) { 447 Object testedUser = i.next(); 448 Object id = loginField.getThroughAccessor(testedUser); 449 if (login.equals(id)) { 450 user = testedUser; 451 break; 452 } 453 } 454 if (login != null && user != null) 455 cachedUsers.put(login, user); 456 } 457 return user; 458 } 459 460 469 470 public String getUserLogin(Object user) { 471 if (user == null) 472 return null; 473 if (loginField == null) 474 return null; 475 return (String ) loginField.getThroughAccessor(user); 476 } 477 478 487 488 public String getUserPassword(Object user) { 489 if (user == null) 490 return null; 491 if (passwordField == null) 492 return null; 493 return (String ) passwordField.getThroughAccessor(user); 494 } 495 496 501 502 public String getCurrentUserLogin() { 503 Object currentUser = getCurrentUser(); 504 if (currentUser == null) 505 return null; 506 if (loginField == null) 507 return null; 508 return (String ) loginField.getThroughAccessor(currentUser); 509 } 510 511 516 517 public String getCurrentUserPassword() { 518 Object currentUser = getCurrentUser(); 519 if (currentUser == null) 520 return null; 521 if (passwordField == null) 522 return null; 523 return (String ) passwordField.getThroughAccessor(currentUser); 524 } 525 526 536 public static boolean userController( 537 String username, 538 Object wrappee, 539 MethodItem method) 540 { 541 loggerAuth.debug("userController(" + username + "...)"); 542 if (username == null) 543 return false; 544 UserAC userAC = (UserAC) ACManager.getACM().getAC("user"); 545 return username.equals(userAC.getCurrentUserLogin()); 546 } 547 548 public ClassItem getUserClass() { 549 return userClass; 550 } 551 552 public FieldItem getLoginField() { 553 return loginField; 554 } 555 556 558 UserWrapper wrapper = new UserWrapper(this); 559 560 ClassItem userClass; 561 FieldItem loginField; 562 FieldItem passwordField; 563 FieldItem profileField; 564 565 public void setUserClass( 566 ClassItem userClass, 567 String loginField, 568 String passwordField, 569 String profileField) { 570 575 this.userClass = userClass; 576 this.loginField = userClass.getField(loginField); 577 if (passwordField != null) { 578 this.passwordField = userClass.getField(passwordField); 579 } 580 if (profileField != null) { 581 this.profileField = userClass.getField(profileField); 582 } 583 } 584 585 public void defineAdministrator(String login, String password) { 586 if (userClass == null) { 587 logger.error( 588 "cannot define administrator if no user class is defined before."); 589 return; 590 } 591 if (getUserFromLogin(login) != null) { 592 logger.debug("Admin user `" + login + "' already defined"); 593 return; 595 } 596 Object admin = null; 597 try { 598 admin = userClass.newInstance(); 599 } catch (Exception e) { 600 logger.error("administrator instantiation failed",e); 601 return; 602 } 603 try { 604 loginField.setThroughWriter(admin, login); 605 } catch (Exception e) { 606 logger.error( 607 "Failed to set login of admin (" 608 + admin + "." + loginField + ") with " + login 609 , e); 610 } 611 try { 612 passwordField.setThroughWriter(admin, password); 613 } catch (Exception e) { 614 logger.error( 615 "Failed to set password of admin (" 616 + admin + "." + passwordField + ") " 617 , e); 618 } 619 setProfileToUser(admin, userManager.getProfile("administrator")); 620 userManager.setDefaultAdmin((Wrappee) admin); 621 logger.debug("Created admin user " + admin); 622 } 623 624 public void autoInitClasses(String classExpr) { 625 logger.debug("autoInitClasses " + classExpr); 626 pointcut( 627 "ALL", 628 classExpr, 629 "CONSTRUCTORS", 630 wrapper, 631 null); 632 } 633 634 public void autoInitClasses(ClassItem cl, 635 String triggerClassExpr, 636 String triggerMethodExpr) 637 { 638 logger.debug( 639 "autoInitClasses " + cl + 640 " on " + triggerClassExpr + "." + triggerMethodExpr); 641 wrapper.addClass(cl); 642 pointcut( 643 "ALL", 644 triggerClassExpr, 645 triggerMethodExpr, 646 wrapper, 647 null); 648 } 649 650 UserManager userManager = new UserManager(); 651 652 public UserManager getUserManager() { 653 return userManager; 654 } 655 656 public void declareProfile(String name) { 657 Collection profiles = 658 ObjectRepository.getObjects(Profile.class); 659 Iterator it = profiles.iterator(); 660 while (it.hasNext()) { 661 Profile cur = (Profile) it.next(); 662 if (cur.getName().equals(name)) { 663 loggerProfile.info("profile " + name + " already defined"); 664 cur.setIsNew(false); 665 userManager.addProfile(cur); 666 return; 668 } 669 } 670 Profile profile = new Profile(name); 671 userManager.addProfile(profile); 672 } 673 674 public void declareProfile(String name, String parent) { 675 Collection profiles = 676 ObjectRepository.getObjects(Profile.class); 677 Iterator it = profiles.iterator(); 678 while (it.hasNext()) { 679 Profile cur = (Profile) it.next(); 680 if (cur.getName().equals(name)) { 681 loggerProfile.info("profile " + name + " already defined"); 682 cur.setIsNew(false); 683 userManager.addProfile(cur); 684 return; 686 } 687 } 688 Profile parentProfile = userManager.getProfile(parent); 689 Profile profile = new Profile(name,parentProfile); 690 userManager.addProfile(profile); 691 } 692 693 public Profile getProfile(String name) { 694 Profile profile = userManager.getProfile(name); 696 if (profile == null) 697 throw new RuntimeException ("No such profile " + name); 698 return profile; 699 } 700 701 706 public void clearProfile(String name) { 707 Profile profile = getProfile(name); 708 profile.clear(); 709 profile.setIsNew(true); 710 } 711 712 public void addReadable(String profile, String resourceExpr) { 713 if (getProfile(profile).isNew()) 714 getProfile(profile).addReadable(resourceExpr); 715 } 716 717 public void addUnreadable(String profile, String resourceExpr) { 718 if (getProfile(profile).isNew()) 719 getProfile(profile).addUnreadable(resourceExpr); 720 } 721 722 public void addWritable(String profile, String resourceExpr) { 723 if (getProfile(profile).isNew()) 724 getProfile(profile).addWritable(resourceExpr); 725 } 726 727 public void addUnwritable(String profile, String resourceExpr) { 728 if (getProfile(profile).isNew()) 729 getProfile(profile).addUnwritable(resourceExpr); 730 } 731 732 public void addRemovable(String profile, String resourceExpr) { 733 if (getProfile(profile).isNew()) 734 getProfile(profile).addRemovable(resourceExpr); 735 } 736 737 public void addUnremovable(String profile, String resourceExpr) { 738 if (getProfile(profile).isNew()) 739 getProfile(profile).addUnremovable(resourceExpr); 740 } 741 742 public void addAddable(String profile, String resourceExpr) { 743 if (getProfile(profile).isNew()) 744 getProfile(profile).addAddable(resourceExpr); 745 } 746 747 public void addCreatable(String profile, String resourceExpr) { 748 if (getProfile(profile).isNew()) 749 getProfile(profile).addCreatable(resourceExpr); 750 } 751 752 public void addUnaddable(String profile, String resourceExpr) { 753 if (getProfile(profile).isNew()) 754 getProfile(profile).addUnaddable(resourceExpr); 755 } 756 757 public MethodItem habilitation; 758 759 public void defineHabilitation(MethodItem habilitation) { 760 this.habilitation = habilitation; 761 } 762 763 public void defineHabilitation(ClassItem cli, MethodItem habilitation) { 764 cli.setAttribute(HABILITATION, habilitation); 765 } 766 767 public void addOwnerFilter( 768 String profile, 769 ClassItem cl, 770 String collectionName) { 771 pointcut( 772 "ALL", 773 cl.getName(), 774 "GETTERS(" + collectionName + ")", 775 "org.objectweb.jac.aspects.user.UserAC$OwnerFilterWrapper", 776 new Object [] { profile }, 777 null, 778 SHARED); 779 } 780 781 public void addFilter(CollectionItem collection, MethodItem filter) { 782 collection.setAttribute(FILTER, filter); 783 pointcut( 784 "ALL", 785 collection.getClassItem().getName(), 786 "GETTERS(" + collection.getName() + ")", 787 "org.objectweb.jac.aspects.user.UserAC$FilterWrapper", 788 null, 789 SHARED); 790 } 791 792 public class FilterWrapper extends Wrapper { 793 public FilterWrapper(AspectComponent ac) { 794 super(ac); 795 } 796 public Object filterResult(Interaction interaction) { 797 Object result = proceed(interaction); 798 String authuser = (String ) this.attr(AuthenticationAC.USER); 799 if (authuser == null) { 800 logger.debug( 801 "user not defined, cannot filter " + interaction.method); 802 return result; 803 } 804 FieldItem returnedField = ((MethodItem)interaction.method).getReturnedField(); 805 if (!(returnedField instanceof CollectionItem)) { 806 logger.warn("Cannot filter non collection field "+returnedField+ 807 " returned by "+interaction.method); 808 return result; 809 } 810 CollectionItem collection = (CollectionItem)returnedField; 811 if (collection == null) { 812 logger.debug( 813 "no returned collection for " + interaction.method); 814 return result; 815 } 816 logger.debug( 817 "filtering collection " + collection + ", user=" + authuser); 818 MethodItem filter = (MethodItem) collection.getAttribute(FILTER); 819 if (filter == null) { 820 logger.debug("no filter for " + collection); 821 return result; 822 } 823 return filter.invokeStatic( 824 new Object [] { 825 result, 826 interaction.wrappee, 827 collection, 828 getUserFromLogin(authuser)}); 829 } 830 831 public Object invoke(MethodInvocation invocation) throws Throwable { 832 return filterResult((Interaction) invocation); 833 } 834 } 835 836 public class OwnerFilterWrapper extends Wrapper { 837 public OwnerFilterWrapper(AspectComponent ac) { 838 super(ac); 839 } 840 841 public OwnerFilterWrapper(AspectComponent ac, String profileName) { 842 super(ac); 843 this.profileName = profileName; 844 } 845 846 String profileName; 847 848 852 public Object filterResult(Interaction interaction) { 853 loggerFilter.debug("filterResult("+interaction.method+")"); 854 Collection c = (Collection ) proceed(interaction); 855 UserAC ac = (UserAC) getAspectComponent(); 856 if (!ac 857 .getProfileFromUser(ac.getCurrentUser()) 858 .getName() 859 .equals(profileName)) { 860 return c; 861 } 862 loggerFilter.debug("filtering..."); 863 Vector result = new Vector (); 864 Iterator it = c.iterator(); 865 while (it.hasNext()) { 866 Object o = it.next(); 867 Object owner = ac.getOwner(o); 868 if (owner == ac.getCurrentUser()) { 869 result.add(o); 870 } 871 } 872 loggerFilter.debug("returning " + result); 873 return result; 874 } 875 public Object invoke(MethodInvocation invocation) throws Throwable { 876 return filterResult((Interaction) invocation); 877 } 878 } 879 880 890 public Object getOwner(Object object) { 891 ClassItem classItem = ClassRepository.get().getClass(object); 892 FieldItem[] fields = classItem.getFields(); 893 for (int i = 0; i < fields.length; i++) { 894 if (fields[i].getTypeItem() == userClass) { 895 return fields[i].getThroughAccessor(object); 896 } 897 } 898 return null; 899 } 900 901 public String [] getDefaultConfigs() { 902 return new String [] { "org/objectweb/jac/aspects/user/user.acc" }; 903 } 904 905 910 public static void viewProfiles(DisplayContext context, String panelID) { 911 org.objectweb.jac.aspects.gui.Actions.viewObject( 912 context, 913 "usermanager#0", 914 panelID); 915 } 916 917 public static UserManager getProfiles() { 918 return (UserManager) NameRepository.get().getObject("usermanager#0"); 919 } 920 921 } 922 923 | Popular Tags |