View Javadoc

1   /**
2    * 2007, Digitalis Informatica. All rights reserved. Distribuicao e Gestao de Informatica, Lda. Estrada de Paco de Arcos
3    * num.9 - Piso -1 2780-666 Paco de Arcos Telefone: (351) 21 4408990 Fax: (351) 21 4408999 http://www.digitalis.pt
4    */
5   package pt.digitalis.dif.controller.security.objects;
6   
7   import java.util.ArrayList;
8   import java.util.HashMap;
9   import java.util.List;
10  import java.util.Map;
11  import java.util.Set;
12  
13  import pt.digitalis.dif.controller.security.managers.IAuthorizationManager;
14  import pt.digitalis.dif.controller.security.managers.IIdentityManager;
15  import pt.digitalis.dif.controller.security.managers.IIdentityManagerPrivate;
16  import pt.digitalis.dif.dem.Entity;
17  import pt.digitalis.dif.dem.interfaces.IStage;
18  import pt.digitalis.dif.exception.InternalFrameworkException;
19  import pt.digitalis.dif.exception.security.AuthorizationManagerException;
20  import pt.digitalis.dif.exception.security.IdentityManagerException;
21  import pt.digitalis.dif.ioc.DIFIoCRegistry;
22  import pt.digitalis.dif.utils.ObjectFormatter;
23  import pt.digitalis.utils.common.collections.CaseInsensitiveHashMap;
24  
25  /**
26   * Default implementation VALIDATE: Check the Cloneable usage good/bad practice!
27   * 
28   * @author Rodrigo Gon�alves <a href="mailto:rgoncalves@digitalis.pt">rgoncalves@digitalis.pt</a>
29   * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a>
30   * @created Dec 3, 2007
31   */
32  public class DIFUserImpl implements IDIFClonableUser, Cloneable {
33  
34      /** The authorization manager implementation */
35      static private IAuthorizationManager authorizationManager = DIFIoCRegistry.getRegistry().getImplementation(
36              IAuthorizationManager.class);
37  
38      /** The identity manager implementation */
39      static private IIdentityManager identityManager = DIFIoCRegistry.getRegistry().getImplementation(
40              IIdentityManager.class);
41  
42      /** User attributes. */
43      private CaseInsensitiveHashMap<Object> attributes = new CaseInsensitiveHashMap<Object>();
44  
45      /** User attributes to remove. */
46      private List<String> attributesToRemove = new ArrayList<String>();
47  
48      /** The email of the user */
49      private String email;
50  
51      /** If the user is enabled */
52      private boolean enabled;
53  
54      /** Local cache for user groups */
55      private Map<String, IDIFGroup> groupsCache = null;
56  
57      /** The unique id for the user */
58      private String id;
59  
60      /** Is "default user"? */
61      private boolean isDefault;
62  
63      /** The full name for the user */
64      private String name;
65  
66      /** The nick for the user */
67      private String nick;
68  
69      /** The password of the user */
70      private String password;
71  
72      /** the user profile group identifier */
73      private String profileID;
74  
75      /** Temporary groups to include into the final user groups. This groups must have the session life expectancy */
76      private final Map<String, IDIFGroup> temporaryGroups = new HashMap<String, IDIFGroup>();
77  
78      /**
79       * Default constructor
80       */
81      public DIFUserImpl()
82      {
83          this.cleanCache();
84      }
85  
86      /**
87       * Constructor from a IDIFUser object
88       * 
89       * @param user
90       *            the IDIFUser to use as a base for the new user to create
91       * @param password
92       *            the password to set
93       * @throws IdentityManagerException
94       *             if the profile can't be accessed
95       */
96      public DIFUserImpl(IDIFUser user, String password) throws IdentityManagerException
97      {
98          setProps(user);
99  
100         this.password = password;
101         this.cleanCache();
102     }
103 
104     /**
105      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#addTempGroup(java.lang.String)
106      */
107     public void addTempGroup(String groupId)
108     {
109         try
110         {
111             IDIFGroup group = identityManager.getGroup(groupId);
112             if (group != null)
113             {
114                 temporaryGroups.put(group.getID(), group);
115             }
116         }
117         catch (IdentityManagerException e)
118         {
119             // Do nothing
120         }
121     }
122 
123     /**
124      * @see pt.digitalis.dif.controller.security.objects.IUserAuthorization#canAccess(pt.digitalis.dif.dem.Entity,
125      *      java.lang.String)
126      */
127     public boolean canAccess(Entity resourceType, String resourceId)
128     {
129         try
130         {
131             return authorizationManager.hasAccessUser(this, resourceType, resourceId)
132                     || authorizationManager.hasAccessPublic(resourceType, resourceId);
133         }
134         catch (AuthorizationManagerException authorizationManagerException)
135         {
136             return false;
137         }
138     }
139 
140     /**
141      * @see pt.digitalis.dif.controller.security.objects.IUserAuthorization#canAccess(pt.digitalis.dif.dem.interfaces.IStage)
142      */
143     public boolean canAccess(IStage stage)
144     {
145         if (stage == null)
146             return false;
147 
148         return this.canAccess(Entity.STAGE, stage.getID());
149     }
150 
151     /**
152      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#cleanCache()
153      */
154     public void cleanCache()
155     {
156         groupsCache = null;
157     }
158 
159     /**
160      * @see java.lang.Object#clone()
161      */
162     @Override
163     protected Object clone() throws CloneNotSupportedException
164     {
165         try
166         {
167             DIFUserImpl clone = new DIFUserImpl(this, this.password);
168 
169             return clone;
170         }
171         catch (IdentityManagerException identityManagerException)
172         {
173             throw new RuntimeException(
174                     "Could not clone object because the identity manager raised an excpetion an vital data could not be fetched!",
175                     identityManagerException);
176         }
177     }
178 
179     /**
180      * @see pt.digitalis.dif.controller.security.objects.IDIFClonableUser#cloneUser()
181      */
182     public IDIFClonableUser cloneUser()
183     {
184         try
185         {
186             return (IDIFClonableUser) this.clone();
187 
188         }
189         catch (CloneNotSupportedException e)
190         {
191             return null;
192         }
193     }
194 
195     /**
196      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#containsAttribute(java.lang.String)
197      */
198     public boolean containsAttribute(String id)
199     {
200         return attributes.containsKey(id);
201     }
202 
203     /**
204      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#containsParameter(java.lang.String)
205      */
206     public boolean containsParameter(String id)
207     {
208         return DIFIoCRegistry.getRegistry().getImplementation(IIdentityManager.class)
209                 .containsUserParameter(this.getID(), id);
210     }
211 
212     /**
213      * @see java.lang.Object#equals(java.lang.Object)
214      */
215     @Override
216     public boolean equals(Object obj)
217     {
218         if (this == obj)
219             return true;
220         if (obj == null)
221             return false;
222         if (getClass() != obj.getClass())
223             return false;
224         DIFUserImpl other = (DIFUserImpl) obj;
225         if (id == null)
226         {
227             if (other.id != null)
228                 return false;
229         }
230         else if (!id.equals(other.id))
231             return false;
232         return true;
233     }
234 
235     /**
236      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getAttribute(java.lang.String)
237      */
238     public Object getAttribute(String id)
239     {
240         return attributes.get(id);
241     }
242 
243     /**
244      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getAttributes()
245      */
246     public CaseInsensitiveHashMap<Object> getAttributes()
247     {
248         return attributes;
249     }
250 
251     /**
252      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getAttributesToRemove()
253      */
254     public List<String> getAttributesToRemove()
255     {
256         return attributesToRemove;
257     }
258 
259     /**
260      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getEmail()
261      */
262     public String getEmail()
263     {
264         return email;
265     }
266 
267     /**
268      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getGroupIDs()
269      */
270     public Set<String> getGroupIDs() throws IdentityManagerException
271     {
272         return getGroups().keySet();
273     }
274 
275     /**
276      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getGroups()
277      */
278     public Map<String, IDIFGroup> getGroups() throws IdentityManagerException
279     {
280         if (groupsCache == null)
281         {
282             groupsCache = identityManager.getUserGroups(id);
283             groupsCache.putAll(this.temporaryGroups);
284         }
285 
286         return groupsCache;
287     }
288 
289     /**
290      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getID()
291      */
292     public String getID()
293     {
294         return id;
295     }
296 
297     /**
298      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getName()
299      */
300     public String getName()
301     {
302         return name;
303     }
304 
305     /**
306      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getNick()
307      */
308     public String getNick()
309     {
310         return nick;
311     }
312 
313     /**
314      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getParameter(String)
315      */
316     public Object getParameter(String id)
317     {
318         return DIFIoCRegistry.getRegistry().getImplementation(IIdentityManager.class)
319                 .getUserParameter(this.getID(), id);
320     }
321 
322     /**
323      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getParameters()
324      */
325     public Map<String, Object> getParameters()
326     {
327         return DIFIoCRegistry.getRegistry().getImplementation(IIdentityManager.class).getUserParameters(this.getID());
328     }
329 
330     /**
331      * @return the user password
332      */
333     public String getPassword()
334     {
335         return password;
336     }
337 
338     /**
339      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getProfile()
340      */
341     public IDIFGroup getProfile() throws IdentityManagerException
342     {
343         if (profileID == null)
344             return null;
345 
346         return getGroups().get(profileID);
347     }
348 
349     /**
350      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#getProfileID()
351      */
352     public String getProfileID()
353     {
354         return this.profileID;
355     }
356 
357     /**
358      * @see java.lang.Object#hashCode()
359      */
360     @Override
361     public int hashCode()
362     {
363         final int prime = 31;
364         int result = 1;
365         result = prime * result + ((id == null) ? 0 : id.hashCode());
366         return result;
367     }
368 
369     /**
370      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#initializeAttributes(java.util.Map)
371      */
372     public void initializeAttributes(Map<String, Object> attrs)
373     {
374         attributes = new CaseInsensitiveHashMap<Object>();
375         attributes.putAll(attrs);
376     }
377 
378     /**
379      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#isDefault()
380      */
381     public boolean isDefault()
382     {
383         return this.isDefault;
384     }
385 
386     /**
387      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#isEnabled()
388      */
389     public boolean isEnabled()
390     {
391         return enabled;
392     }
393 
394     /**
395      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#refresh()
396      */
397     public void refresh()
398     {
399         IDIFUser updatedUser;
400         try
401         {
402             updatedUser = identityManager.getUser(id);
403             if (updatedUser != null)
404             {
405                 setProps(updatedUser);
406             }
407         }
408         catch (IdentityManagerException e)
409         {
410             // Nothing. Exception will be logged and refresh will only apply to cache vars...
411         }
412 
413         cleanCache();
414     }
415 
416     /**
417      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#removeAttribute(java.lang.String)
418      */
419     public void removeAttribute(String id)
420     {
421         attributes.remove(id);
422         attributesToRemove.add(id);
423     }
424 
425     /**
426      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#removeParameter(java.lang.String)
427      */
428     public void removeParameter(String id)
429     {
430         DIFIoCRegistry.getRegistry().getImplementation(IIdentityManager.class).removeUserParameter(this.getID(), id);
431     }
432 
433     /**
434      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#removeTempGroup(java.lang.String)
435      */
436     public void removeTempGroup(String groupId)
437     {
438         temporaryGroups.remove(groupId);
439     }
440 
441     /**
442      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#setAttribute(java.lang.String, java.lang.Object)
443      */
444     public void setAttribute(String id, Object attribute) throws InternalFrameworkException
445     {
446 
447         // Store old value
448         Object formerAttributeValue = this.attributes.get(id);
449 
450         try
451         {
452             // Set new attribute value on object
453             this.attributes.put(id, attribute);
454             // Set new attribute on Id Manager
455             ((IIdentityManagerPrivate) DIFIoCRegistry.getRegistry().getImplementation(IIdentityManager.class))
456                     .persistUserAttribute(this.getID(), id, attribute);
457         }
458         catch (IdentityManagerException identityManagerException)
459         {
460             // Roll back attribute value
461             this.attributes.put(id, formerAttributeValue);
462             // Issue warning
463             throw new InternalFrameworkException("Could not update the attribute value on the Identity Manager!",
464                     identityManagerException, null);
465         }
466     }
467 
468     /**
469      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#setAttributes(java.util.Map)
470      */
471     public void setAttributes(Map<String, Object> attributes) throws InternalFrameworkException
472     {
473         // Store old values
474         CaseInsensitiveHashMap<Object> formerAttributeValues = this.attributes;
475 
476         try
477         {
478             // Set new values on the object
479             this.attributes = new CaseInsensitiveHashMap<Object>();
480 
481             if (attributes != null)
482                 this.attributes.putAll(attributes);
483 
484             // Set values on Id Manager
485             ((IIdentityManagerPrivate) DIFIoCRegistry.getRegistry().getImplementation(IIdentityManager.class))
486                     .persistUserAttributes(this.getID(), attributes);
487         }
488         catch (IdentityManagerException identityManagerException)
489         {
490             // Roll back attribute values
491             this.attributes = formerAttributeValues;
492             // Issue warning
493             throw new InternalFrameworkException("Could not update the attribute values on the Identity Manager!",
494                     identityManagerException, null);
495         }
496     }
497 
498     /**
499      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#setDefault(boolean)
500      */
501     public void setDefault(boolean isDefault)
502     {
503         this.isDefault = isDefault;
504     }
505 
506     /**
507      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#setEmail(java.lang.String)
508      */
509     public void setEmail(String email)
510     {
511         this.email = email;
512     }
513 
514     /**
515      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#setEnabled(boolean)
516      */
517     public void setEnabled(boolean enabled)
518     {
519         this.enabled = enabled;
520     }
521 
522     /**
523      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#setID(java.lang.String)
524      */
525     public void setID(String id)
526     {
527         this.id = id;
528     }
529 
530     /**
531      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#setName(java.lang.String)
532      */
533     public void setName(String name)
534     {
535         this.name = name;
536     }
537 
538     /**
539      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#setNick(java.lang.String)
540      */
541     public void setNick(String nick)
542     {
543         this.nick = nick;
544     }
545 
546     /**
547      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#setParameter(java.lang.String, java.lang.Object)
548      */
549     public void setParameter(String id, Object parameter)
550     {
551         DIFIoCRegistry.getRegistry().getImplementation(IIdentityManager.class)
552                 .setUserParameter(this.getID(), id, parameter);
553     }
554 
555     /**
556      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#setParameters(java.util.Map)
557      */
558     public void setParameters(Map<String, Object> parameters)
559     {
560         DIFIoCRegistry.getRegistry().getImplementation(IIdentityManager.class)
561                 .setUserParameters(this.getID(), parameters);
562     }
563 
564     /**
565      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#setPassword(java.lang.String)
566      */
567     public void setPassword(String password)
568     {
569         this.password = password;
570     }
571 
572     /**
573      * @see pt.digitalis.dif.controller.security.objects.IDIFUser#setProfileID(java.lang.String)
574      */
575     public void setProfileID(String profileGroupID)
576     {
577         this.profileID = profileGroupID;
578 
579         cleanCache();
580     }
581 
582     /**
583      * Sets the internal user properties with the given user ones
584      * 
585      * @param user
586      *            the user to get the updated properties from
587      * @throws IdentityManagerException
588      */
589     private void setProps(IDIFUser user) throws IdentityManagerException
590     {
591 
592         this.id = user.getID();
593         this.nick = user.getNick();
594         this.name = user.getName();
595         this.email = user.getEmail();
596         this.enabled = user.isEnabled();
597         this.attributes = user.getAttributes();
598         this.profileID = user.getProfileID();
599     }
600 
601     /**
602      * @see java.lang.Object#toString()
603      */
604     @Override
605     public String toString()
606     {
607         ObjectFormatter formatter = new ObjectFormatter();
608 
609         formatter.addItem("ID", getID());
610         formatter.addItemIfNotNull("Name", getName());
611         formatter.addItemIfNotNull("Password", getPassword());
612         formatter.addItemIfNotNull("Nick", getNick());
613         formatter.addItemIfNotNull("Email", getEmail());
614         formatter.addItem("Enabled", isEnabled());
615         formatter.addItemIfNotNull("Attributes", attributes);
616         formatter.addItemIfNotNull("Parameters", this.getParameters());
617 
618         try
619         {
620             IDIFGroup profile = getProfile();
621             formatter.addItemIfNotNull("Profile", profile);
622         }
623         catch (IdentityManagerException identityManagerException)
624         {
625             throw new RuntimeException("Could not access the user's profile on the identity manager!",
626                     identityManagerException);
627         }
628 
629         try
630         {
631             Map<String, IDIFGroup> groups = getGroups();
632             formatter.addItemIfNotNull("Groups", groups);
633         }
634         catch (IdentityManagerException identityManagerException)
635         {
636             throw new RuntimeException("Could not access the user's groups on the identity manager!",
637                     identityManagerException);
638         }
639 
640         return formatter.getFormatedObject();
641     }
642 }