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.Collection;
024    import java.util.Iterator;
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.aci.ProtectedItem.MaxValueCountItem;
033    import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
034    import org.apache.directory.shared.ldap.entry.EntryAttribute;
035    import org.apache.directory.shared.ldap.entry.ServerEntry;
036    import org.apache.directory.shared.ldap.entry.Value;
037    import org.apache.directory.shared.ldap.name.DN;
038    import org.apache.directory.shared.ldap.schema.SchemaManager;
039    
040    
041    /**
042     * An {@link ACITupleFilter} that discards all tuples that doesn't satisfy
043     * {@link org.apache.directory.shared.ldap.aci.ProtectedItem.MaxValueCount} constraint if available. (18.8.3.3, X.501)
044     *
045     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
046     * @version $Rev: 927146 $, $Date: 2010-03-24 19:39:54 +0100 (Wed, 24 Mar 2010) $
047     */
048    public class MaxValueCountFilter implements ACITupleFilter
049    {
050        public Collection<ACITuple> filter( 
051                SchemaManager schemaManager, 
052                Collection<ACITuple> tuples, 
053                OperationScope scope, 
054                OperationContext opContext,
055                Collection<DN> userGroupNames, 
056                DN userName, 
057                ServerEntry userEntry, 
058                AuthenticationLevel authenticationLevel,
059                DN entryName, 
060                String attrId, 
061                Value<?> attrValue, 
062                ServerEntry entry, 
063                Collection<MicroOperation> microOperations,
064                ServerEntry entryView )
065            throws NamingException
066        {
067            if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE )
068            {
069                return tuples;
070            }
071    
072            if ( tuples.size() == 0 )
073            {
074                return tuples;
075            }
076    
077            for ( Iterator<ACITuple> i = tuples.iterator(); i.hasNext(); )
078            {
079                ACITuple tuple = i.next();
080                
081                if ( !tuple.isGrant() )
082                {
083                    continue;
084                }
085    
086                for ( Iterator<ProtectedItem> j = tuple.getProtectedItems().iterator(); j.hasNext(); )
087                {
088                    ProtectedItem item = j.next();
089                    
090                    if ( item instanceof ProtectedItem.MaxValueCount )
091                    {
092                        ProtectedItem.MaxValueCount mvc = ( ProtectedItem.MaxValueCount ) item;
093                        
094                        if ( isRemovable( mvc, attrId, entryView ) )
095                        {
096                            i.remove();
097                            break;
098                        }
099                    }
100                }
101            }
102    
103            return tuples;
104        }
105    
106    
107        private boolean isRemovable( ProtectedItem.MaxValueCount mvc, String attrId, ServerEntry entryView ) throws NamingException
108        {
109            for ( Iterator<ProtectedItem.MaxValueCountItem> k = mvc.iterator(); k.hasNext(); )
110            {
111                MaxValueCountItem mvcItem = k.next();
112                if ( attrId.equalsIgnoreCase( mvcItem.getAttributeType() ) )
113                {
114                    EntryAttribute attr = entryView.get( attrId );
115                    int attrCount = attr == null ? 0 : attr.size();
116                    
117                    if ( attrCount > mvcItem.getMaxCount() )
118                    {
119                        return true;
120                    }
121                }
122            }
123    
124            return false;
125        }
126    
127    }