KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > aspects > user > UserAC


1 /*
2   Copyright (C) 2002-2003 Laurent Martelli <laurent@aopsys.com>
3                           Renaud Pawlak <renaud@aopsys.com>
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU Lesser General Public License as
7   published by the Free Software Foundation; either version 2 of the
8   License, or (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   GNU Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

18
19 package org.objectweb.jac.aspects.user;
20
21 import java.util.Collection JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Hashtable JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.Vector JavaDoc;
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 /**
53  * This aspect handles users within an application.
54  *
55  * <p>Any class of the application can be declared as a user
56  * representation. The aspect configurator should then declare which
57  * are the fields of this class that corresponds to the user's id
58  * (that is used to login) and to the password (not required). Users
59  * can then be bounded to profiles that define what are the elements
60  * of the application that have the right to access or not.
61  *
62  * <p>A profile has a list of rules associated to it. When the aspect
63  * needs to know if a user with a given profile is allowed to acess
64  * resource, it inspects the rules of the profile in the order in
65  * their declaration order, and as soon as a rule matches the
66  * resource, this rule determines if the user is granted access to the
67  * resource. A resource is a field or a method of a class. If the
68  * profile inherits another profile, the rules of the inherited
69  * profile are examined first.</p>
70  *
71  * @see #setUserClass(ClassItem,String,String,String)
72  * @see #declareProfile(String)
73  * @see #declareProfile(String,String)
74  * @see Rule
75  * @see Profile
76  */

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 JavaDoc USER = "UserAC.USER";
88     public static final String JavaDoc CONTEXTUAL_PROFILE = "UserAC.CONTEXTUAL_PROFILE";
89     public static final String JavaDoc HABILITATION = "UserAC.HABILITATION";
90     public static final String JavaDoc FILTER = "UserAC.FILTER"; // MethodItem
91

92     /**
93      * The default controller registers its
94      * <code>controlAttribute</code> method as an access controller for
95      * the RTTI. */

96
97     public UserAC() {
98         blockKeywords = new String JavaDoc[] { "profile" };
99         try {
100             MetaItem.registerAccessController(this);
101         } catch (RuntimeException JavaDoc e) {
102             e.printStackTrace();
103         }
104     }
105
106     public void setContextualProfile(ClassItem cl,
107                                      String JavaDoc field,
108                                      String JavaDoc profile)
109     {
110         loggerProfile.debug(
111             "defined contextual profile: " + field + " <--> " + profile);
112         cl.getField(field).setAttribute(CONTEXTUAL_PROFILE, profile);
113     }
114
115     /**
116      * Adds a contextually profiled user.
117      *
118      * @param substance object whose field(s) to set
119      * @param user user object
120      * @param profile set fields tagged with this profile
121      */

122
123     public static void addContextualProfiledUser(
124         Object JavaDoc substance,
125         Object JavaDoc user,
126         Profile profile) {
127
128         Collection JavaDoc c =
129             ClassRepository.get().getClass(substance).getTaggedMembers(
130                 CONTEXTUAL_PROFILE,
131                 profile.getName());
132
133         loggerProfile.debug("found contextual profiles for: " + c);
134         Iterator JavaDoc 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 JavaDoc 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 JavaDoc user) {
153         return (Profile) profileField.getThroughAccessor(user);
154     }
155
156     public void setProfileToUser(Object JavaDoc user, Profile profile) {
157         try {
158             profileField.setThroughWriter(user, profile);
159         } catch (Exception JavaDoc e) {
160             logger.error(
161                 "Failed to set profile of user ("
162                 + user + "." + profileField + ") with " + profile,
163                 e);
164         }
165     }
166
167     /**
168      * Gets the profiles of a user for checking access rights for an
169      * object.
170      *
171      * <p>If the user is the owner of the checked object, the "owner"
172      * profile is returned in addition to the user's profile.</p>
173      *
174      * @param authuser the user's name
175      * @param substance the checked object
176      */

