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   
6   package pt.digitalis.dif.controller.security.managers.impl;
7   
8   import java.util.ArrayList;
9   import java.util.Collection;
10  import java.util.HashMap;
11  import java.util.HashSet;
12  import java.util.Iterator;
13  import java.util.List;
14  import java.util.Map;
15  import java.util.Set;
16  
17  import pt.digitalis.dif.controller.security.managers.IAuthorizationManager;
18  import pt.digitalis.dif.controller.security.managers.IIdentityManager;
19  import pt.digitalis.dif.controller.security.objects.ACLEntry;
20  import pt.digitalis.dif.controller.security.objects.IDIFGroup;
21  import pt.digitalis.dif.controller.security.objects.IDIFUser;
22  import pt.digitalis.dif.dem.Entity;
23  import pt.digitalis.dif.dem.interfaces.IApplication;
24  import pt.digitalis.dif.dem.interfaces.IService;
25  import pt.digitalis.dif.dem.interfaces.IStage;
26  import pt.digitalis.dif.dem.managers.IDEMManager;
27  import pt.digitalis.dif.exception.security.AuthorizationManagerException;
28  import pt.digitalis.dif.exception.security.IdentityManagerException;
29  import pt.digitalis.dif.utils.ObjectFormatter;
30  
31  import com.google.inject.Inject;
32  
33  /**
34   * Provides an abstract implementation for the authorization manager.
35   * 
36   * @author Rodrigo Gonçalves <a href="mailto:rgoncalves@digitalis.pt">rgoncalves@digitalis.pt</a><br/>
37   * @created 2008/03/17
38   */
39  abstract public class AbstractAuthorizationManagerImpl implements IAuthorizationManager {
40  
41      /** The DEM manager */
42      protected IDEMManager demManager;
43  
44      /** T/** Maps the id of an group (K) to a set of ACL entries (V) granted to that group. */
45      private Map<String, Set<ACLEntry>> groupAccessControlList = new HashMap<String, Set<ACLEntry>>();
46  
47      /** The identity manager */
48      protected IIdentityManager identityManager;
49  
50      /** Maps the id of an entity (K) to an ACL entry (V). */
51      private Map<String, ACLEntry> publicAccessControlList = new HashMap<String, ACLEntry>();
52  
53      /** Maps the id of an user (K) to a set of ACL entries (V) granted to that user. */
54      private Map<String, Set<ACLEntry>> userAccessControlList = new HashMap<String, Set<ACLEntry>>();
55  
56      /**
57       * Default constructor
58       * 
59       * @param identityManager
60       *            the identity manager
61       * @param demManager
62       *            the DEM manager
63       */
64      @Inject
65      public AbstractAuthorizationManagerImpl(IIdentityManager identityManager, IDEMManager demManager)
66      {
67          this.identityManager = identityManager;
68          this.demManager = demManager;
69      }
70  
71      /**
72       * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#addACLEntry(pt.digitalis.dif.controller.security.objects.ACLEntry)
73       */
74      public boolean addACLEntry(ACLEntry entry) throws AuthorizationManagerException
75      {
76  
77          if (entry.isUserACL())
78              return addACLEntryToUser(entry);
79          else if (entry.isGroupACL())
80              return addACLEntryToGroup(entry);
81          else if (entry.isPublicAccess())
82              return addACLEntryToPublic(entry);
83          else
84              return false;
85      }
86  
87      /**
88       * Adds a new entry to the group ACL.
89       * 
90       * @param entry
91       *            the entry to add
92       * @return T if the operation succeeded, F otherwise
93       * @throws AuthorizationManagerException
94       *             if a resource needed for checking authorization credentials can't be accessed
95       */
96      protected boolean addACLEntryToGroup(ACLEntry entry) throws AuthorizationManagerException
97      {
98          // Group exists
99          if (getGroupAccessControlList().containsKey(entry.getGroupID()))
100         {
101             return getGroupAccessControlList().get(entry.getGroupID()).add(entry);
102         }
103         else
104         {
105             // Create entry for the group
106             getGroupAccessControlList().put(entry.getGroupID(), new HashSet<ACLEntry>());
107             // Add the ACL
108             return getGroupAccessControlList().get(entry.getGroupID()).add(entry);
109         }
110     }
111 
112     /**
113      * Adds a new entry to the group ACL.
114      * 
115      * @param entry
116      *            the entry to add
117      * @return T if the operation succeeded, F otherwise
118      * @throws AuthorizationManagerException
119      *             if a resource needed for checking authorization credentials can't be accessed
120      */
121     protected boolean addACLEntryToPublic(ACLEntry entry) throws AuthorizationManagerException
122     {
123         getPublicAccessControlList().put(entry.getEntityID(), entry);
124         return true;
125     }
126 
127     /**
128      * Adds a new entry to the user ACL.
129      * 
130      * @param entry
131      *            the entry to add
132      * @return T if the operation succeeded, F otherwise
133      * @throws AuthorizationManagerException
134      *             if a resource needed for checking authorization credentials can't be accessed
135      */
136     protected boolean addACLEntryToUser(ACLEntry entry) throws AuthorizationManagerException
137     {
138         try
139         {
140             // Validate the user and check for it's presence in the repository
141             if (!getUserAccessControlList().containsKey(entry.getUserID()))
142             {
143                 if (identityManager.userExists(entry.getUserID()))
144                 {
145 
146                     // Create the user entry in the ACL repository
147                     getUserAccessControlList().put(entry.getUserID(), new HashSet<ACLEntry>());
148                     getUserAccessControlList().get(entry.getUserID()).add(entry);
149                     return true;
150                 }
151                 else
152                     // Invalid user
153                     return false;
154             }
155             else
156             {
157                 if (checkAccessUser(identityManager.getUser(entry.getUserID()), entry.getEntityType(),
158                         entry.getEntityID()))
159                     // Already has access
160                     return true;
161                 else
162                 {
163                     return getUserAccessControlList().get(entry.getUserID()).add(entry);
164                 }
165             }
166         }
167         catch (IdentityManagerException identityManagerException)
168         {
169             throw new AuthorizationManagerException("Could not access the identity manager to verify user existance!",
170                     identityManagerException);
171         }
172     }
173 
174     /**
175      * Check for access grants
176      * 
177      * @param group
178      *            the group to check
179      * @param entityType
180      *            the entity type
181      * @param entityID
182      *            the entity ID
183      * @return T if the user can access the stage, F otherwise
184      * @throws AuthorizationManagerException
185      *             if a resource needed for checking authorization credentials can't be accessed
186      */
187     protected boolean checkAccessToGroup(IDIFGroup group, Entity entityType, String entityID)
188             throws AuthorizationManagerException
189     {
190 
191         boolean hasAccess = false;
192         try
193         {
194             // Check if it's the entity has public access
195             hasAccess = hasAccessPublic(entityType, entityID);
196 
197             if (!hasAccess)
198             {
199                 if (group == null)
200                     return false;
201 
202                 else
203                 {
204 
205                     // Check direct access grant
206                     hasAccess = checkGroupDirectAccess(group, entityType, entityID);
207                     // If group hasn't direct access, check ancestors
208                     if (!hasAccess)
209                     {
210 
211                         // Get first-level ancestor (parent)
212                         IDIFGroup ancestor = group.getParentGroup();
213 
214                         // If there are ancestors... (prevent ciclic ancestors)
215                         if (ancestor != null && (!ancestor.getID().equalsIgnoreCase(group.getID())))
216                         {
217                             /*
218                              * Check each one for access (grandparents and great-grandparents and the like are checked
219                              * in this loop since the execution flow will pass here and pick the parents of each group
220                              */
221                             while (!hasAccess && ancestor != null)
222                             {
223                                 if (hasAccessGroup(ancestor, entityType, entityID))
224                                     hasAccess = true;
225                                 else
226                                     ancestor = ancestor.getParentGroup();
227                             }
228                         }
229                     }
230                 }
231             }
232         }
233         catch (IdentityManagerException identityManagerException)
234         {
235             throw new AuthorizationManagerException("Could not access identity manager to check if group with ID "
236                     + group.getID() + " exists!", identityManagerException);
237         }
238 
239         return hasAccess;
240     }
241 
242     /**
243      * Check for access grants
244      * 
245      * @param user
246      *            the user to check
247      * @param entityType
248      *            the entity type
249      * @param entityID
250      *            the entity ID
251      * @return T if the user can access the stage, F otherwise
252      * @throws AuthorizationManagerException
253      *             if a resource needed for checking authorization credentials can't be accessed
254      */
255     protected boolean checkAccessUser(IDIFUser user, Entity entityType, String entityID)
256             throws AuthorizationManagerException
257     {
258 
259         boolean hasAccess = false;
260 
261         try
262         {
263             // Check public access for the entity
264             hasAccess = this.hasAccessPublic(entityType, entityID);
265 
266             if (!hasAccess)
267             {
268                 if (user == null)
269                     return false;
270 
271                 else
272                 {
273 
274                     // Check direct grant
275                     hasAccess = checkUserDirectAccess(user, entityType, entityID);
276 
277                     // If the user doesn't have direct access...
278                     if (!hasAccess)
279                     {
280                         // Check user profile access...
281                         if ((user.getProfileID() != null) && (hasAccessGroup(user.getProfile(), entityType, entityID)))
282                             hasAccess = true;
283 
284                         // If profile doesn't have access check access in all user groups...
285                         if (!hasAccess)
286                         {
287                             for (IDIFGroup group: user.getGroups().values())
288                                 if (hasAccessGroup(group, entityType, entityID))
289                                 {
290                                     hasAccess = true;
291                                     break;
292                                 }
293                         }
294                     }
295                 }
296             }
297         }
298         catch (IdentityManagerException identityManagerException)
299         {
300             throw new AuthorizationManagerException(
301                     "The identity manager can't be accessed to check user access privileges!", identityManagerException);
302         }
303 
304         return hasAccess;
305     }
306 
307     /**
308      * Check if a group has access granted to entity
309      * 
310      * @param group
311      *            the groupId
312      * @param entityType
313      *            the entity type
314      * @param entityID
315      *            the entity id
316      * @return validation
317      * @throws AuthorizationManagerException
318      *             If a AuthorizationManager exception Occurrs
319      */
320     /**
321      * Check if a group has access granted to entity
322      * 
323      * @param group
324      *            the groupId
325      * @param entityType
326      *            the entity type
327      * @param entityID
328      *            the entity id
329      * @return validation
330      * @throws AuthorizationManagerException
331      *             If a AuthorizationManager exception Occurrs
332      */
333     protected boolean checkGroupDirectAccess(IDIFGroup group, Entity entityType, String entityID)
334             throws AuthorizationManagerException
335     {
336         boolean hasAccess = false;
337         if (getGroupAccessControlList().containsKey(group.getID()))
338         {
339             Set<ACLEntry> groupEntries = getGroupAccessControlList().get(group.getID());
340 
341             for (ACLEntry entry: groupEntries)
342             {
343                 if (entry.getEntityType().equals(entityType) && entry.getEntityID().equals(entityID)
344                         && entry.isEnabled())
345                 {
346                     hasAccess = true;
347                     break;
348                 }
349             }
350         }
351         return hasAccess;
352     }
353 
354     /**
355      * Implementation if a non-hierarchical check for direct access grants
356      * 
357      * @param user
358      *            the user to check
359      * @param entityType
360      *            the entity type
361      * @param entityID
362      *            the entity ID
363      * @return T if the user can access the stage, F otherwise
364      * @throws AuthorizationManagerException
365      *             if a resource needed for checking authorization credentials can't be accessed
366      */
367     protected boolean checkUserDirectAccess(IDIFUser user, Entity entityType, String entityID)
368             throws AuthorizationManagerException
369     {
370 
371         boolean hasAccess = false;
372         if (getUserAccessControlList().containsKey(user.getID()))
373         {
374             for (ACLEntry entry: getUserAccessControlList().get(user.getID()))
375                 if (entityID.equals(entry.getEntityID()) && entityType == entry.getEntityType() && entry.isEnabled())
376                 {
377                     hasAccess = true;
378                     break;
379                 }
380         }
381         return hasAccess;
382     }
383 
384     /**
385      * Searches a given ACL for a given entity ID and returns the list of entries that match the given entity ID. Method
386      * overload for Map-based ACLs.
387      * 
388      * @param entityID
389      *            the entity ID to search for
390      * @param acl
391      *            the acl to search
392      * @return the list of acl entries
393      */
394     private List<ACLEntry> collectACLEntriesForEntityID(String entityID, Map<String, Set<ACLEntry>> acl)
395     {
396         List<ACLEntry> result = new ArrayList<ACLEntry>();
397 
398         for (String key: acl.keySet())
399         {
400             result.addAll(collectACLEntriesForEntityID(entityID, acl.get(key)));
401         }
402 
403         return result;
404     }
405 
406     /**
407      * Searches a given ACL for a given entity ID and returns the list of entries that match the given entity ID. Method
408      * overload for Set-based ACLs.
409      * 
410      * @param entityID
411      *            the entity ID to search for
412      * @param acl
413      *            the acl to search
414      * @return the list of acl entries
415      */
416     private List<ACLEntry> collectACLEntriesForEntityID(String entityID, Set<ACLEntry> acl)
417     {
418         List<ACLEntry> result = new ArrayList<ACLEntry>();
419 
420         ACLEntry entry = null;
421 
422         for (Iterator<ACLEntry> iterator = acl.iterator(); iterator.hasNext();)
423         {
424             entry = iterator.next();
425             if (entry.getEntityID().equals(entityID) && !result.contains(entry))
426                 result.add(entry);
427 
428         }
429 
430         return result;
431     }
432 
433     /**
434      * Returns a list with ACL entries that match a given entity ID.
435      * 
436      * @param entityID
437      *            the entity ID to search for
438      * @param acl
439      *            the acl to search
440      * @return the list of acl entries
441      */
442     private List<ACLEntry> collectACLEntriesForEntityIDSimpleMap(String entityID, Map<String, ACLEntry> acl)
443     {
444 
445         List<ACLEntry> result = new ArrayList<ACLEntry>();
446 
447         for (ACLEntry entry: acl.values())
448         {
449             if (entry.getEntityID() != null && entry.getEntityID().equals(entityID) && !result.contains(entry))
450                 result.add(entry);
451         }
452 
453         return result;
454     }
455 
456     /**
457      * Creates an ACL entry for a group.
458      * 
459      * @param groupID
460      *            the group ID
461      * @param entityID
462      *            the entity ID
463      * @param entityType
464      *            the entity type
465      * @return the group entry
466      */
467     protected ACLEntry createGroupACLEntry(String groupID, String entityID, Entity entityType)
468     {
469         ACLEntry entry = new ACLEntry();
470         entry.setEntityID(entityID);
471         entry.setEntityType(entityType);
472         entry.setGroupID(groupID);
473 
474         return entry;
475     }
476 
477     /**
478      * Creates a public ACL entry for a given entity.
479      * 
480      * @param entityID
481      *            the entity ID
482      * @param entityType
483      *            the entity type
484      * @return the group entry
485      */
486     protected ACLEntry createPublicACLEntry(String entityID, Entity entityType)
487     {
488         ACLEntry entry = new ACLEntry();
489         entry.setEntityID(entityID);
490         entry.setEntityType(entityType);
491         entry.setPublicAccess();
492 
493         return entry;
494     }
495 
496     /**
497      * Creates an ACL entry for a user.
498      * 
499      * @param userID
500      *            the user ID
501      * @param entityID
502      *            the entity ID
503      * @param entityType
504      *            the entity type
505      * @return the user entry
506      */
507     protected ACLEntry createUserACLEntry(String userID, String entityID, Entity entityType)
508     {
509         ACLEntry entry = new ACLEntry();
510         entry.setEntityID(entityID);
511         entry.setEntityType(entityType);
512         entry.setUserID(userID);
513 
514         return entry;
515     }
516 
517     /**
518      * Implementation for finding inherited ACL entries for a user
519      * 
520      * @param userID
521      * @param group
522      * @return a
523      * @throws IdentityManagerException
524      */
525     protected List<ACLEntry> doFindACLEntriesByUserInherited(String userID, IDIFGroup group)
526             throws IdentityManagerException
527     {
528         List<ACLEntry> result = new ArrayList<ACLEntry>();
529         if (group != null)
530         {
531             Collection<IDIFGroup> subGroups = this.identityManager.getGroupGroups(group.getID()).values();
532             for (IDIFGroup subGrp: subGroups)
533             {
534                 result.addAll(doFindACLEntriesByUserInherited(userID, subGrp));
535             }
536             result.addAll(findACLEntriesByGroup(group.getID()));
537         }
538 
539         return result;
540     }
541 
542     /**
543      * Implementation if a non-hierarchical check for access grants
544      * 
545      * @param entityType
546      *            the entity type
547      * @param entityID
548      *            the entity ID
549      * @return T if the user can access the stage, F otherwise
550      */
551     protected boolean doHasAccessPublic(Entity entityType, String entityID)
552     {
553 
554         if (getPublicAccessControlList().containsKey(entityID))
555         {
556             if (entityID.equals(getPublicAccessControlList().get(entityID).getEntityID())
557                     && entityType == getPublicAccessControlList().get(entityID).getEntityType()
558                     && getPublicAccessControlList().get(entityID).isEnabled())
559                 // Found it!
560                 return true;
561         }
562         // No access!
563         return false;
564     }
565 
566     /**
567      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#findACLEntriesByApplication(java.lang.String)
568      */
569     public List<ACLEntry> findACLEntriesByApplication(String applicationID)
570     {
571         return findACLEntryByEntity(applicationID);
572     }
573 
574     /**
575      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#findACLEntriesByGroup(java.lang.String)
576      */
577     public List<ACLEntry> findACLEntriesByGroup(String groupID)
578     {
579         Set<ACLEntry> results = getGroupAccessControlList().get(groupID);
580 
581         if (results != null)
582             return new ArrayList<ACLEntry>(results);
583         else
584             return new ArrayList<ACLEntry>();
585     }
586 
587     /**
588      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#findACLEntriesByProvider(java.lang.String)
589      */
590     public List<ACLEntry> findACLEntriesByProvider(String providerID)
591     {
592         return findACLEntryByEntity(providerID);
593     }
594 
595     /**
596      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#findACLEntriesByService(java.lang.String)
597      */
598     public List<ACLEntry> findACLEntriesByService(String serviceID)
599     {
600         return findACLEntryByEntity(serviceID);
601     }
602 
603     /**
604      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#findACLEntriesByStage(java.lang.String)
605      */
606     public List<ACLEntry> findACLEntriesByStage(String stageID)
607     {
608         return findACLEntryByEntity(stageID);
609     }
610 
611     /**
612      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#findACLEntriesByUser(java.lang.String)
613      */
614     public List<ACLEntry> findACLEntriesByUser(String userID)
615     {
616         List<ACLEntry> result = new ArrayList<ACLEntry>();
617 
618         if (getUserAccessControlList().containsKey(userID))
619             result.addAll(getUserAccessControlList().get(userID));
620 
621         return result;
622     }
623 
624     /**
625      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#findACLEntriesByUserInherited(java.lang.String)
626      */
627     public List<ACLEntry> findACLEntriesByUserInherited(String userID) throws AuthorizationManagerException
628     {
629         List<ACLEntry> result = new ArrayList<ACLEntry>();
630         // TODO fsouto check this exception
631         try
632         {
633             Map<String, IDIFGroup> userGroups = this.identityManager.getUserGroups(userID);
634             for (IDIFGroup grp: userGroups.values())
635                 result.addAll(this.doFindACLEntriesByUserInherited(userID, grp));
636 
637             // add all the remaining
638             result.addAll(this.findACLEntriesByUser(userID));
639         }
640         catch (IdentityManagerException e)
641         {
642             throw new AuthorizationManagerException(e);
643         }
644         return result;
645     }
646 
647     /**
648      * Helper method that finds all the ACL entries for a given entity. Searches on the three available ACLs.
649      * 
650      * @param entityID
651      *            the entity ID
652      * @return the list of entries for the given entity
653      */
654     private List<ACLEntry> findACLEntryByEntity(String entityID)
655     {
656         // User List
657         List<ACLEntry> result = collectACLEntriesForEntityID(entityID, getUserAccessControlList());
658 
659         // Group List
660         result.addAll(collectACLEntriesForEntityID(entityID, getGroupAccessControlList()));
661 
662         // Public List
663         result.addAll(collectACLEntriesForEntityIDSimpleMap(entityID, getPublicAccessControlList()));
664 
665         return result;
666     }
667 
668     /**
669      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#findPublicACLEntries()
670      */
671     public List<ACLEntry> findPublicACLEntries()
672     {
673         List<ACLEntry> result = new ArrayList<ACLEntry>();
674 
675         for (ACLEntry entry: getPublicAccessControlList().values())
676         {
677             result.add(entry);
678         }
679 
680         return result;
681     }
682 
683     /**
684      * Inspector for the 'groupAccessControlList' attribute.
685      * 
686      * @return the groupAccessControlList value
687      */
688     public Map<String, Set<ACLEntry>> getGroupAccessControlList()
689     {
690         return groupAccessControlList;
691     }
692 
693     /**
694      * Inspector for the 'publicAccessControlList' attribute.
695      * 
696      * @return the publicAccessControlList value
697      */
698     public Map<String, ACLEntry> getPublicAccessControlList()
699     {
700         return publicAccessControlList;
701     }
702 
703     /**
704      * Inspector for the 'userAccessControlList' attribute.
705      * 
706      * @return the userAccessControlList value
707      */
708     public Map<String, Set<ACLEntry>> getUserAccessControlList()
709     {
710         return userAccessControlList;
711     }
712 
713     /**
714      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#grantAccessToGroup(java.lang.String,
715      *      pt.digitalis.dif.dem.Entity, java.lang.String)
716      */
717     public boolean grantAccessToGroup(String groupID, Entity entityType, String entityID)
718             throws AuthorizationManagerException
719     {
720         return addACLEntryToGroup(createGroupACLEntry(groupID, entityID, entityType));
721     }
722 
723     /**
724      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#grantAccessToPublic(pt.digitalis.dif.dem.Entity,
725      *      java.lang.String)
726      */
727     public boolean grantAccessToPublic(Entity entityType, String entityID) throws AuthorizationManagerException
728     {
729         return addACLEntryToPublic(createPublicACLEntry(entityID, entityType));
730     }
731 
732     /**
733      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#grantAccessToUser(java.lang.String,
734      *      pt.digitalis.dif.dem.Entity, java.lang.String)
735      */
736     public boolean grantAccessToUser(String userID, Entity entityType, String entityID)
737             throws AuthorizationManagerException
738     {
739         return addACLEntryToUser(createUserACLEntry(userID, entityID, entityType));
740     }
741 
742     /**
743      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#grantDefaultAccessToGroup(java.lang.String,
744      *      pt.digitalis.dif.dem.Entity, java.lang.String)
745      */
746     public boolean grantDefaultAccessToGroup(String groupID, Entity entityType, String entityID)
747             throws AuthorizationManagerException
748     {
749         ACLEntry entry = createGroupACLEntry(groupID, entityID, entityType);
750         entry.setDefault(true);
751         return addACLEntryToGroup(entry);
752     }
753 
754     /**
755      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#grantDefaultAccessToUser(java.lang.String,
756      *      pt.digitalis.dif.dem.Entity, java.lang.String)
757      */
758     public boolean grantDefaultAccessToUser(String userID, Entity entityType, String entityID)
759             throws AuthorizationManagerException
760     {
761         ACLEntry entry = createUserACLEntry(userID, entityID, entityType);
762         entry.setDefault(true);
763         return addACLEntryToUser(entry);
764     }
765 
766     /**
767      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#grantDefaultPublicAccess(pt.digitalis.dif.dem.Entity,
768      *      java.lang.String)
769      */
770     public boolean grantDefaultPublicAccess(Entity entityType, String entityID) throws AuthorizationManagerException
771     {
772         if (hasAccessPublic(entityType, entityID))
773             // Already has access
774             return true;
775         else
776         {
777             // Grant access
778             ACLEntry entry = createPublicACLEntry(entityID, entityType);
779             entry.setDefault(true);
780             return addACLEntryToPublic(entry);
781         }
782     }
783 
784     /**
785      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#hasAccessGroup(pt.digitalis.dif.controller.security.objects.IDIFGroup,
786      *      pt.digitalis.dif.dem.Entity, java.lang.String)
787      */
788     public final boolean hasAccessGroup(IDIFGroup group, Entity entityType, String entityID)
789             throws AuthorizationManagerException
790     {
791         if (Entity.APPLICATION.equals(entityType))
792             return hasAccessGroup(group, demManager.getApplication(entityID));
793 
794         else if (Entity.SERVICE.equals(entityType))
795             return hasAccessGroup(group, demManager.getService(entityID));
796 
797         else if (Entity.STAGE.equals(entityType))
798             return hasAccessGroup(group, demManager.getStage(entityID));
799 
800         else
801             return false;
802     }
803 
804     /**
805      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#hasAccessGroup(pt.digitalis.dif.controller.security.objects.IDIFGroup,
806      *      pt.digitalis.dif.dem.interfaces.IApplication)
807      */
808     public boolean hasAccessGroup(IDIFGroup group, IApplication application) throws AuthorizationManagerException
809     {
810         if (application == null)
811             return false;
812 
813         return checkAccessToGroup(group, Entity.APPLICATION, application.getID());
814     }
815 
816     /**
817      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#hasAccessGroup(pt.digitalis.dif.controller.security.objects.IDIFGroup,
818      *      pt.digitalis.dif.dem.interfaces.IService)
819      */
820     public boolean hasAccessGroup(IDIFGroup group, IService service) throws AuthorizationManagerException
821     {
822         if (service == null)
823             return false;
824 
825         boolean hasPublicAccess = doHasAccessPublic(Entity.SERVICE, service.getID());
826 
827         return (!hasPublicAccess && checkAccessToGroup(group, Entity.SERVICE, service.getID()))
828                 || (hasPublicAccess && hasAccessGroup(group, service.getApplication()));
829     }
830 
831     /**
832      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#hasAccessGroup(pt.digitalis.dif.controller.security.objects.IDIFGroup,
833      *      pt.digitalis.dif.dem.interfaces.IStage)
834      */
835     public final boolean hasAccessGroup(IDIFGroup group, IStage stage) throws AuthorizationManagerException
836     {
837         if (stage == null)
838             return false;
839 
840         boolean hasPublicAccess = doHasAccessPublic(Entity.STAGE, stage.getID());
841 
842         return (!hasPublicAccess && checkAccessToGroup(group, Entity.STAGE, stage.getID()))
843                 || (hasPublicAccess && hasAccessGroup(group, stage.getService()));
844     }
845 
846     /**
847      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#hasAccessPublic(pt.digitalis.dif.dem.Entity,
848      *      java.lang.String)
849      */
850     public final boolean hasAccessPublic(Entity entityType, String entityID)
851     {
852         if (Entity.APPLICATION.equals(entityType))
853             return hasAccessPublic(demManager.getApplication(entityID));
854 
855         else if (Entity.SERVICE.equals(entityType))
856             return hasAccessPublic(demManager.getService(entityID));
857 
858         else if (Entity.STAGE.equals(entityType))
859             return hasAccessPublic(demManager.getStage(entityID));
860 
861         else
862             return false;
863     }
864 
865     /**
866      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#hasAccessPublic(pt.digitalis.dif.dem.interfaces.IApplication)
867      */
868     public boolean hasAccessPublic(IApplication application)
869     {
870         if (application == null)
871             return false;
872 
873         return doHasAccessPublic(Entity.APPLICATION, application.getID());
874     }
875 
876     /**
877      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#hasAccessPublic(pt.digitalis.dif.dem.interfaces.IService)
878      */
879     public boolean hasAccessPublic(IService service)
880     {
881         if (service == null)
882             return false;
883 
884         return doHasAccessPublic(Entity.SERVICE, service.getID())
885                 && doHasAccessPublic(Entity.APPLICATION, service.getApplication().getID());
886     }
887 
888     /**
889      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#hasAccessPublic(pt.digitalis.dif.dem.interfaces.IStage)
890      */
891     public final boolean hasAccessPublic(IStage stage)
892     {
893         if (stage == null)
894             return false;
895 
896         return doHasAccessPublic(Entity.STAGE, stage.getID())
897                 && doHasAccessPublic(Entity.SERVICE, stage.getService().getID())
898                 && doHasAccessPublic(Entity.APPLICATION, stage.getService().getApplication().getID());
899     }
900 
901     /**
902      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#hasAccessUser(pt.digitalis.dif.controller.security.objects.IDIFUser,
903      *      pt.digitalis.dif.dem.Entity, java.lang.String)
904      */
905     public final boolean hasAccessUser(IDIFUser user, Entity entityType, String entityID)
906             throws AuthorizationManagerException
907     {
908         if (Entity.APPLICATION.equals(entityType))
909             return hasAccessUser(user, demManager.getApplication(entityID));
910 
911         else if (Entity.SERVICE.equals(entityType))
912             return hasAccessUser(user, demManager.getService(entityID));
913 
914         else if (Entity.STAGE.equals(entityType))
915             return hasAccessUser(user, demManager.getStage(entityID));
916 
917         else
918             return false;
919     }
920 
921     /**
922      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#hasAccessUser(pt.digitalis.dif.controller.security.objects.IDIFUser,
923      *      pt.digitalis.dif.dem.interfaces.IApplication)
924      */
925     public boolean hasAccessUser(IDIFUser user, IApplication application) throws AuthorizationManagerException
926     {
927         if (application == null)
928             return false;
929 
930         return checkAccessUser(user, Entity.APPLICATION, application.getID());
931     }
932 
933     /**
934      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#hasAccessUser(pt.digitalis.dif.controller.security.objects.IDIFUser,
935      *      pt.digitalis.dif.dem.interfaces.IService)
936      */
937     public boolean hasAccessUser(IDIFUser user, IService service) throws AuthorizationManagerException
938     {
939         if (service == null)
940             return false;
941 
942         boolean hasPublicAccess = doHasAccessPublic(Entity.SERVICE, service.getID());
943 
944         return (!hasPublicAccess && checkAccessUser(user, Entity.SERVICE, service.getID()))
945                 || (hasPublicAccess && hasAccessUser(user, service.getApplication()));
946     }
947 
948     /**
949      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#hasAccessUser(pt.digitalis.dif.controller.security.objects.IDIFUser,
950      *      pt.digitalis.dif.dem.interfaces.IStage)
951      */
952     public final boolean hasAccessUser(IDIFUser user, IStage stage) throws AuthorizationManagerException
953     {
954         if (stage == null)
955             return false;
956 
957         boolean hasPublicAccess = doHasAccessPublic(Entity.STAGE, stage.getID());
958 
959         return (!hasPublicAccess && checkAccessUser(user, Entity.STAGE, stage.getID()))
960                 || (hasPublicAccess && hasAccessUser(user, stage.getService()));
961     }
962 
963     /**
964      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#revokeAccessFromGroup(java.lang.String,
965      *      pt.digitalis.dif.dem.Entity, java.lang.String)
966      */
967     public boolean revokeAccessFromGroup(String groupID, Entity entityType, String entityID)
968     {
969 
970         // Group exists
971         if (getGroupAccessControlList().containsKey(groupID))
972         {
973             ACLEntry entry = createGroupACLEntry(groupID, entityID, entityType);
974 
975             for (ACLEntry existentEntry: getGroupAccessControlList().get(groupID))
976                 /*
977                  * IMPLEMENTATION NOTE - see note on revokeAccessFromUser(String, Entity, String) method.
978                  */
979                 if ((existentEntry.getGroupID()).equals(entry.getGroupID())
980                         && existentEntry.getEntityType().equals(entry.getEntityType())
981                         && existentEntry.getEntityID().equals(entry.getEntityID()))
982                 {
983                     // If it's not default, remove it!
984                     if (!existentEntry.isDefault())
985                         return getGroupAccessControlList().get(groupID).remove(existentEntry);
986                     // If it's default, disable it
987                     else
988                     {
989                         // Get the ACL for user
990                         Set<ACLEntry> entries = getGroupAccessControlList().get(groupID);
991 
992                         // Search for the entry to disable
993                         for (ACLEntry entryToDisable: entries)
994                         {
995                             if (existentEntry.equals(entryToDisable))
996                             {
997                                 // Remove existing entry
998                                 getGroupAccessControlList().get(groupID).remove(existentEntry);
999                                 // Disable entry
1000                                 entryToDisable.setEnabled(false);
1001                                 // Add disabled entry
1002                                 return getGroupAccessControlList().get(groupID).add(entryToDisable);
1003                             }
1004                         }
1005                     }
1006                 }
1007 
1008             // Not found!
1009             return false;
1010         }
1011         else
1012         {
1013             return false;
1014         }
1015     }
1016 
1017     /**
1018      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#revokeAccessFromPublic(pt.digitalis.dif.dem.Entity,
1019      *      java.lang.String)
1020      */
1021     public boolean revokeAccessFromPublic(Entity entityType, String entityID)
1022     {
1023 
1024         if (getPublicAccessControlList().containsKey(entityID))
1025         {
1026 
1027             // Can't delete a "default" entry!!
1028             if (getPublicAccessControlList().get(entityID).getEntityID().equals(entityID)
1029                     && getPublicAccessControlList().get(entityID).getEntityType().equals(entityType))
1030             {
1031                 if (!getPublicAccessControlList().get(entityID).isDefault())
1032                     getPublicAccessControlList().remove(entityID);
1033                 else
1034                 {
1035                     // Disable existing entry
1036                     getPublicAccessControlList().get(entityID).setEnabled(false);
1037                 }
1038             }
1039             return true;
1040         }
1041 
1042         // Not found!
1043         return false;
1044     }
1045 
1046     /**
1047      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#revokeAccessFromUser(java.lang.String,
1048      *      pt.digitalis.dif.dem.Entity, java.lang.String)
1049      */
1050     public boolean revokeAccessFromUser(String userID, Entity entityType, String entityID)
1051     {
1052 
1053         // User exists
1054         if (getUserAccessControlList().containsKey(userID))
1055         {
1056             ACLEntry entry = createUserACLEntry(userID, entityID, entityType);
1057 
1058             for (ACLEntry existentEntry: getUserAccessControlList().get(userID))
1059 
1060                 if ((existentEntry.getUserID()).equals(entry.getUserID())
1061                         && existentEntry.getEntityType().equals(entry.getEntityType())
1062                         && existentEntry.getEntityID().equals(entry.getEntityID()))
1063                 {
1064                     // If it's not default, remove it!
1065                     if (getUserAccessControlList().get(userID).contains(existentEntry) && !existentEntry.isDefault())
1066                     {
1067                         boolean status = getUserAccessControlList().get(userID).remove(existentEntry);
1068 
1069                         // If there are no more entries associated to the user remove the user
1070                         if (getUserAccessControlList().get(userID).size() == 0)
1071                         {
1072                             getUserAccessControlList().remove(userID);
1073                             status = true;
1074 
1075                         }
1076 
1077                         return status;
1078                     }
1079                     // If it's default, disable it
1080                     else
1081                     {
1082                         // Get the ACL for user
1083                         Set<ACLEntry> entries = getUserAccessControlList().get(userID);
1084 
1085                         // Search for the entry to disable
1086                         for (ACLEntry entryToDisable: entries)
1087                         {
1088                             if (existentEntry.equals(entryToDisable))
1089                             {
1090                                 // Remove existing entry
1091                                 getUserAccessControlList().get(userID).remove(existentEntry);
1092                                 // Disable entry
1093                                 entryToDisable.setEnabled(false);
1094                                 // Add disabled entry
1095                                 return getUserAccessControlList().get(userID).add(entryToDisable);
1096                             }
1097                         }
1098                     }
1099                 }
1100 
1101             // Not found!
1102             return false;
1103         }
1104         else
1105         {
1106             return false;
1107         }
1108     }
1109 
1110     /**
1111      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#revokeACLEntry(pt.digitalis.dif.controller.security.objects.ACLEntry)
1112      */
1113     public boolean revokeACLEntry(ACLEntry entry)
1114     {
1115         if (entry.isUserACL())
1116             return revokeAccessFromUser(entry.getUserID(), entry.getEntityType(), entry.getEntityID());
1117         else if (entry.isGroupACL())
1118             return revokeAccessFromGroup(entry.getGroupID(), entry.getEntityType(), entry.getEntityID());
1119         else if (entry.isPublicAccess())
1120             return revokeAccessFromPublic(entry.getEntityType(), entry.getEntityID());
1121         else
1122             return false;
1123     }
1124 
1125     /**
1126      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#revokeAllAccessFromGroup(java.lang.String)
1127      */
1128     public boolean revokeAllAccessFromGroup(String groupID)
1129     {
1130         if (getGroupAccessControlList().containsKey(groupID))
1131         {
1132             getGroupAccessControlList().remove(groupID);
1133             return true;
1134         }
1135         else
1136             return false;
1137     }
1138 
1139     /**
1140      * @see pt.digitalis.dif.controller.security.managers.IAuthorizationManager#revokeAllAccessFromUser(java.lang.String)
1141      */
1142     public boolean revokeAllAccessFromUser(String userID)
1143     {
1144         if (getUserAccessControlList().containsKey(userID))
1145         {
1146             getUserAccessControlList().remove(userID);
1147             return true;
1148         }
1149         else
1150             return false;
1151     }
1152 
1153     /**
1154      * @see java.lang.Object#toString()
1155      */
1156     @Override
1157     public String toString()
1158     {
1159         ObjectFormatter formatter = new ObjectFormatter();
1160         formatter.addItem("User ACLs", userAccessControlList);
1161         formatter.addItem("Group ACLs", groupAccessControlList);
1162 
1163         return formatter.getFormatedObject();
1164     }
1165 
1166 }