View Javadoc

1   /*
2    *   @(#) $Id: RelatedUserClassFilter.java 326050 2005-10-18 08:19:14Z akarasulu $
3    *   
4    *   Copyright 2004 The Apache Software Foundation
5    *
6    *   Licensed under the Apache License, Version 2.0 (the "License");
7    *   you may not use this file except in compliance with the License.
8    *   You may obtain a copy of the License at
9    *
10   *       http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing, software
13   *   distributed under the License is distributed on an "AS IS" BASIS,
14   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *   See the License for the specific language governing permissions and
16   *   limitations under the License.
17   *
18   */
19  package org.apache.ldap.server.authz.support;
20  
21  import java.util.Collection;
22  import java.util.Iterator;
23  
24  import javax.naming.Name;
25  import javax.naming.NamingException;
26  import javax.naming.directory.Attributes;
27  
28  import org.apache.ldap.common.aci.ACITuple;
29  import org.apache.ldap.common.aci.AuthenticationLevel;
30  import org.apache.ldap.common.aci.UserClass;
31  import org.apache.ldap.common.name.LdapName;
32  import org.apache.ldap.common.subtree.SubtreeSpecification;
33  import org.apache.ldap.server.subtree.SubtreeEvaluator;
34  import org.apache.ldap.server.partition.DirectoryPartitionNexusProxy;
35  
36  
37  /***
38   * An {@link ACITupleFilter} that discards all tuples whose {@link UserClass}es
39   * are not related with the current user. (18.8.3.1, X.501)
40   *
41   * @author The Apache Directory Project
42   * @version $Rev: 326050 $, $Date: 2005-10-18 04:19:14 -0400 (Tue, 18 Oct 2005) $
43   */
44  public class RelatedUserClassFilter implements ACITupleFilter
45  {
46      private static final LdapName ROOTDSE_NAME = new LdapName();
47  
48      private final SubtreeEvaluator subtreeEvaluator;
49  
50      public RelatedUserClassFilter( SubtreeEvaluator subtreeEvaluator )
51      {
52          this.subtreeEvaluator = subtreeEvaluator;
53      }
54  
55      public Collection filter( Collection tuples, OperationScope scope, DirectoryPartitionNexusProxy proxy, Collection userGroupNames, Name userName, Attributes userEntry, AuthenticationLevel authenticationLevel, Name entryName, String attrId, Object attrValue, Attributes entry, Collection microOperations ) throws NamingException
56      {
57          if( tuples.size() == 0 )
58          {
59              return tuples;
60          }
61  
62          for( Iterator i = tuples.iterator(); i.hasNext(); )
63          {
64              ACITuple tuple = ( ACITuple ) i.next();
65              if( tuple.isGrant() )
66              {
67                  if( !isRelated( userGroupNames, userName, userEntry, entryName, tuple.getUserClasses() ) ||
68                          authenticationLevel.compareTo( tuple.getAuthenticationLevel() ) < 0 )
69                  {
70                      i.remove();
71                  }
72              }
73              else // Denials
74              {
75                  if( !isRelated( userGroupNames, userName, userEntry, entryName, tuple.getUserClasses() ) &&
76                          authenticationLevel.compareTo( tuple.getAuthenticationLevel() ) >= 0 )
77                  {
78                      i.remove();
79                  }
80              }
81          }
82  
83          return tuples;
84      }
85  
86      private boolean isRelated( Collection userGroupNames, Name userName, Attributes userEntry, Name entryName, Collection userClasses ) throws NamingException
87      {
88          for( Iterator i = userClasses.iterator(); i.hasNext(); )
89          {
90              UserClass userClass = ( UserClass ) i.next();
91              if( userClass == UserClass.ALL_USERS )
92              {
93                  return true;
94              }
95              else if( userClass == UserClass.THIS_ENTRY )
96              {
97                  if( userName.equals( entryName ) )
98                  {
99                      return true;
100                 }
101             }
102             else if( userClass instanceof UserClass.Name )
103             {
104                 UserClass.Name nameUserClass = ( UserClass.Name ) userClass;
105                 if( nameUserClass.getNames().contains( userName ) )
106                 {
107                     return true;
108                 }
109             }
110             else if( userClass instanceof UserClass.UserGroup )
111             {
112                 UserClass.UserGroup userGroupUserClass = ( UserClass.UserGroup ) userClass;
113                 for( Iterator j = userGroupNames.iterator(); j.hasNext(); )
114                 {
115                     Name userGroupName = ( Name ) j.next();
116                     if( userGroupName != null && userGroupUserClass.getNames().contains( userGroupName ) )
117                     {
118                         return true;
119                     }
120                 }
121             }
122             else if( userClass instanceof UserClass.Subtree )
123             {
124                 UserClass.Subtree subtree = ( UserClass.Subtree ) userClass;
125                 if( matchUserClassSubtree( userName, userEntry, subtree ) )
126                 {
127                     return true;
128                 }
129             }
130             else
131             {
132                 throw new InternalError( "Unexpected userClass: " + userClass.getClass().getName() );
133             }
134         }
135 
136         return false;
137     }
138 
139     private boolean matchUserClassSubtree( Name userName, Attributes userEntry, UserClass.Subtree subtree ) throws NamingException
140     {
141         for( Iterator i = subtree.getSubtreeSpecifications().iterator();
142              i.hasNext(); )
143         {
144             SubtreeSpecification subtreeSpec = ( SubtreeSpecification ) i.next();
145             if( subtreeEvaluator.evaluate(
146                     subtreeSpec, ROOTDSE_NAME, userName, userEntry.get( "userClass" ) ) )
147             {
148                 return true;
149             }
150         }
151 
152         return false;
153     }
154 }