TestModifyDNOperation.java revision 4f6891a8bd4d017a41b5f75748398ff59787501c
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2010 Sun Microsystems, Inc.
* Portions Copyright 2011-2015 ForgeRock AS.
* Portions copyright 2013 Manuel Gaupp
*/
@SuppressWarnings("javadoc")
public class TestModifyDNOperation extends OperationTestCase
{
private InternalClientConnection proxyUserConn;
{
// Add the example.com entry
"dn: dc=example,dc=com",
"objectclass: top",
"objectclass: domain",
"dc: example",
"aci: (targetattr=\"*\")(version 3.0; acl \"Proxy Rights\"; " +
"allow(proxy) userdn=\"ldap:///uid=proxy.user,o=test\";)"
);
// Add the people entry
"dn: ou=People,dc=example,dc=com",
"objectclass: top",
"objectclass: organizationalUnit",
"ou: People"
);
// Add a test entry.
"dn: uid=user.0,ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"givenName: Aaccf",
"sn: Amar",
"cn: Aaccf Amar",
"initials: AQA",
"employeeNumber: 0",
"uid: user.0",
"mail: user.0@example.com",
"userPassword: password",
"telephoneNumber: 380-535-2354",
"homePhone: 707-626-3913",
"pager: 456-345-7750",
"mobile: 366-674-7274",
"street: 99262 Eleventh Street",
"l: Salem",
"st: NM",
"postalCode: 36530",
"postalAddress: Aaccf Amar$99262 Eleventh Street$Salem, NM 36530",
"description: This is the description for Aaccf Amar."
);
// Add a user capable of using the proxied authorization control.
"dn: uid=proxy.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: proxy.user",
"givenName: Proxy",
"sn: User",
"cn: Proxy User",
"userPassword: password",
"ds-privilege-name: bypass-acl",
"ds-privilege-name: proxied-auth");
}
/**
* Invokes a number of operation methods on the provided modify operation
* for which all processing has been completed. This method is used for
* tests that bypass the referential integrity plugin for whatever reason.
*
* @param modifyDNOperation The operation to be tested.
*/
private void
{
// assertEquals(InvocationCounterPlugin.getPreParseCount(), 1);
// assertEquals(InvocationCounterPlugin.getPreOperationCount(), 1);
// assertEquals(InvocationCounterPlugin.getPostOperationCount(), 1);
// assertEquals(InvocationCounterPlugin.getPostResponseCount(), 1);
}
/**
* Invokes a number of operation methods on the provided modify operation
* for which all processing has been completed. The counters
* postResponseCount and preParseCount are incremented twice when
* referential integrity plugin is enabled.
*
* @param modifyDNOperation The operation to be tested.
*/
{
// assertEquals(InvocationCounterPlugin.getPreParseCount(), 2);
// assertEquals(InvocationCounterPlugin.getPreOperationCount(), 1);
// assertEquals(InvocationCounterPlugin.getPostOperationCount(), 1);
// assertEquals(InvocationCounterPlugin.getPostResponseCount(), 2);
}
/**
* Invokes a number of operation methods on the provided modify operation
* for which the pre-operation plugin was not called.
*
* @param modifyDNOperation The operation to be tested.
*/
{
// assertEquals(InvocationCounterPlugin.getPreParseCount(), 1);
// assertEquals(InvocationCounterPlugin.getPreOperationCount(), 0);
// assertEquals(InvocationCounterPlugin.getPostOperationCount(), 1);
// assertEquals(InvocationCounterPlugin.getPostResponseCount(), 1);
}
/**
* Invokes a number of operation methods on the provided modify operation
* for which an error was found during parsing.
*
* @param modifyDNOperation The operation to be tested.
*/
{
// assertEquals(InvocationCounterPlugin.getPreParseCount(), 1);
// assertEquals(InvocationCounterPlugin.getPreOperationCount(), 0);
// assertEquals(InvocationCounterPlugin.getPostOperationCount(), 0);
// assertEquals(InvocationCounterPlugin.getPostResponseCount(), 1);
}
/** {@inheritDoc} */
{
return new ModifyDNOperationBasis[] {
};
}
{
}
{
}
throws DirectoryException
{
{
assertEquals(newEntry.hasValue(attribute, null, ByteString.valueOf("user.test0")), userTest0Exists);
}
}
@Test
public void testRawModify() throws Exception
{
null);
"uid=user.test0,ou=People,dc=example,dc=com", true, true);
null);
"uid=user.0,ou=People,dc=example,dc=com", true, false);
}
@Test
public void testProcessedModify() throws Exception
{
null);
"uid=user.test0,ou=People,dc=example,dc=com", true, true);
null);
"uid=user.0,ou=People,dc=example,dc=com", true, false);
}
/**
* Test if it's possible to modify an rdn to a value that matches the current value
* by changing the case of some characters.
*/
@Test
public void testModifySameDN() throws Exception
{
null);
"uid=user.0,ou=People,dc=example,dc=com"));
"uid=USER.0,ou=People,dc=example,dc=com");
// There should be only one value for "uid"
// Because deleteOldRDN is true, the values from RDN and the entry have to be identical
null);
"uid=user.0,ou=People,dc=example,dc=com"));
}
/**
* Add another attribute to the RDN and change case of the existing value.
*/
@Test
public void testModifyDNchangeCaseAndAddValue() throws Exception
{
"dn: uid=userid.0,ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: userid.0",
"givenName: Babs",
"sn: Jensen",
"cn: Babs Jensen");
null);
"uid=userid.0+cn=test,ou=People,dc=example,dc=com"));
"uid=UserID.0+cn=Test,ou=People,dc=example,dc=com");
// There should be only one value for "uid"
// Even though the value of the RDN changed, the representation of the entry's value should be preserved
}
/**
* Add a value to the RDN which is already part of the entry, but with another string representation.
*/
@Test
public void testModifyDNchangeCaseOfExistingEntryValue() throws Exception
{
"dn: uid=userid.0,ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: userid.0",
"givenName: Babs",
"sn: Jensen",
"cn: Babs Jensen");
null);
"uid=userid.0+sn=jensen,ou=People,dc=example,dc=com"));
"uid=userid.0+sn=JENSEN,ou=People,dc=example,dc=com");
// There should be only one value for "sn"
// Even though the representation of the sn value differs in the RDN,
// the representation of the entry's value should be preserved
}
@Test
public void testRawDeleteOldRDNModify() throws Exception
{
null);
"uid=user.test0,ou=People,dc=example,dc=com", false, true);
null);
"uid=user.0,ou=People,dc=example,dc=com", true, false);
}
@Test
public void testProcessedDeleteOldRDNModify() throws Exception
{
null);
"uid=user.test0,ou=People,dc=example,dc=com", false, true);
null);
"uid=user.0,ou=People,dc=example,dc=com", true, false);
}
@Test
public void testRawNewSuperiorModify() throws Exception
{
"uid=user.test0,dc=example,dc=com", false, true);
"uid=user.0,ou=People,dc=example,dc=com", true, false);
}
@Test
public void testProcessedNewSuperiorModify() throws Exception
{
"uid=user.test0,dc=example,dc=com", false, true);
"uid=user.0,ou=People,dc=example,dc=com", true, false);
}
@Test
public void testRawRDNModify() throws Exception
{
"cn=Aaccf Amar Test,dc=example,dc=com"));
{
}
"uid=user.0,ou=People,dc=example,dc=com"));
{
}
{
}
}
@Test
public void testInvalidEntryModify() throws Exception
{
}
@Test
public void testInvalidRDNModify() throws Exception
{
}
@Test
public void testInvalidSuperiorModify() throws Exception
{
}
@Test
public void testRawNoSuchDNModify() throws Exception
{
}
@Test
public void testRawNoSuchRDNModify() throws Exception
{
}
@Test
public void testRawInvalidSuperiorModify() throws Exception
{
}
@Test
public void testModifySuffix() throws Exception
{
null);
}
@Test
public void testRawProxyAuthV1Modify() throws Exception
{
null);
"uid=user.test0,ou=People,dc=example,dc=com", true, true);
null);
"uid=user.0,ou=People,dc=example,dc=com", true, false);
}
@Test
public void testProcessedProxyAuthV1Modify() throws Exception
{
"cn=Directory Manager,cn=Root DNs,cn=config"));
null);
"uid=user.test0,ou=People,dc=example,dc=com", true, true);
null);
"uid=user.0,ou=People,dc=example,dc=com", true, false);
}
@Test
public void testProcessedProxyAuthV1DeniedModify() throws Exception
{
null);
}
@Test
public void testProcessedProxyAuthV2Modify() throws Exception
{
"dn:cn=Directory Manager,cn=Root DNs,cn=config"));
null);
"uid=user.test0,ou=People,dc=example,dc=com", true, true);
null);
"uid=user.0,ou=People,dc=example,dc=com", true, false);
}
@Test
public void testProcessedProxyAuthV2DeniedModify() throws Exception
{
null);
}
@Test
public void testProcessedProxyAuthV2CriticalityModify() throws Exception
{
null);
}
@Test
public void testProcessedUnsupportedControlModify() throws Exception
{
new LDAPControl("1.1.1.1.1.1", true);
new ModifyDNOperationBasis(conn, InternalClientConnection.nextOperationID(), InternalClientConnection.nextMessageID(),
null);
}
@Test
public void testShortCircuitModify() throws Exception
{
// Since we are going to be watching the post-response count, we need to
// wait for the server to become idle before kicking off the next request to
// ensure that any remaining post-response processing from the previous
// operation has completed.
// Establish a connection to the server.
LDAPWriter w = new LDAPWriter(s);
bindMessage = r.readMessage();
w.writeMessage(message);
message = r.readMessage();
// assertEquals(InvocationCounterPlugin.waitForPostResponse(), 1);
StaticUtils.close(s);
}
public void testWriteLockModify() throws Exception
{
// We need the operation to be run in a separate thread because we are going
// to write lock the entry in the test case thread and check that the
// modify DN operation does not proceed.
// Establish a connection to the server.
try
{
LDAPWriter w = new LDAPWriter(s);
w.writeMessage(message);
message = r.readMessage();
// Since we are going to be watching the post-response count, we need to
// wait for the server to become idle before kicking off the next request
// to ensure that any remaining post-response processing from the previous
// operation has completed.
try
{
//long modifyDNRequests = ldapStatistics.getModifyDNRequests();
//long modifyDNResponses = ldapStatistics.getModifyDNResponses();
w.writeMessage(message);
message = r.readMessage();
// assertEquals(InvocationCounterPlugin.getPreParseCount(), 1);
// assertEquals(InvocationCounterPlugin.getPreOperationCount(), 0);
// assertEquals(InvocationCounterPlugin.getPostOperationCount(), 0);
// // The post response might not have been called yet.
// assertEquals(InvocationCounterPlugin.waitForPostResponse(), 1);
// assertEquals(ldapStatistics.getModifyDNRequests(), modifyDNRequests+1);
// assertEquals(ldapStatistics.getModifyDNResponses(),
// modifyDNResponses+1);
} finally
{
}
} finally
{
StaticUtils.close(s);
}
}
/**
* Tests performing a modify DN operation in which the new RDN contains an
* attribute type marked OBSOLETE in the server schema.
*/
@Test
public void testModifyDNWithObsoleteAttribute()
throws Exception
{
"dn: cn=schema",
"changetype: modify",
"add: attributeTypes",
"attributeTypes: ( testmodifydnwithobsoleteattribute-oid " +
"NAME 'testModifyDNWithObsoleteAttribute' OBSOLETE " +
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
"X-ORGIN 'SchemaBackendTestCase' )");
{
"-h", "127.0.0.1",
"-D", "cn=Directory Manager",
"-w", "password",
"-f", path
};
"dn: cn=oldrdn,o=test",
"changetype: add",
"objectClass: top",
"objectClass: device",
"objectClass: extensibleObject",
"cn: oldrdn",
"",
"dn: cn=oldrdn,o=test",
"changetype: moddn",
"newRDN: testModifyDNWithObsoleteAttribute=foo",
"deleteOldRDN: 0"
);
{
"-h", "127.0.0.1",
"-D", "cn=Directory Manager",
"-w", "password",
"-f", path
};
}
/**
* Tests a subtree rename operation to ensure that subordinate modify DN
* plugins will be invoked as expected.
*/
@Test
public void testSubordinateModifyDNPluginsForSubtreeRename()
throws Exception
{
try
{
"dn: ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People",
"",
"dn: uid=first.test,ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: first.test",
"givenName: First",
"sn: Test",
"cn: First Test",
"userPassword: Password",
"ou: People",
"",
"dn: uid=second.test,ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: second.test",
"givenName: Second",
"sn: Test",
"cn: Second Test",
"userPassword: Password");
true);
// assertEquals(InvocationCounterPlugin.getSubordinateModifyDNCount(), 2);
}
finally
{
// Other tests in this class rely on a predefined structure, so we need to
// make sure to put it back to the way it should be.
setUp();
}
}
/**
* Tests a subtree move operation to ensure that subordinate modify DN
* plugins will be invoked as expected.
*/
@Test
public void testSubordinateModifyDNPluginsForSubtreeMove()
throws Exception
{
try
{
"dn: ou=Org 1,dc=example,dc=com",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: Org 1",
"",
"dn: ou=Org 2,dc=example,dc=com",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: Org 2",
"",
"dn: ou=Org 1.1,ou=Org 1,dc=example,dc=com",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: Org 1.1",
"",
"dn: uid=first.test,ou=Org 1.1,ou=Org 1,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: first.test",
"givenName: First",
"sn: Test",
"cn: First Test",
"userPassword: Password",
"ou: Org 1.1",
"",
"dn: uid=second.test,ou=Org 1.1,ou=Org 1,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: second.test",
"givenName: Second",
"sn: Test",
"cn: Second Test",
"userPassword: Password");
"ou=Org 2.1", true,
"ou=Org 2,dc=example,dc=com");
// assertEquals(InvocationCounterPlugin.getSubordinateModifyDNCount(), 2);
}
finally
{
// Other tests in this class rely on a predefined structure, so we need to
// make sure to put it back to the way it should be.
setUp();
}
}
@Test
public void testCancelBeforeStartup() throws Exception
{
}
/**
* Tests whether an invalid rdn is allowed during an modrdn operation.
* This test uses a valid attribute type with an empty value.
*
* @throws Exception
*/
public void testInvalidModRDN() throws Exception
{
+"/dc=example,dc=com";
/* Create the initial context */
try
{
"uid=,ou=People,dc=example,dc=com");
}
finally
{
/* Close the context when it's done */
}
}
}