| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| |
| package org.apache.directory.studio.test.integration.junit5; |
| |
| |
| import java.net.InetAddress; |
| import java.net.Socket; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Optional; |
| |
| import org.apache.directory.api.ldap.model.cursor.EntryCursor; |
| import org.apache.directory.api.ldap.model.cursor.SearchCursor; |
| import org.apache.directory.api.ldap.model.entry.Attribute; |
| import org.apache.directory.api.ldap.model.entry.DefaultEntry; |
| import org.apache.directory.api.ldap.model.entry.Entry; |
| import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException; |
| import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException; |
| import org.apache.directory.api.ldap.model.ldif.LdifEntry; |
| import org.apache.directory.api.ldap.model.ldif.LdifReader; |
| import org.apache.directory.api.ldap.model.message.AliasDerefMode; |
| import org.apache.directory.api.ldap.model.message.Control; |
| import org.apache.directory.api.ldap.model.message.DeleteRequest; |
| import org.apache.directory.api.ldap.model.message.DeleteRequestImpl; |
| import org.apache.directory.api.ldap.model.message.SearchRequest; |
| import org.apache.directory.api.ldap.model.message.SearchRequestImpl; |
| import org.apache.directory.api.ldap.model.message.SearchScope; |
| import org.apache.directory.api.ldap.model.name.Dn; |
| import org.apache.directory.api.ldap.model.name.Rdn; |
| import org.apache.directory.api.ldap.model.schema.comparators.DnComparator; |
| import org.apache.directory.ldap.client.api.EntryCursorImpl; |
| import org.apache.directory.ldap.client.api.LdapConnection; |
| import org.apache.directory.studio.connection.core.Controls; |
| import org.junit.jupiter.api.Assumptions; |
| |
| |
| /** |
| * A unified test fixture that defines the DIT structure for all tests and for all test LDAP servers. |
| */ |
| public class TestFixture |
| { |
| |
| public static Dn dn( String dn ) |
| { |
| try |
| { |
| return new Dn( dn ); |
| } |
| catch ( LdapInvalidDnException e ) |
| { |
| throw new RuntimeException( e ); |
| } |
| } |
| |
| |
| public static Dn dn( Rdn rdn, Dn dn ) |
| { |
| try |
| { |
| return dn.add( rdn ); |
| } |
| catch ( LdapInvalidDnException e ) |
| { |
| throw new RuntimeException( e ); |
| } |
| } |
| |
| |
| public static Dn dn( String rdn, Dn dn ) |
| { |
| try |
| { |
| return dn.add( rdn ); |
| } |
| catch ( LdapInvalidDnException e ) |
| { |
| throw new RuntimeException( e ); |
| } |
| } |
| |
| public static final String KRB5_REALM = "EXAMPLE>COM"; |
| public static final String KDC_HOST = "kerby.example.com"; |
| public static final int KDC_PORT = 60088; |
| |
| public static void skipIfKdcServerIsNotAvailable() |
| { |
| boolean available = false; |
| try(Socket s = new Socket(KDC_HOST, KDC_PORT)) |
| { |
| available = true; |
| } |
| catch ( Exception e ) |
| { |
| available = false; |
| } |
| |
| if ( !available ) |
| { |
| Assumptions.assumeTrue( false, |
| "Skip test because KDC server " + KDC_HOST + " is not available" ); |
| } |
| } |
| |
| public static final String OBJECT_CLASS_ALL_FILTER = "(objectClass=*)"; |
| |
| public static final String TEST_FIXTURE_LDIF = "TestFixture.ldif"; |
| |
| public static final Dn CONTEXT_DN = dn( "dc=example,dc=org" ); |
| |
| public static final Dn MISC_DN = dn( "ou=misc", CONTEXT_DN ); |
| public static final Dn MISC1_DN = dn( "ou=misc.1", MISC_DN ); |
| public static final Dn MISC11_DN = dn( "ou=misc.1.1", MISC1_DN ); |
| public static final Dn MISC111_DN = dn( "ou=misc.1.1.1", MISC11_DN ); |
| public static final Dn BJENSEN_DN = dn( "cn=Barbara Jensen", MISC_DN ); |
| public static final Dn HNELSON_DN = dn( "uid=hnelson", MISC_DN ); |
| public static final Dn GERMAN_UMLAUT_DN = dn( "cn=Wolfgang K\u00f6lbel", MISC_DN ); |
| public static final Dn MULTI_VALUED_RDN_DN = dn( "cn=Barbara Jensen+uid=bjensen", MISC_DN ); |
| public static final Dn DN_WITH_LEADING_SHARP_BACKSLASH_PREFIXED = dn( "cn=\\#123456", MISC_DN ); |
| public static final Dn DN_WITH_LEADING_SHARP_HEX_PAIR_ESCAPED = dn( "cn=\\23123456", MISC_DN ); |
| public static final Dn DN_WITH_ESCAPED_CHARACTERS_BACKSLASH_PREFIXED = dn( "cn=\\\"\\+\\,\\;\\<\\>\\\\", MISC_DN ); |
| public static final Dn DN_WITH_ESCAPED_CHARACTERS_HEX_PAIR_ESCAPED = dn( "cn=\\22\\2B\\2C\\3B\\3C\\3E\\5C", |
| MISC_DN ); |
| public static final Dn DN_WITH_TRAILING_EQUALS_CHARACTER = dn( "cn=trailing=", MISC_DN ); |
| public static final Dn DN_WITH_TRAILING_EQUALS_CHARACTER_HEX_PAIR_ESCAPED = dn( "cn=trailing\\3D", MISC_DN ); |
| public static final Dn DN_WITH_IP_HOST_NUMBER = dn( "cn=loopback+ipHostNumber=127.0.0.1", MISC_DN ); |
| public static final Dn ALIAS_DN = dn( "cn=alias", MISC_DN ); |
| public static final Dn SUBENTRY_DN = dn( "cn=subentry", MISC_DN ); |
| |
| public static final Dn USERS_DN = dn( "ou=users", CONTEXT_DN ); |
| public static final Dn USER1_DN = dn( "uid=user.1", USERS_DN ); |
| public static final Dn USER2_DN = dn( "uid=user.2", USERS_DN ); |
| public static final Dn USER3_DN = dn( "uid=user.3", USERS_DN ); |
| public static final Dn USER4_DN = dn( "uid=user.4", USERS_DN ); |
| public static final Dn USER5_DN = dn( "uid=user.5", USERS_DN ); |
| public static final Dn USER8_DN = dn( "uid=user.8", USERS_DN ); |
| |
| public static final Dn GROUPS_DN = dn( "ou=groups", CONTEXT_DN ); |
| public static final Dn GROUP1_DN = dn( "cn=group.1", GROUPS_DN ); |
| |
| public static final Dn TARGET_DN = dn( "ou=target", CONTEXT_DN ); |
| |
| public static final Dn REFERRALS_DN = dn( "ou=referrals", CONTEXT_DN ); |
| public static final Dn REFERRAL_TO_USERS_DN = dn( "cn=referral-to-users", REFERRALS_DN ); |
| public static final Dn REFERRAL_TO_USER1_DN = dn( "cn=referral-to-user.1", REFERRALS_DN ); |
| public static final Dn REFERRAL_TO_REFERRAL_TO_USERS_DN = dn( "cn=referral-to-referral-to-users", REFERRALS_DN ); |
| public static final Dn REFERRAL_TO_REFERRALS_DN = dn( "cn=referral-to-referrals", REFERRALS_DN ); |
| public static final Dn REFERRAL_LOOP_1_DN = dn( "cn=referral-loop-1", REFERRALS_DN ); |
| public static final Dn REFERRAL_LOOP_2_DN = dn( "cn=referral-loop-2", REFERRALS_DN ); |
| public static final Dn REFERRAL_TO_MISC_DN = dn( "cn=referral-to-misc", REFERRALS_DN ); |
| |
| /** |
| * Creates the context entry "dc=example,dc=org" if it doesn't exist yet. |
| */ |
| public static void createContextEntry( TestLdapServer ldapServer ) |
| { |
| ldapServer.withAdminConnection( connection -> { |
| if ( !connection.exists( CONTEXT_DN ) ) |
| { |
| connection.add( |
| new DefaultEntry( CONTEXT_DN, "objectClass", "top", "objectClass", "domain", "dc", "example" ) ); |
| } |
| } ); |
| } |
| |
| |
| public static void importData( TestLdapServer ldapServer ) |
| { |
| ldapServer.withAdminConnection( connection -> { |
| try ( LdifReader ldifReader = new LdifReader( TestFixture.class.getResourceAsStream( TEST_FIXTURE_LDIF ) ) ) |
| { |
| ldifReader.setSchemaManager( connection.getSchemaManager() ); |
| for ( LdifEntry entry : ldifReader ) |
| { |
| replaceRefLdapUrl( ldapServer, entry ); |
| connection.add( entry.getEntry() ); |
| } |
| } |
| } ); |
| } |
| |
| |
| private static void replaceRefLdapUrl( TestLdapServer ldapServer, LdifEntry entry ) |
| throws LdapInvalidAttributeValueException |
| { |
| Attribute ref = entry.get( "ref" ); |
| if ( ref != null ) |
| { |
| String oldRefLdapUrl = ref.getString(); |
| String newRefLdapUrl = oldRefLdapUrl.replace( "replace-with-host-port", |
| ldapServer.getHost() + ":" + ldapServer.getPort() ); |
| ref.remove( oldRefLdapUrl ); |
| ref.add( newRefLdapUrl ); |
| } |
| } |
| |
| |
| /** |
| * Cleans all test data. |
| */ |
| public static void cleanup( TestLdapServer ldapServer ) |
| { |
| ldapServer.withAdminConnection( connection -> { |
| // skip cleanup if context entry doesn't exist yet |
| if ( !connection.exists( CONTEXT_DN ) ) |
| { |
| return; |
| } |
| |
| // delete ou=referrals |
| deleteTree( connection, REFERRALS_DN, Optional.empty() ); |
| // delete ou=groups |
| deleteTree( connection, GROUPS_DN, Optional.empty() ); |
| // delete ou=users |
| deleteTree( connection, USERS_DN, Optional.empty() ); |
| // delete ou=misc |
| deleteTree( connection, MISC_DN, Optional.of( Controls.SUBENTRIES_CONTROL ) ); |
| deleteTree( connection, MISC_DN, Optional.empty() ); |
| // delete ou=target |
| deleteTree( connection, TARGET_DN, Optional.of( Controls.SUBENTRIES_CONTROL ) ); |
| deleteTree( connection, TARGET_DN, Optional.empty() ); |
| } ); |
| } |
| |
| |
| private static void deleteTree( LdapConnection connection, Dn baseDn, Optional<Control> control ) |
| throws Exception |
| { |
| SearchRequest searchRequest = new SearchRequestImpl(); |
| searchRequest.setBase( baseDn ); |
| searchRequest.setFilter( OBJECT_CLASS_ALL_FILTER ); |
| searchRequest.setScope( SearchScope.SUBTREE ); |
| searchRequest.setDerefAliases( AliasDerefMode.NEVER_DEREF_ALIASES ); |
| searchRequest.addControl( Controls.MANAGEDSAIT_CONTROL ); |
| control.ifPresent( c -> searchRequest.addControl( c ) ); |
| |
| try ( SearchCursor searchCursor = connection.search( searchRequest ); |
| EntryCursor entryCursor = new EntryCursorImpl( searchCursor ) ) |
| { |
| List<Dn> dns = new ArrayList<>(); |
| for ( Entry entry : entryCursor ) |
| { |
| dns.add( entry.getDn() ); |
| } |
| dns.sort( new DnComparator( "1.1" ) ); |
| for ( Dn dn : dns ) |
| { |
| DeleteRequest deleteRequest = new DeleteRequestImpl(); |
| deleteRequest.setName( dn ); |
| deleteRequest.addControl( Controls.MANAGEDSAIT_CONTROL ); |
| control.ifPresent( c -> deleteRequest.addControl( c ) ); |
| connection.delete( deleteRequest ); |
| } |
| } |
| } |
| |
| } |