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.shared.ldap.aci;
021    
022    
023    import java.io.Serializable;
024    import java.util.ArrayList;
025    import java.util.Collection;
026    import java.util.Collections;
027    import java.util.Iterator;
028    
029    import javax.naming.NamingException;
030    import javax.naming.directory.Attribute;
031    
032    import org.apache.directory.shared.ldap.filter.ExprNode;
033    
034    
035    /**
036     * Defines the items to which the access controls apply.
037     * 
038     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
039     * @version $Rev: 664290 $, $Date: 2008-06-07 08:28:06 +0200 (Sat, 07 Jun 2008) $
040     */
041    public abstract class ProtectedItem implements Serializable
042    {
043        /**
044         * The entry contents as a whole. In case of a family member, it also means
045         * the entry content of each subordinate family member within the same
046         * compound attribute. It does not necessarily include the information in
047         * these entries. This element shall be ignored if the classes element is
048         * present, since this latter element selects protected entries (and
049         * subordinate family members) on the basis of their object class.
050         */
051        public static final Entry ENTRY = new Entry();
052    
053        /**
054         * All user attribute type information associated with the entry, but not
055         * values associated with those attributes.
056         */
057        public static final AllUserAttributeTypes ALL_USER_ATTRIBUTE_TYPES = new AllUserAttributeTypes();
058    
059        /**
060         * All user attribute information associated with the entry, including all
061         * values of all user attributes.
062         */
063        public static final AllUserAttributeTypesAndValues ALL_USER_ATTRIBUTE_TYPES_AND_VALUES = new AllUserAttributeTypesAndValues();
064    
065    
066        /**
067         * Creates a new instance.
068         */
069        protected ProtectedItem()
070        {
071        }
072    
073        
074        /**
075         * The contents of entries (possibly a family member) which are restricted
076         * to those that have object class values that satisfy the predicate defined
077         * by Refinement (see 12.3.5), together (in the case of an ancestor or other
078         * family member) with the entry contents as a whole of each subordinate
079         * family member entry; it does not necessarily include the information in
080         * these entries.
081         */
082        public static class Classes extends ProtectedItem
083        {
084            private static final long serialVersionUID = -8553151906617285325L;
085    
086            private final ExprNode classes;
087    
088    
089            /**
090             * Creates a new instance.
091             * 
092             * @param classes
093             *            refinement
094             */
095            public Classes(ExprNode classes)
096            {
097                this.classes = classes;
098            }
099    
100    
101            public ExprNode getClasses()
102            {
103                return classes;
104            }
105    
106    
107            public boolean equals( Object o )
108            {
109                if ( this == o )
110                {
111                    return true;
112                }
113    
114                if ( o instanceof Classes )
115                {
116                    Classes that = ( Classes ) o;
117                    return this.classes.equals( that.classes );
118                }
119    
120                return false;
121            }
122    
123    
124            /**
125             * @see Object#toString()
126             */
127            public String toString()
128            {
129                StringBuilder buf = new StringBuilder();
130                
131                buf.append( "classes " );
132                classes.printRefinementToBuffer( buf );
133                
134                return buf.toString();
135            }
136        }
137    
138        /**
139         * The entry contents as a whole. In case of a family member, it also means
140         * the entry content of each subordinate family member within the same
141         * compound attribute. It does not necessarily include the information in
142         * these entries. This element shall be ignored if the classes element is
143         * present, since this latter element selects protected entries (and
144         * subordinate family members) on the basis of their object class.
145         */
146        public static class Entry extends ProtectedItem
147        {
148            private static final long serialVersionUID = -6971482229815999874L;
149    
150    
151            private Entry()
152            {
153            }
154    
155    
156            public String toString()
157            {
158                return "entry";
159            }
160        }
161    
162        /**
163         * All user attribute type information associated with the entry, but not
164         * values associated with those attributes.
165         */
166        public static class AllUserAttributeTypes extends ProtectedItem
167        {
168            private static final long serialVersionUID = 3728652941148931359L;
169    
170    
171            private AllUserAttributeTypes()
172            {
173            }
174    
175    
176            public String toString()
177            {
178                return "allUserAttributeTypes";
179            }
180        }
181    
182        /**
183         * All user attribute information associated with the entry, including all
184         * values of all user attributes.
185         */
186        public static class AllUserAttributeTypesAndValues extends ProtectedItem
187        {
188            private static final long serialVersionUID = 7250988885983604442L;
189    
190    
191            private AllUserAttributeTypesAndValues()
192            {
193            }
194    
195    
196            public String toString()
197            {
198                return "allUserAttributeTypesAndValues";
199            }
200        }
201    
202        /**
203         * A base class for all items which protects attribute types (or its values)
204         */
205        private abstract static class AttributeTypeProtectedItem extends ProtectedItem
206        {
207            protected final Collection<String> attributeTypes;
208    
209    
210            /**
211             * Creates a new instance.
212             * 
213             * @param attributeTypes the collection of attirbute IDs
214             */
215            protected AttributeTypeProtectedItem( Collection<String> attributeTypes )
216            {
217                this.attributeTypes = Collections.unmodifiableCollection( attributeTypes );
218            }
219    
220    
221            /**
222             * Returns an iterator of all attribute IDs.
223             */
224            public Iterator<String> iterator()
225            {
226                return attributeTypes.iterator();
227            }
228    
229    
230            public boolean equals( Object o )
231            {
232                if ( this == o )
233                {
234                    return true;
235                }
236    
237                if ( o == null )
238                {
239                    return false;
240                }
241    
242                if ( getClass().isAssignableFrom( o.getClass() ) )
243                {
244                    AttributeTypeProtectedItem that = ( AttributeTypeProtectedItem ) o;
245                    return this.attributeTypes.equals( that.attributeTypes );
246                }
247    
248                return false;
249            }
250            
251            
252            /**
253             * @see Object#toString()
254             */
255            public String toString()
256            {
257                StringBuilder buf = new StringBuilder();
258                
259                buf.append( "{ " );
260                boolean isFirst = true;
261                
262                for ( String attributeType:attributeTypes )
263                {
264                    if ( isFirst ) 
265                    {
266                        isFirst = false;
267                    }
268                    else
269                    {
270                        buf.append( ", " );
271                    }
272    
273                    buf.append( attributeType );
274                }
275                
276                buf.append( " }" );
277                
278                return buf.toString();
279            }
280        }
281    
282        /**
283         * Attribute type information pertaining to specific attributes but not
284         * values associated with the type.
285         */
286        public static class AttributeType extends AttributeTypeProtectedItem
287        {
288            private static final long serialVersionUID = -9039274739078220203L;
289    
290    
291            /**
292             * Creates a new instance.
293             * 
294             * @param attributeTypes
295             *            the collection of attribute IDs.
296             */
297            public AttributeType( Collection<String> attributeTypes )
298            {
299                super( attributeTypes );
300            }
301    
302    
303            public String toString()
304            {
305                return "attributeType " + super.toString();
306            }
307        }
308    
309        /**
310         * All attribute value information pertaining to specific attributes.
311         */
312        public static class AllAttributeValues extends AttributeTypeProtectedItem
313        {
314            private static final long serialVersionUID = -9039274739078220203L;
315    
316    
317            /**
318             * Creates a new instance.
319             * 
320             * @param attributeTypes
321             *            the collection of attribute IDs.
322             */
323            public AllAttributeValues( Collection<String> attributeTypes )
324            {
325                super( attributeTypes );
326            }
327    
328    
329            public String toString()
330            {
331                return "allAttributeValues " + super.toString();
332            }
333        }
334    
335        /**
336         * The attribute value assertion corresponding to the current requestor. The
337         * protected item selfValue applies only when the access controls are to be
338         * applied with respect to a specific authenticated user. It can only apply
339         * in the specific case where the attribute specified is of DN and the
340         * attribute value within the specified attribute matches the DN of the
341         * originator of the operation.
342         */
343        public static class SelfValue extends AttributeTypeProtectedItem
344        {
345            private static final long serialVersionUID = -7788463918070206609L;
346    
347    
348            /**
349             * Creates a new instance.
350             * 
351             * @param attributeTypes the collection of attribute IDs.
352             */
353            public SelfValue( Collection<String> attributeTypes )
354            {
355                super( attributeTypes );
356            }
357    
358    
359            public String toString()
360            {
361                return "selfValue " + super.toString();
362            }
363        }
364    
365        /**
366         * A specific value of specific attributes.
367         */
368        public static class AttributeValue extends ProtectedItem
369        {
370            private static final long serialVersionUID = -258318397837951363L;
371            private final Collection<Attribute> attributes;
372    
373    
374            /**
375             * Creates a new instance.
376             * 
377             * @param attributes
378             *            the collection of {@link Attribute}s.
379             */
380            public AttributeValue( Collection<Attribute> attributes )
381            {
382                this.attributes = Collections.unmodifiableCollection( attributes );
383            }
384    
385    
386            /**
387             * Returns an iterator of all {@link Attribute}s.
388             */
389            public Iterator<Attribute> iterator()
390            {
391                return attributes.iterator();
392            }
393    
394    
395            public boolean equals( Object o )
396            {
397                if ( !super.equals( o ) )
398                {
399                    return false;
400                }
401    
402                if ( o instanceof AttributeValue )
403                {
404                    AttributeValue that = ( AttributeValue ) o;
405                    return this.attributes.equals( that.attributes );
406                }
407    
408                return false;
409            }
410    
411    
412            public String toString()
413            {
414                StringBuilder buf = new StringBuilder();
415                
416                buf.append( "attributeValue {" );
417                
418                for ( Iterator<Attribute> it = attributes.iterator(); it.hasNext(); )
419                {
420                    Attribute attribute = it.next();
421                    buf.append( attribute.getID() );
422                    buf.append( '=' );
423                    
424                    try
425                    {
426                        buf.append( attribute.get( 0 ) );
427                    }
428                    catch ( NamingException e )
429                    {
430                        // doesn't occur here, it is an Attribute
431                    }
432                    
433                    if ( it.hasNext() ) 
434                    {
435                        buf.append( ", " );
436                    }
437                }
438                
439                buf.append( " }" );
440    
441                return buf.toString();
442            }
443        }
444    
445        /**
446         * Restricts the maximum number of attribute values allowed for a specified
447         * attribute type. It is examined if the protected item is an attribute
448         * value of the specified type and the permission sought is add. Values of
449         * that attribute in the entry are counted without regard to context or
450         * access control and as though the operation which adds the values were
451         * successful. If the number of values in the attribute exceeds maxCount,
452         * the ACI item is treated as not granting add access.
453         */
454        public static class MaxValueCount extends ProtectedItem
455        {
456            private static final long serialVersionUID = 5261651541488944572L;
457    
458            private final Collection<ProtectedItem.MaxValueCountItem> items;
459    
460    
461            /**
462             * Creates a new instance.
463             * 
464             * @param items
465             *            the collection of {@link MaxValueCountItem}s.
466             */
467            public MaxValueCount( Collection<MaxValueCountItem> items )
468            {
469                this.items = Collections.unmodifiableCollection( new ArrayList<MaxValueCountItem>( items ) );
470            }
471    
472    
473            /**
474             * Returns an iterator of all {@link MaxValueCountItem}s.
475             */
476            public Iterator<MaxValueCountItem> iterator()
477            {
478                return items.iterator();
479            }
480    
481    
482            public boolean equals( Object o )
483            {
484                if ( !super.equals( o ) )
485                {
486                    return false;
487                }
488    
489                if ( o instanceof MaxValueCount )
490                {
491                    MaxValueCount that = ( MaxValueCount ) o;
492                    return this.items.equals( that.items );
493                }
494    
495                return false;
496            }
497    
498    
499            public String toString()
500            {
501                StringBuilder buf = new StringBuilder();
502                
503                buf.append( "maxValueCount {" );
504    
505                boolean isFirst = true;
506                
507                for ( MaxValueCountItem item:items )
508                {
509                    if ( isFirst )
510                    {
511                        isFirst = false;
512                    }
513                    else
514                    {
515                        buf.append( ", " );
516                    }
517                    
518                    buf.append( item.toString() );
519                }
520                
521                buf.append( "}" );
522    
523                return buf.toString();
524            }
525        }
526    
527        /**
528         * Any attribute value which matches the specified filter, i.e. for which
529         * the specified filter evaluated on that attribute value would return TRUE.
530         */
531        public static class RangeOfValues extends ProtectedItem
532        {
533            private static final long serialVersionUID = -8553151906617285325L;
534    
535            private final ExprNode filter;
536    
537    
538            /**
539             * Creates a new instance.
540             * 
541             * @param filter
542             *            the expression
543             */
544            public RangeOfValues(ExprNode filter)
545            {
546                if ( filter == null )
547                {
548                    throw new NullPointerException( "filter" );
549                }
550    
551                this.filter = filter;
552            }
553    
554    
555            /**
556             * Returns the expression.
557             */
558            public ExprNode getFilter()
559            {
560                return filter;
561            }
562    
563    
564            public boolean equals( Object o )
565            {
566                if ( this == o )
567                {
568                    return true;
569                }
570    
571                if ( o instanceof RangeOfValues )
572                {
573                    RangeOfValues that = ( RangeOfValues ) o;
574                    return this.filter.equals( that.filter );
575                }
576    
577                return false;
578            }
579    
580    
581            public String toString()
582            {
583                StringBuilder buf = new StringBuilder();
584                
585                buf.append( "rangeOfValues " );
586                buf.append( filter.toString() );
587                
588                return buf.toString();
589            }
590        }
591    
592        /**
593         * Restricts the maximum number of immediate subordinates of the superior
594         * entry to an entry being added or imported. It is examined if the
595         * protected item is an entry, the permission sought is add or import, and
596         * the immediate superior entry is in the same DSA as the entry being added
597         * or imported. Immediate subordinates of the superior entry are counted
598         * without regard to context or access control as though the entry addition
599         * or importing were successful. If the number of subordinates exceeds
600         * maxImmSub, the ACI item is treated as not granting add or import access.
601         */
602        public static class MaxImmSub extends ProtectedItem
603        {
604            private static final long serialVersionUID = -8553151906617285325L;
605    
606            private final int value;
607    
608    
609            /**
610             * Creates a new instance.
611             * 
612             * @param value
613             *            The maximum number of immediate subordinates
614             */
615            public MaxImmSub(int value)
616            {
617                this.value = value;
618            }
619    
620    
621            /**
622             * Returns the maximum number of immediate subordinates.
623             */
624            public int getValue()
625            {
626                return value;
627            }
628    
629    
630            public boolean equals( Object o )
631            {
632                if ( this == o )
633                {
634                    return true;
635                }
636    
637                if ( o instanceof MaxImmSub )
638                {
639                    MaxImmSub that = ( MaxImmSub ) o;
640                    return this.value == that.value;
641                }
642    
643                return false;
644            }
645    
646    
647            public String toString()
648            {
649                return "maxImmSub " + value;
650            }
651        }
652    
653        /**
654         * Restricts values added to the attribute type to being values that are
655         * already present in the same entry as values of the attribute valuesIn. It
656         * is examined if the protected item is an attribute value of the specified
657         * type and the permission sought is add. Values of the valuesIn attribute
658         * are checked without regard to context or access control and as though the
659         * operation which adds the values were successful. If the value to be added
660         * is not present in valuesIn the ACI item is treated as not granting add
661         * access.
662         */
663        public static class RestrictedBy extends ProtectedItem
664        {
665            private static final long serialVersionUID = -8157637446588058799L;
666            private final Collection<RestrictedByItem> items;
667    
668    
669            /**
670             * Creates a new instance.
671             * 
672             * @param items the collection of {@link RestrictedByItem}s.
673             */
674            public RestrictedBy( Collection<RestrictedByItem> items)
675            {
676                this.items = Collections.unmodifiableCollection( items );
677            }
678    
679    
680            /**
681             * Returns an iterator of all {@link RestrictedByItem}s.
682             */
683            public Iterator<RestrictedByItem> iterator()
684            {
685                return items.iterator();
686            }
687    
688    
689            public boolean equals( Object o )
690            {
691                if ( !super.equals( o ) )
692                {
693                    return false;
694                }
695    
696                if ( o instanceof RestrictedBy )
697                {
698                    RestrictedBy that = ( RestrictedBy ) o;
699                    return this.items.equals( that.items );
700                }
701    
702                return false;
703            }
704    
705    
706            public String toString()
707            {
708                StringBuilder buf = new StringBuilder();
709                
710                buf.append( "restrictedBy {" );
711    
712                boolean isFirst = true;
713                
714                for ( RestrictedByItem item:items )
715                {
716                    if ( isFirst )
717                    {
718                        isFirst = false;
719                    }
720                    else
721                    {
722                        buf.append( ", " );
723                    }
724                    
725                    buf.append( item.toString() );
726                }
727                
728                buf.append( '}' );
729                
730                return buf.toString();
731            }
732        }
733    
734        /**
735         * An element of {@link MaxValueCount}.
736         */
737        public static class MaxValueCountItem implements Serializable
738        {
739            private static final long serialVersionUID = 43697038363452113L;
740    
741            private String attributeType;
742    
743            private int maxCount;
744    
745    
746            /**
747             * Creates a new instance.
748             * 
749             * @param attributeType
750             *            the attribute ID to limit the maximum count
751             * @param maxCount
752             *            the maximum count of the attribute allowed
753             */
754    
755            public MaxValueCountItem(String attributeType, int maxCount)
756            {
757                this.attributeType = attributeType;
758                this.maxCount = maxCount;
759            }
760    
761    
762            /**
763             * Returns the attribute ID to limit the maximum count.
764             */
765            public String getAttributeType()
766            {
767                return attributeType;
768            }
769    
770    
771            /**
772             * Returns the maximum count of the attribute allowed.
773             */
774            public int getMaxCount()
775            {
776                return maxCount;
777            }
778    
779    
780            public String toString()
781            {
782                return "{ type " + attributeType + ", maxCount " + maxCount + " }";
783            }
784        }
785    
786        /**
787         * An element of {@link RestrictedBy}.
788         */
789        public static class RestrictedByItem implements Serializable
790        {
791            private static final long serialVersionUID = 4319052153538757099L;
792    
793            private String attributeType;
794    
795            private String valuesIn;
796    
797    
798            /**
799             * Creates a new instance.
800             * 
801             * @param attributeType
802             *            the attribute type to restrict
803             * @param valuesIn
804             *            the attribute type only whose values are allowed in
805             *            <tt>attributeType</tt>.
806             */
807            public RestrictedByItem(String attributeType, String valuesIn)
808            {
809                this.attributeType = attributeType;
810                this.valuesIn = valuesIn;
811            }
812    
813    
814            /**
815             * Returns the attribute type to restrict.
816             */
817            public String getAttributeType()
818            {
819                return attributeType;
820            }
821    
822    
823            /**
824             * Returns the attribute type only whose values are allowed in
825             * <tt>attributeType</tt>.
826             */
827            public String getValuesIn()
828            {
829                return valuesIn;
830            }
831    
832    
833            public String toString()
834            {
835                return "{ type " + attributeType + ", valuesIn " + valuesIn + " }";
836            }
837        }
838    }