opends/resource/config/config.ldif
@@ -2394,6 +2394,26 @@ ds-cfg-attribute-type: subschemaSubentry ds-cfg-conflict-behavior: virtual-overrides-real dn: cn=structuralObjectClass,cn=Virtual Attributes,cn=config objectClass: top objectClass: ds-cfg-virtual-attribute objectClass: ds-cfg-structural-object-class-virtual-attribute cn: structuralObjectClass ds-cfg-java-class: org.opends.server.extensions.StructuralObjectClassVirtualAttributeProvider ds-cfg-enabled: true ds-cfg-attribute-type: structuralObjectClass ds-cfg-conflict-behavior: virtual-overrides-real dn: cn=governingStructureRule,cn=Virtual Attributes,cn=config objectClass: top objectClass: ds-cfg-virtual-attribute objectClass: ds-cfg-governing-structure-rule-virtual-attribute cn: governingStructureRule ds-cfg-java-class: org.opends.server.extensions.GoverningStructureRuleVirtualAttributeProvider ds-cfg-enabled: true ds-cfg-attribute-type: governingStructureRule ds-cfg-conflict-behavior: virtual-overrides-real dn: cn=Virtual Static member,cn=Virtual Attributes,cn=config objectClass: top objectClass: ds-cfg-virtual-attribute opends/resource/schema/00-core.ldif
@@ -195,6 +195,12 @@ attributeTypes: ( 2.5.21.8 NAME 'matchingRuleUse' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation X-ORIGIN 'RFC 4512' ) attributeTypes: ( 2.5.21.9 NAME 'structuralObjectClass' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'RFC 4512' ) attributeTypes: ( 2.5.21.10 NAME 'governingStructureRule' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN 'RFC 4512' ) attributeTypes: ( 1.3.6.1.4.1.1466.101.120.5 NAME 'namingContexts' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation X-ORIGIN 'RFC 4512' ) attributeTypes: ( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer' opends/resource/schema/02-config.ldif
@@ -4039,4 +4039,14 @@ SUP ds-cfg-backend STRUCTURAL X-ORIGIN 'OpenDS Directory Server' ) objectClasses: ( 1.3.6.1.4.1.26027.1.2.201 NAME 'ds-cfg-structural-object-class-virtual-attribute' SUP ds-cfg-virtual-attribute STRUCTURAL X-ORIGIN 'OpenDS Directory Server' ) objectClasses: ( 1.3.6.1.4.1.26027.1.2.202 NAME 'ds-cfg-governing-structure-rule-virtual-attribute' SUP ds-cfg-virtual-attribute STRUCTURAL X-ORIGIN 'OpenDS Directory Server' ) opends/src/admin/defn/org/opends/server/admin/std/GoverningStructureRuleVirtualAttributeConfiguration.xml
New file @@ -0,0 +1,69 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- ! 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 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE ! or https://OpenDS.dev.java.net/OpenDS.LICENSE. ! 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 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 2009 Sun Microsystems, Inc. ! --> <adm:managed-object name="governing-structure-rule-virtual-attribute" plural-name="governing-structure-rule-virtual-attributes" package="org.opends.server.admin.std" extends="virtual-attribute" xmlns:adm="http://www.opends.org/admin" xmlns:ldap="http://www.opends.org/admin-ldap"> <adm:synopsis> The <adm:user-friendly-name /> generates a virtual attribute that specifies the DIT structure rule with the schema definitions in effect for the entry. This attribute is defined in RFC 4512. </adm:synopsis> <adm:profile name="ldap"> <ldap:object-class> <ldap:name>ds-cfg-governing-structure-rule-virtual-attribute</ldap:name> <ldap:superior>ds-cfg-virtual-attribute</ldap:superior> </ldap:object-class> </adm:profile> <adm:property-override name="java-class" advanced="true"> <adm:default-behavior> <adm:defined> <adm:value> org.opends.server.extensions.GoverningSturctureRuleVirtualAttributeProvider </adm:value> </adm:defined> </adm:default-behavior> </adm:property-override> <adm:property-override name="conflict-behavior" advanced="true"> <adm:default-behavior> <adm:defined> <adm:value>virtual-overrides-real</adm:value> </adm:defined> </adm:default-behavior> </adm:property-override> <adm:property-override name="attribute-type"> <adm:default-behavior> <adm:defined> <adm:value>governingStructureRule</adm:value> </adm:defined> </adm:default-behavior> </adm:property-override> </adm:managed-object> opends/src/admin/defn/org/opends/server/admin/std/StructuralObjectClassVirtualAttributeConfiguration.xml
New file @@ -0,0 +1,69 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- ! 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 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE ! or https://OpenDS.dev.java.net/OpenDS.LICENSE. ! 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 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 2009 Sun Microsystems, Inc. ! --> <adm:managed-object name="structural-object-class-virtual-attribute" plural-name="structural-object-class-virtual-attributes" package="org.opends.server.admin.std" extends="virtual-attribute" xmlns:adm="http://www.opends.org/admin" xmlns:ldap="http://www.opends.org/admin-ldap"> <adm:synopsis> The <adm:user-friendly-name /> generates a virtual attribute that specifies the structural object class with the schema definitions in effect for the entry. This attribute is defined in RFC 4512. </adm:synopsis> <adm:profile name="ldap"> <ldap:object-class> <ldap:name>ds-cfg-structural-object-class-virtual-attribute</ldap:name> <ldap:superior>ds-cfg-virtual-attribute</ldap:superior> </ldap:object-class> </adm:profile> <adm:property-override name="java-class" advanced="true"> <adm:default-behavior> <adm:defined> <adm:value> org.opends.server.extensions.StructuralObjectClassVirtualAttributeProvider </adm:value> </adm:defined> </adm:default-behavior> </adm:property-override> <adm:property-override name="conflict-behavior" advanced="true"> <adm:default-behavior> <adm:defined> <adm:value>virtual-overrides-real</adm:value> </adm:defined> </adm:default-behavior> </adm:property-override> <adm:property-override name="attribute-type"> <adm:default-behavior> <adm:defined> <adm:value>structuralObjectClass</adm:value> </adm:defined> </adm:default-behavior> </adm:property-override> </adm:managed-object> opends/src/messages/messages/extension.properties
@@ -1134,7 +1134,7 @@ MILD_ERR_UNIQUECHARS_VALIDATOR_NOT_ENOUGH_UNIQUE_CHARS_458=The provided \ password does not contain enough unique characters. The minimum number of \ unique characters that may appear in a user password is %d MILD_ERR_SUBSCHEMASUBENTRY_VATTR_NOT_SEARCHABLE_459=The %s attribute is not \ MILD_ERR_VATTR_NOT_SEARCHABLE_459=The %s attribute is not \ searchable and should not be included in otherwise unindexed search filters MILD_ERR_DICTIONARY_VALIDATOR_PASSWORD_IN_DICTIONARY_460=The provided \ password was found in the server's dictionary opends/src/server/org/opends/server/extensions/GoverningStructureRuleVirtualAttributeProvider.java
New file @@ -0,0 +1,298 @@ /* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 2009 Sun Microsystems, Inc. */ package org.opends.server.extensions; import java.util.Collections; import java.util.List; import java.util.Set; import org.opends.messages.Message; import org.opends.server.admin.std.server. GoverningStructureRuleVirtualAttributeCfg; import org.opends.server.api.VirtualAttributeProvider; import org.opends.server.config.ConfigException; import org.opends.server.core.DirectoryServer; import org.opends.server.core.SearchOperation; import org.opends.server.types.*; import static org.opends.messages.ExtensionMessages.*; /** * This class implements a virtual attribute provider that is meant to serve * the governingStructuralRule operational attribute as described in RFC 4512. */ public class GoverningStructureRuleVirtualAttributeProvider extends VirtualAttributeProvider<GoverningStructureRuleVirtualAttributeCfg> { /** * Creates a new instance of this governingStructureRule virtual attribute * provider. */ public GoverningStructureRuleVirtualAttributeProvider() { super(); // All initialization should be performed in the // initializeVirtualAttributeProvider method. } /** * {@inheritDoc} */ @Override() public void initializeVirtualAttributeProvider( GoverningStructureRuleVirtualAttributeCfg configuration) throws ConfigException, InitializationException { // No initialization is required. } /** * {@inheritDoc} */ @Override() public boolean isMultiValued() { return false; } /** * {@inheritDoc} */ @Override() public Set<AttributeValue> getValues(Entry entry, VirtualAttributeRule rule) { DITStructureRule ditRule = getDITStructureRule(entry); if(ditRule !=null) { return Collections.singleton(AttributeValues.create( rule.getAttributeType(), String.valueOf(ditRule.getRuleID()))); } return Collections.<AttributeValue>emptySet(); } /** * {@inheritDoc} */ @Override() public boolean hasValue(Entry entry, VirtualAttributeRule rule) { return getDITStructureRule(entry)!=null; } /** * {@inheritDoc} */ @Override() public ConditionResult matchesSubstring(Entry entry, VirtualAttributeRule rule, ByteString subInitial, List<ByteString> subAny, ByteString subFinal) { // DITStructureRule cannot be used in substring matching. return ConditionResult.UNDEFINED; } /** * {@inheritDoc} */ @Override() public ConditionResult greaterThanOrEqualTo(Entry entry, VirtualAttributeRule rule, AttributeValue value) { // DITStructureRule cannot be used in ordering matching. return ConditionResult.UNDEFINED; } /** * {@inheritDoc} */ @Override() public ConditionResult lessThanOrEqualTo(Entry entry, VirtualAttributeRule rule, AttributeValue value) { // DITStructureRule cannot be used in ordering matching. return ConditionResult.UNDEFINED; } /** * {@inheritDoc} */ @Override() public ConditionResult approximatelyEqualTo(Entry entry, VirtualAttributeRule rule, AttributeValue value) { // DITStructureRule cannot be used in approximate matching. return ConditionResult.UNDEFINED; } /** * {@inheritDoc}. This virtual attribute will support search operations only * if one of the following is true about the search filter: * <UL> * <LI>It is an equality filter targeting the associated attribute * type.</LI> * <LI>It is an AND filter in which at least one of the components is an * equality filter targeting the associated attribute type.</LI> * <LI>It is an OR filter in which all of the components are equality * filters targeting the associated attribute type.</LI> * </UL> */ @Override() public boolean isSearchable(VirtualAttributeRule rule, SearchOperation searchOperation) { //Non-searchable for unindexed searches. return false; } /** * {@inheritDoc} */ @Override() public void processSearch(VirtualAttributeRule rule, SearchOperation searchOperation) { searchOperation.setResultCode(ResultCode.UNWILLING_TO_PERFORM); Message message = ERR_VATTR_NOT_SEARCHABLE.get( rule.getAttributeType().getNameOrOID()); searchOperation.appendErrorMessage(message); } //Checks if the entry matches the nameform. private boolean matchesNameForm(NameForm nameForm, AcceptRejectWarn structuralPolicy, Entry entry) { RDN rdn = entry.getDN().getRDN(); if (rdn != null) { // Make sure that all the required attributes are present. for (AttributeType t : nameForm.getRequiredAttributes()) { if (! rdn.hasAttributeType(t)) { if (structuralPolicy == AcceptRejectWarn.REJECT) { return false; } } } // Make sure that all attributes in the RDN are allowed. int numAVAs = rdn.getNumValues(); for (int i = 0; i < numAVAs; i++) { AttributeType t = rdn.getAttributeType(i); if (! nameForm.isRequiredOrOptional(t)) { if (structuralPolicy == AcceptRejectWarn.REJECT) { return false; } } } } return true; } //Finds the appropriate DIT structure rule for an entry. private DITStructureRule getDITStructureRule(Entry entry) { ObjectClass oc = entry.getStructuralObjectClass(); List<NameForm> listForms = DirectoryServer.getNameForm(oc); NameForm nameForm = null; DITStructureRule ditRule = null; //We iterate over all the nameforms while creating the entry and //select the first one that matches. Since the entry exists, the same //algorithm should work fine to retrieve the nameform which was //applied while creating the entry. if(listForms != null) { boolean obsolete = true; AcceptRejectWarn structuralPolicy = DirectoryServer.getSingleStructuralObjectClassPolicy(); for(NameForm nf : listForms) { if(!nf.isObsolete()) { obsolete = false; if(matchesNameForm(nf, structuralPolicy, entry)) { nameForm = nf; break; } } } if( nameForm != null && !obsolete) { ditRule = DirectoryServer.getDITStructureRule(nameForm); } } return ditRule; } } opends/src/server/org/opends/server/extensions/StructuralObjectClassVirtualAttributeProvider.java
New file @@ -0,0 +1,214 @@ /* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 2009 Sun Microsystems, Inc. */ package org.opends.server.extensions; import java.util.Collections; import java.util.List; import java.util.Set; import org.opends.messages.Message; import org.opends.server.admin.std.server. StructuralObjectClassVirtualAttributeCfg; import org.opends.server.api.VirtualAttributeProvider; import org.opends.server.config.ConfigException; import org.opends.server.core.SearchOperation; import org.opends.server.types.*; import static org.opends.messages.ExtensionMessages.*; /** * This class implements a virtual attribute provider that is meant to serve * the structuralObjectClass operational attribute as described in RFC 4512. */ public class StructuralObjectClassVirtualAttributeProvider extends VirtualAttributeProvider<StructuralObjectClassVirtualAttributeCfg> { /** * Creates a new instance of this structuralObjectClass virtual attribute * provider. */ public StructuralObjectClassVirtualAttributeProvider() { super(); // All initialization should be performed in the // initializeVirtualAttributeProvider method. } /** * {@inheritDoc} */ @Override() public void initializeVirtualAttributeProvider( StructuralObjectClassVirtualAttributeCfg configuration) throws ConfigException, InitializationException { // No initialization is required. } /** * {@inheritDoc} */ @Override() public boolean isMultiValued() { return false; } /** * {@inheritDoc} */ @Override() public Set<AttributeValue> getValues(Entry entry, VirtualAttributeRule rule) { AttributeValue value = AttributeValues.create(rule.getAttributeType(), entry.getStructuralObjectClass().getNameOrOID()); return Collections.singleton(value); } /** * {@inheritDoc} */ @Override() public boolean hasValue(Entry entry, VirtualAttributeRule rule) { //A structural object class is always present in an entry. return true; } /** * {@inheritDoc} */ @Override() public ConditionResult matchesSubstring(Entry entry, VirtualAttributeRule rule, ByteString subInitial, List<ByteString> subAny, ByteString subFinal) { //Substring matching is not supported. return ConditionResult.UNDEFINED; } /** * {@inheritDoc} */ @Override() public ConditionResult greaterThanOrEqualTo(Entry entry, VirtualAttributeRule rule, AttributeValue value) { // An object class can not be used for ordering. return ConditionResult.UNDEFINED; } /** * {@inheritDoc} */ @Override() public ConditionResult lessThanOrEqualTo(Entry entry, VirtualAttributeRule rule, AttributeValue value) { // An object class can not be used for ordering. return ConditionResult.UNDEFINED; } /** * {@inheritDoc} */ @Override() public ConditionResult approximatelyEqualTo(Entry entry, VirtualAttributeRule rule, AttributeValue value) { // An object class can not be used in approximate matching. return ConditionResult.UNDEFINED; } /** * {@inheritDoc}. This virtual attribute will support search operations only * if one of the following is true about the search filter: * <UL> * <LI>It is an equality filter targeting the associated attribute * type.</LI> * <LI>It is an AND filter in which at least one of the components is an * equality filter targeting the associated attribute type.</LI> * <LI>It is an OR filter in which all of the components are equality * filters targeting the associated attribute type.</LI> * </UL> */ @Override() public boolean isSearchable(VirtualAttributeRule rule, SearchOperation searchOperation) { // This attribute is not searchable, since it will have the same value in // tons of entries. return false; } /** * {@inheritDoc} */ @Override() public void processSearch(VirtualAttributeRule rule, SearchOperation searchOperation) { searchOperation.setResultCode(ResultCode.UNWILLING_TO_PERFORM); Message message = ERR_VATTR_NOT_SEARCHABLE.get( rule.getAttributeType().getNameOrOID()); searchOperation.appendErrorMessage(message); } } opends/src/server/org/opends/server/extensions/SubschemaSubentryVirtualAttributeProvider.java
@@ -194,7 +194,7 @@ { searchOperation.setResultCode(ResultCode.UNWILLING_TO_PERFORM); Message message = ERR_SUBSCHEMASUBENTRY_VATTR_NOT_SEARCHABLE.get( Message message = ERR_VATTR_NOT_SEARCHABLE.get( rule.getAttributeType().getNameOrOID()); searchOperation.appendErrorMessage(message); } opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/GoverningStructureRuleVirtualAttributeProviderTestCase.java
New file @@ -0,0 +1,898 @@ /* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 2009 Sun Microsystems, Inc. */ package org.opends.server.extensions; import static org.opends.server.util.ServerConstants.*; import static org.testng.Assert.*; import java.util.Collections; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.opends.server.TestCaseUtils; import org.opends.server.admin.std.meta.VirtualAttributeCfgDefn; import org.opends.server.core.DirectoryServer; import org.opends.server.protocols.internal.InternalClientConnection; import org.opends.server.protocols.internal.InternalSearchOperation; import org.opends.server.protocols.ldap.LDAPControl; import org.opends.server.types.Attribute; import org.opends.server.types.AttributeType; import org.opends.server.types.AttributeValue; import org.opends.server.types.AttributeValues; import org.opends.server.types.Control; import org.opends.server.types.DN; import org.opends.server.types.DereferencePolicy; import org.opends.server.types.Entry; import org.opends.server.types.SearchFilter; import org.opends.server.types.SearchScope; import org.opends.server.types.VirtualAttributeRule; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** * A set of test cases for the governing structure rule virtual attribute * provider. */ public class GoverningStructureRuleVirtualAttributeProviderTestCase extends ExtensionsTestCase { // The attribute type for the governingStructureRule attribute. private AttributeType governingStructureRuleType; /** * Ensures that the Directory Server is running. * * @throws Exception If an unexpected problem occurs. */ @BeforeClass() public void startServer() throws Exception { TestCaseUtils.startServer(); governingStructureRuleType = DirectoryServer.getAttributeType("governingstructurerule", false); assertNotNull(governingStructureRuleType); int resultCode = TestCaseUtils.applyModifications(true, "dn: cn=schema", "changetype: modify", "add: nameForms", "nameForms: ( domainNameForm-oid NAME 'domainNameForm' OC domain MUST ( dc ) )", "nameForms: ( organizationalNameForm-oid NAME 'organizationalNameForm' OC organization MUST ( o ) )", "-", "add: ditStructureRules", "dITStructureRules: ( 21 NAME 'domainStructureRule' FORM domainNameForm )", "dITStructureRules: ( 22 NAME 'organizationalStructureRule' FORM organizationalNameForm SUP 21 )" ); assertTrue(resultCode == 0); } /** * Ensures that the schema is cleaned up. * * @throws Exception If an unexpected problem occurs. */ @AfterClass() public void cleanup() throws Exception { int resultCode = TestCaseUtils.applyModifications(true, "dn: cn=schema", "changetype: modify", "delete: ditStructureRules", "dITStructureRules: ( 22 NAME 'organizationalStructureRule' FORM organizationalNameForm SUP 21 )", "dITStructureRules: ( 21 NAME 'domainStructureRule' FORM domainNameForm )", "-", "delete: nameForms", "nameForms: ( domainNameForm-oid NAME 'domainNameForm' OC domain MUST ( dc ) )", "nameForms: ( organizationalNameForm-oid NAME 'organizationalNameForm' OC organization MUST ( o ) )" ); assertTrue(resultCode == 0); } /** * Retrieves a set of entry DNs for use in testing the * governingStructureRule virtual attribute. * * @return A set of entry DNs for use in testing the governingStructureRule * virtual attribute. * * @throws Exception If an unexpected problem occurs. */ @DataProvider(name = "testEntryDNs") public Object[][] getTestEntryDNs() throws Exception { return new Object[][] { new Object[] { DN.decode("o=test") }, new Object[] { DN.decode("dc=example,dc=com") } }; } /** * Retrieves a set of entry DNs and corresponding governing structure rule * ids for use in testing the governingStructureRule virtual attribute. * * @return A set of entry DNs and id for use in testing the * governingStructureRule virtual attribute. * * @throws Exception If an unexpected problem occurs. */ @DataProvider(name = "testDNRuleID") public Object[][] getTestEntryDNRuleID() throws Exception { return new Object[][] { {DN.decode("o=test"), "22"}, {DN.decode("dc=example,dc=com"), "21"}, }; } /** * Tests the {@code getEntry} method for the specified entry to ensure that * the entry returned includes the governingStructureRule operational * attribute with the correct value. * * @param entryDN The DN of the entry to retrieve and verify. * @param ruleId The rule id of the DITStructureRule. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testDNRuleID") public void testGetEntry(DN entryDN,String ruleId) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); Entry e = DirectoryServer.getEntry(entryDN); assertNotNull(e); assertTrue(e.hasAttribute(governingStructureRuleType)); List<Attribute> attrList = e.getAttribute(governingStructureRuleType); assertNotNull(attrList); assertFalse(attrList.isEmpty()); for (Attribute a : attrList) { assertTrue(!a.isEmpty()); assertEquals(a.size(), 1); assertTrue(a.contains(AttributeValues.create(governingStructureRuleType, ruleId))); } } /** * Performs an internal search to retrieve the specified entry, ensuring that * the governingStructureRule attribute is not included when the list of attributes * requested is empty (defaulting to all user attributes). * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchEmptyAttrs(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, filter); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertFalse(e.hasAttribute(governingStructureRuleType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the governingStructureRule attribute is not included when the list of requested * attributes is "1.1", meaning no attributes. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchNoAttrs(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("1.1"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertFalse(e.hasAttribute(governingStructureRuleType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the governingStructureRule attribute is not included when all user attributes * are requested. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchAllUserAttrs(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("*"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertFalse(e.hasAttribute(governingStructureRuleType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the governingStructureRuleType attribute is included when all operational attributes * are requested. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchAllOperationalAttrs(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("+"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertTrue(e.hasAttribute(governingStructureRuleType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the governingStructureRule attribute is included when that attribute is * specifically requested. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchGoverningStructureRulesAttr(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("governingStructureRule"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertTrue(e.hasAttribute(governingStructureRuleType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the governingStructureRule attribute is not included when it is not in the list * of attributes that is explicitly requested. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchExcludeGovStructRuleAttr(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("objectClass"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertFalse(e.hasAttribute(governingStructureRuleType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the governingStructureRule attribute is included when that attribute is * specifically requested and the governingStructureRule attribute is used in the * search filter with a matching value. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testDNRuleID") public void testSearchGovStructRuleInMatchingFilter(DN entryDN,String oc) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("governingstructurerule="+oc); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("governingStructureRule"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertTrue(e.hasAttribute(governingStructureRuleType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * no entries are returned when the governingStructureRule attribute is used in the * search filter with a non-matching value. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchGovStructRuleAttrInNonMatchingFilter(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(governingStructureRule=1)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("governingStructureRuleType"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 0); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the governingStructureRule attribute is not included when that attribute is * specifically requested and the real attributes only control is included in * the request. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchGovStructRuleAttrRealAttrsOnly(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("governingStructureRuleType"); LinkedList<Control> requestControls = new LinkedList<Control>(); requestControls.add(new LDAPControl(OID_REAL_ATTRS_ONLY, true)); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = new InternalSearchOperation(conn, InternalClientConnection .nextOperationID(), InternalClientConnection .nextMessageID(), requestControls, entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList, null); searchOperation.run(); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertFalse(e.hasAttribute(governingStructureRuleType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the governingStructureRule attribute is included when that attribute is * specifically requested and the virtual attributes only control is included * in the request. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchGovStructRuleAttrVirtualAttrsOnly(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("governingStructureRule"); LinkedList<Control> requestControls = new LinkedList<Control>(); requestControls.add(new LDAPControl(OID_VIRTUAL_ATTRS_ONLY, true)); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = new InternalSearchOperation(conn, InternalClientConnection .nextOperationID(), InternalClientConnection .nextMessageID(), requestControls, entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList, null); searchOperation.run(); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertTrue(e.hasAttribute(governingStructureRuleType)); } /** * Tests the {@code isMultiValued} method. */ @Test() public void testIsMultiValued() { GoverningStructureRuleVirtualAttributeProvider provider = new GoverningStructureRuleVirtualAttributeProvider(); assertFalse(provider.isMultiValued()); } /** * Tests the {@code getValues} method for an entry. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testGetValues() throws Exception { GoverningStructureRuleVirtualAttributeProvider provider = new GoverningStructureRuleVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectclass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(governingStructureRuleType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); Set<AttributeValue> values = provider.getValues(entry, rule); assertNotNull(values); assertEquals(values.size(), 1); assertTrue(values.contains(AttributeValues.create(governingStructureRuleType, "22"))); } /** * Tests the {@code hasValue} method variant that doesn't take a specific * value. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasAnyValue() throws Exception { GoverningStructureRuleVirtualAttributeProvider provider = new GoverningStructureRuleVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(governingStructureRuleType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); assertTrue(provider.hasValue(entry, rule)); } /** * Tests the {@code hasValue} method variant that takes a specific value when * the provided value is a match. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasMatchingValue() throws Exception { GoverningStructureRuleVirtualAttributeProvider provider = new GoverningStructureRuleVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectclass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(governingStructureRuleType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); assertTrue(provider.hasValue(entry, rule, AttributeValues.create(governingStructureRuleType,"22"))); } /** * Tests the {@code hasValue} method variant that takes a specific value when * the provided value is not a match. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasNonMatchingValue() throws Exception { GoverningStructureRuleVirtualAttributeProvider provider = new GoverningStructureRuleVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(governingStructureRuleType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); assertFalse(provider.hasValue(entry, rule, AttributeValues.create(governingStructureRuleType, "1"))); } /** * Tests the {@code hasAnyValue} method with an empty set of values. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasAnyValueEmptySet() throws Exception { GoverningStructureRuleVirtualAttributeProvider provider = new GoverningStructureRuleVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectclass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(governingStructureRuleType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); assertFalse(provider.hasAnyValue(entry, rule, Collections.<AttributeValue>emptySet())); } /** * Tests the {@code hasAnyValue} method with a set of values containing only * the correct value. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasAnyValueOnlyCorrect() throws Exception { GoverningStructureRuleVirtualAttributeProvider provider = new GoverningStructureRuleVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(governingStructureRuleType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); values.add(AttributeValues.create(governingStructureRuleType, "22")); assertTrue(provider.hasAnyValue(entry, rule, values)); } /** * Tests the {@code hasAnyValue} method with a set of values containing only * an incorrect value. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasAnyValueOnlyIncorrect() throws Exception { GoverningStructureRuleVirtualAttributeProvider provider = new GoverningStructureRuleVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectclass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(governingStructureRuleType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); values.add(AttributeValues.create(governingStructureRuleType, "1")); assertFalse(provider.hasAnyValue(entry, rule, values)); } /** * Tests the {@code hasAnyValue} method with a set of values containing the * correct value as well as multiple incorrect values. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasAnyValueIncludesCorrect() throws Exception { GoverningStructureRuleVirtualAttributeProvider provider = new GoverningStructureRuleVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(governingStructureRuleType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(3); values.add(AttributeValues.create(governingStructureRuleType, "22")); values.add(AttributeValues.create(governingStructureRuleType, "1")); values.add(AttributeValues.create(governingStructureRuleType,"2")); assertTrue(provider.hasAnyValue(entry, rule, values)); } /** * Tests the {@code hasAnyValue} method with a set of multiple values, none of * which are correct. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasAnyValueMissingCorrect() throws Exception { GoverningStructureRuleVirtualAttributeProvider provider = new GoverningStructureRuleVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectclass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(governingStructureRuleType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(3); values.add(AttributeValues.create(governingStructureRuleType, "1")); values.add(AttributeValues.create(governingStructureRuleType, "2")); values.add(AttributeValues.create(governingStructureRuleType,"3")); assertFalse(provider.hasAnyValue(entry, rule, values)); } } opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/StructuralObjectClassVirtualAttributeProviderTestCase.java
New file @@ -0,0 +1,870 @@ /* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 2009 Sun Microsystems, Inc. */ package org.opends.server.extensions; import static org.opends.server.util.ServerConstants.*; import static org.testng.Assert.*; import java.util.Collections; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.opends.server.TestCaseUtils; import org.opends.server.admin.std.meta.VirtualAttributeCfgDefn; import org.opends.server.core.DirectoryServer; import org.opends.server.protocols.internal.InternalClientConnection; import org.opends.server.protocols.internal.InternalSearchOperation; import org.opends.server.protocols.ldap.LDAPControl; import org.opends.server.types.Attribute; import org.opends.server.types.AttributeType; import org.opends.server.types.AttributeValue; import org.opends.server.types.AttributeValues; import org.opends.server.types.Control; import org.opends.server.types.DN; import org.opends.server.types.DereferencePolicy; import org.opends.server.types.Entry; import org.opends.server.types.SearchFilter; import org.opends.server.types.SearchScope; import org.opends.server.types.VirtualAttributeRule; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** * A set of test cases for the structural object class virtual attribute * provider. */ public class StructuralObjectClassVirtualAttributeProviderTestCase extends ExtensionsTestCase { // The attribute type for the structuralobjectclass attribute. private AttributeType structuralObjectClassType; /** * Ensures that the Directory Server is running. * * @throws Exception If an unexpected problem occurs. */ @BeforeClass() public void startServer() throws Exception { TestCaseUtils.startServer(); structuralObjectClassType = DirectoryServer.getAttributeType("structuralobjectclass", false); assertNotNull(structuralObjectClassType); } /** * Retrieves a set of entry DNs for use in testing the * structuralObjectClassType virtual attribute. * * @return A set of entry DNs for use in testing the structuralobjectclass * virtual attribute. * * @throws Exception If an unexpected problem occurs. */ @DataProvider(name = "testEntryDNs") public Object[][] getTestEntryDNs() throws Exception { return new Object[][] { new Object[] { DN.decode("") }, new Object[] { DN.decode("o=test") }, new Object[] { DN.decode("dc=example,dc=com") }, new Object[] { DN.decode("cn=config") }, new Object[] { DN.decode("cn=schema") }, new Object[] { DN.decode("cn=tasks") }, new Object[] { DN.decode("cn=monitor") }, new Object[] { DN.decode("cn=backups") } }; } /** * Retrieves a set of entry DNs and corresponding structural object classes * for use in testing the structuralObjectClassType virtual attribute. * * @return A set of entry DNs and oc for use in testing the * structuralobjectclass virtual attribute. * * @throws Exception If an unexpected problem occurs. */ @DataProvider(name = "testDNOC") public Object[][] getTestEntryDNOC() throws Exception { return new Object[][] { {DN.decode("o=test"), "structuralObjectClass=organization"}, {DN.decode("dc=example,dc=com"), "structuralObjectClass=domain"}, }; } /** * Tests the {@code getEntry} method for the specified entry to ensure that * the entry returned includes the structuralObjectClass operational * attribute with the correct value. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testGetEntry(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); Entry e = DirectoryServer.getEntry(entryDN); assertNotNull(e); assertTrue(e.hasAttribute(structuralObjectClassType)); List<Attribute> attrList = e.getAttribute(structuralObjectClassType); assertNotNull(attrList); assertFalse(attrList.isEmpty()); for (Attribute a : attrList) { assertTrue(!a.isEmpty()); assertEquals(a.size(), 1); assertTrue(a.contains(AttributeValues.create(structuralObjectClassType, e.getStructuralObjectClass().getNameOrOID()))); } } /** * Performs an internal search to retrieve the specified entry, ensuring that * the structuralObjectClass attribute is not included when the list of attributes * requested is empty (defaulting to all user attributes). * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchEmptyAttrs(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, filter); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertFalse(e.hasAttribute(structuralObjectClassType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the structuralObjectClass attribute is not included when the list of requested * attributes is "1.1", meaning no attributes. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchNoAttrs(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("1.1"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertFalse(e.hasAttribute(structuralObjectClassType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the structuralObjectClass attribute is not included when all user attributes * are requested. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchAllUserAttrs(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("*"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertFalse(e.hasAttribute(structuralObjectClassType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the structuralObjectClass attribute is included when all operational attributes * are requested. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchAllOperationalAttrs(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("+"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertTrue(e.hasAttribute(structuralObjectClassType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the structuralObjectClass attribute is included when that attribute is * specifically requested. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchStructuralOCAttr(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("structuralobjectclass"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertTrue(e.hasAttribute(structuralObjectClassType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the structuralObjectClass attribute is not included when it is not in the list * of attributes that is explicitly requested. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchExcludeStructuralOCAttr(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("objectClass"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertFalse(e.hasAttribute(structuralObjectClassType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the structuralObjectClass attribute is included when that attribute is * specifically requested and the structuralObjectClass attribute is used in the * search filter with a matching value. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testDNOC") public void testSearchStructuralOCAttrInMatchingFilter(DN entryDN,String oc) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString(oc); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("structuralObjectClass"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertTrue(e.hasAttribute(structuralObjectClassType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * no entries are returned when the structuralObjectClass attribute is used in the * search filter with a non-matching value. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchStructuralOCAttrInNonMatchingFilter(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(structuralObjectClass=abc)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("structuralObjectClass"); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = conn.processSearch(entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList); assertEquals(searchOperation.getSearchEntries().size(), 0); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the structuralObjectClass attribute is not included when that attribute is * specifically requested and the real attributes only control is included in * the request. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchStructuralOCAttrRealAttrsOnly(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("structuralObjectClass"); LinkedList<Control> requestControls = new LinkedList<Control>(); requestControls.add(new LDAPControl(OID_REAL_ATTRS_ONLY, true)); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = new InternalSearchOperation(conn, InternalClientConnection .nextOperationID(), InternalClientConnection .nextMessageID(), requestControls, entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList, null); searchOperation.run(); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertFalse(e.hasAttribute(structuralObjectClassType)); } /** * Performs an internal search to retrieve the specified entry, ensuring that * the structuralObjectClass attribute is included when that attribute is * specifically requested and the virtual attributes only control is included * in the request. * * @param entryDN The DN of the entry to retrieve and verify. * * @throws Exception If an unexpected problem occurs. */ @Test(dataProvider = "testEntryDNs") public void testSearchStructuralOCAttrVirtualAttrsOnly(DN entryDN) throws Exception { TestCaseUtils.initializeTestBackend(true); TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); SearchFilter filter = SearchFilter.createFilterFromString("(objectClass=*)"); LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); attrList.add("structuralObjectClass"); LinkedList<Control> requestControls = new LinkedList<Control>(); requestControls.add(new LDAPControl(OID_VIRTUAL_ATTRS_ONLY, true)); InternalClientConnection conn = InternalClientConnection.getRootConnection(); InternalSearchOperation searchOperation = new InternalSearchOperation(conn, InternalClientConnection .nextOperationID(), InternalClientConnection .nextMessageID(), requestControls, entryDN, SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, filter, attrList, null); searchOperation.run(); assertEquals(searchOperation.getSearchEntries().size(), 1); Entry e = searchOperation.getSearchEntries().get(0); assertNotNull(e); assertTrue(e.hasAttribute(structuralObjectClassType)); } /** * Tests the {@code isMultiValued} method. */ @Test() public void testIsMultiValued() { StructuralObjectClassVirtualAttributeProvider provider = new StructuralObjectClassVirtualAttributeProvider(); assertFalse(provider.isMultiValued()); } /** * Tests the {@code getValues} method for an entry. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testGetValues() throws Exception { StructuralObjectClassVirtualAttributeProvider provider = new StructuralObjectClassVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(structuralObjectClassType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); Set<AttributeValue> values = provider.getValues(entry, rule); assertNotNull(values); assertEquals(values.size(), 1); assertTrue(values.contains(AttributeValues.create(structuralObjectClassType, entry.getStructuralObjectClass().getNameOrOID()))); } /** * Tests the {@code hasValue} method variant that doesn't take a specific * value. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasAnyValue() throws Exception { StructuralObjectClassVirtualAttributeProvider provider = new StructuralObjectClassVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(structuralObjectClassType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); assertTrue(provider.hasValue(entry, rule)); } /** * Tests the {@code hasValue} method variant that takes a specific value when * the provided value is a match. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasMatchingValue() throws Exception { StructuralObjectClassVirtualAttributeProvider provider = new StructuralObjectClassVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(structuralObjectClassType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); assertTrue(provider.hasValue(entry, rule, AttributeValues.create(structuralObjectClassType, entry.getStructuralObjectClass().getNameOrOID()))); } /** * Tests the {@code hasValue} method variant that takes a specific value when * the provided value is not a match. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasNonMatchingValue() throws Exception { StructuralObjectClassVirtualAttributeProvider provider = new StructuralObjectClassVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(structuralObjectClassType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); assertFalse(provider.hasValue(entry, rule, AttributeValues.create(structuralObjectClassType, "inetorgperson"))); } /** * Tests the {@code hasAnyValue} method with an empty set of values. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasAnyValueEmptySet() throws Exception { StructuralObjectClassVirtualAttributeProvider provider = new StructuralObjectClassVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(structuralObjectClassType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); assertFalse(provider.hasAnyValue(entry, rule, Collections.<AttributeValue>emptySet())); } /** * Tests the {@code hasAnyValue} method with a set of values containing only * the correct value. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasAnyValueOnlyCorrect() throws Exception { StructuralObjectClassVirtualAttributeProvider provider = new StructuralObjectClassVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(structuralObjectClassType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); values.add(AttributeValues.create(structuralObjectClassType, "organization")); assertTrue(provider.hasAnyValue(entry, rule, values)); } /** * Tests the {@code hasAnyValue} method with a set of values containing only * an incorrect value. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasAnyValueOnlyIncorrect() throws Exception { StructuralObjectClassVirtualAttributeProvider provider = new StructuralObjectClassVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(structuralObjectClassType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); values.add(AttributeValues.create(structuralObjectClassType, "inetorgperson")); assertFalse(provider.hasAnyValue(entry, rule, values)); } /** * Tests the {@code hasAnyValue} method with a set of values containing the * correct value as well as multiple incorrect values. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasAnyValueIncludesCorrect() throws Exception { StructuralObjectClassVirtualAttributeProvider provider = new StructuralObjectClassVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(structuralObjectClassType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(3); values.add(AttributeValues.create(structuralObjectClassType, "organization")); values.add(AttributeValues.create(structuralObjectClassType, "inetorgperson")); values.add(AttributeValues.create(structuralObjectClassType, "top")); assertTrue(provider.hasAnyValue(entry, rule, values)); } /** * Tests the {@code hasAnyValue} method with a set of multiple values, none of * which are correct. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testHasAnyValueMissingCorrect() throws Exception { StructuralObjectClassVirtualAttributeProvider provider = new StructuralObjectClassVirtualAttributeProvider(); Entry entry = TestCaseUtils.makeEntry( "dn: o=test", "objectClass: top", "objectClass: organization", "o: test"); entry.processVirtualAttributes(); VirtualAttributeRule rule = new VirtualAttributeRule(structuralObjectClassType, provider, Collections.<DN>emptySet(), Collections.<DN>emptySet(), Collections.<SearchFilter>emptySet(), VirtualAttributeCfgDefn.ConflictBehavior. VIRTUAL_OVERRIDES_REAL); LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(3); values.add(AttributeValues.create(structuralObjectClassType, "inetorgperson")); values.add(AttributeValues.create(structuralObjectClassType, "top")); values.add(AttributeValues.create(structuralObjectClassType, "domain")); assertFalse(provider.hasAnyValue(entry, rule, values)); } }