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   *     https://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.extended.ads_impl.whoAmI;
21  
22  
23  import org.apache.directory.api.asn1.DecoderException;
24  import org.apache.directory.api.asn1.util.Asn1Buffer;
25  import org.apache.directory.api.i18n.I18n;
26  import org.apache.directory.api.ldap.codec.api.AbstractExtendedOperationFactory;
27  import org.apache.directory.api.ldap.codec.api.ExtendedOperationFactory;
28  import org.apache.directory.api.ldap.codec.api.LdapApiService;
29  import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIRequest;
30  import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIRequestImpl;
31  import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIResponse;
32  import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIResponseImpl;
33  import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
34  import org.apache.directory.api.ldap.model.message.ExtendedResponse;
35  import org.apache.directory.api.ldap.model.name.Dn;
36  import org.apache.directory.api.util.Strings;
37  import org.slf4j.Logger;
38  import org.slf4j.LoggerFactory;
39  
40  
41  /**
42   * An {@link ExtendedOperationFactory} for creating WhoAmI extended request response 
43   * pairs.
44   *
45   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
46   */
47  public class WhoAmIFactory extends AbstractExtendedOperationFactory
48  {
49      /** logger */
50      private static final Logger LOG = LoggerFactory.getLogger( WhoAmIFactory.class );
51      
52      /**
53       * Creates a new instance of WhoAmIFactory.
54       *
55       * @param codec The codec for this factory.
56       */
57      public WhoAmIFactory( LdapApiService codec )
58      {
59          super( codec, WhoAmIRequest.EXTENSION_OID );
60      }
61  
62  
63      /**
64       * {@inheritDoc}
65       */
66      @Override
67      public WhoAmIRequest newRequest()
68      {
69          return new WhoAmIRequestImpl();
70      }
71  
72  
73      /**
74       * {@inheritDoc}
75       */
76      @Override
77      public WhoAmIRequest newRequest( byte[] value ) throws DecoderException
78      {
79          WhoAmIRequest whoAmIRequest = new WhoAmIRequestImpl();
80  
81          if ( value != null )
82          {
83              decodeValue( whoAmIRequest, value );
84          }
85  
86          return whoAmIRequest;
87      }
88  
89  
90      /**
91       * {@inheritDoc}
92       */
93      @Override
94      public WhoAmIResponse newResponse() throws DecoderException
95      {
96          return new WhoAmIResponseImpl();
97      }
98  
99  
100     /**
101      * {@inheritDoc}
102      */
103     @Override
104     public WhoAmIResponse newResponse( byte[] value ) throws DecoderException
105     {
106         WhoAmIResponse whoAmIResponse = new WhoAmIResponseImpl();
107 
108         if ( value != null )
109         {
110             decodeValue( whoAmIResponse, value );
111         }
112 
113         return whoAmIResponse;
114     }
115 
116 
117     /**
118      * {@inheritDoc}
119      */
120     @Override
121     public void encodeValue( Asn1Buffer buffer, ExtendedResponse extendedResponse )
122     {
123         if ( extendedResponse == null )
124         {
125             return;
126         }
127 
128         // Reset the responseName, it should always be null for a WhoAMI extended operation
129         extendedResponse.setResponseName( null );
130         
131         // The authzID as a opaque byte array
132         byte[] authzid =  ( ( WhoAmIResponse ) extendedResponse ).getAuthzId();
133         
134         if ( !Strings.isEmpty( authzid ) )
135         {
136             buffer.put( authzid );
137         }
138     }
139     
140     
141     /**
142      * Decode a PDU which must contain a WhoAmIResponse extended operation.
143      * Note that the stream of bytes much contain a full PDU, not a partial one.
144      * 
145      * @param whoAmIResponse The WhoAmI extended response that will be feed
146      * @param data The bytes to be decoded
147      * @return a WhoAmIRequest object
148      * @throws org.apache.directory.api.asn1.DecoderException If the decoding failed
149      */
150     public static WhoAmIResponse decode( WhoAmIResponse whoAmIResponse, byte[] data ) throws DecoderException
151     {
152         if ( Strings.isEmpty( data ) )
153         {
154             ( ( WhoAmIResponseImpl ) whoAmIResponse ).setAuthzId( null );
155         }
156         else
157         {
158             switch ( data.length )
159             {
160                 case 0:
161                     // Error
162                 case 1:
163                     // Error
164                     String msg = I18n.err( I18n.ERR_08226_AUTHZID_TOO_SHORT_MISSING_U_OR_DN );
165                     LOG.error( msg );
166                     throw new DecoderException( msg );
167 
168                 case 2 :
169                     if ( ( data[0] == 'u' ) && ( data[1] == ':' ) )
170                     {
171                         ( ( WhoAmIResponseImpl ) whoAmIResponse ).setAuthzId( data );
172                         ( ( WhoAmIResponseImpl ) whoAmIResponse ).setUserId( Strings.utf8ToString( data, 2, data.length - 2 ) );
173                     }
174                     else
175                     {
176                         msg = I18n.err( I18n.ERR_08227_AUTHZID_MUST_START_WITH_U_OR_DN, Strings.utf8ToString( data ) );
177                         LOG.error( msg );
178                         throw new DecoderException( msg );
179                     }
180                     
181                     break;
182                     
183                 default :
184                     switch ( data[0] )
185                     {
186                         case 'u' :
187                             if ( data[1] == ':' )
188                             {
189                                 ( ( WhoAmIResponseImpl ) whoAmIResponse ).setAuthzId( data );
190                                 ( ( WhoAmIResponseImpl ) whoAmIResponse ).setUserId( Strings.utf8ToString( data, 2, data.length - 2 ) );
191                             }
192                             else
193                             {
194                                 msg = I18n.err( I18n.ERR_08227_AUTHZID_MUST_START_WITH_U_OR_DN, Strings.utf8ToString( data ) );
195                                 LOG.error( msg );
196                                 throw new DecoderException( msg );
197                             }
198                             
199                             break;
200                             
201                         case 'd' :
202                             if ( ( data[1] == 'n' ) && ( data[2] == ':' ) )
203                             {
204                                 // Check that the remaining bytes are a valid DN
205                                 if ( Dn.isValid( Strings.utf8ToString( data, 3, data.length - 3 ) ) )
206                                 {
207                                     ( ( WhoAmIResponseImpl ) whoAmIResponse ).setAuthzId( data );
208                                     
209                                     try
210                                     {
211                                         ( ( WhoAmIResponseImpl ) whoAmIResponse ).setDn( new Dn( Strings.utf8ToString( data, 3, data.length - 3 ) ) );
212                                     }
213                                     catch ( LdapInvalidDnException e )
214                                     {
215                                         // Should never happen
216                                     }
217                                 }
218                                 else
219                                 {
220                                     msg = I18n.err( I18n.ERR_08227_AUTHZID_MUST_START_WITH_U_OR_DN, Strings.utf8ToString( data ) );
221                                     LOG.error( msg );
222                                     throw new DecoderException( msg );
223                                 }
224                             }
225                             else
226                             {
227                                 msg = I18n.err( I18n.ERR_08227_AUTHZID_MUST_START_WITH_U_OR_DN, Strings.utf8ToString( data ) );
228                                 LOG.error( msg );
229                                 throw new DecoderException( msg );
230                             }
231                             
232                             break;
233 
234                         default :
235                             msg = I18n.err( I18n.ERR_08227_AUTHZID_MUST_START_WITH_U_OR_DN, Strings.utf8ToString( data ) );
236                             LOG.error( msg );
237                             throw new DecoderException( msg );
238                     }
239                     
240                     break;
241             }
242         }
243 
244         return whoAmIResponse;
245     }
246 
247     
248     /**
249      * {@inheritDoc}
250      */
251     @Override
252     public void decodeValue( ExtendedResponse extendedResponse, byte[] responseValue ) throws DecoderException
253     {
254         decode( ( WhoAmIResponse ) extendedResponse, responseValue );
255     }
256 }