001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    package org.apache.directory.server.core.authz.support;
021    
022    
023    import java.util.ArrayList;
024    import java.util.Collection;
025    
026    import javax.naming.NamingException;
027    
028    import org.apache.directory.server.core.interceptor.context.OperationContext;
029    import org.apache.directory.shared.ldap.aci.ACITuple;
030    import org.apache.directory.shared.ldap.aci.MicroOperation;
031    import org.apache.directory.shared.ldap.aci.ProtectedItem;
032    import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
033    import org.apache.directory.shared.ldap.entry.ServerEntry;
034    import org.apache.directory.shared.ldap.entry.Value;
035    import org.apache.directory.shared.ldap.name.DN;
036    import org.apache.directory.shared.ldap.schema.SchemaManager;
037    
038    
039    /**
040     * An {@link ACITupleFilter} that chooses the tuples with the most specific
041     * protected item. (18.8.4.3, X.501)
042     * <p>
043     * If more than one tuple remains, choose the tuples with the most specific
044     * protected item. If the protected item is an attribute and there are tuples 
045     * that specify the attribute type explicitly, discard all other tuples. If
046     * the protected item is an attribute value, and there are tuples that specify
047     * the attribute value explicitly, discard all other tuples. A protected item
048     * which is a rangeOfValues is to be treated as specifying an attribute value
049     * explicitly.
050     * 
051     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
052     * @version $Rev: 927146 $, $Date: 2010-03-24 19:39:54 +0100 (Wed, 24 Mar 2010) $
053     */
054    public class MostSpecificProtectedItemFilter implements ACITupleFilter
055    {
056        public Collection<ACITuple> filter( 
057                SchemaManager schemaManager, 
058                Collection<ACITuple> tuples, 
059                OperationScope scope, 
060                OperationContext opContext,
061                Collection<DN> userGroupNames, 
062                DN userName, 
063                ServerEntry userEntry, 
064                AuthenticationLevel authenticationLevel,
065                DN entryName, 
066                String attrId, 
067                Value<?> attrValue, 
068                ServerEntry entry, 
069                Collection<MicroOperation> microOperations,
070                ServerEntry entryView )
071            throws NamingException
072        {
073            if ( tuples.size() <= 1 )
074            {
075                return tuples;
076            }
077    
078            Collection<ACITuple> filteredTuples = new ArrayList<ACITuple>();
079    
080            // If the protected item is an attribute and there are tuples that
081            // specify the attribute type explicitly, discard all other tuples.
082            for ( ACITuple tuple:tuples )
083            {
084                for ( ProtectedItem item:tuple.getProtectedItems() )
085                {
086                    if ( item instanceof ProtectedItem.AttributeType || item instanceof ProtectedItem.AllAttributeValues
087                        || item instanceof ProtectedItem.SelfValue || item instanceof ProtectedItem.AttributeValue )
088                    {
089                        filteredTuples.add( tuple );
090                        break;
091                    }
092                }
093            }
094    
095            if ( filteredTuples.size() > 0 )
096            {
097                return filteredTuples;
098            }
099    
100            // If the protected item is an attribute value, and there are tuples
101            // that specify the attribute value explicitly, discard all other tuples.
102            // A protected item which is a rangeOfValues is to be treated as
103            // specifying an attribute value explicitly. 
104            for ( ACITuple tuple:tuples )
105            {
106                for ( ProtectedItem item:tuple.getProtectedItems() )
107                {
108                    if ( item instanceof ProtectedItem.RangeOfValues )
109                    {
110                        filteredTuples.add( tuple );
111                    }
112                }
113            }
114    
115            if ( filteredTuples.size() > 0 )
116            {
117                return filteredTuples;
118            }
119    
120            return tuples;
121        }
122    }