177
178     protected List JavaDoc getProfiles(String JavaDoc authuser, Object JavaDoc substance) {
179         Vector JavaDoc profiles = new Vector JavaDoc();
180         Object JavaDoc user = getUserFromLogin(authuser);
181         Profile profile = getProfileFromUser(user);
182         if (profile != null)
183             profiles.add(profile);
184         if (substance != null) {
185             Object JavaDoc owner = getOwner(substance);
186             // We consider that everybody is the owner of an object with
187
// no owner so that new objects whose owner is not set yet
188
// can be edited
189
if (owner == user || owner == null) {
190                 profile = userManager.getProfile("owner");
191                 if (profile != null)
192                     profiles.add(profile);
193             }
194
195             // gets the contextual profiles
196
Collection JavaDoc fs =
197                 ClassRepository.get().getClass(substance).getTaggedFields(
198                     CONTEXTUAL_PROFILE,
199                     false);
200             if (fs.size() > 0) {
201                 Iterator JavaDoc 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 JavaDoc) 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 JavaDoc usersCache = new Hashtable JavaDoc();
226
227     /**
228      * Invalidate controlAttribute's cache.
229      *
230      * @see #controlAttribute(Object,MetaItem,String,Object)
231      */

232     public void invalidateCache() {
233         usersCache.clear();
234     }
235
236     static class BooleanThreadLocal extends ThreadLocal JavaDoc {
237         protected Object JavaDoc initialValue() {
238             return Boolean.FALSE;
239         }
240     }
241
242     private BooleanThreadLocal inHabilitation = new BooleanThreadLocal();
243
244     /**
245      * This method controls the access to a given meta item of the RTTI.
246      *
247      * <p>The profile of the current user is fetched and the
248      * permissions are checked against this profile. If the user owns
249      * the object being controlled, the "owner" profile is checked
250      * first.
251      *
252      * @param substance
253      * @param item the meta item that is currently accessed
254      * @param attrName the attribute that is asked on <code>item</code>
255      * @param value the already fetched value (can be overriden or
256      * returned as is)
257      * @return the value that will finally be returned by the RTTI
258      *
259      * @see org.objectweb.jac.core.rtti.MetaItem#getAttribute(String)
260      * @see #invalidateCache() */

261
262     public Object JavaDoc controlAttribute(
263         Object JavaDoc substance,
264         MetaItem item,
265         String JavaDoc attrName,
266         Object JavaDoc value)
267     {
268         loggerProfile.debug(
269             "controlAttribute(" + item + "," + attrName + "," + value + ")");
270         // Avoid infinite recursion when displaying an error box.
271
if (inHabilitation.equals(Boolean.TRUE)) {
272             return value;
273         }
274         String JavaDoc authuser = (String JavaDoc) 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 JavaDoc 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 JavaDoc[] {
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 JavaDoc userCache = (HashMap JavaDoc) usersCache.get(authuser);
318         if (userCache == null) {
319             userCache = new HashMap JavaDoc();
320             usersCache.put(authuser, userCache);
321         }
322         ObjectArray key =
323             new ObjectArray(new Object JavaDoc[] { substance, item, attrName });
324         //Log.trace("profile.cache." + attrName, "key = " + key);
325
if (userCache.containsKey(key)) {
326             /*
327               Log.trace(
328                 "profile.cache." + attrName,
329                 "return cached value " + userCache.get(key));
330             */

331             return userCache.get(key);
332         }
333
334         if (attrName.equals(GuiAC.VISIBLE)) {
335             Collection JavaDoc 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                 // do not show adders if isAddable==false
343
} 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                 // do not show removers if isRemovable==false
357
} 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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     /**
414      * Returns the user that is currently logged in.
415      *
416      * @return the user */

417
418     public Object JavaDoc getCurrentUser() {
419         String JavaDoc authuser =
420             (String JavaDoc) Collaboration.get().getAttribute(AuthenticationAC.USER);
421         if (authuser != null) {
422             return getUserFromLogin(authuser);
423         }
424         return null;
425     }
426
427     /** login -> User */
428     Hashtable JavaDoc cachedUsers = new Hashtable JavaDoc();
429
430     /**
431      * Gets a user from its login as defined in <code>setUserClass</code>.
432      *
433      * @param login the user's id
434      * @return the user (instance of the user's class)
435      * @see #setUserClass(ClassItem,String,String,String)
436      * @see #getUserLogin(Object)
437      * @see #getUserPassword(Object) */

438
439     public Object JavaDoc getUserFromLogin(String JavaDoc login) {
440         Object JavaDoc user = null;
441         user = cachedUsers.get(login);
442         if (user == null) {
443             Collection JavaDoc users = ObjectRepository.getObjects(userClass);
444             Iterator JavaDoc i = users.iterator();
445             // Find a user whose loginField matches the authenticated username
446
while (i.hasNext()) {
447                 Object JavaDoc testedUser = i.next();
448                 Object JavaDoc 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     /**
461      * Gets the login value for a given user.
462      *
463      * @param user the user object
464      * @return its login value (<code>null<code> if the user is
465      * <code>null</code> or if <code>setUserClass</code> is not
466      * correctly defined)
467      * @see #setUserClass(ClassItem,String,String,String)
468      * @see #getUserFromLogin(String) */

469
470     public String JavaDoc getUserLogin(Object JavaDoc user) {
471         if (user == null)
472             return null;
473         if (loginField == null)
474             return null;
475         return (String JavaDoc) loginField.getThroughAccessor(user);
476     }
477
478     /**
479      * Gets the password value for a given user.
480      *
481      * @param user the user object
482      * @return its password value (<code>null<code> if the user is
483      * <code>null</code> or if <code>setUserClass</code> is not
484      * correctly defined)
485      * @see #setUserClass(ClassItem,String,String,String)
486      * @see #getUserFromLogin(String) */

487
488     public String JavaDoc getUserPassword(Object JavaDoc user) {
489         if (user == null)
490             return null;
491         if (passwordField == null)
492             return null;
493         return (String JavaDoc) passwordField.getThroughAccessor(user);
494     }
495
496     /**
497      * Gets the login for the currently logged user.
498      *
499      * @return the login
500      * @see #getCurrentUser() */

501
502     public String JavaDoc getCurrentUserLogin() {
503         Object JavaDoc currentUser = getCurrentUser();
504         if (currentUser == null)
505             return null;
506         if (loginField == null)
507             return null;
508         return (String JavaDoc) loginField.getThroughAccessor(currentUser);
509     }
510
511     /**
512      * Gets the password for the currently logged user.
513      *
514      * @return the password
515      * @see #getCurrentUser() */

516
517     public String JavaDoc getCurrentUserPassword() {
518         Object JavaDoc currentUser = getCurrentUser();
519         if (currentUser == null)
520             return null;
521         if (passwordField == null)
522             return null;
523         return (String JavaDoc) passwordField.getThroughAccessor(currentUser);
524     }
525
526     /**
527      * This controlling method can be used by the authentification
528      * aspect to control that the authenticated user is valid.
529      *
530      * @param username the username that is given by the authenticator
531      * @param wrappee the object that is currently accessed
532      * @param method the method that is currently called
533      * @see org.objectweb.jac.aspects.authentication.AuthenticationAC
534      * @see org.objectweb.jac.aspects.authentication.AuthenticationAC#setController(String,String,MethodItem)
535      */

536     public static boolean userController(
537         String JavaDoc username,
538         Object JavaDoc 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     // UserConf interface
557

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 JavaDoc loginField,
568         String JavaDoc passwordField,
569         String JavaDoc profileField) {
570         /*if(!User.class.isAssignableFrom(userClass.getActualClass())) {
571            Log.error(userClass+" MUST implement org.objectweb.jac.aspects.user.User.\n"+
572                      "Please correct this and start the application again.");
573            System.exit(-1);
574            }*/

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 JavaDoc login, String JavaDoc 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             // admin already defined
594
return;
595         }
596         Object JavaDoc admin = null;
597         try {
598             admin = userClass.newInstance();
599         } catch (Exception JavaDoc e) {
600             logger.error("administrator instantiation failed",e);
601             return;
602         }
603         try {
604             loginField.setThroughWriter(admin, login);
605         } catch (Exception JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc triggerClassExpr,
636                                 String JavaDoc 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 JavaDoc name) {
657         Collection JavaDoc profiles =
658             ObjectRepository.getObjects(Profile.class);
659         Iterator JavaDoc 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                 //cur.clear();
667
return;
668             }
669         }
670         Profile profile = new Profile(name);
671         userManager.addProfile(profile);
672     }
673
674     public void declareProfile(String JavaDoc name, String JavaDoc parent) {
675         Collection JavaDoc profiles =
676             ObjectRepository.getObjects(Profile.class);
677         Iterator JavaDoc 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                 //cur.clear();
685
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 JavaDoc name) {
694         //(Profile)ObjectRepository.getObjects("org.objectweb.jac.aspects.user.Profile","name='"+name+"'");
695
Profile profile = userManager.getProfile(name);
696         if (profile == null)
697             throw new RuntimeException JavaDoc("No such profile " + name);
698         return profile;
699     }
700
701     /**
702      * Use this config method to clear a profile so that it can be
703      * reinitialized from the config file.
704      * @param name name of the profile to clear
705      */

706     public void clearProfile(String JavaDoc name) {
707         Profile profile = getProfile(name);
708         profile.clear();
709         profile.setIsNew(true);
710     }
711
712     public void addReadable(String JavaDoc profile, String JavaDoc resourceExpr) {
713         if (getProfile(profile).isNew())
714             getProfile(profile).addReadable(resourceExpr);
715     }
716
717     public void addUnreadable(String JavaDoc profile, String JavaDoc resourceExpr) {
718         if (getProfile(profile).isNew())
719             getProfile(profile).addUnreadable(resourceExpr);
720     }
721
722     public void addWritable(String JavaDoc profile, String JavaDoc resourceExpr) {
723         if (getProfile(profile).isNew())
724             getProfile(profile).addWritable(resourceExpr);
725     }
726
727     public void addUnwritable(String JavaDoc profile, String JavaDoc resourceExpr) {
728         if (getProfile(profile).isNew())
729             getProfile(profile).addUnwritable(resourceExpr);
730     }
731
732     public void addRemovable(String JavaDoc profile, String JavaDoc resourceExpr) {
733         if (getProfile(profile).isNew())
734             getProfile(profile).addRemovable(resourceExpr);
735     }
736
737     public void addUnremovable(String JavaDoc profile, String JavaDoc resourceExpr) {
738         if (getProfile(profile).isNew())
739             getProfile(profile).addUnremovable(resourceExpr);
740     }
741
742     public void addAddable(String JavaDoc profile, String JavaDoc resourceExpr) {
743         if (getProfile(profile).isNew())
744             getProfile(profile).addAddable(resourceExpr);
745     }
746
747     public void addCreatable(String JavaDoc profile, String JavaDoc resourceExpr) {
748         if (getProfile(profile).isNew())
749             getProfile(profile).addCreatable(resourceExpr);
750     }
751
752     public void addUnaddable(String JavaDoc profile, String JavaDoc 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 JavaDoc profile,
769         ClassItem cl,
770         String JavaDoc collectionName) {
771         pointcut(
772             "ALL",
773             cl.getName(),
774             "GETTERS(" + collectionName + ")",
775             "org.objectweb.jac.aspects.user.UserAC$OwnerFilterWrapper",
776             new Object JavaDoc[] { 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 JavaDoc filterResult(Interaction interaction) {
797             Object JavaDoc result = proceed(interaction);
798             String JavaDoc authuser = (String JavaDoc) 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 JavaDoc[] {
825                     result,
826                     interaction.wrappee,
827                     collection,
828                     getUserFromLogin(authuser)});
829         }
830
831         public Object JavaDoc invoke(MethodInvocation invocation) throws Throwable JavaDoc {
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 JavaDoc profileName) {
842             super(ac);
843             this.profileName = profileName;
844         }
845
846         String JavaDoc profileName;
847
848         /**
849          * Filters the result of a collection's getter to keep only the
850          * object that are owned by the currently logged user.
851          */

852         public Object JavaDoc filterResult(Interaction interaction) {
853             loggerFilter.debug("filterResult("+interaction.method+")");
854             Collection JavaDoc c = (Collection JavaDoc) 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 JavaDoc result = new Vector JavaDoc();
864             Iterator JavaDoc it = c.iterator();
865             while (it.hasNext()) {
866                 Object JavaDoc o = it.next();
867                 Object JavaDoc 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 JavaDoc invoke(MethodInvocation invocation) throws Throwable JavaDoc {
876             return filterResult((Interaction) invocation);
877         }
878     }
879
880     /**
881      * <p>Returns the owner of an object.</p>
882      *
883      * <p>The owner of an object is defined as the value of a field
884      * whose type is the type defined by <code>setUserClass</code>
885      *
886      * @param object the object
887      * @return the owner of the object, or null if the object does not
888      * have a owner.
889      */

890     public Object JavaDoc getOwner(Object JavaDoc 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 JavaDoc[] getDefaultConfigs() {
902         return new String JavaDoc[] { "org/objectweb/jac/aspects/user/user.acc" };
903     }
904
905     /**
906      * Display the profiles.
907      *
908      * <p>This method can be used as a menu callback by applications.
909      */

910     public static void viewProfiles(DisplayContext context, String JavaDoc 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