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 package org.apache.directory.server.core.integ; 020 021 022 import java.io.File; 023 import java.io.IOException; 024 import java.util.ArrayList; 025 import java.util.List; 026 027 import javax.naming.NamingException; 028 import javax.naming.directory.Attribute; 029 import javax.naming.directory.BasicAttribute; 030 import javax.naming.directory.DirContext; 031 import javax.naming.directory.ModificationItem; 032 import javax.naming.ldap.LdapContext; 033 import javax.naming.ldap.LdapName; 034 035 import org.apache.commons.io.FileUtils; 036 import org.apache.directory.ldap.client.api.LdapConnection; 037 import org.apache.directory.server.constants.ServerDNConstants; 038 import org.apache.directory.server.core.CoreSession; 039 import org.apache.directory.server.core.DirectoryService; 040 import org.apache.directory.server.core.LdapPrincipal; 041 import org.apache.directory.server.core.jndi.ServerLdapContext; 042 import org.apache.directory.server.i18n.I18n; 043 import org.apache.directory.server.ldap.LdapServer; 044 import org.apache.directory.shared.ldap.constants.AuthenticationLevel; 045 import org.apache.directory.shared.ldap.constants.SchemaConstants; 046 import org.apache.directory.shared.ldap.entry.DefaultServerEntry; 047 import org.apache.directory.shared.ldap.entry.EntryAttribute; 048 import org.apache.directory.shared.ldap.entry.client.DefaultClientAttribute; 049 import org.apache.directory.shared.ldap.exception.LdapException; 050 import org.apache.directory.shared.ldap.ldif.ChangeType; 051 import org.apache.directory.shared.ldap.ldif.LdifEntry; 052 import org.apache.directory.shared.ldap.ldif.LdifReader; 053 import org.apache.directory.shared.ldap.name.DN; 054 import org.apache.directory.shared.ldap.name.RDN; 055 import org.apache.directory.shared.ldap.schema.registries.Schema; 056 import org.slf4j.Logger; 057 import org.slf4j.LoggerFactory; 058 059 060 /** 061 * Integration test utility methods. 062 * 063 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 064 * @version $Rev$, $Date$ 065 */ 066 public class IntegrationUtils 067 { 068 /** The class logger */ 069 private static final Logger LOG = LoggerFactory.getLogger( IntegrationUtils.class ); 070 071 private static final List<LdapConnection> openConnections = new ArrayList<LdapConnection>(); 072 073 /** 074 * Deletes the working directory. 075 * 076 * @param wkdir the working directory to delete 077 * @throws IOException if the working directory cannot be deleted 078 */ 079 public static void doDelete( File wkdir ) throws IOException 080 { 081 if ( wkdir.exists() ) 082 { 083 try 084 { 085 FileUtils.deleteDirectory( wkdir ); 086 } 087 catch ( IOException e ) 088 { 089 LOG.error( I18n.err( I18n.ERR_115 ), e ); 090 } 091 } 092 if ( wkdir.exists() ) 093 { 094 throw new IOException( I18n.err( I18n.ERR_116, wkdir ) ); 095 } 096 } 097 098 099 /** 100 * Inject an ldif String into the server. DN must be relative to the 101 * root. 102 * 103 * @param service the directory service to use 104 * @param ldif the ldif containing entries to add to the server. 105 * @throws NamingException if there is a problem adding the entries from the LDIF 106 */ 107 public static void injectEntries( DirectoryService service, String ldif ) throws Exception 108 { 109 LdifReader reader = new LdifReader(); 110 List<LdifEntry> entries = reader.parseLdif( ldif ); 111 112 for ( LdifEntry entry : entries ) 113 { 114 if ( entry.isChangeAdd() ) 115 { 116 service.getAdminSession().add( 117 new DefaultServerEntry( service.getSchemaManager(), entry.getEntry() ) ); 118 } 119 else if ( entry.isChangeModify() ) 120 { 121 service.getAdminSession().modify( 122 entry.getDn(), entry.getModificationItems() ); 123 } 124 else 125 { 126 String message = I18n.err( I18n.ERR_117, entry.getChangeType() ); 127 LOG.error( message ); 128 throw new NamingException( message ); 129 } 130 } 131 132 // And close the reader 133 reader.close(); 134 } 135 136 137 public static LdifEntry getUserAddLdif() throws LdapException 138 { 139 return getUserAddLdif( "uid=akarasulu,ou=users,ou=system", "test".getBytes(), "Alex Karasulu", "Karasulu" ); 140 } 141 142 143 public static LdapContext getContext( String principalDn, DirectoryService service, String dn ) 144 throws Exception 145 { 146 if ( principalDn == null ) 147 { 148 principalDn = ""; 149 } 150 151 DN userDn = new DN( principalDn ); 152 userDn.normalize( service.getSchemaManager().getNormalizerMapping() ); 153 LdapPrincipal principal = new LdapPrincipal( userDn, AuthenticationLevel.SIMPLE ); 154 155 if ( dn == null ) 156 { 157 dn = ""; 158 } 159 160 CoreSession session = service.getSession( principal ); 161 LdapContext ctx = new ServerLdapContext( service, session, new LdapName( dn ) ); 162 return ctx; 163 } 164 165 166 public static CoreSession getCoreSession( String principalDn, DirectoryService service, String dn ) 167 throws Exception 168 { 169 if ( principalDn == null ) 170 { 171 principalDn = ""; 172 } 173 174 DN userDn = new DN( principalDn ); 175 userDn.normalize( service.getSchemaManager().getNormalizerMapping() ); 176 LdapPrincipal principal = new LdapPrincipal( userDn, AuthenticationLevel.SIMPLE ); 177 178 if ( dn == null ) 179 { 180 dn = ""; 181 } 182 183 CoreSession session = service.getSession( principal ); 184 return session; 185 } 186 187 188 public static LdapContext getSystemContext( DirectoryService service ) throws Exception 189 { 190 return getContext( ServerDNConstants.ADMIN_SYSTEM_DN, service, ServerDNConstants.SYSTEM_DN ); 191 } 192 193 194 public static LdapContext getSchemaContext( DirectoryService service ) throws Exception 195 { 196 return getContext( ServerDNConstants.ADMIN_SYSTEM_DN, service, SchemaConstants.OU_SCHEMA ); 197 } 198 199 200 public static LdapContext getRootContext( DirectoryService service ) throws Exception 201 { 202 return getContext( ServerDNConstants.ADMIN_SYSTEM_DN, service, "" ); 203 } 204 205 206 public static void apply( DirectoryService service, LdifEntry entry ) throws Exception 207 { 208 DN dn = new DN( entry.getDn() ); 209 CoreSession session = service.getAdminSession(); 210 211 switch( entry.getChangeType().getChangeType() ) 212 { 213 case( ChangeType.ADD_ORDINAL ): 214 session.add( 215 new DefaultServerEntry( service.getSchemaManager(), entry.getEntry() ) ); 216 break; 217 218 case( ChangeType.DELETE_ORDINAL ): 219 session.delete( dn ); 220 break; 221 222 case( ChangeType.MODDN_ORDINAL ): 223 case( ChangeType.MODRDN_ORDINAL ): 224 RDN newRdn = new RDN( entry.getNewRdn() ); 225 226 if ( entry.getNewSuperior() != null ) 227 { 228 // It's a move. The superior have changed 229 // Let's see if it's a rename too 230 RDN oldRdn = dn.getRdn(); 231 DN newSuperior = new DN( entry.getNewSuperior() ); 232 233 if ( dn.size() == 0 ) 234 { 235 throw new IllegalStateException( I18n.err( I18n.ERR_475 ) ); 236 } 237 else if ( oldRdn.equals( newRdn ) ) 238 { 239 // Same rdn : it's a move 240 session.move( dn, newSuperior ); 241 } 242 else 243 { 244 // it's a move and rename 245 session.moveAndRename( dn, newSuperior, newRdn, entry.isDeleteOldRdn() ); 246 } 247 } 248 else 249 { 250 // it's a rename 251 session.rename( dn, newRdn, entry.isDeleteOldRdn() ); 252 } 253 254 break; 255 256 case( ChangeType.MODIFY_ORDINAL ): 257 session.modify( dn, entry.getModificationItems() ); 258 break; 259 260 default: 261 throw new IllegalStateException( I18n.err( I18n.ERR_476, entry.getChangeType() ) ); 262 } 263 } 264 265 266 public static LdifEntry getUserAddLdif( String dnstr, byte[] password, String cn, String sn ) 267 throws LdapException 268 { 269 DN dn = new DN( dnstr ); 270 LdifEntry ldif = new LdifEntry(); 271 ldif.setDn( dnstr ); 272 ldif.setChangeType( ChangeType.Add ); 273 274 EntryAttribute attr = new DefaultClientAttribute( "objectClass", 275 "top", "person", "organizationalPerson", "inetOrgPerson" ); 276 ldif.addAttribute( attr ); 277 278 attr = new DefaultClientAttribute( "ou", "Engineering", "People" ); 279 ldif.addAttribute( attr ); 280 281 String uid = ( String ) dn.getRdn().getNormValue(); 282 ldif.putAttribute( "uid", uid ); 283 284 ldif.putAttribute( "l", "Bogusville" ); 285 ldif.putAttribute( "cn", cn ); 286 ldif.putAttribute( "sn", sn ); 287 ldif.putAttribute( "mail", uid + "@apache.org" ); 288 ldif.putAttribute( "telephoneNumber", "+1 408 555 4798" ); 289 ldif.putAttribute( "facsimileTelephoneNumber", "+1 408 555 9751" ); 290 ldif.putAttribute( "roomnumber", "4612" ); 291 ldif.putAttribute( "userPassword", password ); 292 293 String givenName = cn.split( " " )[0]; 294 ldif.putAttribute( "givenName", givenName ); 295 return ldif; 296 } 297 298 // ----------------------------------------------------------------------- 299 // Enable/Disable Schema Tests 300 // ----------------------------------------------------------------------- 301 302 303 public static void enableSchema( DirectoryService service, String schemaName ) throws Exception 304 { 305 LdapContext schemaRoot = getSchemaContext( service ); 306 307 // now enable the test schema 308 ModificationItem[] mods = new ModificationItem[1]; 309 Attribute attr = new BasicAttribute( "m-disabled", "FALSE" ); 310 mods[0] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr ); 311 schemaRoot.modifyAttributes( "cn=" + schemaName, mods ); 312 } 313 314 315 public static void disableSchema( DirectoryService service, String schemaName ) throws Exception 316 { 317 LdapContext schemaRoot = getSchemaContext( service ); 318 319 // now enable the test schema 320 ModificationItem[] mods = new ModificationItem[1]; 321 Attribute attr = new BasicAttribute( "m-disabled", "TRUE" ); 322 mods[0] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr ); 323 schemaRoot.modifyAttributes( "cn=" + schemaName, mods ); 324 } 325 326 327 /** 328 * A helper method which tells if a schema is disabled. 329 */ 330 public static boolean isDisabled( DirectoryService service, String schemaName ) 331 { 332 Schema schema = service.getSchemaManager().getLoadedSchema( schemaName ); 333 334 return ( schema == null ) || schema.isDisabled(); 335 } 336 337 338 /** 339 * A helper method which tells if a schema is loaded. 340 */ 341 public static boolean isLoaded( DirectoryService service, String schemaName ) 342 { 343 Schema schema = service.getSchemaManager().getLoadedSchema( schemaName ); 344 345 return ( schema != null ); 346 } 347 348 349 /** 350 * A helper method which tells if a schema is enabled. A shema must be 351 * loaded and enabled. 352 */ 353 public static boolean isEnabled( DirectoryService service, String schemaName ) 354 { 355 Schema schema = service.getSchemaManager().getLoadedSchema( schemaName ); 356 357 return ( schema != null ) && schema.isEnabled(); 358 } 359 360 361 /** 362 * gets a LdapConnection bound using the default admin DN uid=admin,ou=system and password "secret" 363 */ 364 public static LdapConnection getAdminConnection( LdapServer ldapServer ) throws Exception 365 { 366 return getConnectionAs( ldapServer, ServerDNConstants.ADMIN_SYSTEM_DN, "secret" ); 367 } 368 369 370 public static LdapConnection getConnectionAs( LdapServer ldapServer, String dn, String password ) throws Exception 371 { 372 return getConnectionAs( "localhost", ldapServer.getPort(), dn, password ); 373 } 374 375 376 public static LdapConnection getConnectionAs( LdapServer ldapServer, DN dn, String password ) throws Exception 377 { 378 return getConnectionAs( "localhost", ldapServer.getPort(), dn.getName(), password ); 379 } 380 381 382 public static LdapConnection getConnectionAs( String host, int port, String dn, String password ) throws Exception 383 { 384 LdapConnection connection = new LdapConnection( host, port ); 385 connection.bind( dn, password ); 386 openConnections.add( connection ); 387 return connection; 388 } 389 390 391 public static void closeConections() 392 { 393 394 for( LdapConnection con : openConnections ) 395 { 396 if( con == null ) 397 { 398 continue; 399 } 400 401 try 402 { 403 if( con.isConnected() ) 404 { 405 con.close(); 406 } 407 } 408 catch( Exception e ) 409 { 410 // shouldn't happen, but print the stacktrace so that less pain during development to find the cause 411 e.printStackTrace(); 412 } 413 } 414 415 openConnections.clear(); 416 } 417 }