| /* |
| * 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.server.core.subtree; |
| |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| |
| import java.util.Set; |
| |
| import org.apache.directory.server.core.administrative.AdministrativePoint; |
| import org.apache.directory.server.core.administrative.Subentry; |
| import org.apache.directory.server.core.annotations.ApplyLdifs; |
| import org.apache.directory.server.core.annotations.CreateDS; |
| import org.apache.directory.server.core.integ.FrameworkRunner; |
| import org.apache.directory.shared.ldap.entry.Entry; |
| import org.apache.directory.shared.ldap.entry.EntryAttribute; |
| import org.apache.directory.shared.ldap.ldif.LdifUtils; |
| import org.apache.directory.shared.ldap.message.AddResponse; |
| import org.apache.directory.shared.ldap.message.ModifyDnResponse; |
| import org.apache.directory.shared.ldap.message.ResultCodeEnum; |
| import org.apache.directory.shared.ldap.name.DN; |
| import org.apache.directory.shared.ldap.util.tree.DnNode; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| |
| /** |
| * Test cases for the AdministrativePoint interceptor Add operation. |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| */ |
| @RunWith(FrameworkRunner.class) |
| @CreateDS(name = "AdministrativePointServiceIT") |
| @ApplyLdifs( |
| { |
| // An entry used to create a User session |
| "dn: cn=testUser,ou=system", |
| "objectClass: top", |
| "objectClass: person", |
| "cn: testUser", |
| "sn: test User", |
| "userpassword: test", |
| "", |
| // An entry used as a root for tests |
| "dn: ou=test,ou=system", |
| "objectClass: top", |
| "objectClass: organizationalUnit", |
| "ou: test" |
| }) |
| public class SubentryRenameOperationIT extends AbstractSubentryUnitTest |
| { |
| // =================================================================== |
| // Test the Rename operation for APs |
| // ------------------------------------------------------------------- |
| // Failure expected |
| // ------------------------------------------------------------------- |
| |
| |
| // ------------------------------------------------------------------- |
| // Success expected |
| // ------------------------------------------------------------------- |
| /** |
| * |
| */ |
| @Test |
| public void testRenameSAP() throws Exception |
| { |
| DN sapDn = service.getDNFactory().create( "ou=SAP,ou=system" ); |
| DN sapDnNew = service.getDNFactory().create( "ou=SAPnew,ou=system" ); |
| |
| // First add an SAP |
| createCaSAP( "ou=SAP,ou=system" ); |
| |
| // Add a subentry |
| createCaSubentry( "cn=test,ou=SAP,ou=system", "{}" ); |
| |
| // Add an entry |
| Entry e1 = LdifUtils.createEntry( |
| "ou=e1,ou=SAP,ou=system", |
| "ObjectClass: top", |
| "ObjectClass: organizationalUnit", |
| "ou: e1" ); |
| |
| createEntryAdmin( e1 ); |
| |
| long sapCaSeqNumber = getCaSeqNumber( "ou=SAP,ou=system" ); |
| |
| // Now, try to rename the SAP |
| ModifyDnResponse response = adminConnection.rename( "ou=SAP,ou=system", "ou=SAPnew" ); |
| |
| assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() ); |
| |
| // Check that the seqNumber has not changed |
| assertNull( adminConnection.lookup( sapDn, "CollectiveAttributeSeqNumber" ) ); |
| assertEquals( sapCaSeqNumber, getCaSeqNumber( "ou=SAPnew,ou=system" ) ); |
| |
| // Check that the cache have been updated |
| DnNode<AdministrativePoint> caCache = service.getCollectiveAttributeAPCache(); |
| |
| assertNull( caCache.getElement( sapDn ) ); |
| assertNotNull( caCache.getElement( sapDnNew ) ); |
| } |
| |
| |
| /** |
| * Test a rename of an IAP. We will use this data structure : |
| * <pre> |
| * ou=test,ou=system |
| * | |
| * +-- [ou=SAP] |
| * | |
| * +-- <cn=test1> base="ou=europe,ou=IAP2,ou=IAP1", will select europe, france, paris |
| * | |
| * +-- ou=IAP1 |
| * | |
| * +-- <cn=test2> base="ou=france,ou=europe,ou=IAP2" will select france, paris |
| * | |
| * +-- ou=IAP2 |
| * | |
| * +-- <cn=test3> base="ou=paris,ou=france,ou=europe" will select paris |
| * | |
| * +-- ou=europe |
| * | |
| * +-- ou=france |
| * | |
| * +-- ou=paris |
| * </pre> |
| * |
| * We will rename ou=IAP2, and the cn=test1 or cn=test2 will now select nothing |
| */ |
| @Test |
| public void testRenameIAP() throws Exception |
| { |
| // Create the APs |
| createCaSAP( "ou=SAP,ou=test,ou=system" ); |
| createCaIAP( "ou=IAP1,ou=SAP,ou=test,ou=system" ); |
| createCaIAP( "ou=IAP2,ou=IAP1,ou=SAP,ou=test,ou=system" ); |
| |
| // Create the subentries |
| createCaSubentry( "cn=test1,ou=SAP,ou=test,ou=system", "{base \"ou=europe,ou=IAP2,ou=IAP1\"}" ); |
| createCaSubentry( "cn=test2,ou=IAP1,ou=SAP,ou=test,ou=system", "{base \"ou=france,ou=europe,ou=IAP2\"}" ); |
| createCaSubentry( "cn=test3,ou=IAP2,ou=IAP1,ou=SAP,ou=test,ou=system", "{base \"ou=paris,ou=france,ou=europe\"}" ); |
| |
| // Add entries |
| Entry e1 = LdifUtils.createEntry( |
| "ou=europe,ou=IAP2,ou=IAP1,ou=SAP,ou=test,ou=system", |
| "ObjectClass: top", |
| "ObjectClass: organizationalUnit", |
| "ou: europe" ); |
| |
| createEntryAdmin( e1 ); |
| |
| Entry e2 = LdifUtils.createEntry( |
| "ou=france,ou=europe,ou=IAP2,ou=IAP1,ou=SAP,ou=test,ou=system", |
| "ObjectClass: top", |
| "ObjectClass: organizationalUnit", |
| "ou: france" ); |
| |
| createEntryAdmin( e2 ); |
| |
| Entry e3 = LdifUtils.createEntry( |
| "ou=paris,ou=france,ou=europe,ou=IAP2,ou=IAP1,ou=SAP,ou=test,ou=system", |
| "ObjectClass: top", |
| "ObjectClass: organizationalUnit", |
| "ou: paris" ); |
| |
| createEntryAdmin( e3 ); |
| |
| // Check that the entries are referring the subentries |
| String sapUuid = getEntryUuid( "cn=test1,ou=SAP,ou=test,ou=system" ); |
| String iap1Uuid = getEntryUuid( "cn=test2,ou=IAP1,ou=SAP,ou=test,ou=system" ); |
| String iap2Uuid = getEntryUuid( "cn=test3,ou=IAP2,ou=IAP1,ou=SAP,ou=test,ou=system" ); |
| |
| e1 = adminConnection.lookup( "ou=europe,ou=IAP2,ou=IAP1,ou=SAP,ou=test,ou=system", "+" ); |
| e2 = adminConnection.lookup( "ou=france,ou=europe,ou=IAP2,ou=IAP1,ou=SAP,ou=test,ou=system", "+" ); |
| e3 = adminConnection.lookup( "ou=paris,ou=france,ou=europe,ou=IAP2,ou=IAP1,ou=SAP,ou=test,ou=system", "+" ); |
| |
| assertTrue( e1.contains( "CollectiveAttributeSubentriesUUID", sapUuid ) ); |
| assertTrue( e2.contains( "CollectiveAttributeSubentriesUUID", sapUuid, iap1Uuid ) ); |
| assertTrue( e3.contains( "CollectiveAttributeSubentriesUUID", sapUuid, iap1Uuid, iap2Uuid ) ); |
| |
| dumpBase( "ou=test,ou=system" ); |
| dumpSubentries( "ou=test,ou=system" ); |
| dumpApCache(); |
| dumpSubentryCache(); |
| |
| // Now, rename IAP2 |
| ModifyDnResponse response = adminConnection.rename( "ou=IAP2,ou=IAP1,ou=SAP,ou=test,ou=system", "ou=IAPnew" ); |
| |
| assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() ); |
| |
| dumpBase( "ou=test,ou=system" ); |
| dumpSubentries( "ou=test,ou=system" ); |
| dumpApCache(); |
| dumpSubentryCache(); |
| |
| // Check the references |
| e1 = adminConnection.lookup( "ou=europe,ou=IAPnew,ou=IAP1,ou=SAP,ou=test,ou=system", "+" ); |
| e2 = adminConnection.lookup( "ou=france,ou=europe,ou=IAPnew,ou=IAP1,ou=SAP,ou=test,ou=system", "+" ); |
| e3 = adminConnection.lookup( "ou=paris,ou=france,ou=europe,ou=IAPnew,ou=IAP1,ou=SAP,ou=test,ou=system", "+" ); |
| |
| assertFalse( e1.containsAttribute( "CollectiveAttributeSubentriesUUID" ) ); |
| assertFalse( e2.containsAttribute( "CollectiveAttributeSubentriesUUID" ) ); |
| assertTrue( e3.contains( "CollectiveAttributeSubentriesUUID", iap2Uuid ) ); |
| assertFalse( e3.contains( "CollectiveAttributeSubentriesUUID", iap1Uuid, sapUuid ) ); |
| } |
| |
| |
| // =================================================================== |
| // Test the Add operation for Subentries |
| // ------------------------------------------------------------------- |
| // Failure expected |
| // ------------------------------------------------------------------- |
| /** |
| * Test the renaming of a subentry using another AT than CN |
| */ |
| @Test |
| public void testRenameSubentryUsingOC() throws Exception |
| { |
| // First add an SAP |
| createCaSAP( "ou=SAP,ou=system" ); |
| |
| // Add a subentry |
| createCaSubentry( "cn=test,ou=SAP,ou=system", "{}" ); |
| |
| // Now, try to rename the subentry to "objectClass=subentry, ..." |
| ModifyDnResponse response = adminConnection.rename( "cn=test,ou=SAP,ou=system", "objectClass=subentry" ); |
| |
| assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, response.getLdapResult().getResultCode() ); |
| } |
| |
| |
| /** |
| * Test the renaming of a subentry to a name already in use |
| */ |
| @Test |
| public void testRenameSubentryAlreadyExist() throws Exception |
| { |
| // First add an SAP |
| createCaSAP( "ou=SAP,ou=system" ); |
| |
| // Add a subentry |
| createCaSubentry( "cn=test,ou=SAP,ou=system", "{}" ); |
| |
| // Add a second subentry |
| createCaSubentry( "cn=test2,ou=SAP,ou=system", "{}" ); |
| |
| // Now, try to rename the subentry to "sn=test, ..." |
| ModifyDnResponse response = adminConnection.rename( "cn=test,ou=SAP,ou=system", "cn=test2" ); |
| |
| assertEquals( ResultCodeEnum.ENTRY_ALREADY_EXISTS, response.getLdapResult().getResultCode() ); |
| } |
| |
| |
| /** |
| * Test the renaming of a subentry using an empty CN |
| */ |
| @Test |
| public void testRenameSubentryEmptyCN() throws Exception |
| { |
| // First add an SAP |
| createCaSAP( "ou=SAP,ou=system" ); |
| |
| // Add a subentry |
| createCaSubentry( "cn=test,ou=SAP,ou=system", "{}" ); |
| |
| // Now, try to rename the subentry to "cn=,..." |
| ModifyDnResponse response = adminConnection.rename( "cn=test,ou=SAP,ou=system", "cn=" ); |
| |
| assertEquals( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, response.getLdapResult().getResultCode() ); |
| } |
| |
| |
| // ------------------------------------------------------------------- |
| // Success expected |
| // ------------------------------------------------------------------- |
| /** |
| * Test the rename of a subentry under an AAP, with 2 roles |
| */ |
| @Test |
| public void testRenameSubentryUnderAAP() throws Exception |
| { |
| DN aapDn = service.getDNFactory().create( "ou=AAP,ou=system" ); |
| DN oldSubentryDn = service.getDNFactory().create( "cn=test,ou=AAP,ou=system" ); |
| DN newSubentryDn = service.getDNFactory().create( "cn=test1,ou=AAP,ou=system" ); |
| |
| // First add an AAP |
| createAAP( "ou=AAP,ou=system" ); |
| |
| // Add a subentry now |
| Entry subentry = LdifUtils.createEntry( |
| "cn=test,ou=AAP,ou=system", |
| "ObjectClass: top", |
| "ObjectClass: subentry", |
| "ObjectClass: collectiveAttributeSubentry", |
| "ObjectClass: accessControlSubentry", |
| "cn: test", |
| "subtreeSpecification: {}", |
| "c-o: Test Org", |
| "prescriptiveACI: { " |
| + " identificationTag \"addAci\", " |
| + " precedence 14, " |
| + " authenticationLevel none, " |
| + " itemOrUserFirst userFirst: " |
| + " { " |
| + " userClasses { userGroup { \"cn=Administrators,ou=groups,ou=system\" } }," |
| + " userPermissions " |
| + " { " |
| + " { " |
| + " protectedItems { entry, allUserAttributeTypesAndValues }, " |
| + " grantsAndDenials { grantCompare, grantRead, grantBrowse } " |
| + " } " |
| + " } " |
| + " } " |
| + "}" ); |
| |
| AddResponse addResponse = adminConnection.add( subentry ); |
| assertEquals( ResultCodeEnum.SUCCESS, addResponse.getLdapResult().getResultCode() ); |
| |
| long acSeqNumber = getAcSeqNumber( "ou=AAP,ou=system" ); |
| long caSeqNumber = getCaSeqNumber( "ou=AAP,ou=system" ); |
| |
| // Check the rename |
| ModifyDnResponse renameResponse = adminConnection.rename( "cn=test,ou=AAP,ou=system", "cn=test1" ); |
| assertEquals( ResultCodeEnum.SUCCESS, renameResponse.getLdapResult().getResultCode() ); |
| |
| // The SeqNumber should not have changed |
| assertEquals(acSeqNumber, getAcSeqNumber( "ou=AAP,ou=system" ) ); |
| assertEquals(caSeqNumber, getCaSeqNumber( "ou=AAP,ou=system" ) ); |
| |
| // The APCache should point to the new subentries |
| // First, AC |
| AdministrativePoint acAP = service.getAccessControlAPCache().getElement( aapDn ); |
| |
| assertNotNull( acAP ); |
| Set<Subentry> subentries = acAP.getSubentries(); |
| |
| assertNotNull( subentries ); |
| |
| for ( Subentry sub : subentries ) |
| { |
| assertEquals( "test1", sub.getCn().getString() ); |
| } |
| |
| // Then CA |
| AdministrativePoint caAP = service.getAccessControlAPCache().getElement( aapDn ); |
| |
| assertNotNull( caAP ); |
| subentries = caAP.getSubentries(); |
| |
| assertNotNull( subentries ); |
| |
| for ( Subentry sub : subentries ) |
| { |
| assertEquals( "test1", sub.getCn().getString() ); |
| } |
| |
| // Now check the UUID cache |
| Subentry[] subArray = service.getSubentryCache().getSubentries( oldSubentryDn ); |
| |
| assertNull( subArray ); |
| |
| subArray = service.getSubentryCache().getSubentries( newSubentryDn ); |
| |
| assertNotNull( subArray ); |
| |
| for ( Subentry sub : subentries ) |
| { |
| if ( sub != null ) |
| { |
| assertEquals( "test1", sub.getCn().getString() ); |
| } |
| } |
| } |
| |
| |
| /** |
| * Test the rename of a subentry under a SAP |
| */ |
| @Test |
| public void testRenameSubentryUnderSAP() throws Exception |
| { |
| DN sapDn = service.getDNFactory().create( "ou=SAP,ou=system" ); |
| DN oldSubentryDn = service.getDNFactory().create( "cn=test,ou=SAP,ou=system" ); |
| DN newSubentryDn = service.getDNFactory().create( "cn=test1,ou=SAP,ou=system" ); |
| |
| // First add an SAP |
| createCaSAP( "ou=SAP,ou=system" ); |
| |
| // Add a subentry now |
| createCaSubentry( "cn=test,ou=SAP,ou=system", "{}" ); |
| |
| long caSeqNumber = getCaSeqNumber( "ou=SAP,ou=system" ); |
| |
| // Check the rename |
| ModifyDnResponse renameResponse = adminConnection.rename( "cn=test,ou=SAP,ou=system", "cn=test1" ); |
| assertEquals( ResultCodeEnum.SUCCESS, renameResponse.getLdapResult().getResultCode() ); |
| |
| // The SeqNumber should not have changed |
| assertEquals(caSeqNumber, getCaSeqNumber( "ou=SAP,ou=system" ) ); |
| |
| // The CA APCache should point to the new subentries |
| // Then CA |
| AdministrativePoint caAP = service.getCollectiveAttributeAPCache().getElement( sapDn ); |
| |
| assertNotNull( caAP ); |
| Set<Subentry> subentries = caAP.getSubentries(); |
| |
| assertNotNull( subentries ); |
| |
| for ( Subentry sub : subentries ) |
| { |
| assertEquals( "test1", sub.getCn().getString() ); |
| } |
| |
| // Now check the UUID cache |
| Subentry[] subArray = service.getSubentryCache().getSubentries( oldSubentryDn ); |
| |
| assertNull( subArray ); |
| |
| subArray = service.getSubentryCache().getSubentries( newSubentryDn ); |
| |
| assertNotNull( subArray ); |
| |
| for ( Subentry sub : subentries ) |
| { |
| if ( sub != null ) |
| { |
| assertEquals( "test1", sub.getCn().getString() ); |
| } |
| } |
| } |
| |
| |
| /** |
| * Test the rename of a subentry under a IAP with no reference to a local name |
| */ |
| @Test |
| public void testRenameSubentryUnderIAPNoLocalName() throws Exception |
| { |
| DN iapDn = service.getDNFactory().create( "ou=IAP,ou=SAP,ou=system" ); |
| DN oldSubentryDn = service.getDNFactory().create( "cn=test,ou=IAP,ou=SAP,ou=system" ); |
| DN newSubentryDn = service.getDNFactory().create( "cn=test1,ou=IAP,ou=SAP,ou=system" ); |
| |
| // First add an SAP |
| createCaSAP( "ou=SAP,ou=system" ); |
| |
| // Add a subentry now, with no localname |
| createCaSubentry( "cn=test,ou=SAP,ou=system", "{}" ); |
| |
| long sapCaSeqNumber = getCaSeqNumber( "ou=SAP,ou=system" ); |
| String sapCaSeUuid = getEntryUuid( "cn=test,ou=SAP,ou=system" ); |
| |
| // Add an IAP |
| createCaIAP( "ou=IAP,ou=SAP,ou=system" ); |
| |
| // Add the associated subentry |
| createCaSubentry( "cn=test,ou=IAP,ou=SAP,ou=system", "{}" ); |
| |
| long iapCaSeqNumber = getCaSeqNumber( "ou=IAP,ou=SAP,ou=system" ); |
| String iapCaSeUuid = getEntryUuid( "cn=test,ou=IAP,ou=SAP,ou=system" ); |
| |
| // Add an entry under the SAP |
| Entry e1 = LdifUtils.createEntry( |
| "ou=e1,ou=SAP,ou=system", |
| "ObjectClass: top", |
| "ObjectClass: organizationalUnit", |
| "ou: e1" ); |
| |
| createEntryAdmin( e1 ); |
| |
| // Add an entry under the IAP |
| Entry e2 = LdifUtils.createEntry( |
| "ou=e2,ou=IAP,ou=SAP,ou=system", |
| "ObjectClass: top", |
| "ObjectClass: organizationalUnit", |
| "ou: e2" ); |
| |
| createEntryAdmin( e2 ); |
| |
| // Check that the first entry refers the first subentry |
| assertEquals( sapCaSeUuid, getCaUuidRef( "ou=e1,ou=SAP,ou=system" ) ); |
| |
| // Check that the second entry refers both subentries |
| Entry result = adminConnection.lookup( "ou=e2,ou=IAP,ou=SAP,ou=system", "CollectiveAttributeSubentriesUuid" ); |
| assertNotNull( result ); |
| EntryAttribute attribute = result.get( "CollectiveAttributeSubentriesUuid" ); |
| |
| assertEquals( 2, attribute.size() ); |
| assertTrue( attribute.contains( sapCaSeUuid, iapCaSeUuid ) ); |
| |
| // Rename the IAP subentry |
| ModifyDnResponse renameResponse = adminConnection.rename( "cn=test,ou=IAP,ou=SAP,ou=system", "cn=test1" ); |
| assertEquals( ResultCodeEnum.SUCCESS, renameResponse.getLdapResult().getResultCode() ); |
| |
| // The SeqNumber should not have changed |
| assertEquals( sapCaSeqNumber, getCaSeqNumber( "ou=SAP,ou=system" ) ); |
| assertEquals( iapCaSeqNumber, getCaSeqNumber( "ou=IAP,ou=SAP,ou=system" ) ); |
| |
| // The CA APCache should point to the new subentries |
| AdministrativePoint caAP = service.getCollectiveAttributeAPCache().getElement( iapDn ); |
| |
| assertNotNull( caAP ); |
| Set<Subentry> subentries = caAP.getSubentries(); |
| |
| assertNotNull( subentries ); |
| |
| for ( Subentry sub : subentries ) |
| { |
| assertEquals( "test1", sub.getCn().getString() ); |
| } |
| |
| // Now check the UUID cache |
| Subentry[] subArray = service.getSubentryCache().getSubentries( oldSubentryDn ); |
| |
| assertNull( subArray ); |
| |
| subArray = service.getSubentryCache().getSubentries( newSubentryDn ); |
| |
| assertNotNull( subArray ); |
| |
| for ( Subentry sub : subentries ) |
| { |
| if ( sub != null ) |
| { |
| assertEquals( "test1", sub.getCn().getString() ); |
| } |
| } |
| } |
| |
| |
| // =================================================================== |
| // Test the Rename operation for Entries |
| // ------------------------------------------------------------------- |
| // ------------------------------------------------------------------- |
| // Success expected |
| // ------------------------------------------------------------------- |
| } |