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.api.ldap.extras.controls.ppolicy_impl;
21  
22  
23  import java.nio.ByteBuffer;
24  
25  import org.apache.directory.api.asn1.Asn1Object;
26  import org.apache.directory.api.asn1.DecoderException;
27  import org.apache.directory.api.asn1.EncoderException;
28  import org.apache.directory.api.asn1.ber.Asn1Decoder;
29  import org.apache.directory.api.asn1.ber.tlv.BerValue;
30  import org.apache.directory.api.asn1.ber.tlv.TLV;
31  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
32  import org.apache.directory.api.i18n.I18n;
33  import org.apache.directory.api.ldap.codec.api.ControlDecorator;
34  import org.apache.directory.api.ldap.codec.api.LdapApiService;
35  import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicy;
36  import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyImpl;
37  import org.apache.directory.api.ldap.extras.controls.ppolicy.PasswordPolicyResponse;
38  
39  
40  /**
41   * PasswordPolicy decorator.
42   *
43   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
44   */
45  public class PasswordPolicyDecorator extends ControlDecorator<PasswordPolicy> implements PasswordPolicy
46  {
47      /** An instance of this decoder */
48      private static final Asn1Decoder DECODER = new Asn1Decoder();
49  
50      // Storage for computed lengths
51      private int ppolicySeqLength = 0;
52      private int warningLength = 0;
53  
54  
55      /**
56       * Creates a new instance of PasswordPolicyDecorator.
57       * 
58       * @param codec The LDAP Service to use
59       */
60      public PasswordPolicyDecorator( LdapApiService codec )
61      {
62          super( codec, new PasswordPolicyImpl() );
63      }
64  
65  
66      /**
67       * Creates a new instance of PasswordPolicyDecorator.
68       * 
69       * @param codec The LDAP Service to use
70       * @param hasResponse The hasResponse flag
71       */
72      public PasswordPolicyDecorator( LdapApiService codec, boolean hasResponse )
73      {
74          super( codec, new PasswordPolicyImpl( hasResponse ) );
75      }
76  
77  
78      /**
79       * Creates a new instance of PasswordPolicyDecorator.
80       * 
81       * @param codec The LDAP Service to use
82       * @param policy The asswordPolicy to use
83       */
84      public PasswordPolicyDecorator( LdapApiService codec, PasswordPolicy policy )
85      {
86          super( codec, policy );
87      }
88  
89  
90      /**
91       * {@inheritDoc}
92       */
93      @Override
94      public void setValue( byte[] value )
95      {
96          if ( ( value == null ) || ( value.length <= 2 ) )
97          {
98              setResponse( null );
99          }
100         else if ( !hasResponse() )
101         {
102             setResponse( true );
103         }
104 
105         super.setValue( value );
106     }
107 
108 
109     @Override
110     public int computeLength()
111     {
112         // reset the length values
113         valueLength = 0;
114         ppolicySeqLength = 0;
115         warningLength = 0;
116 
117         if ( !hasResponse() )
118         {
119             return 0;
120         }
121 
122         if ( getResponse().getTimeBeforeExpiration() >= 0 )
123         {
124             int timeBeforeExpirationValueLength = BerValue.getNbBytes( getResponse().getTimeBeforeExpiration() );
125             warningLength = 1 + TLV.getNbBytes( timeBeforeExpirationValueLength ) + timeBeforeExpirationValueLength;
126         }
127         else if ( getResponse().getGraceAuthNRemaining() >= 0 )
128         {
129             int graceAuthNsRemainingValueLength = BerValue.getNbBytes( getResponse().getGraceAuthNRemaining() );
130             warningLength = 1 + TLV.getNbBytes( graceAuthNsRemainingValueLength ) + graceAuthNsRemainingValueLength;
131         }
132 
133         if ( warningLength != 0 )
134         {
135             ppolicySeqLength = 1 + TLV.getNbBytes( warningLength ) + warningLength;
136         }
137 
138         if ( getResponse().getPasswordPolicyError() != null )
139         {
140             ppolicySeqLength += 1 + 1 + 1;
141         }
142 
143         valueLength = 1 + TLV.getNbBytes( ppolicySeqLength ) + ppolicySeqLength;
144 
145         return valueLength;
146     }
147 
148 
149     @Override
150     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
151     {
152         if ( !hasResponse() )
153         {
154             return buffer;
155         }
156 
157         if ( buffer == null )
158         {
159             throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
160         }
161 
162         // Encode the Sequence tag
163         buffer.put( UniversalTag.SEQUENCE.getValue() );
164         buffer.put( TLV.getBytes( ppolicySeqLength ) );
165 
166         if ( ( getResponse().getTimeBeforeExpiration() < 0 ) && ( getResponse().getGraceAuthNRemaining() < 0 ) && (
167             getResponse().getPasswordPolicyError() == null ) )
168         {
169             return buffer;
170         }
171         else
172         {
173             if ( warningLength > 0 )
174             {
175                 // Encode the Warning tag
176                 buffer.put( ( byte ) PasswordPolicyTags.PPOLICY_WARNING_TAG.getValue() );
177                 buffer.put( TLV.getBytes( warningLength ) );
178 
179                 if ( getResponse().getTimeBeforeExpiration() >= 0 )
180                 {
181                     BerValue.encode(
182                         buffer,
183                         ( byte ) PasswordPolicyTags.TIME_BEFORE_EXPIRATION_TAG.getValue(),
184                         getResponse().getTimeBeforeExpiration() );
185                 }
186                 else if ( getResponse().getGraceAuthNRemaining() >= 0 )
187                 {
188                     BerValue.encode(
189                         buffer,
190                         ( byte ) PasswordPolicyTags.GRACE_AUTHNS_REMAINING_TAG.getValue(),
191                         getResponse().getGraceAuthNRemaining() );
192                 }
193             }
194 
195             if ( getResponse().getPasswordPolicyError() != null )
196             {
197                 BerValue.encode(
198                     buffer,
199                     ( byte ) PasswordPolicyTags.PPOLICY_ERROR_TAG.getValue(),
200                     getResponse().getPasswordPolicyError().getValue() );
201             }
202         }
203 
204         return buffer;
205     }
206 
207 
208     @Override
209     public String toString()
210     {
211         StringBuilder sb = new StringBuilder();
212 
213         sb.append( "  PasswordPolicyResponse control :\n" );
214         sb.append( "   oid          : '" ).append( getOid() ).append( '\n' );
215 
216         if ( hasResponse() && getResponse().getTimeBeforeExpiration() >= 0 )
217         {
218             sb.append( "   timeBeforeExpiration          : '" ).append( getResponse().getTimeBeforeExpiration() )
219                 .append( '\n' );
220         }
221         else if ( hasResponse() && getResponse().getGraceAuthNRemaining() >= 0 )
222         {
223             sb.append( "   graceAuthNsRemaining          : '" ).append( getResponse().getGraceAuthNRemaining() )
224                 .append( '\n' );
225         }
226 
227         if ( hasResponse() && getResponse().getPasswordPolicyError() != null )
228         {
229             sb.append( "   ppolicyError          : '" ).append( getResponse().getPasswordPolicyError().toString() )
230                 .append( '\n' );
231         }
232 
233         return sb.toString();
234     }
235 
236 
237     /**
238      * {@inheritDoc}
239      */
240     @Override
241     public Asn1Object decode( byte[] controlBytes ) throws DecoderException
242     {
243         if ( !hasResponse() )
244         {
245             return this;
246         }
247 
248         ByteBuffer bb = ByteBuffer.wrap( controlBytes );
249         PasswordPolicyContainer container = new PasswordPolicyContainer( getCodecService(), this );
250         DECODER.decode( bb, container );
251         return this;
252     }
253 
254 
255     /**
256      *
257      * {@inheritDoc}
258      */
259     @Override
260     public boolean hasResponse()
261     {
262         return getDecorated().hasResponse();
263     }
264 
265 
266     /**
267      *
268      * {@inheritDoc}
269      */
270     @Override
271     public void setResponse( PasswordPolicyResponse response )
272     {
273         getDecorated().setResponse( response );
274     }
275 
276 
277     /**
278      *
279      * {@inheritDoc}
280      */
281     @Override
282     public PasswordPolicyResponse setResponse( boolean hasResponse )
283     {
284         return getDecorated().setResponse( hasResponse );
285     }
286 
287 
288     /**
289      *
290      * {@inheritDoc}
291      */
292     @Override
293     public PasswordPolicyResponse getResponse()
294     {
295         return getDecorated().getResponse();
296     }
297 }