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.UserClass;
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 user
041     * class. (18.8.4.2)
042     * <p>
043     * If more than one tuple remains, choose the tuples with the most specific user
044     * class. If there are any tuples matching the requestor with UserClasses element
045     * name or thisEntry, discard all other tuples. Otherwise if there are any tuples
046     * matching UserGroup, discard all other tuples. Otherwise if there are any tuples
047     * matching subtree, discard all other tuples.
048     *
049     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
050     * @version $Rev: 927146 $, $Date: 2010-03-24 19:39:54 +0100 (Wed, 24 Mar 2010) $
051     */
052    public class MostSpecificUserClassFilter implements ACITupleFilter
053    {
054        public Collection<ACITuple> filter( 
055                SchemaManager schemaManager, 
056                Collection<ACITuple> tuples, 
057                OperationScope scope, 
058                OperationContext opContext,
059                Collection<DN> userGroupNames, 
060                DN userName, 
061                ServerEntry userEntry, 
062                AuthenticationLevel authenticationLevel,
063                DN entryName, 
064                String attrId, 
065                Value<?> attrValue, 
066                ServerEntry entry, 
067                Collection<MicroOperation> microOperations,
068                ServerEntry entryView )
069            throws NamingException
070        {
071            if ( tuples.size() <= 1 )
072            {
073                return tuples;
074            }
075    
076            Collection<ACITuple> filteredTuples = new ArrayList<ACITuple>();
077    
078            // If there are any tuples matching the requestor with UserClasses
079            // element name or thisEntry, discard all other tuples.
080            for ( ACITuple tuple:tuples )
081            {
082                for ( UserClass userClass:tuple.getUserClasses() )
083                {
084                    if ( userClass instanceof UserClass.Name || userClass instanceof UserClass.ThisEntry )
085                    {
086                        filteredTuples.add( tuple );
087                        break;
088                    }
089                }
090            }
091    
092            if ( filteredTuples.size() > 0 )
093            {
094                return filteredTuples;
095            }
096    
097            // Otherwise if there are any tuples matching UserGroup,
098            // discard all other tuples.
099            for ( ACITuple tuple:tuples )
100            {
101                for ( UserClass userClass:tuple.getUserClasses() )
102                {
103                    if ( userClass instanceof UserClass.UserGroup )
104                    {
105                        filteredTuples.add( tuple );
106                        break;
107                    }
108                }
109            }
110    
111            if ( filteredTuples.size() > 0 )
112            {
113                return filteredTuples;
114            }
115    
116            // Otherwise if there are any tuples matching subtree,
117            // discard all other tuples.
118            for ( ACITuple tuple:tuples )
119            {
120                for ( UserClass userClass:tuple.getUserClasses() )
121                {
122                    if ( userClass instanceof UserClass.Subtree )
123                    {
124                        filteredTuples.add( tuple );
125                        break;
126                    }
127                }
128            }
129    
130            if ( filteredTuples.size() > 0 )
131            {
132                return filteredTuples;
133            }
134    
135            return tuples;
136        }
137    
138    }