View Javadoc

1   /* 
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.security.spi.impl;
18  
19  import java.security.Principal;
20  import java.util.Collection;
21  import java.util.HashSet;
22  import java.util.Iterator;
23  import java.util.Set;
24  import java.util.prefs.Preferences;
25  
26  import org.apache.jetspeed.security.HierarchyResolver;
27  import org.apache.jetspeed.security.SecurityException;
28  import org.apache.jetspeed.security.impl.GeneralizationHierarchyResolver;
29  import org.apache.jetspeed.security.impl.GroupPrincipalImpl;
30  import org.apache.jetspeed.security.impl.RolePrincipalImpl;
31  import org.apache.jetspeed.security.impl.UserPrincipalImpl;
32  import org.apache.jetspeed.security.om.InternalGroupPrincipal;
33  import org.apache.jetspeed.security.om.InternalRolePrincipal;
34  import org.apache.jetspeed.security.om.InternalUserPrincipal;
35  import org.apache.jetspeed.security.om.impl.InternalUserPrincipalImpl;
36  import org.apache.jetspeed.security.spi.SecurityAccess;
37  import org.apache.jetspeed.security.spi.SecurityMappingHandler;
38  
39  /***
40   * @see org.apache.jetspeed.security.spi.SecurityMappingHandler
41   * @author <a href="mailto:dlestrat@apache.org">David Le Strat </a>
42   */
43  public class DefaultSecurityMappingHandler implements SecurityMappingHandler
44  {
45  
46      /*** The role hierarchy resolver. */
47      HierarchyResolver roleHierarchyResolver = new GeneralizationHierarchyResolver();
48  
49      /*** The group hierarchy resolver. */
50      HierarchyResolver groupHierarchyResolver = new GeneralizationHierarchyResolver();
51  
52      /*** Common queries. */
53      private SecurityAccess commonQueries = null;
54  
55      /***
56       * <p>
57       * Constructor providing access to the common queries.
58       * </p>
59       */
60      public DefaultSecurityMappingHandler(SecurityAccess commonQueries)
61      {
62          this.commonQueries = commonQueries;
63      }
64  
65      /***
66       * <p>
67       * Constructor providing access to the common queries and hierarchy
68       * resolvers.
69       * </p>
70       */
71      public DefaultSecurityMappingHandler(SecurityAccess commonQueries, HierarchyResolver roleHierarchyResolver,
72              HierarchyResolver groupHierarchyResolver)
73      {
74          this.commonQueries = commonQueries;
75          if (null != roleHierarchyResolver)
76          {
77              this.roleHierarchyResolver = roleHierarchyResolver;
78          }
79          if (null != groupHierarchyResolver)
80          {
81              this.groupHierarchyResolver = groupHierarchyResolver;
82          }
83      }
84  
85      /***
86       * @return Returns the roleHierarchyResolver.
87       */
88      public HierarchyResolver getRoleHierarchyResolver()
89      {
90          return roleHierarchyResolver;
91      }
92  
93      /***
94       * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#setRoleHierarchyResolver(org.apache.jetspeed.security.HierarchyResolver)
95       */
96      public void setRoleHierarchyResolver(HierarchyResolver roleHierarchyResolver)
97      {
98          this.roleHierarchyResolver = roleHierarchyResolver;
99      }
100 
101     /***
102      * @return Returns the groupHierarchyResolver.
103      */
104     public HierarchyResolver getGroupHierarchyResolver()
105     {
106         return groupHierarchyResolver;
107     }
108 
109     /***
110      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#setGroupHierarchyResolver(org.apache.jetspeed.security.HierarchyResolver)
111      */
112     public void setGroupHierarchyResolver(HierarchyResolver groupHierarchyResolver)
113     {
114         this.groupHierarchyResolver = groupHierarchyResolver;
115     }
116 
117     /***
118      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#getRolePrincipals(java.lang.String)
119      */
120     public Set getRolePrincipals(String username)
121     {
122         Set rolePrincipals = new HashSet();
123         InternalUserPrincipal internalUser = commonQueries.getInternalUserPrincipal(username);
124         if (null != internalUser)
125         {
126             Collection internalRoles = internalUser.getRolePrincipals();
127             if (null != internalRoles)
128             {
129                 Iterator internalRolesIter = internalRoles.iterator();
130                 while (internalRolesIter.hasNext())
131                 {
132                     InternalRolePrincipal internalRole = (InternalRolePrincipal) internalRolesIter.next();
133                     Preferences preferences = Preferences.userRoot().node(internalRole.getFullPath());
134                     String[] fullPaths = roleHierarchyResolver.resolve(preferences);
135                     for (int i = 0; i < fullPaths.length; i++)
136                     {
137                         Principal rolePrincipal = new RolePrincipalImpl(RolePrincipalImpl
138                                 .getPrincipalNameFromFullPath(fullPaths[i]));
139                         if (!rolePrincipals.contains(rolePrincipal))
140                         {
141                             rolePrincipals.add(rolePrincipal);
142                         }
143                     }
144                 }
145             }
146         }
147         return rolePrincipals;
148     }
149 
150     /***
151      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#setUserPrincipalInRole(java.lang.String,
152      *      java.lang.String)
153      */
154     public void setUserPrincipalInRole(String username, String roleFullPathName) throws SecurityException
155     {
156         InternalUserPrincipal internalUser = commonQueries.getInternalUserPrincipal(username);
157         boolean isMappingOnly = false;
158         if (null == internalUser)
159         {
160             // This is a record for mapping only.
161             isMappingOnly = true;
162             internalUser = new InternalUserPrincipalImpl(UserPrincipalImpl.getFullPathFromPrincipalName(username));
163         }
164         Collection internalRoles = internalUser.getRolePrincipals();
165         // This should not be null. Check for null should be made by the caller.
166         InternalRolePrincipal internalRole = commonQueries.getInternalRolePrincipal(RolePrincipalImpl
167                 .getFullPathFromPrincipalName(roleFullPathName));
168         // Check anyway.
169         if (null == internalRole)
170         {
171             throw new SecurityException(SecurityException.ROLE_DOES_NOT_EXIST.create(roleFullPathName));
172         }
173         internalRoles.add(internalRole);
174         internalUser.setRolePrincipals(internalRoles);
175         commonQueries.setInternalUserPrincipal(internalUser, isMappingOnly);
176     }
177 
178     /***
179      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#removeUserPrincipalInRole(java.lang.String,
180      *      java.lang.String)
181      */
182     public void removeUserPrincipalInRole(String username, String roleFullPathName) throws SecurityException
183     {
184         boolean isMappingOnly = false;
185         // Check is the record is used for mapping only.
186         InternalUserPrincipal internalUser = commonQueries.getInternalUserPrincipal(username, false);
187         if (null == internalUser)
188         {
189             internalUser = commonQueries.getInternalUserPrincipal(username, true);
190             isMappingOnly = true;
191         }
192         if (null != internalUser)
193         {
194             Collection internalRoles = internalUser.getRolePrincipals();
195             // This should not be null. Check for null should be made by the caller.
196             InternalRolePrincipal internalRole = commonQueries.getInternalRolePrincipal(RolePrincipalImpl
197                     .getFullPathFromPrincipalName(roleFullPathName));
198             // Check anyway.
199             if (null == internalRole)
200             {
201                 throw new SecurityException(SecurityException.ROLE_DOES_NOT_EXIST.create(roleFullPathName));
202             }
203             internalRoles.remove(internalRole);
204             // Remove dead mapping records. I.e. No mapping is associated with the specific record.
205             if (isMappingOnly && internalRoles.isEmpty() && internalUser.getGroupPrincipals().isEmpty()
206                     && internalUser.getPermissions().isEmpty())
207             {
208                 commonQueries.removeInternalUserPrincipal(internalUser);
209             }
210             else
211             {
212                 internalUser.setRolePrincipals(internalRoles);
213                 commonQueries.setInternalUserPrincipal(internalUser, isMappingOnly);
214             }
215         }
216         else
217         {
218             throw new SecurityException(SecurityException.USER_DOES_NOT_EXIST.create(username));
219         }
220     }
221 
222     /***
223      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#getRolePrincipalsInGroup(java.lang.String)
224      */
225     public Set getRolePrincipalsInGroup(String groupFullPathName)
226     {
227         Set rolePrincipals = new HashSet();
228 
229         Preferences preferences = Preferences.userRoot().node(
230                 GroupPrincipalImpl.getFullPathFromPrincipalName(groupFullPathName));
231         String[] fullPaths = groupHierarchyResolver.resolve(preferences);
232         for (int i = 0; i < fullPaths.length; i++)
233         {
234             InternalGroupPrincipal internalGroup = commonQueries.getInternalGroupPrincipal(fullPaths[i]);
235             if (null != internalGroup)
236             {
237                 Collection internalRoles = internalGroup.getRolePrincipals();
238                 if (null != internalRoles)
239                 {
240                     Iterator internalRolesIter = internalRoles.iterator();
241                     while (internalRolesIter.hasNext())
242                     {
243                         InternalRolePrincipal internalRole = (InternalRolePrincipal) internalRolesIter.next();
244                         Principal rolePrincipal = new RolePrincipalImpl(UserPrincipalImpl
245                                 .getPrincipalNameFromFullPath(internalRole.getFullPath()));
246                         if (!rolePrincipals.contains(rolePrincipal))
247                         {
248                             rolePrincipals.add(rolePrincipal);
249                         }
250                     }
251                 }
252             }
253         }
254         return rolePrincipals;
255     }
256 
257     /***
258      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#setRolePrincipalInGroup(java.lang.String,
259      *      java.lang.String)
260      */
261     public void setRolePrincipalInGroup(String groupFullPathName, String roleFullPathName) throws SecurityException
262     {
263         InternalGroupPrincipal internalGroup = commonQueries.getInternalGroupPrincipal(GroupPrincipalImpl
264                 .getFullPathFromPrincipalName(groupFullPathName));
265         if (null == internalGroup)
266         {
267             throw new SecurityException(SecurityException.GROUP_DOES_NOT_EXIST.create(groupFullPathName));
268         }
269         Collection internalRoles = internalGroup.getRolePrincipals();
270         InternalRolePrincipal internalRole = commonQueries.getInternalRolePrincipal(RolePrincipalImpl
271                 .getFullPathFromPrincipalName(roleFullPathName));
272         internalRoles.add(internalRole);
273         internalGroup.setRolePrincipals(internalRoles);
274         commonQueries.setInternalGroupPrincipal(internalGroup, false);
275     }
276 
277     /***
278      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#removeRolePrincipalInGroup(java.lang.String,
279      *      java.lang.String)
280      */
281     public void removeRolePrincipalInGroup(String groupFullPathName, String roleFullPathName) throws SecurityException
282     {
283         InternalGroupPrincipal internalGroup = commonQueries.getInternalGroupPrincipal(GroupPrincipalImpl
284                 .getFullPathFromPrincipalName(groupFullPathName));
285         if (null == internalGroup)
286         {
287             throw new SecurityException(SecurityException.GROUP_DOES_NOT_EXIST.create(internalGroup));
288         }
289         Collection internalRoles = internalGroup.getRolePrincipals();
290         InternalRolePrincipal internalRole = commonQueries.getInternalRolePrincipal(RolePrincipalImpl
291                 .getFullPathFromPrincipalName(roleFullPathName));
292         internalRoles.remove(internalRole);
293         internalGroup.setRolePrincipals(internalRoles);
294         commonQueries.setInternalGroupPrincipal(internalGroup, false);
295     }
296 
297     /***
298      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#getGroupPrincipals(java.lang.String)
299      */
300     public Set getGroupPrincipals(String username)
301     {
302         Set groupPrincipals = new HashSet();
303         InternalUserPrincipal internalUser = commonQueries.getInternalUserPrincipal(username);
304         if (null != internalUser)
305         {
306             Collection internalGroups = internalUser.getGroupPrincipals();
307             if (null != internalGroups)
308             {
309                 Iterator internalGroupsIter = internalGroups.iterator();
310                 while (internalGroupsIter.hasNext())
311                 {
312                     InternalGroupPrincipal internalGroup = (InternalGroupPrincipal) internalGroupsIter.next();
313                     Preferences preferences = Preferences.userRoot().node(internalGroup.getFullPath());
314                     String[] fullPaths = groupHierarchyResolver.resolve(preferences);
315                     for (int i = 0; i < fullPaths.length; i++)
316                     {
317                         groupPrincipals.add(new GroupPrincipalImpl(GroupPrincipalImpl
318                                 .getPrincipalNameFromFullPath(fullPaths[i])));
319                     }
320                 }
321             }
322         }
323         return groupPrincipals;
324     }
325 
326     /***
327      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#getGroupPrincipalsInRole(java.lang.String)
328      */
329     public Set getGroupPrincipalsInRole(String roleFullPathName)
330     {
331         Set groupPrincipals = new HashSet();
332 
333         Preferences preferences = Preferences.userRoot().node(
334                 RolePrincipalImpl.getFullPathFromPrincipalName(roleFullPathName));
335         String[] fullPaths = roleHierarchyResolver.resolve(preferences);
336         for (int i = 0; i < fullPaths.length; i++)
337         {
338             InternalRolePrincipal internalRole = commonQueries.getInternalRolePrincipal(fullPaths[i]);
339             if (null != internalRole)
340             {
341                 Collection internalGroups = internalRole.getGroupPrincipals();
342                 if (null != internalGroups)
343                 {
344                     Iterator internalGroupsIter = internalGroups.iterator();
345                     while (internalGroupsIter.hasNext())
346                     {
347                         InternalGroupPrincipal internalGroup = (InternalGroupPrincipal) internalGroupsIter.next();
348                         Principal groupPrincipal = new GroupPrincipalImpl(GroupPrincipalImpl
349                                 .getPrincipalNameFromFullPath(internalGroup.getFullPath()));
350                         if (!groupPrincipals.contains(groupPrincipal))
351                         {
352                             groupPrincipals.add(groupPrincipal);
353                         }
354                     }
355                 }
356             }
357         }
358         return groupPrincipals;
359     }
360 
361     /***
362      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#getUserPrincipalsInRole(java.lang.String)
363      */
364     public Set getUserPrincipalsInRole(String roleFullPathName)
365     {
366         Set userPrincipals = new HashSet();
367 
368         Preferences preferences = Preferences.userRoot().node(
369                 RolePrincipalImpl.getFullPathFromPrincipalName(roleFullPathName));
370         String[] fullPaths = roleHierarchyResolver.resolve(preferences);
371         for (int i = 0; i < fullPaths.length; i++)
372         {
373             InternalRolePrincipal internalRole = commonQueries.getInternalRolePrincipal(fullPaths[i]);
374             if (null != internalRole)
375             {
376                 Collection internalUsers = internalRole.getUserPrincipals();
377                 if (null != internalUsers)
378                 {
379                     Iterator internalUsersIter = internalUsers.iterator();
380                     while (internalUsersIter.hasNext())
381                     {
382                         InternalUserPrincipal internalUser = (InternalUserPrincipal) internalUsersIter.next();
383                         Principal userPrincipal = new UserPrincipalImpl(UserPrincipalImpl
384                                 .getPrincipalNameFromFullPath(internalUser.getFullPath()));
385                         if (!userPrincipals.contains(userPrincipal))
386                         {
387                             userPrincipals.add(userPrincipal);
388                         }
389                     }
390                 }
391             }
392         }
393         return userPrincipals;
394     }
395 
396     /***
397      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#getUserPrincipalsInGroup(java.lang.String)
398      */
399     public Set getUserPrincipalsInGroup(String groupFullPathName)
400     {
401         Set userPrincipals = new HashSet();
402 
403         Preferences preferences = Preferences.userRoot().node(
404                 GroupPrincipalImpl.getFullPathFromPrincipalName(groupFullPathName));
405         String[] fullPaths = groupHierarchyResolver.resolve(preferences);
406         for (int i = 0; i < fullPaths.length; i++)
407         {
408             InternalGroupPrincipal internalGroup = commonQueries.getInternalGroupPrincipal(fullPaths[i]);
409             if (null != internalGroup)
410             {
411                 Collection internalUsers = internalGroup.getUserPrincipals();
412                 if (null != internalUsers)
413                 {
414                     Iterator internalUsersIter = internalUsers.iterator();
415                     while (internalUsersIter.hasNext())
416                     {
417                         InternalUserPrincipal internalUser = (InternalUserPrincipal) internalUsersIter.next();
418                         Principal userPrincipal = new UserPrincipalImpl(UserPrincipalImpl
419                                 .getPrincipalNameFromFullPath(internalUser.getFullPath()));
420                         if (!userPrincipals.contains(userPrincipal))
421                         {
422                             userPrincipals.add(userPrincipal);
423                         }
424                     }
425                 }
426             }
427         }
428         return userPrincipals;
429     }
430 
431     /***
432      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#setUserPrincipalInGroup(java.lang.String,
433      *      java.lang.String)
434      */
435     public void setUserPrincipalInGroup(String username, String groupFullPathName) throws SecurityException
436     {
437         InternalUserPrincipal internalUser = commonQueries.getInternalUserPrincipal(username);
438         boolean isMappingOnly = false;
439         if (null == internalUser)
440         {
441             // This is a record for mapping only.
442             isMappingOnly = true;
443             internalUser = new InternalUserPrincipalImpl(UserPrincipalImpl.getFullPathFromPrincipalName(username));
444         }
445         Collection internalGroups = internalUser.getGroupPrincipals();
446         // This should not be null. Check for null should be made by the caller.
447         InternalGroupPrincipal internalGroup = commonQueries.getInternalGroupPrincipal(GroupPrincipalImpl
448                 .getFullPathFromPrincipalName(groupFullPathName));
449         // Check anyway.
450         if (null == internalGroup)
451         {
452             throw new SecurityException(SecurityException.GROUP_DOES_NOT_EXIST.create(groupFullPathName));
453         }
454         internalGroups.add(internalGroup);
455         internalUser.setGroupPrincipals(internalGroups);
456         commonQueries.setInternalUserPrincipal(internalUser, isMappingOnly);
457     }
458 
459     /***
460      * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#removeUserPrincipalInGroup(java.lang.String,
461      *      java.lang.String)
462      */
463     public void removeUserPrincipalInGroup(String username, String groupFullPathName) throws SecurityException
464     {
465         boolean isMappingOnly = false;
466         // Check is the record is used for mapping only.
467         InternalUserPrincipal internalUser = commonQueries.getInternalUserPrincipal(username, false);
468         if (null == internalUser)
469         {
470             internalUser = commonQueries.getInternalUserPrincipal(username, true);
471             isMappingOnly = true;
472         }
473         if (null != internalUser)
474         {
475             Collection internalGroups = internalUser.getGroupPrincipals();
476             // This should not be null. Check for null should be made by the caller.
477             InternalGroupPrincipal internalGroup = commonQueries.getInternalGroupPrincipal(GroupPrincipalImpl
478                     .getFullPathFromPrincipalName(groupFullPathName));
479             // Check anyway.
480             if (null == internalGroup)
481             {
482                 throw new SecurityException(SecurityException.GROUP_DOES_NOT_EXIST.create(groupFullPathName));
483             }
484             internalGroups.remove(internalGroup);
485             // Remove dead mapping records. I.e. No mapping is associated with the specific record.
486             if (isMappingOnly && internalGroups.isEmpty() && internalUser.getRolePrincipals().isEmpty()
487                     && internalUser.getPermissions().isEmpty())
488             {
489                 commonQueries.removeInternalUserPrincipal(internalUser);
490             }
491             else
492             {
493             internalUser.setGroupPrincipals(internalGroups);
494             commonQueries.setInternalUserPrincipal(internalUser, isMappingOnly);
495             }
496         }
497         else
498         {
499             throw new SecurityException(SecurityException.USER_DOES_NOT_EXIST.create(username));
500         }
501     }
502     
503 }