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 * https://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 */ 020package org.apache.directory.api.ldap.extras.extended.ads_impl.whoAmI; 021 022 023import org.apache.directory.api.asn1.DecoderException; 024import org.apache.directory.api.asn1.util.Asn1Buffer; 025import org.apache.directory.api.i18n.I18n; 026import org.apache.directory.api.ldap.codec.api.AbstractExtendedOperationFactory; 027import org.apache.directory.api.ldap.codec.api.ExtendedOperationFactory; 028import org.apache.directory.api.ldap.codec.api.LdapApiService; 029import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIRequest; 030import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIRequestImpl; 031import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIResponse; 032import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIResponseImpl; 033import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException; 034import org.apache.directory.api.ldap.model.message.ExtendedResponse; 035import org.apache.directory.api.ldap.model.name.Dn; 036import org.apache.directory.api.util.Strings; 037import org.slf4j.Logger; 038import org.slf4j.LoggerFactory; 039 040 041/** 042 * An {@link ExtendedOperationFactory} for creating WhoAmI extended request response 043 * pairs. 044 * 045 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 046 */ 047public class WhoAmIFactory extends AbstractExtendedOperationFactory 048{ 049 /** logger */ 050 private static final Logger LOG = LoggerFactory.getLogger( WhoAmIFactory.class ); 051 052 /** 053 * Creates a new instance of WhoAmIFactory. 054 * 055 * @param codec The codec for this factory. 056 */ 057 public WhoAmIFactory( LdapApiService codec ) 058 { 059 super( codec, WhoAmIRequest.EXTENSION_OID ); 060 } 061 062 063 /** 064 * {@inheritDoc} 065 */ 066 @Override 067 public WhoAmIRequest newRequest() 068 { 069 return new WhoAmIRequestImpl(); 070 } 071 072 073 /** 074 * {@inheritDoc} 075 */ 076 @Override 077 public WhoAmIRequest newRequest( byte[] value ) throws DecoderException 078 { 079 WhoAmIRequest whoAmIRequest = new WhoAmIRequestImpl(); 080 081 if ( value != null ) 082 { 083 decodeValue( whoAmIRequest, value ); 084 } 085 086 return whoAmIRequest; 087 } 088 089 090 /** 091 * {@inheritDoc} 092 */ 093 @Override 094 public WhoAmIResponse newResponse() throws DecoderException 095 { 096 return new WhoAmIResponseImpl(); 097 } 098 099 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}