View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  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,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.core.authz.support;
21  
22  
23  import java.util.Collection;
24  import java.util.Iterator;
25  
26  import org.apache.directory.api.ldap.aci.ACITuple;
27  import org.apache.directory.api.ldap.aci.ProtectedItem;
28  import org.apache.directory.api.ldap.aci.protectedItem.AllAttributeValuesItem;
29  import org.apache.directory.api.ldap.aci.protectedItem.AttributeTypeItem;
30  import org.apache.directory.api.ldap.aci.protectedItem.AttributeValueItem;
31  import org.apache.directory.api.ldap.aci.protectedItem.ClassesItem;
32  import org.apache.directory.api.ldap.aci.protectedItem.MaxImmSubItem;
33  import org.apache.directory.api.ldap.aci.protectedItem.MaxValueCountElem;
34  import org.apache.directory.api.ldap.aci.protectedItem.MaxValueCountItem;
35  import org.apache.directory.api.ldap.aci.protectedItem.RangeOfValuesItem;
36  import org.apache.directory.api.ldap.aci.protectedItem.RestrictedByElem;
37  import org.apache.directory.api.ldap.aci.protectedItem.RestrictedByItem;
38  import org.apache.directory.api.ldap.aci.protectedItem.SelfValueItem;
39  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
40  import org.apache.directory.api.ldap.model.entry.Attribute;
41  import org.apache.directory.api.ldap.model.entry.Entry;
42  import org.apache.directory.api.ldap.model.entry.Value;
43  import org.apache.directory.api.ldap.model.exception.LdapException;
44  import org.apache.directory.api.ldap.model.name.Dn;
45  import org.apache.directory.api.ldap.model.schema.AttributeType;
46  import org.apache.directory.api.ldap.model.schema.SchemaManager;
47  import org.apache.directory.server.core.api.event.Evaluator;
48  import org.apache.directory.server.core.api.subtree.RefinementEvaluator;
49  import org.apache.directory.server.i18n.I18n;
50  
51  
52  /**
53   * An {@link ACITupleFilter} that discards all tuples whose {@link ProtectedItem}s
54   * are not related with the operation. (18.8.3.2, X.501)
55   *
56   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
57   */
58  public class RelatedProtectedItemFilter implements ACITupleFilter
59  {
60      private final RefinementEvaluator refinementEvaluator;
61      private final Evaluator entryEvaluator;
62      private final SchemaManager schemaManager;
63  
64  
65      public RelatedProtectedItemFilter( RefinementEvaluator refinementEvaluator, Evaluator entryEvaluator,
66          SchemaManager schemaManager )
67      {
68          this.refinementEvaluator = refinementEvaluator;
69          this.entryEvaluator = entryEvaluator;
70          this.schemaManager = schemaManager;
71      }
72  
73  
74      /**
75       * {@inheritDoc}
76       */
77      @Override
78      public Collection<ACITuple> filter( AciContext aciContext, OperationScope scope, Entry userEntry )
79          throws LdapException
80      {
81          if ( aciContext.getAciTuples().isEmpty() )
82          {
83              return aciContext.getAciTuples();
84          }
85  
86          for ( Iterator<ACITuple> i = aciContext.getAciTuples().iterator(); i.hasNext(); )
87          {
88              ACITuple tuple = i.next();
89  
90              if ( !isRelated( tuple, scope, aciContext.getUserDn(), aciContext.getEntryDn(),
91                  aciContext.getAttributeType(), aciContext.getAttrValue(), aciContext.getEntry() ) )
92              {
93                  i.remove();
94              }
95          }
96  
97          return aciContext.getAciTuples();
98      }
99  
100 
101     private boolean isRelated( ACITuple tuple, OperationScope scope, Dn userName, Dn entryName,
102         AttributeType attributeType, Value attrValue, Entry entry ) throws LdapException, InternalError
103     {
104         String oid = null;
105 
106         if ( attributeType != null )
107         {
108             oid = attributeType.getOid();
109         }
110 
111         for ( ProtectedItem item : tuple.getProtectedItems() )
112         {
113             if ( item == ProtectedItem.ENTRY )
114             {
115                 if ( scope != OperationScope.ENTRY )
116                 {
117                     continue;
118                 }
119 
120                 return true;
121             }
122             else if ( ( item == ProtectedItem.ALL_USER_ATTRIBUTE_TYPES ) 
123                     || ( item == ProtectedItem.ALL_USER_ATTRIBUTE_TYPES_AND_VALUES ) )
124             {
125                 if ( scope != OperationScope.ATTRIBUTE_TYPE && scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE )
126                 {
127                     continue;
128                 }
129 
130                 return true;
131             }
132             else if ( item instanceof AllAttributeValuesItem )
133             {
134                 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE )
135                 {
136                     continue;
137                 }
138 
139                 AllAttributeValuesItem aav = ( AllAttributeValuesItem ) item;
140 
141                 for ( Iterator<AttributeType> iterator = aav.iterator(); iterator.hasNext(); )
142                 {
143                     AttributeType attr = iterator.next();
144 
145                     if ( oid.equals( attr.getOid() ) )
146                     {
147                         return true;
148                     }
149                 }
150             }
151             else if ( item instanceof AttributeTypeItem )
152             {
153                 if ( scope != OperationScope.ATTRIBUTE_TYPE )
154                 {
155                     continue;
156                 }
157 
158                 AttributeTypeItem at = ( AttributeTypeItem ) item;
159 
160                 for ( Iterator<AttributeType> iterator = at.iterator(); iterator.hasNext(); )
161                 {
162                     AttributeType attr = iterator.next();
163 
164                     if ( oid.equals( attr.getOid() ) )
165                     {
166                         return true;
167                     }
168                 }
169             }
170             else if ( item instanceof AttributeValueItem )
171             {
172                 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE )
173                 {
174                     continue;
175                 }
176 
177                 AttributeValueItem av = ( AttributeValueItem ) item;
178 
179                 for ( Iterator<Attribute> j = av.iterator(); j.hasNext(); )
180                 {
181                     Attribute entryAttribute = j.next();
182 
183                     AttributeType attr = entryAttribute.getAttributeType();
184                     String attrOid;
185 
186                     if ( attr != null )
187                     {
188                         attrOid = entryAttribute.getAttributeType().getOid();
189                     }
190                     else
191                     {
192                         attr = schemaManager.lookupAttributeTypeRegistry( entryAttribute.getId() );
193                         attrOid = attr.getOid();
194                         entryAttribute.apply( attr );
195                     }
196 
197                     if ( oid.equals( attrOid ) && entryAttribute.contains( attrValue ) )
198                     {
199                         return true;
200                     }
201                 }
202             }
203             else if ( item instanceof ClassesItem )
204             {
205                 ClassesItem refinement = ( ClassesItem ) item;
206 
207                 if ( refinementEvaluator
208                     .evaluate( refinement.getClasses(), entry.get( SchemaConstants.OBJECT_CLASS_AT ) ) )
209                 {
210                     return true;
211                 }
212             }
213             else if ( item instanceof MaxImmSubItem )
214             {
215                 return true;
216             }
217             else if ( item instanceof MaxValueCountItem )
218             {
219                 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE )
220                 {
221                     continue;
222                 }
223 
224                 MaxValueCountItem mvc = ( MaxValueCountItem ) item;
225 
226                 for ( Iterator<MaxValueCountElem> j = mvc.iterator(); j.hasNext(); )
227                 {
228                     MaxValueCountElem mvcItem = j.next();
229 
230                     if ( oid.equals( mvcItem.getAttributeType().getOid() ) )
231                     {
232                         return true;
233                     }
234                 }
235             }
236             else if ( item instanceof RangeOfValuesItem )
237             {
238                 RangeOfValuesItem rov = ( RangeOfValuesItem ) item;
239 
240                 if ( entryEvaluator.evaluate( rov.getRefinement(), entryName, entry ) )
241                 {
242                     return true;
243                 }
244             }
245             else if ( item instanceof RestrictedByItem )
246             {
247                 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE )
248                 {
249                     continue;
250                 }
251 
252                 RestrictedByItem rb = ( RestrictedByItem ) item;
253 
254                 for ( Iterator<RestrictedByElem> j = rb.iterator(); j.hasNext(); )
255                 {
256                     RestrictedByElem rbItem = j.next();
257 
258                     if ( oid.equals( rbItem.getAttributeType().getOid() ) )
259                     {
260                         return true;
261                     }
262                 }
263             }
264             else if ( item instanceof SelfValueItem )
265             {
266                 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE && scope != OperationScope.ATTRIBUTE_TYPE )
267                 {
268                     continue;
269                 }
270 
271                 SelfValueItem sv = ( SelfValueItem ) item;
272 
273                 for ( Iterator<AttributeType> iterator = sv.iterator(); iterator.hasNext(); )
274                 {
275                     AttributeType attr = iterator.next();
276 
277                     if ( oid.equals( attr.getOid() ) )
278                     {
279                         Attribute entryAttribute = entry.get( oid );
280 
281                         if ( ( entryAttribute != null ) && entryAttribute.contains( userName.getNormName() ) )
282                         {
283                             return true;
284                         }
285                     }
286                 }
287             }
288             else
289             {
290                 throw new InternalError( I18n.err( I18n.ERR_232, item.getClass().getName() ) );
291             }
292         }
293 
294         return false;
295     }
296 }