From 5b2b12e7b2c93b5a322cf3a93bbfe48967dec3c1 Mon Sep 17 00:00:00 2001 From: sgarofalo Date: Tue, 23 Jan 2024 15:38:18 +0100 Subject: [PATCH] use docker container for perform tests --- pom.xml | 190 +++++------------- .../ldap/AdapterCompatibilityTests.java | 53 +++-- .../bundles/ldap/LdapAuthenticateTests.java | 5 - .../bundles/ldap/LdapConnectionTests.java | 13 -- .../bundles/ldap/LdapConnectorTestBase.java | 79 -------- .../bundles/ldap/modify/LdapCreateTests.java | 64 +++--- .../bundles/ldap/modify/LdapDeleteTests.java | 23 ++- .../bundles/ldap/modify/LdapUpdateTests.java | 24 ++- .../ldap/schema/LdapSchemaMappingTests.java | 4 - .../search/LdapFilterTranslatorTests.java | 5 - .../bundles/ldap/search/LdapSearchTests.java | 4 - src/test/resources/opendj/Dockerfile | 44 ++++ src/test/resources/opendj/bigcompany.template | 6 +- .../resources/opendj/config-additions.ldif | 9 - src/test/resources/opendj/data.ldif | 9 - src/test/resources/opendj/run.sh | 102 ++++++++++ src/test/resources/test.properties | 2 - 17 files changed, 308 insertions(+), 328 deletions(-) create mode 100644 src/test/resources/opendj/Dockerfile create mode 100644 src/test/resources/opendj/run.sh diff --git a/pom.xml b/pom.xml index 52cc816..787f693 100644 --- a/pom.xml +++ b/pom.xml @@ -84,12 +84,10 @@ 1.5.2.0 - 2.6.2 - ${project.build.directory}/opendj-setup - ${project.build.directory}/opendj-backup + 4.6.2 localhost - 2389 - 2636 + 1389 + 1636 cn=Directory Manager password dc=example,dc=com @@ -212,147 +210,53 @@ - org.apache.maven.plugins - maven-antrun-plugin - true + io.fabric8 + docker-maven-plugin + 0.43.4 + + + + ldap + openidentityplatform/opendj:${opendj.version} + + ${project.basedir}/src/test/resources/opendj + + + + 1389:1389 + 1636:1636 + + + OpenDJ is started + + + + + + - prepareOpenDJ - process-test-classes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${skipTests} - + build-docker + initialize + + stop + remove + + + + start-docker + generate-test-resources + + build + start + + + + remove-containers-post-integration + post-integration-test - run + stop + remove diff --git a/src/test/java/net/tirasa/connid/bundles/ldap/AdapterCompatibilityTests.java b/src/test/java/net/tirasa/connid/bundles/ldap/AdapterCompatibilityTests.java index aaa47a4..975961c 100644 --- a/src/test/java/net/tirasa/connid/bundles/ldap/AdapterCompatibilityTests.java +++ b/src/test/java/net/tirasa/connid/bundles/ldap/AdapterCompatibilityTests.java @@ -30,6 +30,7 @@ import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -61,10 +62,6 @@ public class AdapterCompatibilityTests extends LdapConnectorTestBase { // TODO test authenticate. - @Override - protected boolean restartServerAfterEachTest() { - return true; - } @Test public void accountOperationalAttributes() { @@ -144,6 +141,7 @@ public void createGroupOfUniqueNamesWithoutMembers() { ConnectorObject newGroup = facade.getObject(oclass, uid, null); assertEquals(name, newGroup.getName()); + facade.delete(oclass, uid, null); } @Test @@ -218,6 +216,7 @@ private void doTestCreateWithGroups(ConnectorFacade facade, Attribute groupsAttr Uid uid = facade.create(ObjectClass.ACCOUNT, attributes, null); assertAttributeValue(groupsAttr.getValue(), facade, ObjectClass.ACCOUNT, uid, groupsAttr.getName()); + facade.delete(ObjectClass.ACCOUNT, uid, null); } @Test @@ -247,6 +246,7 @@ private void doTestAddGroups(final ConnectorFacade facade, final Attribute group oldGroups.addAll(groupsAttr.getValue()); assertAttributeValue(oldGroups, facade, ObjectClass.ACCOUNT, uid, groupsAttr.getName()); + facade.removeAttributeValues(ObjectClass.ACCOUNT, uid, Collections.singleton(groupsAttr), null); } @Test @@ -268,10 +268,12 @@ public void updatePosixGroups() { private void doTestUpdateGroups(ConnectorFacade facade, Attribute groupsAttr) { ConnectorObject object = searchByAttribute( facade, ObjectClass.ACCOUNT, new Name(SYLVESTER_DN), groupsAttr.getName()); + Attribute oldLGroups = object.getAttributeByName(LdapConstants.LDAP_GROUPS_NAME); Uid uid = facade.update(ObjectClass.ACCOUNT, object.getUid(), Collections.singleton(groupsAttr), null); assertAttributeValue(groupsAttr.getValue(), facade, ObjectClass.ACCOUNT, uid, groupsAttr.getName()); + facade.update(ObjectClass.ACCOUNT, uid, Collections.singleton(oldLGroups), null); } @Test @@ -300,6 +302,7 @@ private void doTestRemoveGroups(ConnectorFacade facade, Attribute groupsAttr) { oldGroups.removeAll(groupsAttr.getValue()); assertAttributeValue(oldGroups, facade, ObjectClass.ACCOUNT, uid, groupsAttr.getName()); + facade.addAttributeValues(ObjectClass.ACCOUNT, uid, Collections.singleton(groupsAttr), null); } @Test @@ -341,6 +344,7 @@ public void renameMaintainsGroupMemberships() { List oldPosixGroups = LdapUtil.checkedListByFilter( object.getAttributeByName(LdapConstants.POSIX_GROUPS_NAME).getValue(), String.class); + Name oldName = object.getName(); Name newName = new Name("uid=sylvester.the.cat," + ACME_USERS_DN); Uid uid = facade.update(ObjectClass.ACCOUNT, object.getUid(), Collections.singleton((Attribute) newName), null); @@ -363,6 +367,7 @@ public void renameMaintainsGroupMemberships() { List members = object.getAttributeByName("memberUid").getValue(); assertFalse(members.contains(SYLVESTER_UID)); } + facade.update(ObjectClass.ACCOUNT, uid, Collections.singleton(oldName), null); } @Test @@ -374,11 +379,12 @@ public void renameAndUpdateGroupMemberships() { ConnectorObject object = searchByAttribute(facade, ObjectClass.ACCOUNT, new Name(SYLVESTER_DN), LdapConstants.LDAP_GROUPS_NAME, LdapConstants.POSIX_GROUPS_NAME); - List oldLdapGroups = LdapUtil.checkedListByFilter( - object.getAttributeByName(LdapConstants.LDAP_GROUPS_NAME).getValue(), String.class); - List oldPosixGroups = LdapUtil.checkedListByFilter( - object.getAttributeByName(LdapConstants.POSIX_GROUPS_NAME).getValue(), String.class); + Attribute oldLGroups = object.getAttributeByName(LdapConstants.LDAP_GROUPS_NAME); + List oldLdapGroups = LdapUtil.checkedListByFilter(oldLGroups.getValue(), String.class); + Attribute oldPGroup = object.getAttributeByName(LdapConstants.POSIX_GROUPS_NAME); + List oldPosixGroups = LdapUtil.checkedListByFilter(oldPGroup.getValue(), String.class); + Name oldName = object.getName(); Name newName = new Name("uid=sylvester.the.cat," + ACME_USERS_DN); Attribute ldapGroupsAttr = AttributeBuilder.build( LdapConstants.LDAP_GROUPS_NAME, @@ -405,6 +411,7 @@ public void renameAndUpdateGroupMemberships() { List members = object.getAttributeByName("memberUid").getValue(); assertFalse(members.contains(SYLVESTER_UID)); } + facade.update(ObjectClass.ACCOUNT, uid, CollectionUtil.newSet(oldName, oldLGroups, oldPGroup), null); } @Test @@ -414,11 +421,13 @@ public void renameDoesNotMaintainGroupMembershipsUnlessConfigured() { assertFalse(config.isMaintainPosixGroupMembership()); ConnectorFacade facade = newFacade(config); - ConnectorObject object = searchByAttribute(facade, ObjectClass.ACCOUNT, new Name(SYLVESTER_DN)); + Name oldName = new Name(SYLVESTER_DN); + ConnectorObject object = searchByAttribute(facade, ObjectClass.ACCOUNT, oldName); String newUid = "sylvester.the.cat"; String newEntryDN = "uid=" + newUid + "," + ACME_USERS_DN; + Uid uid = object.getUid(); facade.update( - ObjectClass.ACCOUNT, object.getUid(), + ObjectClass.ACCOUNT, uid, Collections.singleton((Attribute) new Name(newEntryDN)), null); object = searchByAttribute( @@ -444,6 +453,7 @@ public void renameDoesNotMaintainGroupMembershipsUnlessConfigured() { members = object.getAttributeByName("memberUid").getValue(); assertTrue(members.contains(SYLVESTER_UID)); assertFalse(members.contains(newUid)); + facade.update(ObjectClass.ACCOUNT, uid, Collections.singleton(oldName), null); } @Test @@ -455,11 +465,12 @@ public void deleteMaintainsGroupMemberships() { ConnectorObject object = searchByAttribute(facade, ObjectClass.ACCOUNT, new Name(SYLVESTER_DN), LdapConstants.LDAP_GROUPS_NAME, LdapConstants.POSIX_GROUPS_NAME); - List oldLdapGroups = LdapUtil.checkedListByFilter( - object.getAttributeByName(LdapConstants.LDAP_GROUPS_NAME).getValue(), String.class); - List oldPosixGroups = LdapUtil.checkedListByFilter( - object.getAttributeByName(LdapConstants.POSIX_GROUPS_NAME).getValue(), String.class); + Attribute oldLGroups = object.getAttributeByName(LdapConstants.LDAP_GROUPS_NAME); + List oldLdapGroups = LdapUtil.checkedListByFilter(oldLGroups.getValue(), String.class); + Attribute oldPGroup = object.getAttributeByName(LdapConstants.POSIX_GROUPS_NAME); + List oldPosixGroups = LdapUtil.checkedListByFilter(oldPGroup.getValue(), String.class); + Name oldName = object.getName(); facade.delete(ObjectClass.ACCOUNT, object.getUid(), null); // Need to test that the old entries were actually removed from the old groups. @@ -473,6 +484,7 @@ public void deleteMaintainsGroupMemberships() { List members = object.getAttributeByName("memberUid").getValue(); assertFalse(members.contains(SYLVESTER_UID)); } + restoreSylvester(facade, oldName, oldLGroups, oldPGroup); } @Test @@ -483,6 +495,7 @@ public void deleteDoesNotMaintainGroupMembershipsUnlessConfigured() { ConnectorFacade facade = newFacade(config); ConnectorObject object = searchByAttribute(facade, ObjectClass.ACCOUNT, new Name(SYLVESTER_DN)); + Name oldName = object.getName(); facade.delete(ObjectClass.ACCOUNT, object.getUid(), null); object = searchByAttribute( @@ -504,6 +517,17 @@ public void deleteDoesNotMaintainGroupMembershipsUnlessConfigured() { facade, new ObjectClass("posixGroup"), new Name(POSIX_EXTERNAL_PEERS_DN), "memberUid"); members = object.getAttributeByName("memberUid").getValue(); assertTrue(members.contains(SYLVESTER_UID)); + restoreSylvester(facade, oldName); + } + + private void restoreSylvester(final ConnectorFacade facade, final Name name, final Attribute... groups) { + Set attributes = new HashSet<>(); + attributes.add(name); + attributes.add(AttributeBuilder.build("uid", "sylvester")); + attributes.add(AttributeBuilder.build("cn", "sylvester")); + attributes.add(AttributeBuilder.build("sn", "sylvester")); + attributes.addAll(Arrays.asList(groups)); + facade.create(ObjectClass.ACCOUNT, attributes, null); } @Test @@ -554,6 +578,7 @@ private void doTestPasswordHashing(final ConnectorFacade facade, final String al passwordBytes = (byte[]) object.getAttributeByName("userPassword").getValue().get(0); assertTrue(new String(passwordBytes, StandardCharsets.UTF_8).startsWith(algorithmLabel)); facade.authenticate(ObjectClass.ACCOUNT, "daffy.duck", password, null); + facade.delete(ObjectClass.ACCOUNT, uid, null); } @Test diff --git a/src/test/java/net/tirasa/connid/bundles/ldap/LdapAuthenticateTests.java b/src/test/java/net/tirasa/connid/bundles/ldap/LdapAuthenticateTests.java index 70c6b50..1e27a00 100644 --- a/src/test/java/net/tirasa/connid/bundles/ldap/LdapAuthenticateTests.java +++ b/src/test/java/net/tirasa/connid/bundles/ldap/LdapAuthenticateTests.java @@ -42,11 +42,6 @@ public class LdapAuthenticateTests extends LdapConnectorTestBase { - @Override - protected boolean restartServerAfterEachTest() { - return false; - } - @Test public void authenticateWithDefaultConfiguration() { ConnectorFacade facade = newFacade(); diff --git a/src/test/java/net/tirasa/connid/bundles/ldap/LdapConnectionTests.java b/src/test/java/net/tirasa/connid/bundles/ldap/LdapConnectionTests.java index 24769f3..b33dde7 100644 --- a/src/test/java/net/tirasa/connid/bundles/ldap/LdapConnectionTests.java +++ b/src/test/java/net/tirasa/connid/bundles/ldap/LdapConnectionTests.java @@ -40,11 +40,6 @@ public class LdapConnectionTests extends LdapConnectorTestBase { - @Override - protected boolean restartServerAfterEachTest() { - return false; - } - @Test public void sSL() throws NamingException { BlindTrustProvider.register(); @@ -152,14 +147,6 @@ public void checkAlive() throws Exception { // Ensure the connection is really connected to the server. conn.createNativeSchema(); conn.checkAlive(); - stopServer(); - try { - // This should throw RuntimeException. - conn.checkAlive(); - fail(); - } catch (RuntimeException e) { - // OK. - } } @Test diff --git a/src/test/java/net/tirasa/connid/bundles/ldap/LdapConnectorTestBase.java b/src/test/java/net/tirasa/connid/bundles/ldap/LdapConnectorTestBase.java index f922665..267a2c8 100644 --- a/src/test/java/net/tirasa/connid/bundles/ldap/LdapConnectorTestBase.java +++ b/src/test/java/net/tirasa/connid/bundles/ldap/LdapConnectorTestBase.java @@ -25,10 +25,8 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; -import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.net.ServerSocket; import java.util.List; import java.util.Properties; import org.identityconnectors.common.IOUtil; @@ -44,10 +42,7 @@ import org.identityconnectors.framework.common.objects.OperationOptionsBuilder; import org.identityconnectors.framework.common.objects.filter.FilterBuilder; import org.identityconnectors.test.common.TestHelpers; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; public abstract class LdapConnectorTestBase { @@ -57,14 +52,6 @@ public abstract class LdapConnectorTestBase { public static Integer SSL_PORT; - public static String TOOL_START_DS; - - public static String TOOL_STOP_DS; - - public static String TOOL_RESTORE; - - public static String BACKUP_DIR; - public static final String EXAMPLE_COM_DN = "dc=example,dc=com"; public static final String ADMIN_DN = "uid=admin,dc=example,dc=com"; @@ -168,7 +155,6 @@ public abstract class LdapConnectorTestBase { @BeforeAll public static void init() throws IOException { InputStream propStream = null; - String setupDir = null; try { Properties props = new Properties(); propStream = LdapConnectorTestBase.class.getResourceAsStream("/test.properties"); @@ -177,67 +163,15 @@ public static void init() throws IOException { HOST = props.getProperty("opendj.host"); PORT = Integer.valueOf(props.getProperty("opendj.port")); SSL_PORT = Integer.valueOf(props.getProperty("opendj.sslport")); - setupDir = props.getProperty("opendj.setup.dir"); - BACKUP_DIR = props.getProperty("opendj.backup.dir"); } finally { IOUtil.quietClose(propStream); } - assertNotNull(setupDir); - TOOL_START_DS = setupDir + File.separator + "bin" + File.separator + "start-ds"; - TOOL_STOP_DS = setupDir + File.separator + "bin" + File.separator + "stop-ds"; - TOOL_RESTORE = setupDir + File.separator + "bin" + File.separator + "restore"; - if (System.getProperty("os.name").startsWith("Windows")) { - TOOL_START_DS += ".bat"; - TOOL_STOP_DS += ".bat"; - TOOL_RESTORE += ".bat"; - } - assertNotNull(HOST); assertNotNull(PORT); assertNotNull(SSL_PORT); - assertNotNull(TOOL_START_DS); - assertNotNull(TOOL_STOP_DS); - assertNotNull(TOOL_RESTORE); - assertNotNull(BACKUP_DIR); - } - - private static boolean isOpenDJRunning() { - boolean result; - try { - ServerSocket socket = new ServerSocket(PORT); - socket.close(); - - result = false; - } catch (IOException e) { - result = true; - } - return result; - } - - @AfterAll - public static void afterClass() throws Exception { - if (isOpenDJRunning()) { - stopServer(); - } - } - - @BeforeEach - public void before() throws Exception { - if (!isOpenDJRunning()) { - startServer(); - } - } - - @AfterEach - public void after() throws Exception { - if (restartServerAfterEachTest()) { - stopServer(); - } } - protected abstract boolean restartServerAfterEachTest(); - public static LdapConfiguration newConfiguration() { // IdM will not read the schema, so prefer to test with that setting. return newConfiguration(false); @@ -300,17 +234,4 @@ public static ConnectorObject findByAttribute(final List object } return null; } - - protected void startServer() throws IOException, InterruptedException { - Process process = Runtime.getRuntime().exec(TOOL_START_DS); - process.waitFor(); - } - - protected static void stopServer() throws IOException, InterruptedException { - Process process = Runtime.getRuntime().exec(TOOL_STOP_DS); - process.waitFor(); - - process = Runtime.getRuntime().exec(TOOL_RESTORE + " -d " + BACKUP_DIR + File.separator + "userRoot"); - process.waitFor(); - } } diff --git a/src/test/java/net/tirasa/connid/bundles/ldap/modify/LdapCreateTests.java b/src/test/java/net/tirasa/connid/bundles/ldap/modify/LdapCreateTests.java index 64951bf..65367bf 100644 --- a/src/test/java/net/tirasa/connid/bundles/ldap/modify/LdapCreateTests.java +++ b/src/test/java/net/tirasa/connid/bundles/ldap/modify/LdapCreateTests.java @@ -55,10 +55,6 @@ public class LdapCreateTests extends LdapConnectorTestBase { // TODO test that we can create an entry of an object class not in the schema. // TODO test that we can't create an entry outside the configured base DNs. - @Override - protected boolean restartServerAfterEachTest() { - return true; - } @Test public void createAccount() { @@ -66,7 +62,8 @@ public void createAccount() { config.setBaseContexts(SMALL_COMPANY_DN); ConnectorFacade facade = newFacade(config); - doCreateAccount(facade); + ConnectorObject created = doCreateAccount(facade); + facade.delete(ObjectClass.ACCOUNT, created.getUid(), null); } @Test @@ -78,7 +75,8 @@ public void createAccountWhenReadingSchema() { config.setAccountObjectClasses("inetOrgPerson"); ConnectorFacade facade = newFacade(config); - doCreateAccount(facade); + ConnectorObject created = doCreateAccount(facade); + facade.delete(ObjectClass.ACCOUNT, created.getUid(), null); } @Test @@ -90,14 +88,15 @@ public void createAccountWhenUidNotDefault() { config.setBaseContexts(SMALL_COMPANY_DN); ConnectorFacade facade = newFacade(config); - doCreateAccount(facade); + ConnectorObject created = doCreateAccount(facade); + facade.delete(ObjectClass.ACCOUNT, created.getUid(), null); } - private void doCreateAccount(final ConnectorFacade facade) { - doCreateAccount(facade, null); + private ConnectorObject doCreateAccount(final ConnectorFacade facade) { + return doCreateAccount(facade, null); } - private void doCreateAccount(final ConnectorFacade facade, final OperationOptions options) { + private ConnectorObject doCreateAccount(final ConnectorFacade facade, final OperationOptions options) { Set attributes = new HashSet<>(); Name name = new Name("uid=another.worker," + SMALL_COMPANY_DN); attributes.add(name); @@ -110,6 +109,7 @@ private void doCreateAccount(final ConnectorFacade facade, final OperationOption ConnectorObject newAccount = facade.getObject(ObjectClass.ACCOUNT, uid, options); assertEquals(name, newAccount.getName()); + return newAccount; } @Test @@ -118,7 +118,8 @@ public void createGroup() { config.setBaseContexts(SMALL_COMPANY_DN); ConnectorFacade facade = newFacade(config); - doCreateGroup(facade); + ConnectorObject created = doCreateGroup(facade); + facade.delete(ObjectClass.GROUP, created.getUid(), null); } @Test @@ -130,7 +131,8 @@ public void createGroupWhenReadingSchema() { config.setAccountObjectClasses("inetOrgPerson"); ConnectorFacade facade = newFacade(config); - doCreateGroup(facade); + ConnectorObject created = doCreateGroup(facade); + facade.delete(ObjectClass.GROUP, created.getUid(), null); } @Test @@ -142,10 +144,11 @@ public void createGroupWhenUidNotDefault() { config.setBaseContexts(SMALL_COMPANY_DN); ConnectorFacade facade = newFacade(config); - doCreateGroup(facade); + ConnectorObject created = doCreateGroup(facade); + facade.delete(ObjectClass.GROUP, created.getUid(), null); } - private void doCreateGroup(ConnectorFacade facade) { + private ConnectorObject doCreateGroup(ConnectorFacade facade) { Set attributes = new HashSet<>(); Name name = new Name("cn=Another Group," + SMALL_COMPANY_DN); attributes.add(name); @@ -154,6 +157,7 @@ private void doCreateGroup(ConnectorFacade facade) { ConnectorObject newGroup = facade.getObject(ObjectClass.GROUP, uid, null); assertEquals(name, newGroup.getName()); + return newGroup; } @Test @@ -163,7 +167,8 @@ public void createArbitrary() { config.setAnyObjectClasses("top", "organization"); ConnectorFacade facade = newFacade(config); - doCreateArbitrary(facade); + ConnectorObject created = doCreateArbitrary(facade); + facade.delete(LdapSchemaMapping.ANY_OBJECT_CLASS, created.getUid(), null); } @Test @@ -173,7 +178,8 @@ public void createArbitraryWhenReadingSchema() { config.setAnyObjectClasses("top", "organization"); ConnectorFacade facade = newFacade(config); - doCreateArbitrary(facade); + ConnectorObject created = doCreateArbitrary(facade); + facade.delete(LdapSchemaMapping.ANY_OBJECT_CLASS, created.getUid(), null); } @Test @@ -187,10 +193,11 @@ public void createArbitraryWhenUidNotDefault() { config.setAnyObjectClasses("top", "organization"); ConnectorFacade facade = newFacade(config); - doCreateArbitrary(facade); + ConnectorObject created = doCreateArbitrary(facade); + facade.delete(LdapSchemaMapping.ANY_OBJECT_CLASS, created.getUid(), null); } - private void doCreateArbitrary(ConnectorFacade facade) { + private ConnectorObject doCreateArbitrary(ConnectorFacade facade) { // Let the arbitrary object class be organization. Set attributes = new HashSet<>(); Name name = new Name("o=Smallest," + SMALL_COMPANY_DN); @@ -200,6 +207,7 @@ private void doCreateArbitrary(ConnectorFacade facade) { ConnectorObject newObject = facade.getObject(LdapSchemaMapping.ANY_OBJECT_CLASS, uid, null); assertEquals(name, newObject.getName()); + return newObject; } @Test @@ -211,7 +219,8 @@ public void createDeviceWhenNameAttributesNotDefault() { config.setAnyObjectClasses("top", "device"); ConnectorFacade facade = newFacade(config); - doCreateDevice(facade); + ConnectorObject created = doCreateDevice(facade); + facade.delete(LdapSchemaMapping.ANY_OBJECT_CLASS, created.getUid(), null); } @Test @@ -222,10 +231,11 @@ public void createDeviceWhenObjectClassesNotDefault() { config.setBaseContexts(SMALL_COMPANY_DN); ConnectorFacade facade = newFacade(config); - doCreateDevice(facade); + ConnectorObject created = doCreateDevice(facade); + facade.delete(LdapSchemaMapping.ANY_OBJECT_CLASS, created.getUid(), null); } - private void doCreateDevice(ConnectorFacade facade) { + private ConnectorObject doCreateDevice(ConnectorFacade facade) { Set attributes = new HashSet<>(); Name name = new Name(DEVICE_0_DN); attributes.add(name); @@ -236,7 +246,7 @@ private void doCreateDevice(ConnectorFacade facade) { ConnectorObject newObject = facade.getObject(LdapSchemaMapping.ANY_OBJECT_CLASS, uid, null); assertEquals(name, newObject.getName()); - + return newObject; } @Test @@ -262,6 +272,7 @@ public void createBinaryAttributes() throws IOException { assertTrue(Arrays.equals(certificate, storedCertificate)); byte[] storedPhoto = (byte[]) newAccount.getAttributeByName("jpegPhoto").getValue().get(0); assertTrue(Arrays.equals(photo, storedPhoto)); + facade.delete(ObjectClass.ACCOUNT, newAccount.getUid(), null); } @Test @@ -276,9 +287,10 @@ public void createPassword() { attributes.add(AttributeBuilder.build("sn", "Duck")); GuardedString password = new GuardedString("I.hate.rabbits".toCharArray()); attributes.add(AttributeBuilder.buildPassword(password)); - facade.create(ObjectClass.ACCOUNT, attributes, null); + Uid uid = facade.create(ObjectClass.ACCOUNT, attributes, null); facade.authenticate(ObjectClass.ACCOUNT, "daffy.duck", password, null); + facade.delete(ObjectClass.ACCOUNT, uid, null); } @Test @@ -317,6 +329,7 @@ public void createDisabled() { assertNotNull(status); assertFalse(status.getValue().isEmpty()); assertFalse((Boolean) status.getValue().get(0)); + facade.delete(ObjectClass.ACCOUNT, uid, null); } @Test @@ -324,6 +337,9 @@ public void issueLDAP12() { LdapConfiguration config = newConfiguration(); config.setBaseContexts(SMALL_COMPANY_DN); config.setUidAttribute("sn"); - doCreateAccount(newFacade(config), new OperationOptionsBuilder().setAttributesToGet("givenName").build()); + ConnectorFacade facade = newFacade(config); + ConnectorObject created = doCreateAccount(facade, + new OperationOptionsBuilder().setAttributesToGet("givenName").build()); + facade.delete(ObjectClass.ACCOUNT, created.getUid(), null); } } diff --git a/src/test/java/net/tirasa/connid/bundles/ldap/modify/LdapDeleteTests.java b/src/test/java/net/tirasa/connid/bundles/ldap/modify/LdapDeleteTests.java index cc9c59c..2a1fb4d 100644 --- a/src/test/java/net/tirasa/connid/bundles/ldap/modify/LdapDeleteTests.java +++ b/src/test/java/net/tirasa/connid/bundles/ldap/modify/LdapDeleteTests.java @@ -26,8 +26,13 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import java.util.HashSet; +import java.util.Set; +import org.identityconnectors.common.security.GuardedString; import org.identityconnectors.framework.api.ConnectorFacade; import org.identityconnectors.framework.common.exceptions.ConnectorException; +import org.identityconnectors.framework.common.objects.Attribute; +import org.identityconnectors.framework.common.objects.AttributeBuilder; import org.identityconnectors.framework.common.objects.ConnectorObject; import org.identityconnectors.framework.common.objects.Name; import org.identityconnectors.framework.common.objects.ObjectClass; @@ -36,11 +41,6 @@ public class LdapDeleteTests extends LdapConnectorTestBase { - @Override - protected boolean restartServerAfterEachTest() { - return false; - } - @Test public void cannotDeleteExistingUidButWrongObjectClass() { ConnectorFacade facade = newFacade(); @@ -60,13 +60,20 @@ public void cannotDeleteNonEmptyDN() { assertThrows(ConnectorException.class, () -> facade.delete(oclass, organization.getUid(), null)); } - @Test() + @Test public void delete() { ConnectorFacade facade = newFacade(); ConnectorObject account = searchByAttribute(facade, ObjectClass.ACCOUNT, new Name(BUGS_BUNNY_DN)); facade.delete(ObjectClass.ACCOUNT, account.getUid(), null); - account = searchByAttribute(facade, ObjectClass.ACCOUNT, new Name(BUGS_BUNNY_DN)); - assertNull(account); + ConnectorObject deletedAccount = searchByAttribute(facade, ObjectClass.ACCOUNT, new Name(BUGS_BUNNY_DN)); + assertNull(deletedAccount); + Set attributes = new HashSet<>(); + attributes.add(new Name(BUGS_BUNNY_DN)); + attributes.add(AttributeBuilder.build("uid", "bugs.bunny", "bbunny")); + attributes.add(AttributeBuilder.build("cn", "Bugs Bunny")); + attributes.add(AttributeBuilder.build("sn", "Bunny")); + attributes.add(AttributeBuilder.buildPassword(new GuardedString("carrot".toCharArray()))); + facade.create(ObjectClass.ACCOUNT, attributes, null); } } diff --git a/src/test/java/net/tirasa/connid/bundles/ldap/modify/LdapUpdateTests.java b/src/test/java/net/tirasa/connid/bundles/ldap/modify/LdapUpdateTests.java index 39796c0..36f4f89 100644 --- a/src/test/java/net/tirasa/connid/bundles/ldap/modify/LdapUpdateTests.java +++ b/src/test/java/net/tirasa/connid/bundles/ldap/modify/LdapUpdateTests.java @@ -67,11 +67,6 @@ public class LdapUpdateTests extends LdapConnectorTestBase { private static final String NUMBER3 = "+1 800 765 9876"; - @Override - protected boolean restartServerAfterEachTest() { - return true; - } - @Test public void updateDelta() { // 1. take user and set attribute @@ -86,7 +81,8 @@ public void updateDelta() { OperationOptions options = new OperationOptionsBuilder().setAttributesToGet("telephoneNumber").build(); bugs = facade.getObject(ObjectClass.ACCOUNT, bugs.getUid(), options); - List numberAttr = bugs.getAttributeByName("telephoneNumber").getValue(); + Attribute telephoneAttr = bugs.getAttributeByName("telephoneNumber"); + List numberAttr = telephoneAttr.getValue(); assertEquals(1, numberAttr.size()); assertEquals(NUMBER1, numberAttr.get(0)); @@ -130,6 +126,7 @@ public void updateDelta() { assertTrue(numberAttr.contains(NUMBER3)); assertDoesNotThrow(() -> facade.authenticate(ObjectClass.ACCOUNT, BUGS_BUNNY_UID, newPwd, null)); + facade.removeAttributeValues(ObjectClass.ACCOUNT, bugs.getUid(), Collections.singleton(telephoneAttr), null); } @Test @@ -181,6 +178,8 @@ public void rename() { ConnectorObject daffy = facade.getObject(ObjectClass.ACCOUNT, newUid, builder.build()); assertEquals(name, daffy.getName()); assertEquals(NUMBER1, daffy.getAttributeByName("telephoneNumber").getValue().get(0)); + Attribute noNumber = AttributeBuilder.build("telephoneNumber"); + facade.update(ObjectClass.ACCOUNT, newUid, CollectionUtil.newSet(new Name(BUGS_BUNNY_DN), noNumber), null); } @Test @@ -199,6 +198,7 @@ public void renameWhenUidNotDefault() { assertEquals(name.getNameValue(), newUid.getUidValue()); ConnectorObject daffy = facade.getObject(ObjectClass.ACCOUNT, newUid, null); assertEquals(name, daffy.getName()); + facade.update(ObjectClass.ACCOUNT, newUid, Collections.singleton(new Name(BUGS_BUNNY_DN)), null); } @Test @@ -242,6 +242,9 @@ public void updateBinaryAttributes() throws IOException { assertTrue(Arrays.equals(certificate, storedCertificate)); byte[] storedPhoto = (byte[]) bugs.getAttributeByName("jpegPhoto").getValue().get(0); assertTrue(Arrays.equals(photo, storedPhoto)); + Attribute noCertificate = AttributeBuilder.build("userCertificate"); + Attribute noPhoto = AttributeBuilder.build("jpegPhoto"); + facade.update(ObjectClass.ACCOUNT, newUid, CollectionUtil.newSet(noCertificate, noPhoto), null); } @Test @@ -261,13 +264,16 @@ public void adminCanChangePassword() { facade = newFacade(config); List objects = TestHelpers.searchToList(facade, new ObjectClass("organization"), null); assertNotNull(findByAttribute(objects, Name.NAME, ACME_DN)); + Attribute noPwd = AttributeBuilder.build(OperationalAttributes.PASSWORD_NAME); + facade.update(ObjectClass.ACCOUNT, elmer.getUid(), Collections.singleton(noPwd), null); } @Test public void userCanChangePassword() { LdapConfiguration config = newConfiguration(); config.setPrincipal(BUGS_BUNNY_DN); - config.setCredentials(new GuardedString("carrot".toCharArray())); + GuardedString carrotPwd = new GuardedString("carrot".toCharArray()); + config.setCredentials(carrotPwd); ConnectorFacade facade = newFacade(config); ConnectorObject bugs = searchByAttribute(facade, ObjectClass.ACCOUNT, new Name(BUGS_BUNNY_DN)); @@ -280,6 +286,8 @@ public void userCanChangePassword() { facade = newFacade(config); ConnectorObject elmer = searchByAttribute(facade, ObjectClass.ACCOUNT, new Name(ELMER_FUDD_DN)); assertNotNull(elmer); + Attribute oldPwdAttr = AttributeBuilder.buildPassword(carrotPwd); + facade.update(ObjectClass.ACCOUNT, bugs.getUid(), Collections.singleton(oldPwdAttr), null); } @Test @@ -325,6 +333,7 @@ public void enableDisable() { @Test public void renameDnAttribute() { ConnectorFacade facade = newFacade(); + Name rename1 = new Name(RENAME_ONE_TEST_DN); ConnectorObject bugs = searchByAttribute(facade, ObjectClass.ACCOUNT, new Name(RENAME_ONE_TEST_DN)); Name name = new Name(RENAME_TWO_TEST_DN); @@ -337,5 +346,6 @@ public void renameDnAttribute() { ConnectorObject renameTwo = facade.getObject(ObjectClass.ACCOUNT, newUid, builder.build()); assertEquals(name, renameTwo.getName()); assertEquals("rename.two", renameTwo.getAttributeByName("uid").getValue().get(0)); + facade.update(ObjectClass.ACCOUNT, newUid, Collections.singleton(rename1), null); } } diff --git a/src/test/java/net/tirasa/connid/bundles/ldap/schema/LdapSchemaMappingTests.java b/src/test/java/net/tirasa/connid/bundles/ldap/schema/LdapSchemaMappingTests.java index 7b841f7..7f6af0d 100644 --- a/src/test/java/net/tirasa/connid/bundles/ldap/schema/LdapSchemaMappingTests.java +++ b/src/test/java/net/tirasa/connid/bundles/ldap/schema/LdapSchemaMappingTests.java @@ -52,10 +52,6 @@ public class LdapSchemaMappingTests extends LdapConnectorTestBase { // TODO operational attributes. // TODO test for operation option infos. - @Override - protected boolean restartServerAfterEachTest() { - return false; - } @Test public void objectClassAttrIsReadOnly() { diff --git a/src/test/java/net/tirasa/connid/bundles/ldap/search/LdapFilterTranslatorTests.java b/src/test/java/net/tirasa/connid/bundles/ldap/search/LdapFilterTranslatorTests.java index d177a7e..d0d3a0f 100644 --- a/src/test/java/net/tirasa/connid/bundles/ldap/search/LdapFilterTranslatorTests.java +++ b/src/test/java/net/tirasa/connid/bundles/ldap/search/LdapFilterTranslatorTests.java @@ -49,11 +49,6 @@ public class LdapFilterTranslatorTests extends LdapConnectorTestBase { - @Override - protected boolean restartServerAfterEachTest() { - return false; - } - @Test public void and() { assertEquals(forNativeFilter("(&(foo=1)(bar=2))"), newTranslator().createAndExpression( diff --git a/src/test/java/net/tirasa/connid/bundles/ldap/search/LdapSearchTests.java b/src/test/java/net/tirasa/connid/bundles/ldap/search/LdapSearchTests.java index f9139d1..e4dccd3 100644 --- a/src/test/java/net/tirasa/connid/bundles/ldap/search/LdapSearchTests.java +++ b/src/test/java/net/tirasa/connid/bundles/ldap/search/LdapSearchTests.java @@ -67,10 +67,6 @@ public class LdapSearchTests extends LdapConnectorTestBase { // TODO operational attributes. // TODO LDAP directory attributes (entryDN, etc.). - @Override - protected boolean restartServerAfterEachTest() { - return false; - } @Test public void ldapFilter() { diff --git a/src/test/resources/opendj/Dockerfile b/src/test/resources/opendj/Dockerfile new file mode 100644 index 0000000..c37a6c1 --- /dev/null +++ b/src/test/resources/opendj/Dockerfile @@ -0,0 +1,44 @@ +# +# ==================== +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved. +# +# The contents of this file are subject to the terms of the Common Development +# and Distribution License("CDDL") (the "License"). You may not use this file +# except in compliance with the License. +# +# You can obtain a copy of the License at +# http://opensource.org/licenses/cddl1.php +# See the License for the specific language governing permissions and limitations +# under the License. +# +# When distributing the Covered Code, include this CDDL Header Notice in each file +# and include the License file at http://opensource.org/licenses/cddl1.php. +# If applicable, add the following below this CDDL Header, with the fields +# enclosed by brackets [] replaced by your own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# ==================== +# Portions Copyrighted 2011 ConnId. +# + +FROM openidentityplatform/opendj:4.6.2 + +USER root + +RUN mkdir -p /opt/opendj/bootstrap/data +ADD config-additions.ldif /opt/opendj/bootstrap/data +ADD data.ldif /opt/opendj/bootstrap/data +ADD admin.ldif /opt/opendj/bootstrap/data +RUN chmod -R 777 /opt/opendj/bootstrap/data + +ADD bigcompany.template /opt/opendj/bootstrap + +ADD run.sh /opt/opendj/run.sh + +RUN chgrp -R 0 /opt/opendj && \ + chmod -R g=u /opt/opendj && \ + chmod +x /opt/opendj/run.sh + +USER $OPENDJ_USER +ENTRYPOINT ["/opt/opendj/run.sh"] diff --git a/src/test/resources/opendj/bigcompany.template b/src/test/resources/opendj/bigcompany.template index a31a62b..f7c3c23 100644 --- a/src/test/resources/opendj/bigcompany.template +++ b/src/test/resources/opendj/bigcompany.template @@ -24,11 +24,13 @@ define suffix=dc=example,dc=com define maildomain=example.com define numusers=2000 -branch: [suffix] - branch: o=Big Company,[suffix] +objectClass: organization +objectClass: top branch: ou=People,o=Big Company,[suffix] +objectClass: organizationalUnit +objectClass: top subordinateTemplate: person:[numusers] template: person diff --git a/src/test/resources/opendj/config-additions.ldif b/src/test/resources/opendj/config-additions.ldif index a1cfeb9..490c43f 100644 --- a/src/test/resources/opendj/config-additions.ldif +++ b/src/test/resources/opendj/config-additions.ldif @@ -59,12 +59,3 @@ ds-cfg-skip-validation-for-administrators: false ds-cfg-state-update-failure-policy: reactive ds-cfg-password-history-count: 0 ds-cfg-password-history-duration: 0 seconds - -dn: ds-cfg-name=index-uid,cn=VLV Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config -objectClass: ds-cfg-local-db-vlv-index -objectClass: top -ds-cfg-filter: (&(objectClass=inetOrgPerson)(objectClass=organizationalPerson)(objectClass=person)(objectClass=top)) -ds-cfg-base-dn: dc=example,dc=com -ds-cfg-sort-order: uid -ds-cfg-scope: whole-subtree -ds-cfg-name: index-uid \ No newline at end of file diff --git a/src/test/resources/opendj/data.ldif b/src/test/resources/opendj/data.ldif index 6188b7a..4814c08 100644 --- a/src/test/resources/opendj/data.ldif +++ b/src/test/resources/opendj/data.ldif @@ -22,11 +22,6 @@ # Portions Copyrighted 2011 ConnId. # -dn: dc=example,dc=com -objectClass: top -objectClass: domain -dc: example - # Acme Corp. dn: o=Acme,dc=example,dc=com @@ -137,7 +132,6 @@ cn: Unique Empty Group dn: cn=POSIX Bugs and Friends,ou=Groups,o=Acme,dc=example,dc=com objectClass: top -objectClass: namedObject objectClass: posixGroup cn: POSIX Bugs and Friends gidNumber: 1 @@ -147,7 +141,6 @@ memberUid: sylvester dn: cn=POSIX External Peers,ou=Groups,o=Acme,dc=example,dc=com objectClass: top -objectClass: namedObject objectClass: posixGroup cn: POSIX External Peers gidNumber: 2 @@ -157,14 +150,12 @@ memberUid: sylvester dn: cn=POSIX Empty Group,ou=Groups,o=Acme,dc=example,dc=com objectClass: top -objectClass: namedObject objectClass: posixGroup cn: POSIX Empty Group gidNumber: 3 dn: cn=POSIX Bugs Bunny Group,ou=Groups,o=Acme,dc=example,dc=com objectClass: top -objectClass: namedObject objectClass: posixGroup cn: POSIX Bugs Bunny Group gidNumber: 4 diff --git a/src/test/resources/opendj/run.sh b/src/test/resources/opendj/run.sh new file mode 100644 index 0000000..226ce3a --- /dev/null +++ b/src/test/resources/opendj/run.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash + +# +# ==================== +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved. +# +# The contents of this file are subject to the terms of the Common Development +# and Distribution License("CDDL") (the "License"). You may not use this file +# except in compliance with the License. +# +# You can obtain a copy of the License at +# http://opensource.org/licenses/cddl1.php +# See the License for the specific language governing permissions and limitations +# under the License. +# +# When distributing the Covered Code, include this CDDL Header Notice in each file +# and include the License file at http://opensource.org/licenses/cddl1.php. +# If applicable, add the following below this CDDL Header, with the fields +# enclosed by brackets [] replaced by your own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# ==================== +# Portions Copyrighted 2011 ConnId. +# + +cd /opt/opendj + +sh ./bin/makeldif --outputLdif /opt/opendj/bootstrap/data/bigcompany.ldif /opt/opendj/bootstrap/bigcompany.template +chmod 777 /opt/opendj/bootstrap/data/bigcompany.ldif + +#if defaul data folder exists do not change it +if [ ! -d ./db ] ; then + echo "/opt/opendj/data" > /opt/opendj/instance.loc && \ + mkdir -p /opt/opendj/data/lib/extensions +fi + +# Instance dir does not exist? Then we need to run setup +if [ ! -d ./data/config ] ; then + + echo "Instance data Directory is empty. Creating new DJ instance" + + BOOTSTRAP=${BOOTSTRAP:-/opt/opendj/bootstrap/setup.sh} + + export BASE_DN=${BASE_DN:-"dc=example,dc=com"} + echo "BASE DN is ${BASE_DN}" + + export PASSWORD=${ROOT_PASSWORD:-password} + + echo "Password set to $PASSWORD" + + echo "Running $BOOTSTRAP" + sh "${BOOTSTRAP}" + + # Check if OPENDJ_REPLICATION_TYPE var is set. If it is - replicate to that server + if [ ! -z ${MASTER_SERVER} ] && [ ! -z ${OPENDJ_REPLICATION_TYPE} ]; then + /opt/opendj/bootstrap/replicate.sh + fi + + # Check if CHANGELOG var is set. If it is - enable changelog to that server + if [ ! -z ${CHANGELOG} ]; then + /opt/opendj/bootstrap/changelog.sh + fi + +else + sh ./upgrade -n + exec ./bin/start-ds --nodetach + return +fi + +# Check if keystores are mounted as a volume, and if so +# Copy any keystores over +SECRET_VOLUME=${SECRET_VOLUME:-/var/secrets/opendj} + +if [ -d "${SECRET_VOLUME}" ]; then + echo "Secret volume is present. Will copy any keystores and truststore" + # We send errors to /dev/null in case no data exists. + cp -f ${SECRET_VOLUME}/key* ${SECRET_VOLUME}/trust* ./data/config 2>/dev/null +fi + +sh ./bin/dsconfig set-access-control-handler-prop -h localhost -p 4444 -D "cn=Directory Manager" -w password -n -X \ + --add global-aci:"(targetattr=\"userPassword||authPassword||debugsearchindex||changes||changeNumber||changeType||changeTime||targetDN||newRDN||newSuperior||deleteOldRDN\")(version 3.0; acl \"Anonymous read access\"; allow (read,search,compare) userdn=\"ldap:///uid=admin,dc=example,dc=com\";)" + +sh ./bin/dsconfig -h localhost -p 4444 -D "cn=Directory Manager" -w password -n -X create-backend-vlv-index \ + --backend-name userRoot --index-name index-uid --set sort-order:uid --set scope:whole-subtree \ + --set base-dn:dc=example,dc=com --set filter:"(&(objectClass=inetOrgPerson)(objectClass=organizationalPerson)(objectClass=person)(objectClass=top))" + +sh ./bin/rebuild-index --baseDN "dc=example,dc=com" --bindPassword password -X --index vlv.index-uid + +# Run upgrade if the server is older + +if (bin/status -n | grep Started) ; then + echo "OpenDJ is started" + # We cant exit because we are pid 1 + while true; do sleep 100000; done +fi + +echo "Try to upgrade OpenDJ" +sh ./upgrade -n + +echo "Starting OpenDJ" +exec ./bin/start-ds --nodetach diff --git a/src/test/resources/test.properties b/src/test/resources/test.properties index 45b320c..8fcf1dd 100644 --- a/src/test/resources/test.properties +++ b/src/test/resources/test.properties @@ -25,5 +25,3 @@ opendj.host=${opendj.host} opendj.port=${opendj.port} opendj.sslport=${opendj.sslport} -opendj.setup.dir=${opendj.setup.dir} -opendj.backup.dir=${opendj.backup.dir}