| | |
| | | objectClass: ds-cfg-branch |
| | | cn: Virtual Attributes |
| | | |
| | | dn: cn=entryDN,cn=Virtual Attributes,cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-virtual-attribute |
| | | cn: entryDN |
| | | ds-cfg-virtual-attribute-class: org.opends.server.extensions.EntryDNVirtualAttributeProvider |
| | | ds-cfg-virtual-attribute-enabled: true |
| | | ds-cfg-virtual-attribute-type: entryDN |
| | | ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real |
| | | |
| | | dn: cn=isMemberOf,cn=Virtual Attributes,cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-virtual-attribute |
| | | cn: isMemberOf |
| | | ds-cfg-virtual-attribute-class: org.opends.server.extensions.IsMemberOfVirtualAttributeProvider |
| | | ds-cfg-virtual-attribute-enabled: true |
| | | ds-cfg-virtual-attribute-type: isMemberOf |
| | | ds-cfg-virtual-attribute-filter: (objectClass=person) |
| | | ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real |
| | | |
| | | dn: cn=subschemaSubentry,cn=Virtual Attributes,cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-virtual-attribute |
| | | cn: subschemaSubentry |
| | | ds-cfg-virtual-attribute-class: org.opends.server.extensions.SubschemaSubentryVirtualAttributeProvider |
| | | ds-cfg-virtual-attribute-enabled: true |
| | | ds-cfg-virtual-attribute-type: subschemaSubentry |
| | | ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real |
| | | |
| | | dn: cn=Work Queue,cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-work-queue |
| | |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 1274' ) |
| | | attributeTypes: ( 0.9.2342.19200300.100.1.31 NAME 'cNAMERecord' |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 1274' ) |
| | | attributeTypes: ( 2.16.840.1.113730.3.1.602 NAME 'entryDN' |
| | | DESC 'DN of the entry' EQUALITY distinguishedNameMatch |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION |
| | | USAGE directoryOperation X-ORIGIN 'draft-zeilenga-ldap-entrydn' ) |
| | | objectClasses: ( 2.5.6.0 NAME 'top' ABSTRACT MUST objectClass |
| | | X-ORIGIN 'RFC 4512' ) |
| | | objectClasses: ( 2.5.6.1 NAME 'alias' SUP top STRUCTURAL MUST aliasedObjectName |
| | |
| | | NAME 'ds-cfg-case-sensitive-validation' |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.26027.1.1.325 |
| | | NAME 'ds-cfg-virtual-attribute-class' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 |
| | | SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.26027.1.1.326 |
| | | NAME 'ds-cfg-virtual-attribute-enabled' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 |
| | | SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.26027.1.1.327 |
| | | NAME 'ds-cfg-virtual-attribute-type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 |
| | | SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.26027.1.1.328 |
| | | NAME 'ds-cfg-virtual-attribute-base-dn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.26027.1.1.329 |
| | | NAME 'ds-cfg-virtual-attribute-group-dn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.26027.1.1.330 |
| | | NAME 'ds-cfg-virtual-attribute-filter' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.26027.1.1.331 |
| | | NAME 'ds-cfg-virtual-attribute-conflict-behavior' |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.1 |
| | | NAME 'ds-cfg-access-control-handler' SUP top STRUCTURAL |
| | | MUST ( cn $ ds-cfg-acl-handler-class $ ds-cfg-acl-handler-enabled ) |
| | |
| | | SUP ds-cfg-password-validator STRUCTURAL |
| | | MUST ( ds-cfg-maximum-consecutive-length $ ds-cfg-case-sensitive-validation ) |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.91 NAME 'ds-cfg-virtual-attribute' |
| | | SUP top STRUCTURAL MUST ( cn $ ds-cfg-virtual-attribute-class $ |
| | | ds-cfg-virtual-attribute-enabled $ ds-cfg-virtual-attribute-type $ |
| | | ds-cfg-virtual-attribute-conflict-behavior ) |
| | | MAY ( ds-cfg-virtual-attribute-base-dn $ ds-cfg-virtual-attribute-group-dn $ |
| | | ds-cfg-virtual-attribute-filter ) X-ORIGIN 'OpenDS Directory Server' ) |
| | | |
| | |
| | | </ldap:rdn-sequence> |
| | | </adm:profile> |
| | | </adm:relation> |
| | | <adm:relation name="virtual-attribute"> |
| | | <adm:one-to-many /> |
| | | <adm:profile name="ldap"> |
| | | <ldap:rdn-sequence> |
| | | cn=Virtual Attributes,cn=config |
| | | </ldap:rdn-sequence> |
| | | </adm:profile> |
| | | </adm:relation> |
| | | <adm:product-name>OpenDS Directory Server</adm:product-name> |
| | | </adm:root-managed-object> |
| New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <adm:managed-object name="virtual-attribute" |
| | | plural-name="virtual-attributes" |
| | | package="org.opends.server.admin.std" |
| | | xmlns:adm="http://www.opends.org/admin" |
| | | xmlns:ldap="http://www.opends.org/admin-ldap"> |
| | | <adm:synopsis> |
| | | <adm:user-friendly-plural-name /> |
| | | are responsible for dynamically generating attribute values that appear in |
| | | entries but are not persistently stored in the backend. |
| | | </adm:synopsis> |
| | | <adm:profile name="ldap"> |
| | | <ldap:object-class> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.2.91</ldap:oid> |
| | | <ldap:name>ds-cfg-virtual-attribute</ldap:name> |
| | | <ldap:superior>top</ldap:superior> |
| | | </ldap:object-class> |
| | | </adm:profile> |
| | | |
| | | <adm:property name="provider-class" mandatory="true"> |
| | | <adm:synopsis> |
| | | The fully-qualified name of the Java class that provides the |
| | | <adm:user-friendly-name /> |
| | | implementation. |
| | | </adm:synopsis> |
| | | <adm:syntax> |
| | | <adm:java-class> |
| | | <adm:instance-of> |
| | | org.opends.server.api.VirtualAttributeProvider |
| | | </adm:instance-of> |
| | | </adm:java-class> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.1.325</ldap:oid> |
| | | <ldap:name>ds-cfg-virtual-attribute-class</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | |
| | | <adm:property name="enabled" mandatory="true"> |
| | | <adm:synopsis> |
| | | Indicate whether the |
| | | <adm:user-friendly-name /> |
| | | is enabled for use. |
| | | </adm:synopsis> |
| | | <adm:syntax> |
| | | <adm:boolean /> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.1.326</ldap:oid> |
| | | <ldap:name>ds-cfg-virtual-attribute-enabled</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | |
| | | <adm:property name="attribute-type" mandatory="true"> |
| | | <adm:synopsis> |
| | | Specifies the attribute type for the attribute whose values should be |
| | | dynamically assigned by the virtual attribute. |
| | | </adm:synopsis> |
| | | <adm:syntax> |
| | | <adm:attribute-type /> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.1.327</ldap:oid> |
| | | <ldap:name>ds-cfg-virtual-attribute-type</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | |
| | | <adm:property name="base-dn" mandatory="false" multi-valued="true"> |
| | | <adm:synopsis> |
| | | Specifies the base DNs for the branches containing entries that may be |
| | | eligible to use this virtual attribute. |
| | | </adm:synopsis> |
| | | <adm:default-behavior> |
| | | <adm:alias> |
| | | <adm:synopsis> |
| | | The location of the entry in the server will not be taken into account |
| | | when determining whether an entry is eligible to use this virtual |
| | | attribute. |
| | | </adm:synopsis> |
| | | </adm:alias> |
| | | </adm:default-behavior> |
| | | <adm:syntax> |
| | | <adm:dn /> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.1.328</ldap:oid> |
| | | <ldap:name>ds-cfg-virtual-attribute-base-dn</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | |
| | | <adm:property name="group-dn" mandatory="false" multi-valued="true"> |
| | | <adm:synopsis> |
| | | Specifies the DNs for the groups whose members may be eligible to use this |
| | | virtual attribute. |
| | | </adm:synopsis> |
| | | <adm:default-behavior> |
| | | <adm:alias> |
| | | <adm:synopsis> |
| | | Group membership will not be taken into accountwhen determining |
| | | whether an entry is eligible to use this virtual attribute. |
| | | </adm:synopsis> |
| | | </adm:alias> |
| | | </adm:default-behavior> |
| | | <adm:syntax> |
| | | <adm:dn /> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.1.329</ldap:oid> |
| | | <ldap:name>ds-cfg-virtual-attribute-group-dn</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | |
| | | <adm:property name="filter" mandatory="false" multi-valued="true"> |
| | | <adm:synopsis> |
| | | Specifies the search filters for entries that may be eligible to use this |
| | | virtual attribute. |
| | | </adm:synopsis> |
| | | <adm:default-behavior> |
| | | <adm:defined> |
| | | <adm:value>(objectClass=*)</adm:value> |
| | | </adm:defined> |
| | | </adm:default-behavior> |
| | | <adm:syntax> |
| | | <adm:string /> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.1.330</ldap:oid> |
| | | <ldap:name>ds-cfg-virtual-attribute-filter</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | |
| | | <adm:property name="conflict-behavior" mandatory="false"> |
| | | <adm:synopsis> |
| | | Specifies the behavior that the server should exhibit for entries that |
| | | contain one or more real values for the associated attribute. |
| | | </adm:synopsis> |
| | | <adm:default-behavior> |
| | | <adm:defined> |
| | | <adm:value>real-overrides-virtual</adm:value> |
| | | </adm:defined> |
| | | </adm:default-behavior> |
| | | <adm:syntax> |
| | | <adm:enumeration> |
| | | <adm:value name="real-overrides-virtual"> |
| | | <adm:synopsis> |
| | | Any real values contained in the entry should be preserved and |
| | | virtual values should not be generated. |
| | | </adm:synopsis> |
| | | </adm:value> |
| | | <adm:value name="virtual-overrides-real"> |
| | | <adm:synopsis> |
| | | Any real values contained in the entry should be suppressed and |
| | | virtual values should be generated. |
| | | </adm:synopsis> |
| | | </adm:value> |
| | | <adm:value name="merge-real-and-virtual"> |
| | | <adm:synopsis> |
| | | Any real values contained in the entry should be preserved and |
| | | merged with the set of generated virtual values. |
| | | </adm:synopsis> |
| | | </adm:value> |
| | | </adm:enumeration> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:oid>1.3.6.1.4.1.26027.1.1.331</ldap:oid> |
| | | <ldap:name>ds-cfg-virtual-attribute-conflict-behavior</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | </adm:managed-object> |
| | |
| | | */ |
| | | public abstract class ClientConnection |
| | | { |
| | | |
| | | |
| | | |
| | | // The set of authentication information for this client connection. |
| | | private AuthenticationInfo authenticationInfo; |
| | | |
| | |
| | | * searches performed using this client |
| | | * connection. |
| | | */ |
| | | public final void setSizeLimit(int sizeLimit) |
| | | public void setSizeLimit(int sizeLimit) |
| | | { |
| | | this.sizeLimit = sizeLimit; |
| | | } |
| | |
| | | * entries that should be check for |
| | | * matches during a search. |
| | | */ |
| | | public final void setLookthroughLimit(int lookthroughLimit) |
| | | public void setLookthroughLimit(int lookthroughLimit) |
| | | { |
| | | this.lookthroughLimit = lookthroughLimit; |
| | | } |
| | |
| | | * searches performed using this client |
| | | * connection. |
| | | */ |
| | | public final void setTimeLimit(int timeLimit) |
| | | public void setTimeLimit(int timeLimit) |
| | | { |
| | | this.timeLimit = timeLimit; |
| | | } |
| | |
| | | */ |
| | | public abstract class Group |
| | | { |
| | | |
| | | |
| | | |
| | | /** |
| | | * Initializes a "shell" instance of this group implementation that |
| | | * may be used to identify and instantiate instances of this type of |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2006-2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.api; |
| | | |
| | | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | |
| | | import org.opends.server.admin.std.server.VirtualAttributeCfg; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.core.SearchOperation; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ConditionResult; |
| | | import org.opends.server.types.DebugLogLevel; |
| | | import org.opends.server.types.Entry; |
| | | import org.opends.server.types.InitializationException; |
| | | import org.opends.server.types.VirtualAttributeRule; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines the set of methods and structures that must be |
| | | * implemented by a Directory Server module that implements the |
| | | * functionality required for one or more virtual attributes. |
| | | * |
| | | * @param <T> The type of configuration handled by this virtual |
| | | * attribute provider. |
| | | */ |
| | | public abstract class VirtualAttributeProvider |
| | | <T extends VirtualAttributeCfg> |
| | | { |
| | | /** |
| | | * Initializes this virtual attribute based on the information in |
| | | * the provided configuration entry. |
| | | * |
| | | * @param configuration The configuration to use to initialize |
| | | * this virtual attribute provider. |
| | | * |
| | | * @throws ConfigException If an unrecoverable problem arises in |
| | | * the process of performing the |
| | | * initialization. |
| | | * |
| | | * @throws InitializationException If a problem occurs during |
| | | * initialization that is not |
| | | * related to the server |
| | | * configuration. |
| | | */ |
| | | public abstract void initializeVirtualAttributeProvider( |
| | | T configuration) |
| | | throws ConfigException, InitializationException; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs any finalization that may be necessary whenever this |
| | | * virtual attribute provider is taken out of service. |
| | | */ |
| | | public void finalizeVirtualAttributeProvider() |
| | | { |
| | | // No implementation required by default. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this virtual attribute provider may generate |
| | | * multiple values. |
| | | * |
| | | * @return {@code true} if this virtual attribute provider may |
| | | * generate multiple values, or {@code false} if not. |
| | | */ |
| | | public abstract boolean isMultiValued(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Generates a set of values for the provided entry. |
| | | * |
| | | * @param entry The entry for which the values are to be |
| | | * generated. |
| | | * @param rule The virtual attribute rule which defines the |
| | | * constraints for the virtual attribute. |
| | | * |
| | | * @return The set of values generated for the provided entry. It |
| | | * may be empty, but it must not be {@code null}. |
| | | */ |
| | | public abstract LinkedHashSet<AttributeValue> |
| | | getValues(Entry entry, |
| | | VirtualAttributeRule rule); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this virtual attribute provider will generate |
| | | * at least one value for the provided entry. |
| | | * |
| | | * @param entry The entry for which to make the determination. |
| | | * @param rule The virtual attribute rule which defines the |
| | | * constraints for the virtual attribute. |
| | | * |
| | | * @return {@code true} if this virtual attribute provider will |
| | | * generate at least one value for the provided entry, or |
| | | * {@code false} if not. |
| | | */ |
| | | public boolean hasValue(Entry entry, VirtualAttributeRule rule) |
| | | { |
| | | return (! getValues(entry, rule).isEmpty()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this virtual attribute provider will generate |
| | | * the provided value. |
| | | * |
| | | * @param entry The entry for which to make the determination. |
| | | * @param rule The virtual attribute rule which defines the |
| | | * constraints for the virtual attribute. |
| | | * @param value The value for which to make the determination. |
| | | * |
| | | * @return {@code true} if this virtual attribute provider will |
| | | * generate the specified vaule for the provided entry, or |
| | | * {@code false} if not. |
| | | */ |
| | | public boolean hasValue(Entry entry, VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | return getValues(entry, rule).contains(value); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this virtual attribute provider will generate |
| | | * all of the values in the provided collection. |
| | | * |
| | | * @param entry The entry for which to make the determination. |
| | | * @param rule The virtual attribute rule which defines the |
| | | * constraints for the virtual attribute. |
| | | * @param values The set of values for which to make the |
| | | * determination. |
| | | * |
| | | * @return {@code true} if this attribute provider will generate |
| | | * all of the values in the provided collection, or |
| | | * {@code false} if it will not generate at least one of |
| | | * them. |
| | | */ |
| | | public boolean hasAllValues(Entry entry, VirtualAttributeRule rule, |
| | | Collection<AttributeValue> values) |
| | | { |
| | | for (AttributeValue value : values) |
| | | { |
| | | if (! getValues(entry, rule).contains(value)) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this virutal attribute provider will generate |
| | | * any of the values in the provided collection. |
| | | * |
| | | * @param entry The entry for which to make the determination. |
| | | * @param rule The virtual attribute rule which defines the |
| | | * constraints for the virtual attribute. |
| | | * @param values The set of values for which to make the |
| | | * determination. |
| | | * |
| | | * @return {@code true} if this attribute provider will generate |
| | | * at least one of the values in the provided collection, |
| | | * or {@code false} if it will not generate any of them. |
| | | */ |
| | | public boolean hasAnyValue(Entry entry, VirtualAttributeRule rule, |
| | | Collection<AttributeValue> values) |
| | | { |
| | | for (AttributeValue value : values) |
| | | { |
| | | if (getValues(entry, rule).contains(value)) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this virtual attribute provider will generate |
| | | * any value which matches the provided substring. |
| | | * |
| | | * @param entry The entry for which to make the |
| | | * determination. |
| | | * @param rule The virtual attribute rule which defines the |
| | | * constraints for the virtual attribute. |
| | | * @param subInitial The subInitial component to use in the |
| | | * determination. |
| | | * @param subAny The subAny components to use in the |
| | | * determination. |
| | | * @param subFinal The subFinal component to use in the |
| | | * determination. |
| | | * |
| | | * @return <CODE>UNDEFINED</CODE> if this attribute does not have a |
| | | * substring matching rule, <CODE>TRUE</CODE> if at least |
| | | * one value matches the provided substring, or |
| | | * <CODE>FALSE</CODE> otherwise. |
| | | */ |
| | | public ConditionResult matchesSubstring(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | ByteString subInitial, |
| | | List<ByteString> subAny, |
| | | ByteString subFinal) |
| | | { |
| | | SubstringMatchingRule matchingRule = |
| | | rule.getAttributeType().getSubstringMatchingRule(); |
| | | if (matchingRule == null) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | ByteString normalizedSubInitial; |
| | | if (subInitial == null) |
| | | { |
| | | normalizedSubInitial = null; |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | normalizedSubInitial = |
| | | matchingRule.normalizeSubstring(subInitial); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // The substring couldn't be normalized. We have to return |
| | | // "undefined". |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | |
| | | |
| | | ArrayList<ByteString> normalizedSubAny; |
| | | if (subAny == null) |
| | | { |
| | | normalizedSubAny = null; |
| | | } |
| | | else |
| | | { |
| | | normalizedSubAny = |
| | | new ArrayList<ByteString>(subAny.size()); |
| | | for (ByteString subAnyElement : subAny) |
| | | { |
| | | try |
| | | { |
| | | normalizedSubAny.add(matchingRule.normalizeSubstring( |
| | | subAnyElement)); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // The substring couldn't be normalized. We have to return |
| | | // "undefined". |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | ByteString normalizedSubFinal; |
| | | if (subFinal == null) |
| | | { |
| | | normalizedSubFinal = null; |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | normalizedSubFinal = |
| | | matchingRule.normalizeSubstring(subFinal); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // The substring couldn't be normalized. We have to return |
| | | // "undefined". |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | |
| | | |
| | | ConditionResult result = ConditionResult.FALSE; |
| | | for (AttributeValue value : getValues(entry, rule)) |
| | | { |
| | | try |
| | | { |
| | | if (matchingRule.valueMatchesSubstring( |
| | | value.getNormalizedValue(), |
| | | normalizedSubInitial, |
| | | normalizedSubAny, |
| | | normalizedSubFinal)) |
| | | { |
| | | return ConditionResult.TRUE; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // The value couldn't be normalized. If we can't find a |
| | | // definite match, then we should return "undefined". |
| | | result = ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this virtual attribute provider will generate |
| | | * any value for the provided entry that is greater than or equal to |
| | | * the given value. |
| | | * |
| | | * @param entry The entry for which to make the determination. |
| | | * @param rule The virtual attribute rule which defines the |
| | | * constraints for the virtual attribute. |
| | | * @param value The value for which to make the determination. |
| | | * |
| | | * @return {@code UNDEFINED} if the associated attribute type does |
| | | * not have an ordering matching rule, {@code TRUE} if at |
| | | * least one of the generated values will be greater than |
| | | * or equal to the specified value, or {@code FALSE} if |
| | | * none of the generated values will be greater than or |
| | | * equal to the specified value. |
| | | */ |
| | | public ConditionResult greaterThanOrEqualTo(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | OrderingMatchingRule matchingRule = |
| | | rule.getAttributeType().getOrderingMatchingRule(); |
| | | if (matchingRule == null) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | ByteString normalizedValue; |
| | | try |
| | | { |
| | | normalizedValue = value.getNormalizedValue(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We couldn't normalize the provided value. We should return |
| | | // "undefined". |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | ConditionResult result = ConditionResult.FALSE; |
| | | for (AttributeValue v : getValues(entry, rule)) |
| | | { |
| | | try |
| | | { |
| | | ByteString nv = v.getNormalizedValue(); |
| | | int comparisonResult = |
| | | matchingRule.compareValues(nv, normalizedValue); |
| | | if (comparisonResult >= 0) |
| | | { |
| | | return ConditionResult.TRUE; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We couldn't normalize one of the attribute values. If we |
| | | // can't find a definite match, then we should return |
| | | // "undefined". |
| | | result = ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this virtual attribute provider will generate |
| | | * any value for the provided entry that is less than or equal to |
| | | * the given value. |
| | | * |
| | | * @param entry The entry for which to make the determination. |
| | | * @param rule The virtual attribute rule which defines the |
| | | * constraints for the virtual attribute. |
| | | * @param value The value for which to make the determination. |
| | | * |
| | | * @return {@code UNDEFINED} if the associated attribute type does |
| | | * not have an ordering matching rule, {@code TRUE} if at |
| | | * least one of the generated values will be less than or |
| | | * equal to the specified value, or {@code FALSE} if none |
| | | * of the generated values will be greater than or equal to |
| | | * the specified value. |
| | | */ |
| | | public ConditionResult lessThanOrEqualTo(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | OrderingMatchingRule matchingRule = |
| | | rule.getAttributeType().getOrderingMatchingRule(); |
| | | if (matchingRule == null) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | ByteString normalizedValue; |
| | | try |
| | | { |
| | | normalizedValue = value.getNormalizedValue(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We couldn't normalize the provided value. We should return |
| | | // "undefined". |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | ConditionResult result = ConditionResult.FALSE; |
| | | for (AttributeValue v : getValues(entry, rule)) |
| | | { |
| | | try |
| | | { |
| | | ByteString nv = v.getNormalizedValue(); |
| | | int comparisonResult = |
| | | matchingRule.compareValues(nv, normalizedValue); |
| | | if (comparisonResult <= 0) |
| | | { |
| | | return ConditionResult.TRUE; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We couldn't normalize one of the attribute values. If we |
| | | // can't find a definite match, then we should return |
| | | // "undefined". |
| | | result = ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this virtual attribute provider will generate |
| | | * any value for the provided entry that is approximately equal to |
| | | * the given value. |
| | | * |
| | | * @param entry The entry for which to make the determination. |
| | | * @param rule The virtual attribute rule which defines the |
| | | * constraints for the virtual attribute. |
| | | * @param value The value for which to make the determination. |
| | | * |
| | | * @return {@code UNDEFINED} if the associated attribute type does |
| | | * not have an aproximate matching rule, {@code TRUE} if at |
| | | * least one of the generated values will be approximately |
| | | * equal to the specified value, or {@code FALSE} if none |
| | | * of the generated values will be approximately equal to |
| | | * the specified value. |
| | | */ |
| | | public ConditionResult approximatelyEqualTo(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | ApproximateMatchingRule matchingRule = |
| | | rule.getAttributeType().getApproximateMatchingRule(); |
| | | if (matchingRule == null) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | ByteString normalizedValue; |
| | | try |
| | | { |
| | | normalizedValue = matchingRule.normalizeValue(value.getValue()); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We couldn't normalize the provided value. We should return |
| | | // "undefined". |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | ConditionResult result = ConditionResult.FALSE; |
| | | for (AttributeValue v : getValues(entry, rule)) |
| | | { |
| | | try |
| | | { |
| | | ByteString nv = matchingRule.normalizeValue(v.getValue()); |
| | | if (matchingRule.approximatelyMatch(nv, normalizedValue)) |
| | | { |
| | | return ConditionResult.TRUE; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | // We couldn't normalize one of the attribute values. If we |
| | | // can't find a definite match, then we should return |
| | | // "undefined". |
| | | result = ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this attribute may be included in search |
| | | * filters as part of the criteria for locating entries. |
| | | * |
| | | * @param rule The virtual attribute rule which defines |
| | | * the constraints for the virtual |
| | | * attribute. |
| | | * @param searchOperation The search operation for which to make |
| | | * the determination. |
| | | * |
| | | * @return <CODE>true</CODE> if this attribute may be included in |
| | | * search filters, or <CODE>false</CODE> if not. |
| | | */ |
| | | public abstract boolean isSearchable(VirtualAttributeRule rule, |
| | | SearchOperation |
| | | searchOperation); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Processes the provided search operation in which the search |
| | | * criteria includes an operation targeted at this virtual |
| | | * attribute. This method should only be called if |
| | | * <CODE>isSearchable</CODE> returns true and it is not possible to |
| | | * construct a manageable candidate list by processing other |
| | | * elements of the search criteria. |
| | | * |
| | | * @param rule The virtual attribute rule which defines |
| | | * the constraints for the virtual |
| | | * attribute. |
| | | * @param searchOperation The search operation to be processed. |
| | | */ |
| | | public abstract void processSearch(VirtualAttributeRule rule, |
| | | SearchOperation searchOperation); |
| | | } |
| | | |
| | |
| | | extends Backend |
| | | implements ConfigurableComponent |
| | | { |
| | | |
| | | |
| | | |
| | | // The DN of the configuration entry for this backend. |
| | | private DN configEntryDN; |
| | | |
| | |
| | | { |
| | | super(); |
| | | |
| | | |
| | | |
| | | // Perform all initialization in initializeBackend. |
| | | } |
| | | |
| | |
| | | // If the requested entry was the backend base entry, then retrieve it. |
| | | if (entryDN.equals(backupBaseDN)) |
| | | { |
| | | return backupBaseEntry; |
| | | return backupBaseEntry.duplicate(true); |
| | | } |
| | | |
| | | |
| | |
| | | userAttrs.put(t, attrList); |
| | | |
| | | |
| | | return new Entry(entryDN, ocMap, userAttrs, opAttrs); |
| | | Entry e = new Entry(entryDN, ocMap, userAttrs, opAttrs); |
| | | e.processVirtualAttributes(); |
| | | return e; |
| | | } |
| | | |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | return new Entry(entryDN, ocMap, userAttrs, opAttrs); |
| | | Entry e = new Entry(entryDN, ocMap, userAttrs, opAttrs); |
| | | e.processVirtualAttributes(); |
| | | return e; |
| | | } |
| | | |
| | | |
| | |
| | | public class MemoryBackend |
| | | extends Backend |
| | | { |
| | | |
| | | |
| | | |
| | | // The base DNs for this backend. |
| | | private DN[] baseDNs; |
| | | |
| | |
| | | { |
| | | super(); |
| | | |
| | | |
| | | |
| | | // Perform all initialization in initializeBackend. |
| | | } |
| | | |
| | |
| | | public synchronized void addEntry(Entry entry, AddOperation addOperation) |
| | | throws DirectoryException |
| | | { |
| | | Entry e = entry.duplicate(true); |
| | | |
| | | // See if the target entry already exists. If so, then fail. |
| | | DN entryDN = entry.getDN(); |
| | | DN entryDN = e.getDN(); |
| | | if (entryMap.containsKey(entryDN)) |
| | | { |
| | | int msgID = MSGID_MEMORYBACKEND_ENTRY_ALREADY_EXISTS; |
| | |
| | | // If the entry is one of the base DNs, then add it. |
| | | if (baseDNSet.contains(entryDN)) |
| | | { |
| | | entryMap.put(entryDN, entry); |
| | | entryMap.put(entryDN, e); |
| | | return; |
| | | } |
| | | |
| | |
| | | throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message, msgID); |
| | | } |
| | | |
| | | entryMap.put(entryDN, entry); |
| | | entryMap.put(entryDN, e); |
| | | HashSet<DN> children = childDNs.get(parentDN); |
| | | if (children == null) |
| | | { |
| | |
| | | ModifyOperation modifyOperation) |
| | | throws DirectoryException |
| | | { |
| | | Entry e = entry.duplicate(true); |
| | | |
| | | // Make sure the entry exists. If not, then throw an exception. |
| | | DN entryDN = entry.getDN(); |
| | | DN entryDN = e.getDN(); |
| | | if (! entryMap.containsKey(entryDN)) |
| | | { |
| | | int msgID = MSGID_MEMORYBACKEND_ENTRY_DOESNT_EXIST; |
| | |
| | | |
| | | |
| | | // Replace the old entry with the new one. |
| | | entryMap.put(entryDN, entry); |
| | | entryMap.put(entryDN, e); |
| | | } |
| | | |
| | | |
| | |
| | | ModifyDNOperation modifyDNOperation) |
| | | throws DirectoryException |
| | | { |
| | | Entry e = entry.duplicate(true); |
| | | |
| | | // Make sure that the target entry exists. |
| | | if (! entryMap.containsKey(currentDN)) |
| | | { |
| | |
| | | |
| | | |
| | | // Make sure that no entry exists with the new DN. |
| | | if (entryMap.containsKey(entry.getDN())) |
| | | if (entryMap.containsKey(e.getDN())) |
| | | { |
| | | int msgID = MSGID_MEMORYBACKEND_ENTRY_ALREADY_EXISTS; |
| | | String message = getMessage(msgID, String.valueOf(entry.getDN())); |
| | | String message = getMessage(msgID, String.valueOf(e.getDN())); |
| | | throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message, msgID); |
| | | } |
| | | |
| | |
| | | boolean matchFound = false; |
| | | for (DN dn : baseDNs) |
| | | { |
| | | if (dn.isAncestorOf(entry.getDN())) |
| | | if (dn.isAncestorOf(e.getDN())) |
| | | { |
| | | matchFound = true; |
| | | break; |
| | |
| | | |
| | | |
| | | // Make sure that the parent of the new entry exists. |
| | | DN parentDN = entry.getDN().getParentDNInSuffix(); |
| | | DN parentDN = e.getDN().getParentDNInSuffix(); |
| | | if ((parentDN == null) || (! entryMap.containsKey(parentDN))) |
| | | { |
| | | int msgID = MSGID_MEMORYBACKEND_RENAME_PARENT_DOESNT_EXIST; |
| | |
| | | |
| | | // Delete the current entry and add the new one. |
| | | deleteEntry(currentDN, null); |
| | | addEntry(entry, null); |
| | | addEntry(e, null); |
| | | } |
| | | |
| | | |
| | |
| | | extends Backend |
| | | implements ConfigurableComponent |
| | | { |
| | | |
| | | |
| | | |
| | | // The set of user-defined attributes that will be included in the base |
| | | // monitor entry. |
| | | private ArrayList<Attribute> userDefinedAttributes; |
| | |
| | | { |
| | | super(); |
| | | |
| | | |
| | | |
| | | // Perform all initialization in initializeBackend. |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | // Construct and return the entry. |
| | | return new Entry(baseMonitorDN, monitorClasses, monitorUserAttrs, |
| | | monitorOperationalAttrs); |
| | | Entry e = new Entry(baseMonitorDN, monitorClasses, monitorUserAttrs, |
| | | monitorOperationalAttrs); |
| | | e.processVirtualAttributes(); |
| | | return e; |
| | | } |
| | | |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | return new Entry(entryDN, monitorClasses, attrMap, |
| | | new HashMap<AttributeType,List<Attribute>>(0)); |
| | | Entry e = new Entry(entryDN, monitorClasses, attrMap, |
| | | new HashMap<AttributeType,List<Attribute>>(0)); |
| | | e.processVirtualAttributes(); |
| | | return e; |
| | | } |
| | | |
| | | |
| | |
| | | extends Backend |
| | | implements ConfigurableComponent |
| | | { |
| | | |
| | | |
| | | |
| | | // The set of standard "static" attributes that we will always include in the |
| | | // root DSE entry and won't change while the server is running. |
| | | private ArrayList<Attribute> staticDSEAttributes; |
| | |
| | | { |
| | | super(); |
| | | |
| | | |
| | | |
| | | // Perform all initialization in initializeBackend. |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | |
| | | // Add the "subschemaSubentry" attribute. |
| | | DN schemaDN = DirectoryServer.getSchemaDN(); |
| | | if (schemaDN != null) |
| | | { |
| | | Attribute subschemaSubentryAttr = |
| | | createAttribute(ATTR_SUBSCHEMA_SUBENTRY, ATTR_SUBSCHEMA_SUBENTRY_LC, |
| | | String.valueOf(schemaDN)); |
| | | ArrayList<Attribute> subschemaSubentryAttrs = new ArrayList<Attribute>(1); |
| | | subschemaSubentryAttrs.add(subschemaSubentryAttr); |
| | | if (showAllAttributes || |
| | | (! subschemaSubentryAttr.getAttributeType().isOperational())) |
| | | { |
| | | dseUserAttrs.put(subschemaSubentryAttr.getAttributeType(), |
| | | subschemaSubentryAttrs); |
| | | } |
| | | else |
| | | { |
| | | dseOperationalAttrs.put(subschemaSubentryAttr.getAttributeType(), |
| | | subschemaSubentryAttrs); |
| | | } |
| | | } |
| | | |
| | | |
| | | // Add all the standard "static" attributes. |
| | | for (Attribute a : staticDSEAttributes) |
| | | { |
| | |
| | | |
| | | |
| | | // Construct and return the entry. |
| | | return new Entry(rootDSEDN, dseObjectClasses, dseUserAttrs, |
| | | dseOperationalAttrs); |
| | | Entry e = new Entry(rootDSEDN, dseObjectClasses, dseUserAttrs, |
| | | dseOperationalAttrs); |
| | | e.processVirtualAttributes(); |
| | | return e; |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | // Construct and return the entry. |
| | | return new Entry(entryDN, schemaObjectClasses, userAttrs, operationalAttrs); |
| | | Entry e = new Entry(entryDN, schemaObjectClasses, userAttrs, |
| | | operationalAttrs); |
| | | e.processVirtualAttributes(); |
| | | return e; |
| | | } |
| | | |
| | | |
| | |
| | | //Try to decode the entry based on the version number. On later versions, |
| | | //a case could be written to upgrade entries if it is not the current |
| | | //version |
| | | Entry entry = null; |
| | | switch(entryVersion) |
| | | { |
| | | case JebFormat.FORMAT_VERSION : |
| | | try |
| | | { |
| | | return JebFormat.entryFromDatabase(entryBytes); |
| | | entry = JebFormat.entryFromDatabase(entryBytes); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | |
| | | String message = getMessage(msgID, id.toString()); |
| | | throw new JebException(msgID, message); |
| | | } |
| | | break; |
| | | |
| | | //case 0x00 : |
| | | // Call upgrade method? Call 0x00 decode method? |
| | | default : |
| | |
| | | String message = getMessage(msgID, id.toString(), entryVersion); |
| | | throw new JebException(msgID, message); |
| | | } |
| | | |
| | | if (entry != null) |
| | | { |
| | | entry.processVirtualAttributes(); |
| | | } |
| | | |
| | | return entry; |
| | | } |
| | | |
| | | /** |
| | |
| | | { |
| | | for (Attribute a : list) |
| | | { |
| | | if (a.isVirtual()) |
| | | { |
| | | continue; |
| | | } |
| | | userAttrElements.add(new LDAPAttribute(a).encode()); |
| | | } |
| | | } |
| | |
| | | { |
| | | for (Attribute a : list) |
| | | { |
| | | if (a.isVirtual()) |
| | | { |
| | | continue; |
| | | } |
| | | opAttrElements.add(new LDAPAttribute(a).encode()); |
| | | } |
| | | } |
| | |
| | | extends Backend |
| | | implements ConfigurableComponent |
| | | { |
| | | |
| | | |
| | | |
| | | /** |
| | | * The set of time units that will be used for expressing the task retention |
| | | * time. |
| | |
| | | { |
| | | super(); |
| | | |
| | | |
| | | |
| | | // Perform all initialization in initializeBackend. |
| | | } |
| | | |
| | |
| | | public void addEntry(Entry entry, AddOperation addOperation) |
| | | throws DirectoryException |
| | | { |
| | | Entry e = entry.duplicate(false); |
| | | |
| | | // Get the DN for the entry and then get its parent. |
| | | DN entryDN = entry.getDN(); |
| | | DN entryDN = e.getDN(); |
| | | DN parentDN = entryDN.getParentDNInSuffix(); |
| | | |
| | | if (parentDN == null) |
| | |
| | | // treat the provided entry like a scheduled task. |
| | | if (parentDN.equals(scheduledTaskParentDN)) |
| | | { |
| | | Task task = taskScheduler.entryToScheduledTask(entry, addOperation); |
| | | Task task = taskScheduler.entryToScheduledTask(e, addOperation); |
| | | taskScheduler.scheduleTask(task, true); |
| | | return; |
| | | } |
| | |
| | | // treat the provided entry like a recurring task. |
| | | if (parentDN.equals(recurringTaskParentDN)) |
| | | { |
| | | RecurringTask recurringTask = taskScheduler.entryToRecurringTask(entry); |
| | | RecurringTask recurringTask = taskScheduler.entryToRecurringTask(e); |
| | | taskScheduler.addRecurringTask(recurringTask, true); |
| | | return; |
| | | } |
| | |
| | | */ |
| | | public Entry getTaskRootEntry() |
| | | { |
| | | return taskRootEntry; |
| | | return taskRootEntry.duplicate(true); |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public Entry getScheduledTaskParentEntry() |
| | | { |
| | | return scheduledTaskParentEntry; |
| | | return scheduledTaskParentEntry.duplicate(true); |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public Entry getRecurringTaskParentEntry() |
| | | { |
| | | return recurringTaskParentEntry; |
| | | return recurringTaskParentEntry.duplicate(true); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | if (scheduledTaskEntryDN.equals(taskEntry.getDN())) |
| | | { |
| | | return taskEntry; |
| | | return taskEntry.duplicate(true); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | try |
| | | { |
| | | Entry e = t.getTaskEntry(); |
| | | Entry e = t.getTaskEntry().duplicate(true); |
| | | if (filter.matchesEntry(e)) |
| | | { |
| | | if (! searchOperation.returnEntry(e, null)) |
| | |
| | | |
| | | if (recurringTaskEntryDN.equals(recurringTaskEntry.getDN())) |
| | | { |
| | | return recurringTaskEntry; |
| | | return recurringTaskEntry.duplicate(true); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | try |
| | | { |
| | | Entry e = rt.getRecurringTaskEntry(); |
| | | Entry e = rt.getRecurringTaskEntry().duplicate(true); |
| | | if (filter.matchesEntry(e)) |
| | | { |
| | | if (! searchOperation.returnEntry(e, null)) |
| | |
| | | */ |
| | | public ConfigEntry duplicate() |
| | | { |
| | | return new ConfigEntry(entry.duplicate(), parent); |
| | | return new ConfigEntry(entry.duplicate(false), parent); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | if (postReadRequest != null) |
| | | { |
| | | Entry addedEntry = entry.duplicate(); |
| | | Entry addedEntry = entry.duplicate(true); |
| | | |
| | | if (! postReadRequest.allowsAttribute( |
| | | DirectoryServer.getObjectClassAttributeType())) |
| | |
| | | |
| | | if (preReadRequest != null) |
| | | { |
| | | Entry entryCopy = entry.duplicate(); |
| | | Entry entryCopy = entry.duplicate(true); |
| | | |
| | | if (! preReadRequest.allowsAttribute( |
| | | DirectoryServer.getObjectClassAttributeType())) |
| | |
| | | // between the mechanism name and the handler). |
| | | private ConcurrentHashMap<String,SASLMechanismHandler> saslMechanismHandlers; |
| | | |
| | | // The set of virtual attributes defined in the server (mapped between the |
| | | // lowercase names and the virtual attributes). |
| | | private ConcurrentHashMap<String,VirtualAttribute> virtualAttributes; |
| | | |
| | | // The connection handler configuration manager for the Directory Server. |
| | | private ConnectionHandlerConfigManager connectionHandlerConfigManager; |
| | | |
| | |
| | | private CopyOnWriteArrayList<SynchronizationProvider> |
| | | synchronizationProviders; |
| | | |
| | | // The set of virtual attributes defined in the server. |
| | | private CopyOnWriteArrayList<VirtualAttributeRule> virtualAttributes; |
| | | |
| | | // The set of backend initialization listeners registered with the Directory |
| | | // Server. |
| | | private CopyOnWriteArraySet<BackendInitializationListener> |
| | |
| | | // The trust manager provider configuration manager for the Directory Server. |
| | | private TrustManagerProviderConfigManager trustManagerProviderConfigManager; |
| | | |
| | | // The virtual attribute provider configuration manager for the Directory |
| | | // Server. |
| | | private VirtualAttributeConfigManager virtualAttributeConfigManager; |
| | | |
| | | // The work queue that will be used to service client requests. |
| | | private WorkQueue workQueue; |
| | | |
| | |
| | | directoryServer.supportedControls = new TreeSet<String>(); |
| | | directoryServer.supportedFeatures = new TreeSet<String>(); |
| | | directoryServer.virtualAttributes = |
| | | new ConcurrentHashMap<String,VirtualAttribute>(); |
| | | new CopyOnWriteArrayList<VirtualAttributeRule>(); |
| | | directoryServer.connectionHandlers = |
| | | new CopyOnWriteArrayList<ConnectionHandler>(); |
| | | directoryServer.identityMappers = |
| | |
| | | supportedControls.add(OID_MATCHED_VALUES); |
| | | supportedControls.add(OID_LDAP_SUBENTRIES); |
| | | supportedControls.add(OID_PASSWORD_POLICY_CONTROL); |
| | | supportedControls.add(OID_REAL_ATTRS_ONLY); |
| | | supportedControls.add(OID_VIRTUAL_ATTRS_ONLY); |
| | | } |
| | | |
| | | |
| | |
| | | private void initializeVirtualAttributes() |
| | | throws ConfigException, InitializationException |
| | | { |
| | | // NYI |
| | | virtualAttributeConfigManager = new VirtualAttributeConfigManager(); |
| | | virtualAttributeConfigManager.initializeVirtualAttributes(); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of virtual attribute rules registered with the Directory |
| | | * Server. |
| | | * |
| | | * @return The set of virtual attribute rules registered with the Directory |
| | | * Server. |
| | | */ |
| | | public static List<VirtualAttributeRule> getVirtualAttributes() |
| | | { |
| | | return directoryServer.virtualAttributes; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of virtual attribute rules registered with the Directory |
| | | * Server that are applicable to the provided entry. |
| | | * |
| | | * @param entry The entry for which to retrieve the applicable virtual |
| | | * attribute rules. |
| | | * |
| | | * @return The set of virtual attribute rules registered with the Directory |
| | | * Server that apply to the given entry. It may be an empty list if |
| | | * there are no applicable virtual attribute rules. |
| | | */ |
| | | public static List<VirtualAttributeRule> getVirtualAttributes(Entry entry) |
| | | { |
| | | LinkedList<VirtualAttributeRule> ruleList = |
| | | new LinkedList<VirtualAttributeRule>(); |
| | | |
| | | for (VirtualAttributeRule rule : directoryServer.virtualAttributes) |
| | | { |
| | | if (rule.appliesToEntry(entry)) |
| | | { |
| | | ruleList.add(rule); |
| | | } |
| | | } |
| | | |
| | | return ruleList; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Registers the provided virtual attribute rule with the Directory Server. |
| | | * |
| | | * @param rule The virtual attribute rule to be registered. |
| | | */ |
| | | public static void registerVirtualAttribute(VirtualAttributeRule rule) |
| | | { |
| | | synchronized (directoryServer.virtualAttributes) |
| | | { |
| | | directoryServer.virtualAttributes.add(rule); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Deregisters the provided virtual attribute rule with the Directory Server. |
| | | * |
| | | * @param rule The virutal attribute rule to be deregistered. |
| | | */ |
| | | public static void deregisterVirtualAttribute(VirtualAttributeRule rule) |
| | | { |
| | | synchronized (directoryServer.virtualAttributes) |
| | | { |
| | | directoryServer.virtualAttributes.remove(rule); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Replaces the specified virtual attribute rule in the set of virtual |
| | | * attributes registered with the Directory Server. If the old rule cannot |
| | | * be found in the list, then the set of registered virtual attributes is not |
| | | * updated. |
| | | * |
| | | * @param oldRule The existing rule that should be replaced with the new |
| | | * rule. |
| | | * @param newRule The new rule that should be used in place of the existing |
| | | * rule. |
| | | * |
| | | * @return {@code true} if the old rule was found and replaced with the new |
| | | * version, or {@code false} if it was not. |
| | | */ |
| | | public static boolean replaceVirtualAttribute(VirtualAttributeRule oldRule, |
| | | VirtualAttributeRule newRule) |
| | | { |
| | | synchronized (directoryServer.virtualAttributes) |
| | | { |
| | | int pos = directoryServer.virtualAttributes.indexOf(oldRule); |
| | | if (pos >= 0) |
| | | { |
| | | directoryServer.virtualAttributes.set(pos, newRule); |
| | | return true; |
| | | } |
| | | else |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a reference to the JMX MBean server that is associated with the |
| | | * Directory Server. |
| | | * |
| | |
| | | |
| | | // Duplicate the entry and set its new DN. Also, create an empty list |
| | | // to hold the attribute-level modifications. |
| | | newEntry = currentEntry.duplicate(); |
| | | newEntry = currentEntry.duplicate(false); |
| | | newEntry.setDN(newDN); |
| | | modifications = new ArrayList<Modification>(); |
| | | |
| | |
| | | |
| | | if (preReadRequest != null) |
| | | { |
| | | Entry entry = currentEntry.duplicate(); |
| | | Entry entry = currentEntry.duplicate(true); |
| | | |
| | | if (! preReadRequest.allowsAttribute( |
| | | DirectoryServer.getObjectClassAttributeType())) |
| | |
| | | |
| | | if (postReadRequest != null) |
| | | { |
| | | Entry entry = newEntry.duplicate(); |
| | | Entry entry = newEntry.duplicate(true); |
| | | |
| | | if (! postReadRequest.allowsAttribute( |
| | | DirectoryServer.getObjectClassAttributeType())) |
| | |
| | | |
| | | |
| | | // Create a duplicate of the entry and apply the changes to it. |
| | | modifiedEntry = currentEntry.duplicate(); |
| | | modifiedEntry = currentEntry.duplicate(false); |
| | | |
| | | if (! noOp) |
| | | { |
| | |
| | | |
| | | if (preReadRequest != null) |
| | | { |
| | | Entry entry = currentEntry.duplicate(); |
| | | Entry entry = currentEntry.duplicate(true); |
| | | |
| | | if (! preReadRequest.allowsAttribute( |
| | | DirectoryServer.getObjectClassAttributeType())) |
| | |
| | | |
| | | if (postReadRequest != null) |
| | | { |
| | | Entry entry = modifiedEntry.duplicate(); |
| | | Entry entry = modifiedEntry.duplicate(true); |
| | | |
| | | if (! postReadRequest.allowsAttribute( |
| | | DirectoryServer.getObjectClassAttributeType())) |
| | |
| | | PostOperationSearchOperation, PostResponseSearchOperation, |
| | | SearchEntrySearchOperation, SearchReferenceSearchOperation |
| | | { |
| | | |
| | | |
| | | |
| | | // Indicates whether a search result done response has been sent to the |
| | | // client. |
| | | private AtomicBoolean responseSent; |
| | |
| | | // entries. |
| | | private boolean includeUsableControl; |
| | | |
| | | // Indicates whether to only real attributes should be returned. |
| | | private boolean realAttributesOnly; |
| | | |
| | | // Indicates whether LDAP subentries should be returned. |
| | | private boolean returnLDAPSubentries; |
| | | |
| | | // Indicates whether to include attribute types only or both types and values. |
| | | private boolean typesOnly; |
| | | |
| | | // Indicates whether to only virtual attributes should be returned. |
| | | private boolean virtualAttributesOnly; |
| | | |
| | | // The raw, unprocessed base DN as included in the request from the client. |
| | | private ByteString rawBaseDN; |
| | | |
| | |
| | | persistentSearch = null; |
| | | returnLDAPSubentries = false; |
| | | matchedValuesControl = null; |
| | | realAttributesOnly = false; |
| | | virtualAttributesOnly = false; |
| | | } |
| | | |
| | | |
| | |
| | | Entry entryToReturn; |
| | | if ((attributes == null) || attributes.isEmpty()) |
| | | { |
| | | entryToReturn = entry.duplicateWithoutOperationalAttributes(typesOnly); |
| | | entryToReturn = entry.duplicateWithoutOperationalAttributes(typesOnly, |
| | | true); |
| | | } |
| | | else |
| | | { |
| | |
| | | } |
| | | |
| | | |
| | | if (realAttributesOnly) |
| | | { |
| | | entryToReturn.stripVirtualAttributes(); |
| | | } |
| | | else if (virtualAttributesOnly) |
| | | { |
| | | entryToReturn.stripRealAttributes(); |
| | | } |
| | | |
| | | |
| | | // If there is a matched values control, then further pare down the entry |
| | | // based on the filters that it contains. |
| | | if ((matchedValuesControl != null) && (! typesOnly)) |
| | |
| | | { |
| | | includeUsableControl = true; |
| | | } |
| | | else if (oid.equals(OID_REAL_ATTRS_ONLY)) |
| | | { |
| | | realAttributesOnly = true; |
| | | } |
| | | else if (oid.equals(OID_VIRTUAL_ATTRS_ONLY)) |
| | | { |
| | | virtualAttributesOnly = true; |
| | | } |
| | | |
| | | // NYI -- Add support for additional controls. |
| | | else if (c.isCritical()) |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.core; |
| | | |
| | | |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | |
| | | import org.opends.server.admin.ClassPropertyDefinition; |
| | | import org.opends.server.admin.server.ConfigurationAddListener; |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import org.opends.server.admin.server.ConfigurationDeleteListener; |
| | | import org.opends.server.admin.std.meta.VirtualAttributeCfgDefn; |
| | | import org.opends.server.admin.std.server.VirtualAttributeCfg; |
| | | import org.opends.server.admin.std.server.RootCfg; |
| | | import org.opends.server.admin.server.ServerManagementContext; |
| | | import org.opends.server.api.VirtualAttributeProvider; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.types.ConfigChangeResult; |
| | | import org.opends.server.types.DebugLogLevel; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.ErrorLogCategory; |
| | | import org.opends.server.types.ErrorLogSeverity; |
| | | import org.opends.server.types.InitializationException; |
| | | import org.opends.server.types.ResultCode; |
| | | import org.opends.server.types.SearchFilter; |
| | | import org.opends.server.types.VirtualAttributeRule; |
| | | |
| | | import static org.opends.server.loggers.Error.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.messages.ConfigMessages.*; |
| | | import static org.opends.server.messages.MessageHandler.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines a utility that will be used to manage the set of |
| | | * virtual attribute providers defined in the Directory Server. It will |
| | | * initialize the providers when the server starts, and then will manage any |
| | | * additions, removals, or modifications to any virtual attribute providers |
| | | * while the server is running. |
| | | */ |
| | | public class VirtualAttributeConfigManager |
| | | implements ConfigurationChangeListener<VirtualAttributeCfg>, |
| | | ConfigurationAddListener<VirtualAttributeCfg>, |
| | | ConfigurationDeleteListener<VirtualAttributeCfg> |
| | | { |
| | | // A mapping between the DNs of the config entries and the associated |
| | | // virtual attribute rules. |
| | | private ConcurrentHashMap<DN,VirtualAttributeRule> rules; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new instance of this virtual attribute config manager. |
| | | */ |
| | | public VirtualAttributeConfigManager() |
| | | { |
| | | rules = new ConcurrentHashMap<DN,VirtualAttributeRule>(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Initializes all virtual attribute providers currently defined in the |
| | | * Directory Server configuration. This should only be called at Directory |
| | | * Server startup. |
| | | * |
| | | * @throws ConfigException If a configuration problem causes the virtual |
| | | * attribute provider initialization process to |
| | | * fail. |
| | | * |
| | | * @throws InitializationException If a problem occurs while initializing |
| | | * the virtual attribute providers that is |
| | | * not related to the server configuration. |
| | | */ |
| | | public void initializeVirtualAttributes() |
| | | throws ConfigException, InitializationException |
| | | { |
| | | // Get the root configuration object. |
| | | ServerManagementContext managementContext = |
| | | ServerManagementContext.getInstance(); |
| | | RootCfg rootConfiguration = |
| | | managementContext.getRootConfiguration(); |
| | | |
| | | |
| | | // Register as an add and delete listener with the root configuration so we |
| | | // can be notified if any virtual attribute provider entries are added or |
| | | // removed. |
| | | rootConfiguration.addVirtualAttributeAddListener(this); |
| | | rootConfiguration.addVirtualAttributeDeleteListener(this); |
| | | |
| | | |
| | | //Initialize the existing virtual attribute providers. |
| | | for (String providerName : rootConfiguration.listVirtualAttributes()) |
| | | { |
| | | VirtualAttributeCfg cfg = |
| | | rootConfiguration.getVirtualAttribute(providerName); |
| | | cfg.addChangeListener(this); |
| | | |
| | | if (cfg.isEnabled()) |
| | | { |
| | | String className = cfg.getProviderClass(); |
| | | try |
| | | { |
| | | VirtualAttributeProvider<? extends VirtualAttributeCfg> provider = |
| | | loadProvider(className, cfg); |
| | | |
| | | LinkedHashSet<SearchFilter> filters = |
| | | new LinkedHashSet<SearchFilter>(); |
| | | for (String filterString : cfg.getFilter()) |
| | | { |
| | | try |
| | | { |
| | | filters.add(SearchFilter.createFilterFromString(filterString)); |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, de); |
| | | } |
| | | |
| | | int msgID = MSGID_CONFIG_VATTR_INVALID_SEARCH_FILTER; |
| | | String message = getMessage(msgID, filterString, |
| | | String.valueOf(cfg.dn()), |
| | | de.getErrorMessage()); |
| | | throw new ConfigException(msgID, message, de); |
| | | } |
| | | } |
| | | |
| | | if (cfg.getAttributeType().isSingleValue()) |
| | | { |
| | | if (provider.isMultiValued()) |
| | | { |
| | | int msgID = MSGID_CONFIG_VATTR_SV_TYPE_WITH_MV_PROVIDER; |
| | | String message = getMessage(msgID, String.valueOf(cfg.dn()), |
| | | cfg.getAttributeType().getNameOrOID(), |
| | | className); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | else if (cfg.getConflictBehavior() == |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | MERGE_REAL_AND_VIRTUAL) |
| | | { |
| | | int msgID = MSGID_CONFIG_VATTR_SV_TYPE_WITH_MERGE_VALUES; |
| | | String message = getMessage(msgID, String.valueOf(cfg.dn()), |
| | | cfg.getAttributeType().getNameOrOID()); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | } |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(cfg.getAttributeType(), provider, |
| | | cfg.getBaseDN(), cfg.getGroupDN(), |
| | | filters, cfg.getConflictBehavior()); |
| | | rules.put(cfg.dn(), rule); |
| | | DirectoryServer.registerVirtualAttribute(rule); |
| | | } |
| | | catch (InitializationException ie) |
| | | { |
| | | logError(ErrorLogCategory.CONFIGURATION, |
| | | ErrorLogSeverity.SEVERE_ERROR, |
| | | ie.getMessage(), ie.getMessageID()); |
| | | continue; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isConfigurationAddAcceptable( |
| | | VirtualAttributeCfg configuration, |
| | | List<String> unacceptableReasons) |
| | | { |
| | | if (configuration.isEnabled()) |
| | | { |
| | | // Get the name of the class and make sure we can instantiate it as a |
| | | // virtual attribute provider. |
| | | String className = configuration.getProviderClass(); |
| | | try |
| | | { |
| | | loadProvider(className, null); |
| | | } |
| | | catch (InitializationException ie) |
| | | { |
| | | unacceptableReasons.add(ie.getMessage()); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // If there were any search filters provided, then make sure they are all |
| | | // valid. |
| | | for (String filterString : configuration.getFilter()) |
| | | { |
| | | try |
| | | { |
| | | SearchFilter.createFilterFromString(filterString); |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, de); |
| | | } |
| | | |
| | | int msgID = MSGID_CONFIG_VATTR_INVALID_SEARCH_FILTER; |
| | | String message = getMessage(msgID, filterString, |
| | | String.valueOf(configuration.dn()), |
| | | de.getErrorMessage()); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // If we've gotten here, then it's fine. |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ConfigChangeResult applyConfigurationAdd( |
| | | VirtualAttributeCfg configuration) |
| | | { |
| | | ResultCode resultCode = ResultCode.SUCCESS; |
| | | boolean adminActionRequired = false; |
| | | ArrayList<String> messages = new ArrayList<String>(); |
| | | |
| | | configuration.addChangeListener(this); |
| | | |
| | | if (! configuration.isEnabled()) |
| | | { |
| | | return new ConfigChangeResult(resultCode, adminActionRequired, messages); |
| | | } |
| | | |
| | | // Make sure that we can parse all of the search filters. |
| | | LinkedHashSet<SearchFilter> filters = |
| | | new LinkedHashSet<SearchFilter>(); |
| | | for (String filterString : configuration.getFilter()) |
| | | { |
| | | try |
| | | { |
| | | filters.add(SearchFilter.createFilterFromString(filterString)); |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, de); |
| | | } |
| | | |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.INVALID_ATTRIBUTE_SYNTAX; |
| | | } |
| | | |
| | | int msgID = MSGID_CONFIG_VATTR_INVALID_SEARCH_FILTER; |
| | | String message = getMessage(msgID, filterString, |
| | | String.valueOf(configuration.dn()), |
| | | de.getErrorMessage()); |
| | | messages.add(message); |
| | | } |
| | | } |
| | | |
| | | // Get the name of the class and make sure we can instantiate it as a |
| | | // certificate mapper. |
| | | VirtualAttributeProvider<? extends VirtualAttributeCfg> provider = null; |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | String className = configuration.getProviderClass(); |
| | | try |
| | | { |
| | | provider = loadProvider(className, configuration); |
| | | } |
| | | catch (InitializationException ie) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | messages.add(ie.getMessage()); |
| | | } |
| | | } |
| | | |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(configuration.getAttributeType(), provider, |
| | | configuration.getBaseDN(), |
| | | configuration.getGroupDN(), |
| | | filters, |
| | | configuration.getConflictBehavior()); |
| | | |
| | | rules.put(configuration.dn(), rule); |
| | | DirectoryServer.registerVirtualAttribute(rule); |
| | | } |
| | | |
| | | return new ConfigChangeResult(resultCode, adminActionRequired, messages); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isConfigurationDeleteAcceptable( |
| | | VirtualAttributeCfg configuration, |
| | | List<String> unacceptableReasons) |
| | | { |
| | | // We will always allow getting rid of a virtual attribute rule. |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ConfigChangeResult applyConfigurationDelete( |
| | | VirtualAttributeCfg configuration) |
| | | { |
| | | ResultCode resultCode = ResultCode.SUCCESS; |
| | | boolean adminActionRequired = false; |
| | | ArrayList<String> messages = new ArrayList<String>(); |
| | | |
| | | VirtualAttributeRule rule = rules.remove(configuration.dn()); |
| | | if (rule != null) |
| | | { |
| | | DirectoryServer.deregisterVirtualAttribute(rule); |
| | | rule.getProvider().finalizeVirtualAttributeProvider(); |
| | | } |
| | | |
| | | return new ConfigChangeResult(resultCode, adminActionRequired, messages); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isConfigurationChangeAcceptable( |
| | | VirtualAttributeCfg configuration, |
| | | List<String> unacceptableReasons) |
| | | { |
| | | if (configuration.isEnabled()) |
| | | { |
| | | // Get the name of the class and make sure we can instantiate it as a |
| | | // virtual attribute provider. |
| | | String className = configuration.getProviderClass(); |
| | | try |
| | | { |
| | | loadProvider(className, null); |
| | | } |
| | | catch (InitializationException ie) |
| | | { |
| | | unacceptableReasons.add(ie.getMessage()); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // If there were any search filters provided, then make sure they are all |
| | | // valid. |
| | | for (String filterString : configuration.getFilter()) |
| | | { |
| | | try |
| | | { |
| | | SearchFilter.createFilterFromString(filterString); |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, de); |
| | | } |
| | | |
| | | int msgID = MSGID_CONFIG_VATTR_INVALID_SEARCH_FILTER; |
| | | String message = getMessage(msgID, filterString, |
| | | String.valueOf(configuration.dn()), |
| | | de.getErrorMessage()); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // If we've gotten here, then it's fine. |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ConfigChangeResult applyConfigurationChange( |
| | | VirtualAttributeCfg configuration) |
| | | { |
| | | ResultCode resultCode = ResultCode.SUCCESS; |
| | | boolean adminActionRequired = false; |
| | | ArrayList<String> messages = new ArrayList<String>(); |
| | | |
| | | |
| | | // Get the existing rule if it's already enabled. |
| | | VirtualAttributeRule existingRule = rules.get(configuration.dn()); |
| | | |
| | | |
| | | // If the new configuration has the rule disabled, then disable it if it |
| | | // is enabled, or do nothing if it's already disabled. |
| | | if (! configuration.isEnabled()) |
| | | { |
| | | if (existingRule != null) |
| | | { |
| | | DirectoryServer.deregisterVirtualAttribute(existingRule); |
| | | existingRule.getProvider().finalizeVirtualAttributeProvider(); |
| | | } |
| | | |
| | | return new ConfigChangeResult(resultCode, adminActionRequired, messages); |
| | | } |
| | | |
| | | |
| | | // Make sure that we can parse all of the search filters. |
| | | LinkedHashSet<SearchFilter> filters = |
| | | new LinkedHashSet<SearchFilter>(); |
| | | for (String filterString : configuration.getFilter()) |
| | | { |
| | | try |
| | | { |
| | | filters.add(SearchFilter.createFilterFromString(filterString)); |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, de); |
| | | } |
| | | |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.INVALID_ATTRIBUTE_SYNTAX; |
| | | } |
| | | |
| | | int msgID = MSGID_CONFIG_VATTR_INVALID_SEARCH_FILTER; |
| | | String message = getMessage(msgID, filterString, |
| | | String.valueOf(configuration.dn()), |
| | | de.getErrorMessage()); |
| | | messages.add(message); |
| | | } |
| | | } |
| | | |
| | | // Get the name of the class and make sure we can instantiate it as a |
| | | // certificate mapper. |
| | | VirtualAttributeProvider<? extends VirtualAttributeCfg> provider = null; |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | String className = configuration.getProviderClass(); |
| | | try |
| | | { |
| | | provider = loadProvider(className, configuration); |
| | | } |
| | | catch (InitializationException ie) |
| | | { |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | messages.add(ie.getMessage()); |
| | | } |
| | | } |
| | | |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(configuration.getAttributeType(), provider, |
| | | configuration.getBaseDN(), |
| | | configuration.getGroupDN(), |
| | | filters, |
| | | configuration.getConflictBehavior()); |
| | | |
| | | rules.put(configuration.dn(), rule); |
| | | if (existingRule == null) |
| | | { |
| | | DirectoryServer.registerVirtualAttribute(rule); |
| | | } |
| | | else |
| | | { |
| | | DirectoryServer.replaceVirtualAttribute(existingRule, rule); |
| | | existingRule.getProvider().finalizeVirtualAttributeProvider(); |
| | | } |
| | | } |
| | | |
| | | return new ConfigChangeResult(resultCode, adminActionRequired, messages); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Loads the specified class, instantiates it as a certificate mapper, and |
| | | * optionally initializes that instance. |
| | | * |
| | | * @param className The fully-qualified name of the certificate mapper |
| | | * class to load, instantiate, and initialize. |
| | | * @param configuration The configuration to use to initialize the |
| | | * certificate mapper, or {@code null} if the |
| | | * certificate mapper should not be initialized. |
| | | * |
| | | * @return The possibly initialized certificate mapper. |
| | | * |
| | | * @throws InitializationException If a problem occurred while attempting to |
| | | * initialize the certificate mapper. |
| | | */ |
| | | private VirtualAttributeProvider<? extends VirtualAttributeCfg> |
| | | loadProvider(String className, VirtualAttributeCfg configuration) |
| | | throws InitializationException |
| | | { |
| | | try |
| | | { |
| | | VirtualAttributeCfgDefn definition = |
| | | VirtualAttributeCfgDefn.getInstance(); |
| | | ClassPropertyDefinition propertyDefinition = |
| | | definition.getProviderClassPropertyDefinition(); |
| | | Class<? extends VirtualAttributeProvider> providerClass = |
| | | propertyDefinition.loadClass(className, |
| | | VirtualAttributeProvider.class); |
| | | VirtualAttributeProvider<? extends VirtualAttributeCfg> provider = |
| | | (VirtualAttributeProvider<? extends VirtualAttributeCfg>) |
| | | providerClass.newInstance(); |
| | | |
| | | if (configuration != null) |
| | | { |
| | | Method method = |
| | | provider.getClass().getMethod("initializeVirtualAttributeProvider", |
| | | configuration.definition().getServerConfigurationClass()); |
| | | method.invoke(provider, configuration); |
| | | } |
| | | |
| | | return provider; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | int msgID = MSGID_CONFIG_VATTR_INITIALIZATION_FAILED; |
| | | String message = getMessage(msgID, className, |
| | | String.valueOf(configuration.dn()), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | return null; |
| | | } |
| | | |
| | | return configEntry.getEntry(); |
| | | return configEntry.getEntry().duplicate(true); |
| | | } |
| | | |
| | | |
| | |
| | | public void addEntry(Entry entry, AddOperation addOperation) |
| | | throws DirectoryException |
| | | { |
| | | Entry e = entry.duplicate(false); |
| | | |
| | | // If there is an add operation, then make sure that the associated user has |
| | | // both the CONFIG_READ and CONFIG_WRITE privileges. |
| | | if (addOperation != null) |
| | |
| | | { |
| | | // Make sure that the target DN does not already exist. If it does, then |
| | | // fail. |
| | | DN entryDN = entry.getDN(); |
| | | DN entryDN = e.getDN(); |
| | | if (configEntries.containsKey(entryDN)) |
| | | { |
| | | int msgID = MSGID_CONFIG_FILE_ADD_ALREADY_EXISTS; |
| | |
| | | |
| | | |
| | | // Encapsulate the provided entry in a config entry. |
| | | ConfigEntry newEntry = new ConfigEntry(entry, parentEntry); |
| | | ConfigEntry newEntry = new ConfigEntry(e, parentEntry); |
| | | |
| | | |
| | | // See if the parent entry has any add listeners. If so, then iterate |
| | |
| | | public void replaceEntry(Entry entry, ModifyOperation modifyOperation) |
| | | throws DirectoryException |
| | | { |
| | | Entry e = entry.duplicate(false); |
| | | |
| | | // If there is a modify operation, then make sure that the associated user |
| | | // has both the CONFIG_READ and CONFIG_WRITE privileges. Also, if the |
| | | // operation targets the set of root privileges then make sure the user has |
| | |
| | | try |
| | | { |
| | | // Get the DN of the target entry for future reference. |
| | | DN entryDN = entry.getDN(); |
| | | DN entryDN = e.getDN(); |
| | | |
| | | |
| | | // Get the target entry. If it does not exist, then fail. |
| | |
| | | |
| | | |
| | | // Create a new config entry to use for the validation testing. |
| | | ConfigEntry newEntry = new ConfigEntry(entry, currentEntry.getParent()); |
| | | ConfigEntry newEntry = new ConfigEntry(e, currentEntry.getParent()); |
| | | |
| | | |
| | | // See if there are any config change listeners registered for this entry. |
| | |
| | | // We'll just overwrite the core entry in the current config entry so that |
| | | // we keep all the registered listeners, references to the parent and |
| | | // children, and other metadata. |
| | | currentEntry.setEntry(entry); |
| | | currentEntry.setEntry(e); |
| | | writeUpdatedConfig(); |
| | | |
| | | |
| | |
| | | case BASE_OBJECT: |
| | | // We are only interested in the base entry itself. See if it matches |
| | | // and if so then return the entry. |
| | | Entry e = baseEntry.getEntry(); |
| | | Entry e = baseEntry.getEntry().duplicate(true); |
| | | if (filter.matchesEntry(e)) |
| | | { |
| | | searchOperation.returnEntry(e, null); |
| | |
| | | // Iterate through them and return the ones that match the filter. |
| | | for (ConfigEntry child : baseEntry.getChildren().values()) |
| | | { |
| | | e = child.getEntry(); |
| | | e = child.getEntry().duplicate(true); |
| | | if (filter.matchesEntry(e)) |
| | | { |
| | | if (! searchOperation.returnEntry(e, null)) |
| | |
| | | SearchOperation searchOperation) |
| | | throws DirectoryException |
| | | { |
| | | Entry e = baseEntry.getEntry(); |
| | | Entry e = baseEntry.getEntry().duplicate(true); |
| | | if (filter.matchesEntry(e)) |
| | | { |
| | | if (! searchOperation.returnEntry(e, null)) |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | |
| | | import org.opends.server.admin.std.server.VirtualAttributeCfg; |
| | | 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.AttributeType; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ByteStringFactory; |
| | | import org.opends.server.types.ConditionResult; |
| | | import org.opends.server.types.DebugLogLevel; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.Entry; |
| | | import org.opends.server.types.InitializationException; |
| | | import org.opends.server.types.SearchFilter; |
| | | import org.opends.server.types.SearchScope; |
| | | import org.opends.server.types.VirtualAttributeRule; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class implements a virtual attribute provider that is meant to serve the |
| | | * entryDN operational attribute as described in draft-zeilenga-ldap-entrydn. |
| | | */ |
| | | public class EntryDNVirtualAttributeProvider |
| | | extends VirtualAttributeProvider<VirtualAttributeCfg> |
| | | { |
| | | /** |
| | | * Creates a new instance of this entryDN virtual attribute provider. |
| | | */ |
| | | public EntryDNVirtualAttributeProvider() |
| | | { |
| | | super(); |
| | | |
| | | // All initialization should be performed in the |
| | | // initializeVirtualAttributeProvider method. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void initializeVirtualAttributeProvider( |
| | | VirtualAttributeCfg configuration) |
| | | throws ConfigException, InitializationException |
| | | { |
| | | // No initialization is required. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean isMultiValued() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LinkedHashSet<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | { |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); |
| | | |
| | | String normDNString = entry.getDN().toNormalizedString(); |
| | | values.add(new AttributeValue(ByteStringFactory.create(normDNString), |
| | | ByteStringFactory.create(normDNString))); |
| | | |
| | | return values; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean hasValue(Entry entry, VirtualAttributeRule rule) |
| | | { |
| | | // This virtual attribute provider will always generate a value. |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean hasValue(Entry entry, VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | try |
| | | { |
| | | String normalizedDN = entry.getDN().toNormalizedString(); |
| | | String normalizedValue = value.getNormalizedStringValue(); |
| | | return normalizedDN.equals(normalizedValue); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean hasAnyValue(Entry entry, VirtualAttributeRule rule, |
| | | Collection<AttributeValue> values) |
| | | { |
| | | String ndnString = entry.getDN().toNormalizedString(); |
| | | |
| | | AttributeValue v = new AttributeValue(ByteStringFactory.create(ndnString), |
| | | ByteStringFactory.create(ndnString)); |
| | | return values.contains(v); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult matchesSubstring(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | ByteString subInitial, |
| | | List<ByteString> subAny, |
| | | ByteString subFinal) |
| | | { |
| | | // DNs cannot be used in substring matching. |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult greaterThanOrEqualTo(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | // DNs cannot be used in ordering matching. |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult lessThanOrEqualTo(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | // DNs cannot be used in ordering matching. |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult approximatelyEqualTo(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | // DNs 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) |
| | | { |
| | | return isSearchable(rule.getAttributeType(), searchOperation.getFilter(), |
| | | 0); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided search filter is one that may be used with |
| | | * this virtual attribute provider, optionally operating in a recursive manner |
| | | * to make the determination. |
| | | * |
| | | * @param attributeType The attribute type used to hold the entryDN value. |
| | | * @param searchFilter The search filter for which to make the |
| | | * determination. |
| | | * @param depth The current recursion depth for this processing. |
| | | * |
| | | * @return {@code true} if the provided filter may be used with this virtual |
| | | * attribute provider, or {@code false} if not. |
| | | */ |
| | | private boolean isSearchable(AttributeType attributeType, SearchFilter filter, |
| | | int depth) |
| | | { |
| | | switch (filter.getFilterType()) |
| | | { |
| | | case AND: |
| | | if (depth >= MAX_NESTED_FILTER_DEPTH) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | for (SearchFilter f : filter.getFilterComponents()) |
| | | { |
| | | if (isSearchable(attributeType, f, depth+1)) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | |
| | | case OR: |
| | | if (depth >= MAX_NESTED_FILTER_DEPTH) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | for (SearchFilter f : filter.getFilterComponents()) |
| | | { |
| | | if (! isSearchable(attributeType, f, depth+1)) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | |
| | | case EQUALITY: |
| | | return filter.getAttributeType().equals(attributeType); |
| | | |
| | | default: |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void processSearch(VirtualAttributeRule rule, |
| | | SearchOperation searchOperation) |
| | | { |
| | | SearchFilter filter = searchOperation.getFilter(); |
| | | LinkedHashSet<DN> dnSet = new LinkedHashSet<DN>(); |
| | | extractDNs(rule.getAttributeType(), filter, dnSet); |
| | | |
| | | if (dnSet.isEmpty()) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | DN baseDN = searchOperation.getBaseDN(); |
| | | SearchScope scope = searchOperation.getScope(); |
| | | for (DN dn : dnSet) |
| | | { |
| | | if (! dn.matchesBaseAndScope(baseDN, scope)) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | try |
| | | { |
| | | Entry entry = DirectoryServer.getEntry(dn); |
| | | if ((entry != null) && filter.matchesEntry(entry)) |
| | | { |
| | | searchOperation.returnEntry(entry, null); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Extracts the user DNs from the provided filter, operating recursively as |
| | | * necessary, and adds them to the provided set. |
| | | * |
| | | * @param attributeType The attribute type holding the entryDN value. |
| | | * @param filter The search filter to be processed. |
| | | * @param dnSet The set into which the identified DNs should be |
| | | * placed. |
| | | */ |
| | | private void extractDNs(AttributeType attributeType, SearchFilter filter, |
| | | LinkedHashSet<DN> dnSet) |
| | | { |
| | | switch (filter.getFilterType()) |
| | | { |
| | | case AND: |
| | | case OR: |
| | | for (SearchFilter f : filter.getFilterComponents()) |
| | | { |
| | | extractDNs(attributeType, f, dnSet); |
| | | } |
| | | break; |
| | | |
| | | case EQUALITY: |
| | | if (filter.getAttributeType().equals(attributeType)) |
| | | { |
| | | try |
| | | { |
| | | dnSet.add(DN.decode(filter.getAssertionValue().getValue())); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | |
| | | import org.opends.server.admin.std.server.VirtualAttributeCfg; |
| | | import org.opends.server.api.Group; |
| | | 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.AttributeType; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ConditionResult; |
| | | import org.opends.server.types.DebugLogLevel; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.Entry; |
| | | import org.opends.server.types.InitializationException; |
| | | import org.opends.server.types.MemberList; |
| | | import org.opends.server.types.SearchFilter; |
| | | import org.opends.server.types.SearchScope; |
| | | import org.opends.server.types.VirtualAttributeRule; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class implements a virtual attribute provider that is meant to serve the |
| | | * isMemberOf operational attribute. This attribute will be used to provide a |
| | | * list of all groups in which the specified user is a member. |
| | | */ |
| | | public class IsMemberOfVirtualAttributeProvider |
| | | extends VirtualAttributeProvider<VirtualAttributeCfg> |
| | | { |
| | | /** |
| | | * Creates a new instance of this entryDN virtual attribute provider. |
| | | */ |
| | | public IsMemberOfVirtualAttributeProvider() |
| | | { |
| | | super(); |
| | | |
| | | // All initialization should be performed in the |
| | | // initializeVirtualAttributeProvider method. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void initializeVirtualAttributeProvider( |
| | | VirtualAttributeCfg configuration) |
| | | throws ConfigException, InitializationException |
| | | { |
| | | // No initialization is required. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean isMultiValued() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LinkedHashSet<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | { |
| | | // FIXME -- This probably isn't the most efficient implementation. |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(); |
| | | for (Group g : DirectoryServer.getGroupManager().getGroupInstances()) |
| | | { |
| | | try |
| | | { |
| | | if (g.isMember(entry)) |
| | | { |
| | | values.add(new AttributeValue(rule.getAttributeType(), |
| | | g.getGroupDN().toString())); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return values; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean hasValue(Entry entry, VirtualAttributeRule rule) |
| | | { |
| | | // FIXME -- This probably isn't the most efficient implementation. |
| | | for (Group g : DirectoryServer.getGroupManager().getGroupInstances()) |
| | | { |
| | | try |
| | | { |
| | | if (g.isMember(entry)) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean hasValue(Entry entry, VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | try |
| | | { |
| | | DN groupDN = DN.decode(value.getValue()); |
| | | Group g = DirectoryServer.getGroupManager().getGroupInstance(groupDN); |
| | | if (g == null) |
| | | { |
| | | return false; |
| | | } |
| | | else |
| | | { |
| | | return g.isMember(entry); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean hasAnyValue(Entry entry, VirtualAttributeRule rule, |
| | | Collection<AttributeValue> values) |
| | | { |
| | | for (AttributeValue value : values) |
| | | { |
| | | if (hasValue(entry, rule, value)) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult matchesSubstring(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | ByteString subInitial, |
| | | List<ByteString> subAny, |
| | | ByteString subFinal) |
| | | { |
| | | // DNs cannot be used in substring matching. |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult greaterThanOrEqualTo(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | // DNs cannot be used in ordering matching. |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult lessThanOrEqualTo(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | // DNs cannot be used in ordering matching. |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult approximatelyEqualTo(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | // DNs 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> |
| | | * </UL> |
| | | */ |
| | | @Override() |
| | | public boolean isSearchable(VirtualAttributeRule rule, |
| | | SearchOperation searchOperation) |
| | | { |
| | | return isSearchable(rule.getAttributeType(), searchOperation.getFilter(), |
| | | 0); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided search filter is one that may be used with |
| | | * this virtual attribute provider, optionally operating in a recursive manner |
| | | * to make the determination. |
| | | * |
| | | * @param attributeType The attribute type used to hold the entryDN value. |
| | | * @param searchFilter The search filter for which to make the |
| | | * determination. |
| | | * @param depth The current recursion depth for this processing. |
| | | * |
| | | * @return {@code true} if the provided filter may be used with this virtual |
| | | * attribute provider, or {@code false} if not. |
| | | */ |
| | | private boolean isSearchable(AttributeType attributeType, SearchFilter filter, |
| | | int depth) |
| | | { |
| | | switch (filter.getFilterType()) |
| | | { |
| | | case AND: |
| | | if (depth >= MAX_NESTED_FILTER_DEPTH) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | for (SearchFilter f : filter.getFilterComponents()) |
| | | { |
| | | if (isSearchable(attributeType, f, depth+1)) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | |
| | | case EQUALITY: |
| | | return filter.getAttributeType().equals(attributeType); |
| | | |
| | | default: |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void processSearch(VirtualAttributeRule rule, |
| | | SearchOperation searchOperation) |
| | | { |
| | | SearchFilter filter = searchOperation.getFilter(); |
| | | Group group = extractGroup(rule.getAttributeType(), filter); |
| | | if (group == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | DN baseDN = searchOperation.getBaseDN(); |
| | | SearchScope scope = searchOperation.getScope(); |
| | | try |
| | | { |
| | | MemberList memberList = group.getMembers(); |
| | | while (memberList.hasMoreMembers()) |
| | | { |
| | | try |
| | | { |
| | | Entry e = memberList.nextMemberEntry(); |
| | | if (e.matchesBaseAndScope(baseDN, scope) && |
| | | filter.matchesEntry(e)) |
| | | { |
| | | searchOperation.returnEntry(e, null); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | searchOperation.setResponseData(de); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Extracts the first group DN encountered in the provided filter, operating |
| | | * recursively as necessary. |
| | | * |
| | | * @param attributeType The attribute type holding the entryDN value. |
| | | * @param filter The search filter to be processed. |
| | | * |
| | | * @return The first group encountered in the provided filter, or |
| | | * {@code null} if there is no match. |
| | | */ |
| | | private Group extractGroup(AttributeType attributeType, SearchFilter filter) |
| | | { |
| | | switch (filter.getFilterType()) |
| | | { |
| | | case AND: |
| | | for (SearchFilter f : filter.getFilterComponents()) |
| | | { |
| | | Group g = extractGroup(attributeType, f); |
| | | if (g != null) |
| | | { |
| | | return g; |
| | | } |
| | | } |
| | | break; |
| | | |
| | | case EQUALITY: |
| | | if (filter.getAttributeType().equals(attributeType)) |
| | | { |
| | | try |
| | | { |
| | | DN dn = DN.decode(filter.getAssertionValue().getValue()); |
| | | return DirectoryServer.getGroupManager().getGroupInstance(dn); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | } |
| | | |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2006-2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | |
| | | import org.opends.server.admin.std.server.VirtualAttributeCfg; |
| | | 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.AttributeValue; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ConditionResult; |
| | | import org.opends.server.types.Entry; |
| | | import org.opends.server.types.InitializationException; |
| | | import org.opends.server.types.ResultCode; |
| | | import org.opends.server.types.VirtualAttributeRule; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.messages.ExtensionsMessages.*; |
| | | import static org.opends.server.messages.MessageHandler.*; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class implements a virtual attribute provider that is meant to serve the |
| | | * subschemaSubentry operational attribute as described in RFC 4512. |
| | | */ |
| | | public class SubschemaSubentryVirtualAttributeProvider |
| | | extends VirtualAttributeProvider<VirtualAttributeCfg> |
| | | { |
| | | /** |
| | | * Creates a new instance of this subschemaSubentry virtual attribute |
| | | * provider. |
| | | */ |
| | | public SubschemaSubentryVirtualAttributeProvider() |
| | | { |
| | | super(); |
| | | |
| | | // All initialization should be performed in the |
| | | // initializeVirtualAttributeProvider method. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void initializeVirtualAttributeProvider( |
| | | VirtualAttributeCfg configuration) |
| | | throws ConfigException, InitializationException |
| | | { |
| | | // No initialization is required. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean isMultiValued() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LinkedHashSet<AttributeValue> getValues(Entry entry, |
| | | VirtualAttributeRule rule) |
| | | { |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); |
| | | |
| | | values.add(new AttributeValue(rule.getAttributeType(), |
| | | DirectoryServer.getSchemaDN().toString())); |
| | | |
| | | return values; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult matchesSubstring(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | ByteString subInitial, |
| | | List<ByteString> subAny, |
| | | ByteString subFinal) |
| | | { |
| | | // DNs cannot be used in substring matching. |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult greaterThanOrEqualTo(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | // DNs cannot be used in ordering matching. |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult lessThanOrEqualTo(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | // DNs cannot be used in ordering matching. |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult approximatelyEqualTo(Entry entry, |
| | | VirtualAttributeRule rule, |
| | | AttributeValue value) |
| | | { |
| | | // DNs 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) |
| | | { |
| | | // 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); |
| | | |
| | | int msgID = MSGID_SUBSCHEMASUBENTRY_VATTR_NOT_SEARCHABLE; |
| | | String message = getMessage(msgID, rule.getAttributeType().getNameOrOID()); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.RDN; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugCaught; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import org.opends.server.types.DebugLogLevel; |
| | | import org.opends.server.types.RDN; |
| | | import org.opends.server.types.SearchScope; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | | |
| | |
| | | public class LazyDN |
| | | extends DN |
| | | { |
| | | |
| | | |
| | | |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because this |
| | | * class implements the {@code java.io.Serializable} interface. This value |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean matchesBaseAndScope(DN baseDN, SearchScope scope) |
| | | throws RuntimeException |
| | | { |
| | | return getDecodedDN().matchesBaseAndScope(baseDN, scope); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean equals(Object o) |
| | | throws RuntimeException |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * The message ID for the message that will be used if a virtual attribute |
| | | * definition has an invalid search filter. This takes three arguments, which |
| | | * are the filter string, the configuration entry DN, and a message explaining |
| | | * the problem that occurred. |
| | | */ |
| | | public static final int MSGID_CONFIG_VATTR_INVALID_SEARCH_FILTER = |
| | | CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 649; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The message ID for the message that will be used if an error occurs while |
| | | * trying to load and/or initialize a class as a virtual attribute provider. |
| | | * This takes three arguments, which are the class name, the configuration |
| | | * entry DN, and string representation of the exception that was caught. |
| | | */ |
| | | public static final int MSGID_CONFIG_VATTR_INITIALIZATION_FAILED = |
| | | CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 650; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The message ID for the message that will be used if the configured |
| | | * attribute type is single-valued, but the virtual attribute provider may |
| | | * generate multiple values. This takes three arguments, which are the DN of |
| | | * the configuration entry, the name or OID of the attribute type, and the |
| | | * name of the virtual attribute provider class. |
| | | */ |
| | | public static final int MSGID_CONFIG_VATTR_SV_TYPE_WITH_MV_PROVIDER = |
| | | CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 651; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The message ID for the message that will be used if the configured |
| | | * attribute type is single-valued, but the conflict behavior is to merge the |
| | | * real and virtual values. This takes two arguments, which are the DN of |
| | | * the configuration entry and the name or OID of the attribute type. |
| | | */ |
| | | public static final int MSGID_CONFIG_VATTR_SV_TYPE_WITH_MERGE_VALUES = |
| | | CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 652; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Associates a set of generic messages with the message IDs defined in this |
| | | * class. |
| | | */ |
| | |
| | | registerMessage(MSGID_CONFIG_CHANGE_RESULT_MESSAGES, |
| | | "%s.%s succeeded but generated the following messages " + |
| | | "for entry %s: %s."); |
| | | |
| | | |
| | | registerMessage(MSGID_CONFIG_VATTR_INVALID_SEARCH_FILTER, |
| | | "Unable to parse value \"%s\" from config entry \"%s\" " + |
| | | "as a valid search filter: %s."); |
| | | registerMessage(MSGID_CONFIG_VATTR_SV_TYPE_WITH_MV_PROVIDER, |
| | | "The virtual attribute configuration in entry \"%s\" is " + |
| | | "not valid because attribute type %s is single-valued " + |
| | | "but provider %s may generate multiple values."); |
| | | registerMessage(MSGID_CONFIG_VATTR_SV_TYPE_WITH_MERGE_VALUES, |
| | | "The virtual attribute configuration in entry \"%s\" is " + |
| | | "not valid because attribute type %s is single-valued " + |
| | | "but the conflict behavior is configured to merge real " + |
| | | "and virtual values."); |
| | | registerMessage(MSGID_CONFIG_VATTR_INITIALIZATION_FAILED, |
| | | "An error occurred while trying to load an instance " + |
| | | "of class %s referenced in configuration entry %s as a " + |
| | | "virtual attribute provider: %s."); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * The message ID for the message that will be used if a search operation has |
| | | * a filter targeting the subschemaSubentry virtual attribute, which is not |
| | | * searchable. This takes a single argument, which is the name of the |
| | | * subschemaSubentry attribute type. |
| | | */ |
| | | public static final int MSGID_SUBSCHEMASUBENTRY_VATTR_NOT_SEARCHABLE = |
| | | CATEGORY_MASK_EXTENSIONS | SEVERITY_MASK_MILD_ERROR | 459; |
| | | |
| | | |
| | | /** |
| | | * Associates a set of generic messages with the message IDs defined in this |
| | | * class. |
| | | */ |
| | |
| | | "The provided password does not contain enough unique " + |
| | | "characters. The minimum number of unique characters " + |
| | | "that may appear in a user password is %d."); |
| | | |
| | | |
| | | registerMessage(MSGID_SUBSCHEMASUBENTRY_VATTR_NOT_SEARCHABLE, |
| | | "The %s attribute is not searchable and should not be " + |
| | | "included in otherwise unindexed search filters."); |
| | | } |
| | | } |
| | | |
| | |
| | | public class InternalClientConnection |
| | | extends ClientConnection |
| | | { |
| | | |
| | | |
| | | // The message ID counter to use for internal connections. |
| | | private static AtomicInteger nextMessageID; |
| | | |
| | |
| | | this.authenticationInfo = |
| | | new AuthenticationInfo(internalUserEntry, true); |
| | | super.setAuthenticationInfo(authenticationInfo); |
| | | setSizeLimit(0); |
| | | setTimeLimit(0); |
| | | setLookthroughLimit(0); |
| | | super.setSizeLimit(0); |
| | | super.setTimeLimit(0); |
| | | super.setLookthroughLimit(0); |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | |
| | | |
| | | this.authenticationInfo = authInfo; |
| | | super.setAuthenticationInfo(authInfo); |
| | | setSizeLimit(0); |
| | | setTimeLimit(0); |
| | | setLookthroughLimit(0); |
| | | super.setSizeLimit(0); |
| | | super.setTimeLimit(0); |
| | | super.setLookthroughLimit(0); |
| | | |
| | | connectionID = nextConnectionID.getAndDecrement(); |
| | | operationList = new LinkedList<Operation>(); |
| | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void setSizeLimit(int sizeLimit) |
| | | { |
| | | // No implementation required. We never want to set a nonzero |
| | | // size limit for internal client connections. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void setLookthroughLimit(int lookthroughLimit) |
| | | { |
| | | // No implementation required. We never want to set a nonzero |
| | | // lookthrough limit for internal client connections. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void setTimeLimit(int timeLimit) |
| | | { |
| | | // No implementation required. We never want to set a nonzero |
| | | // time limit for internal client connections. |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this client connection is currently using a |
| | | * secure mechanism to communicate with the server. Note that this |
| | | * may change over time based on operations performed by the client |
| | |
| | | { |
| | | controlOID = OID_SUBTREE_DELETE_CONTROL; |
| | | } |
| | | else if (lowerOID.equals("realattrsonly") || |
| | | lowerOID.equals("realattributesonly")) |
| | | { |
| | | controlOID = OID_REAL_ATTRS_ONLY; |
| | | } |
| | | else if (lowerOID.equals("virtualattrsonly") || |
| | | lowerOID.equals("virtualattributesonly")) |
| | | { |
| | | controlOID = OID_VIRTUAL_ATTRS_ONLY; |
| | | } |
| | | |
| | | if (idx < 0) |
| | | { |
| | |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.util.Base64; |
| | | |
| | | import static |
| | | org.opends.server.loggers.debug.DebugLogger.debugCaught; |
| | | import static |
| | | org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | |
| | | */ |
| | | public class Attribute |
| | | { |
| | | |
| | | |
| | | |
| | | // The attribute type for this attribute. |
| | | private final AttributeType attributeType; |
| | | |
| | |
| | | */ |
| | | public boolean hasValue() |
| | | { |
| | | return (! values.isEmpty()); |
| | | return (! getValues().isEmpty()); |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public boolean hasValue(AttributeValue value) |
| | | { |
| | | return values.contains(value); |
| | | return getValues().contains(value); |
| | | } |
| | | |
| | | |
| | |
| | | { |
| | | for (AttributeValue value : values) |
| | | { |
| | | if (! this.values.contains(value)) |
| | | if (! getValues().contains(value)) |
| | | { |
| | | return false; |
| | | } |
| | |
| | | { |
| | | for (AttributeValue value : values) |
| | | { |
| | | if (this.values.contains(value)) |
| | | if (getValues().contains(value)) |
| | | { |
| | | return true; |
| | | } |
| | |
| | | |
| | | |
| | | ConditionResult result = ConditionResult.FALSE; |
| | | for (AttributeValue value : values) |
| | | for (AttributeValue value : getValues()) |
| | | { |
| | | try |
| | | { |
| | |
| | | } |
| | | |
| | | ConditionResult result = ConditionResult.FALSE; |
| | | for (AttributeValue v : values) |
| | | for (AttributeValue v : getValues()) |
| | | { |
| | | try |
| | | { |
| | |
| | | } |
| | | |
| | | ConditionResult result = ConditionResult.FALSE; |
| | | for (AttributeValue v : values) |
| | | for (AttributeValue v : getValues()) |
| | | { |
| | | try |
| | | { |
| | |
| | | } |
| | | |
| | | ConditionResult result = ConditionResult.FALSE; |
| | | for (AttributeValue v : values) |
| | | for (AttributeValue v : getValues()) |
| | | { |
| | | try |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this is a virtual attribute rather than a real |
| | | * attribute. |
| | | * |
| | | * @return {@code true} if this is a virtual attribute, or |
| | | * {@code false} if it is a real attribute. |
| | | */ |
| | | public boolean isVirtual() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a duplicate of this attribute that can be modified |
| | | * without impacting this attribute. |
| | | * |
| | |
| | | else |
| | | { |
| | | LinkedHashSet<AttributeValue> valuesCopy = |
| | | new LinkedHashSet<AttributeValue>(values.size()); |
| | | for (AttributeValue v : values) |
| | | { |
| | | valuesCopy.add(v); |
| | | } |
| | | new LinkedHashSet<AttributeValue>(getValues()); |
| | | |
| | | return new Attribute(attributeType, name, optionsCopy, |
| | | valuesCopy); |
| | |
| | | return false; |
| | | } |
| | | |
| | | if (values.size() != a.values.size()) |
| | | if (getValues().size() != a.getValues().size()) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | if (! hasAllValues(a.values)) |
| | | if (! hasAllValues(a.getValues())) |
| | | { |
| | | return false; |
| | | } |
| | |
| | | public int hashCode() |
| | | { |
| | | int hashCode = attributeType.hashCode(); |
| | | for (AttributeValue value : values) |
| | | for (AttributeValue value : getValues()) |
| | | { |
| | | hashCode += value.hashCode(); |
| | | } |
| | |
| | | buffer.append(", {"); |
| | | |
| | | boolean firstValue = true; |
| | | for (AttributeValue value : values) |
| | | for (AttributeValue value : getValues()) |
| | | { |
| | | if (! firstValue) |
| | | { |
| | |
| | | */ |
| | | public void toLDIF(StringBuilder buffer) |
| | | { |
| | | for (AttributeValue value : values) |
| | | for (AttributeValue value : getValues()) |
| | | { |
| | | buffer.append(name); |
| | | |
| | |
| | | |
| | | |
| | | /******************** |
| | | * NOTE: Any changes to the set of public methods defined in this |
| | | * class or the arguments that they contain must also be made |
| | | * in the org.opends.server.interop.LazyDN package to ensure |
| | | * continued interoperability with third-party applications |
| | | * that rely on that functionality. |
| | | * NOTE: Any changes to the set of non-static public methods defined |
| | | * in this class or the arguments that they contain must also |
| | | * be made in the org.opends.server.interop.LazyDN package to |
| | | * ensure continued interoperability with third-party |
| | | * applications that rely on that functionality. |
| | | ********************/ |
| | | |
| | | |
| | |
| | | import org.opends.server.protocols.asn1.ASN1OctetString; |
| | | |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | import static |
| | | org.opends.server.loggers.debug.DebugLogger.debugCaught; |
| | | import static |
| | | org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.messages.MessageHandler.*; |
| | | import static org.opends.server.messages.SchemaMessages.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | |
| | | public class DN |
| | | implements Comparable<DN>, Serializable |
| | | { |
| | | |
| | | |
| | | |
| | | /** |
| | | * A singleton instance of the null DN (a DN with no components). |
| | | */ |
| | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this entry falls within the range of the |
| | | * provided search base DN and scope. |
| | | * |
| | | * @param baseDN The base DN for which to make the determination. |
| | | * @param scope The search scope for which to make the |
| | | * determination. |
| | | * |
| | | * @return <CODE>true</CODE> if this entry is within the given |
| | | * base and scope, or <CODE>false</CODE> if it is not. |
| | | */ |
| | | public boolean matchesBaseAndScope(DN baseDN, SearchScope scope) |
| | | { |
| | | switch (scope) |
| | | { |
| | | case BASE_OBJECT: |
| | | // The base DN must equal this DN. |
| | | return equals(baseDN); |
| | | |
| | | case SINGLE_LEVEL: |
| | | // The parent DN must equal the base DN. |
| | | return baseDN.equals(getParent()); |
| | | |
| | | case WHOLE_SUBTREE: |
| | | // This DN must be a descendant of the provided base DN. |
| | | return isDescendantOf(baseDN); |
| | | |
| | | case SUBORDINATE_SUBTREE: |
| | | // This DN must be a descendant of the provided base DN, but |
| | | // not equal to it. |
| | | return ((! equals(baseDN)) && isDescendantOf(baseDN)); |
| | | |
| | | default: |
| | | // This is a scope that we don't recognize. |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Decodes the provided ASN.1 octet string as a DN. |
| | | * |
| | | * @param dnString The ASN.1 octet string to decode as a DN. |
| | |
| | | import org.opends.server.protocols.asn1.ASN1OctetString; |
| | | import org.opends.server.util.LDIFException; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugCaught; |
| | | import static |
| | | org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import static |
| | | org.opends.server.loggers.debug.DebugLogger.debugVerbose; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugInfo; |
| | | import static |
| | | org.opends.server.loggers.debug.DebugLogger.debugWarning; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.loggers.Error.*; |
| | | import static org.opends.server.messages.CoreMessages.*; |
| | | import static org.opends.server.messages.MessageHandler.*; |
| | |
| | | public class Entry |
| | | implements ProtocolElement |
| | | { |
| | | |
| | | |
| | | // Indicates whether virtual attribute processing has been performed |
| | | // for this entry. |
| | | private boolean virtualAttributeProcessingPerformed; |
| | | |
| | | // The set of operational attributes for this entry. |
| | | private Map<AttributeType,List<Attribute>> operationalAttributes; |
| | |
| | | // The set of user attributes for this entry. |
| | | private Map<AttributeType,List<Attribute>> userAttributes; |
| | | |
| | | // The set of suppressed real attributes for this entry. |
| | | private Map<AttributeType,List<Attribute>> suppressedAttributes; |
| | | |
| | | // The set of objectclasses for this entry. |
| | | private Map<ObjectClass,String> objectClasses; |
| | | |
| | |
| | | Map<AttributeType,List<Attribute>> |
| | | operationalAttributes) |
| | | { |
| | | attachment = null; |
| | | schema = DirectoryServer.getSchema(); |
| | | attachment = null; |
| | | schema = DirectoryServer.getSchema(); |
| | | virtualAttributeProcessingPerformed = false; |
| | | |
| | | |
| | | suppressedAttributes = |
| | | new LinkedHashMap<AttributeType,List<Attribute>>(); |
| | | |
| | | |
| | | if (dn == null) |
| | |
| | | * Creates a duplicate of this entry that may be altered without |
| | | * impacting the information in this entry. |
| | | * |
| | | * @param processVirtual Indicates whether virtual attribute |
| | | * processing should be performed for the |
| | | * entry. |
| | | * |
| | | * @return A duplicate of this entry that may be altered without |
| | | * impacting the information in this entry. |
| | | */ |
| | | public Entry duplicate() |
| | | public Entry duplicate(boolean processVirtual) |
| | | { |
| | | HashMap<ObjectClass,String> objectClassesCopy = |
| | | new HashMap<ObjectClass,String>(objectClasses); |
| | |
| | | operationalAttributes.size()); |
| | | deepCopy(operationalAttributes, operationalAttrsCopy, false); |
| | | |
| | | return new Entry(dn, objectClassesCopy, userAttrsCopy, |
| | | operationalAttrsCopy); |
| | | for (AttributeType t : suppressedAttributes.keySet()) |
| | | { |
| | | List<Attribute> attrList = suppressedAttributes.get(t); |
| | | if (t.isOperational()) |
| | | { |
| | | operationalAttributes.put(t, attrList); |
| | | } |
| | | else |
| | | { |
| | | userAttributes.put(t, attrList); |
| | | } |
| | | } |
| | | |
| | | Entry e = new Entry(dn, objectClassesCopy, userAttrsCopy, |
| | | operationalAttrsCopy); |
| | | if (processVirtual) |
| | | { |
| | | e.processVirtualAttributes(); |
| | | } |
| | | return e; |
| | | } |
| | | |
| | | |
| | |
| | | * attributes that may be altered without impacting the information |
| | | * in this entry. |
| | | * |
| | | * @param typesOnly Indicates whether to include attribute types |
| | | * only without values. |
| | | * @param typesOnly Indicates whether to include attribute |
| | | * types only without values. |
| | | * @param processVirtual Indicates whether virtual attribute |
| | | * processing should be performed for the |
| | | * entry. |
| | | * |
| | | * @return A duplicate of this entry that may be altered without |
| | | * impacting the information in this entry and that does |
| | | * not contain any operational attributes. |
| | | */ |
| | | public Entry duplicateWithoutOperationalAttributes( |
| | | boolean typesOnly) |
| | | boolean typesOnly, boolean processVirtual) |
| | | { |
| | | HashMap<ObjectClass,String> objectClassesCopy; |
| | | if (typesOnly) |
| | |
| | | HashMap<AttributeType,List<Attribute>> operationalAttrsCopy = |
| | | new HashMap<AttributeType,List<Attribute>>(0); |
| | | |
| | | return new Entry(dn, objectClassesCopy, userAttrsCopy, |
| | | operationalAttrsCopy); |
| | | for (AttributeType t : suppressedAttributes.keySet()) |
| | | { |
| | | List<Attribute> attrList = suppressedAttributes.get(t); |
| | | if (! t.isOperational()) |
| | | { |
| | | userAttributes.put(t, attrList); |
| | | } |
| | | } |
| | | |
| | | Entry e = new Entry(dn, objectClassesCopy, userAttrsCopy, |
| | | operationalAttrsCopy); |
| | | |
| | | if (processVirtual) |
| | | { |
| | | e.processVirtualAttributes(false); |
| | | } |
| | | |
| | | return e; |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * Performs a deep copy from the source map to the target map. In |
| | | * this case, the attributes in the list will be duplicates rather |
| | | * than re-using the same reference. |
| | | * than re-using the same reference. Virtual attributes will not be |
| | | * included when making the copy. |
| | | * |
| | | * @param source The source map from which to obtain the |
| | | * information. |
| | | * @param target The target map into which to place the copied |
| | | * information. |
| | | * @param omitValues <CODE>true</CODE> if the values should be |
| | | * omitted. |
| | | * @param source The source map from which to obtain the |
| | | * information. |
| | | * @param target The target map into which to place the |
| | | * copied information. |
| | | * @param omitValues Indicates whether to omit attribute values |
| | | * when processing. |
| | | */ |
| | | private void deepCopy(Map<AttributeType,List<Attribute>> source, |
| | | Map<AttributeType,List<Attribute>> target, |
| | |
| | | |
| | | for (Attribute a : sourceList) |
| | | { |
| | | if (a.isVirtual()) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | targetList.add(a.duplicate(omitValues)); |
| | | } |
| | | |
| | | target.put(t, targetList); |
| | | if (! targetList.isEmpty()) |
| | | { |
| | | target.put(t, targetList); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | public boolean matchesBaseAndScope(DN baseDN, SearchScope scope) |
| | | { |
| | | switch (scope) |
| | | return dn.matchesBaseAndScope(baseDN, scope); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs any necessary virtual attribute processing for this |
| | | * entry. This should only be called at the time the entry is |
| | | * decoded or created within the backend. |
| | | */ |
| | | public void processVirtualAttributes() |
| | | { |
| | | processVirtualAttributes(true); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs any necessary virtual attribute processing for this |
| | | * entry. This should only be called at the time the entry is |
| | | * decoded or created within the backend. |
| | | * |
| | | * @param includeOperational Indicates whether to include |
| | | * operational attributes. |
| | | */ |
| | | public void processVirtualAttributes(boolean includeOperational) |
| | | { |
| | | for (VirtualAttributeRule rule : |
| | | DirectoryServer.getVirtualAttributes(this)) |
| | | { |
| | | case BASE_OBJECT: |
| | | // The entry DN must equal the base DN. |
| | | return baseDN.equals(dn); |
| | | AttributeType attributeType = rule.getAttributeType(); |
| | | if (attributeType.isOperational() && (! includeOperational)) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | case SINGLE_LEVEL: |
| | | // The parent DN for this entry must equal the base DN. |
| | | return baseDN.equals(dn.getParentDNInSuffix()); |
| | | List<Attribute> attrList = userAttributes.get(attributeType); |
| | | if ((attrList == null) || attrList.isEmpty()) |
| | | { |
| | | attrList = operationalAttributes.get(attributeType); |
| | | if ((attrList == null) || attrList.isEmpty()) |
| | | { |
| | | // There aren't any conflicts, so we can just add the |
| | | // attribute to the entry. |
| | | attrList = new LinkedList<Attribute>(); |
| | | attrList.add(new VirtualAttribute(attributeType, this, |
| | | rule)); |
| | | if (attributeType.isOperational()) |
| | | { |
| | | operationalAttributes.put(attributeType, attrList); |
| | | } |
| | | else |
| | | { |
| | | userAttributes.put(attributeType, attrList); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // There is a conflict with an existing operational |
| | | // attribute. |
| | | if (attrList.get(0).isVirtual()) |
| | | { |
| | | // The existing attribute is already virtual, so we've got |
| | | // a different conflict, but we'll let the first win. |
| | | // FIXME -- Should we handle this differently? |
| | | continue; |
| | | } |
| | | |
| | | case WHOLE_SUBTREE: |
| | | // The base DN must be an ancestor of the entry DN. |
| | | return baseDN.isAncestorOf(dn); |
| | | // The conflict is with a real attribute. See what the |
| | | // conflict behavior is and figure out how to handle it. |
| | | switch (rule.getConflictBehavior()) |
| | | { |
| | | case REAL_OVERRIDES_VIRTUAL: |
| | | // We don't need to update the entry because the real |
| | | // attribute will take precedence. |
| | | break; |
| | | |
| | | case SUBORDINATE_SUBTREE: |
| | | // The base DN must be an ancstor of the entry DN, but it |
| | | // must not equal the entry DN. |
| | | return ((! baseDN.equals(dn)) && baseDN.isAncestorOf(dn)); |
| | | case VIRTUAL_OVERRIDES_REAL: |
| | | // We need to move the real attribute to the suppressed |
| | | // list and replace it with the virtual attribute. |
| | | suppressedAttributes.put(attributeType, attrList); |
| | | attrList = new LinkedList<Attribute>(); |
| | | attrList.add(new VirtualAttribute(attributeType, this, |
| | | rule)); |
| | | operationalAttributes.put(attributeType, attrList); |
| | | break; |
| | | |
| | | default: |
| | | // This is a scope that we don't recognize. |
| | | return false; |
| | | case MERGE_REAL_AND_VIRTUAL: |
| | | // We need to add the virtual attribute to the list and |
| | | // keep the existing real attribute(s). |
| | | attrList.add(new VirtualAttribute(attributeType, this, |
| | | rule)); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // There is a conflict with an existing user attribute. |
| | | if (attrList.get(0).isVirtual()) |
| | | { |
| | | // The existing attribute is already virtual, so we've got |
| | | // a different conflict, but we'll let the first win. |
| | | // FIXME -- Should we handle this differently? |
| | | continue; |
| | | } |
| | | |
| | | // The conflict is with a real attribute. See what the |
| | | // conflict behavior is and figure out how to handle it. |
| | | switch (rule.getConflictBehavior()) |
| | | { |
| | | case REAL_OVERRIDES_VIRTUAL: |
| | | // We don't need to update the entry because the real |
| | | // attribute will take precedence. |
| | | break; |
| | | |
| | | case VIRTUAL_OVERRIDES_REAL: |
| | | // We need to move the real attribute to the suppressed |
| | | // list and replace it with the virtual attribute. |
| | | suppressedAttributes.put(attributeType, attrList); |
| | | attrList = new LinkedList<Attribute>(); |
| | | attrList.add(new VirtualAttribute(attributeType, this, |
| | | rule)); |
| | | userAttributes.put(attributeType, attrList); |
| | | break; |
| | | |
| | | case MERGE_REAL_AND_VIRTUAL: |
| | | // We need to add the virtual attribute to the list and |
| | | // keep the existing real attribute(s). |
| | | attrList.add(new VirtualAttribute(attributeType, this, |
| | | rule)); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | virtualAttributeProcessingPerformed = true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether virtual attribute processing has been performed |
| | | * for this entry. |
| | | * |
| | | * @return {@code true} if virtual attribute processing has been |
| | | * performed for this entry, or {@code false} if not. |
| | | */ |
| | | public boolean virtualAttributeProcessingPerformed() |
| | | { |
| | | return virtualAttributeProcessingPerformed; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Strips out all real attributes from this entry so that it only |
| | | * contains virtual attributes. |
| | | */ |
| | | public void stripRealAttributes() |
| | | { |
| | | // The objectClass attribute will always be a real attribute. |
| | | objectClasses.clear(); |
| | | |
| | | Iterator<Map.Entry<AttributeType,List<Attribute>>> |
| | | attrListIterator = userAttributes.entrySet().iterator(); |
| | | while (attrListIterator.hasNext()) |
| | | { |
| | | Map.Entry<AttributeType,List<Attribute>> mapEntry = |
| | | attrListIterator.next(); |
| | | Iterator<Attribute> attrIterator = |
| | | mapEntry.getValue().iterator(); |
| | | while (attrIterator.hasNext()) |
| | | { |
| | | Attribute a = attrIterator.next(); |
| | | if (! a.isVirtual()) |
| | | { |
| | | attrIterator.remove(); |
| | | } |
| | | } |
| | | |
| | | if (mapEntry.getValue().isEmpty()) |
| | | { |
| | | attrListIterator.remove(); |
| | | } |
| | | } |
| | | |
| | | attrListIterator = operationalAttributes.entrySet().iterator(); |
| | | while (attrListIterator.hasNext()) |
| | | { |
| | | Map.Entry<AttributeType,List<Attribute>> mapEntry = |
| | | attrListIterator.next(); |
| | | Iterator<Attribute> attrIterator = |
| | | mapEntry.getValue().iterator(); |
| | | while (attrIterator.hasNext()) |
| | | { |
| | | Attribute a = attrIterator.next(); |
| | | if (! a.isVirtual()) |
| | | { |
| | | attrIterator.remove(); |
| | | } |
| | | } |
| | | |
| | | if (mapEntry.getValue().isEmpty()) |
| | | { |
| | | attrListIterator.remove(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Strips out all virtual attributes from this entry so that it only |
| | | * contains real attributes. |
| | | */ |
| | | public void stripVirtualAttributes() |
| | | { |
| | | Iterator<Map.Entry<AttributeType,List<Attribute>>> |
| | | attrListIterator = userAttributes.entrySet().iterator(); |
| | | while (attrListIterator.hasNext()) |
| | | { |
| | | Map.Entry<AttributeType,List<Attribute>> mapEntry = |
| | | attrListIterator.next(); |
| | | Iterator<Attribute> attrIterator = |
| | | mapEntry.getValue().iterator(); |
| | | while (attrIterator.hasNext()) |
| | | { |
| | | Attribute a = attrIterator.next(); |
| | | if (a.isVirtual()) |
| | | { |
| | | attrIterator.remove(); |
| | | } |
| | | } |
| | | |
| | | if (mapEntry.getValue().isEmpty()) |
| | | { |
| | | attrListIterator.remove(); |
| | | } |
| | | } |
| | | |
| | | attrListIterator = operationalAttributes.entrySet().iterator(); |
| | | while (attrListIterator.hasNext()) |
| | | { |
| | | Map.Entry<AttributeType,List<Attribute>> mapEntry = |
| | | attrListIterator.next(); |
| | | Iterator<Attribute> attrIterator = |
| | | mapEntry.getValue().iterator(); |
| | | while (attrIterator.hasNext()) |
| | | { |
| | | Attribute a = attrIterator.next(); |
| | | if (a.isVirtual()) |
| | | { |
| | | attrIterator.remove(); |
| | | } |
| | | } |
| | | |
| | | if (mapEntry.getValue().isEmpty()) |
| | | { |
| | | attrListIterator.remove(); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | List<Attribute> attrList = userAttributes.get(attrType); |
| | | for (Attribute a : attrList) |
| | | { |
| | | if (a.isVirtual() && |
| | | (! exportConfig.includeVirtualAttributes())) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | if (exportConfig.typesOnly()) |
| | | { |
| | | StringBuilder attrName = new StringBuilder(a.getName()); |
| | |
| | | } |
| | | |
| | | |
| | | // Finally, the set of operational attributes. |
| | | // Next, the set of operational attributes. |
| | | if (exportConfig.includeOperationalAttributes()) |
| | | { |
| | | for (AttributeType attrType : operationalAttributes.keySet()) |
| | |
| | | operationalAttributes.get(attrType); |
| | | for (Attribute a : attrList) |
| | | { |
| | | if (a.isVirtual() && |
| | | (! exportConfig.includeVirtualAttributes())) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | if (exportConfig.typesOnly()) |
| | | { |
| | | StringBuilder attrName = new StringBuilder(a.getName()); |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | // If we are not supposed to include virtual attributes, then |
| | | // write any attributes that may normally be suppressed by a |
| | | // virtual attribute. |
| | | if (! exportConfig.includeVirtualAttributes()) |
| | | { |
| | | for (AttributeType t : suppressedAttributes.keySet()) |
| | | { |
| | | if (exportConfig.includeAttribute(t)) |
| | | { |
| | | for (Attribute a : suppressedAttributes.get(t)) |
| | | { |
| | | if (exportConfig.typesOnly()) |
| | | { |
| | | StringBuilder attrName = new StringBuilder(a.getName()); |
| | | for (String o : a.getOptions()) |
| | | { |
| | | attrName.append(";"); |
| | | attrName.append(o); |
| | | } |
| | | attrName.append(":"); |
| | | |
| | | writeLDIFLine(attrName, writer, wrapLines, wrapColumn); |
| | | } |
| | | else |
| | | { |
| | | StringBuilder attrName = new StringBuilder(a.getName()); |
| | | for (String o : a.getOptions()) |
| | | { |
| | | attrName.append(";"); |
| | | attrName.append(o); |
| | | } |
| | | |
| | | for (AttributeValue v : a.getValues()) |
| | | { |
| | | StringBuilder attrLine = new StringBuilder(); |
| | | attrLine.append(attrName); |
| | | appendLDIFSeparatorAndValue(attrLine, |
| | | v.getValueBytes()); |
| | | writeLDIFLine(attrLine, writer, wrapLines, |
| | | wrapColumn); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // Make sure there is a blank line after the entry. |
| | | writer.newLine(); |
| | | |
| | |
| | | */ |
| | | public class LDIFExportConfig |
| | | { |
| | | |
| | | |
| | | |
| | | // Indicates whether the data should be compressed as it is written. |
| | | private boolean compressData; |
| | | |
| | |
| | | // export. |
| | | private boolean includeOperationalAttributes; |
| | | |
| | | // Indicates whether to include virutal attributes in the export. |
| | | private boolean includeVirtualAttributes; |
| | | |
| | | // Indicates whether to invoke LDIF export plugins on entries being |
| | | // exported. |
| | | private boolean invokeExportPlugins; |
| | |
| | | hashData = false; |
| | | includeObjectClasses = true; |
| | | includeOperationalAttributes = true; |
| | | includeVirtualAttributes = false; |
| | | invokeExportPlugins = false; |
| | | signHash = false; |
| | | typesOnly = false; |
| | |
| | | hashData = false; |
| | | includeObjectClasses = true; |
| | | includeOperationalAttributes = true; |
| | | includeVirtualAttributes = false; |
| | | invokeExportPlugins = false; |
| | | signHash = false; |
| | | typesOnly = false; |
| | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether virtual attributes should be included in the |
| | | * export. |
| | | * |
| | | * @return {@code true} if virtual attributes should be included in |
| | | * the export, or {@code false} if not. |
| | | */ |
| | | public boolean includeVirtualAttributes() |
| | | { |
| | | return includeVirtualAttributes; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies whether virtual attributes should be included in the |
| | | * export. |
| | | * |
| | | * @param includeVirtualAttributes Specifies whether virtual |
| | | * attributes should be included |
| | | * in the export. |
| | | */ |
| | | public void setIncludeVirtualAttributes( |
| | | boolean includeVirtualAttributes) |
| | | { |
| | | this.includeVirtualAttributes = includeVirtualAttributes; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of attributes that should be excluded from the |
| | | * entries written to LDIF. The set that is returned may be altered |
| | | * by the caller. |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.types; |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | |
| | | import org.opends.server.admin.std.server.VirtualAttributeCfg; |
| | | import org.opends.server.api.VirtualAttributeProvider; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines a virtual attribute, which is a special kind of |
| | | * attribute whose values do not actually exist in persistent storage |
| | | * but rather are computed or otherwise obtained dynamically. |
| | | */ |
| | | public class VirtualAttribute |
| | | extends Attribute |
| | | { |
| | | // The entry with which this virtual attribute is associated. |
| | | private final Entry entry; |
| | | |
| | | // The virtual attribute provider for this virtual attribute. |
| | | private final VirtualAttributeProvider< |
| | | ? extends VirtualAttributeCfg> provider; |
| | | |
| | | // The virtual attribute rule for this virtual attribute. |
| | | private final VirtualAttributeRule rule; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new virtual attribute with the provided information. |
| | | * |
| | | * @param attributeType The attribute type for this virtual |
| | | * attribute. |
| | | * @param entry The entry in which this virtual attribute |
| | | * exists. |
| | | * @param rule The virutal attribute rule that governs |
| | | * the behavior of this virtual attribute. |
| | | */ |
| | | public VirtualAttribute(AttributeType attributeType, Entry entry, |
| | | VirtualAttributeRule rule) |
| | | { |
| | | super(attributeType); |
| | | |
| | | this.entry = entry; |
| | | this.rule = rule; |
| | | |
| | | provider = rule.getProvider(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the entry in which this virtual attribute exists. |
| | | * |
| | | * @return The entry in which this virtual attribute exists. |
| | | */ |
| | | public Entry getEntry() |
| | | { |
| | | return entry; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the virtual attribute rule that governs the behavior of |
| | | * this virtual attribute. |
| | | * |
| | | * @return The virtual attribute rule that governs the behavior of |
| | | * this virtual attribute. |
| | | */ |
| | | public VirtualAttributeRule getVirtualAttributeRule() |
| | | { |
| | | return rule; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public LinkedHashSet<AttributeValue> getValues() |
| | | { |
| | | return provider.getValues(entry, rule); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean hasValue() |
| | | { |
| | | return provider.hasValue(entry, rule); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean hasValue(AttributeValue value) |
| | | { |
| | | return provider.hasValue(entry, rule, value); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean hasAllValues(Collection<AttributeValue> values) |
| | | { |
| | | return provider.hasAllValues(entry, rule, values); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean hasAnyValue(Collection<AttributeValue> values) |
| | | { |
| | | return provider.hasAnyValue(entry, rule, values); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult matchesSubstring(ByteString subInitial, |
| | | List<ByteString> subAny, |
| | | ByteString subFinal) |
| | | { |
| | | return provider.matchesSubstring(entry, rule, subInitial, subAny, |
| | | subFinal); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult greaterThanOrEqualTo(AttributeValue value) |
| | | { |
| | | return provider.greaterThanOrEqualTo(entry, rule, value); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult lessThanOrEqualTo(AttributeValue value) |
| | | { |
| | | return provider.lessThanOrEqualTo(entry, rule, value); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public ConditionResult approximatelyEqualTo(AttributeValue value) |
| | | { |
| | | return provider.approximatelyEqualTo(entry, rule, value); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public boolean isVirtual() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public Attribute duplicate(boolean omitValues) |
| | | { |
| | | return new VirtualAttribute(getAttributeType(), entry, rule); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void toString(StringBuilder buffer) |
| | | { |
| | | buffer.append("VirtualAttribute("); |
| | | buffer.append(getAttributeType().getNameOrOID()); |
| | | buffer.append(", {"); |
| | | |
| | | boolean firstValue = true; |
| | | for (AttributeValue value : getValues()) |
| | | { |
| | | if (! firstValue) |
| | | { |
| | | buffer.append(", "); |
| | | } |
| | | |
| | | value.toString(buffer); |
| | | firstValue = false; |
| | | } |
| | | |
| | | buffer.append("})"); |
| | | } |
| | | } |
| | | |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.types; |
| | | |
| | | |
| | | |
| | | import java.util.Iterator; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.server.admin.std.meta.VirtualAttributeCfgDefn; |
| | | import org.opends.server.admin.std.server.VirtualAttributeCfg; |
| | | import org.opends.server.api.Group; |
| | | import org.opends.server.api.VirtualAttributeProvider; |
| | | import org.opends.server.core.DirectoryServer; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.util.Validator.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines a virtual attribute rule, which associates a |
| | | * virtual attribute provider with its associated configuration, |
| | | * including the attribute type for which the values should be |
| | | * generated; the base DN(s), group DN(s), and search filter(s) that |
| | | * should be used to identify which entries should have the virtual |
| | | * attribute, and how conflicts between real and virtual values should |
| | | * be handled. |
| | | */ |
| | | public class VirtualAttributeRule |
| | | { |
| | | // The attribute type for which the values should be generated. |
| | | private final AttributeType attributeType; |
| | | |
| | | // The set of base DNs for branches that are eligible to have this |
| | | // virtual attribute. |
| | | private final Set<DN> baseDNs; |
| | | |
| | | // The set of DNs for groups whose members are eligible to have this |
| | | // virtual attribute. |
| | | private final Set<DN> groupDNs; |
| | | |
| | | // The set of search filters for entries that are eligible to have |
| | | // this virtual attribute. |
| | | private final Set<SearchFilter> filters; |
| | | |
| | | // The virtual attribute provider used to generate the values. |
| | | private final VirtualAttributeProvider< |
| | | ? extends VirtualAttributeCfg> provider; |
| | | |
| | | // The behavior that should be exhibited for entries that already |
| | | // have real values for the target attribute. |
| | | private final VirtualAttributeCfgDefn.ConflictBehavior |
| | | conflictBehavior; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new virtual attribute rule with the provided |
| | | * information. |
| | | * |
| | | * @param attributeType The attribute type for which the values |
| | | * should be generated. |
| | | * @param provider The virtual attribute provider to use |
| | | * to generate the values. |
| | | * @param baseDNs The set of base DNs for branches that |
| | | * are eligible to have this virtual |
| | | * attribute. |
| | | * @param groupDNs The set of DNs for groups whose members |
| | | * are eligible to have this virtual |
| | | * attribute. |
| | | * @param filters The set of search filters for entries |
| | | * that are eligible to have this virtual |
| | | * attribute. |
| | | * @param conflictBehavior The behavior that the server should |
| | | * exhibit for entries that already have |
| | | * one or more real values for the target |
| | | * attribute. |
| | | */ |
| | | public VirtualAttributeRule(AttributeType attributeType, |
| | | VirtualAttributeProvider<? extends VirtualAttributeCfg> |
| | | provider, |
| | | Set<DN> baseDNs, Set<DN> groupDNs, |
| | | Set<SearchFilter> filters, |
| | | VirtualAttributeCfgDefn.ConflictBehavior |
| | | conflictBehavior) |
| | | { |
| | | ensureNotNull(attributeType, provider, baseDNs, groupDNs); |
| | | ensureNotNull(filters, conflictBehavior); |
| | | |
| | | this.attributeType = attributeType; |
| | | this.provider = provider; |
| | | this.baseDNs = baseDNs; |
| | | this.groupDNs = groupDNs; |
| | | this.filters = filters; |
| | | this.conflictBehavior = conflictBehavior; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the attribute type for which the values should be |
| | | * generated. |
| | | * |
| | | * @return The attribute type for which the values should be |
| | | * generated. |
| | | */ |
| | | public AttributeType getAttributeType() |
| | | { |
| | | return attributeType; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * |
| | | * Retrieves the virtual attribute provider used to generate the |
| | | * values. |
| | | * |
| | | * @return The virtual attribute provider to use to generate the |
| | | * values. |
| | | */ |
| | | public VirtualAttributeProvider<? extends VirtualAttributeCfg> |
| | | getProvider() |
| | | { |
| | | return provider; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of base DNs for branches that are eligible to |
| | | * have this virtual attribute. |
| | | * |
| | | * @return The set of base DNs for branches that are eligible to |
| | | * have this virtual attribute. |
| | | */ |
| | | public Set<DN> getBaseDNs() |
| | | { |
| | | return baseDNs; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of DNs for groups whose members are eligible to |
| | | * have this virtual attribute. |
| | | * |
| | | * @return The set of DNs for groups whose members are eligible to |
| | | * have this virtual attribute. |
| | | */ |
| | | public Set<DN> getGroupDNs() |
| | | { |
| | | return groupDNs; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of search filters for entries that are eligible |
| | | * to have this virtual attribute. |
| | | * |
| | | * @return The set of search filters for entries that are eligible |
| | | * to have this virtual attribute. |
| | | */ |
| | | public Set<SearchFilter> getFilters() |
| | | { |
| | | return filters; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the behavior that the server should exhibit for entries |
| | | * that already have one or more real values for the target |
| | | * attribute. |
| | | * |
| | | * @return The behavior that the server should exhibit for entries |
| | | * that already have one or more real values for the target |
| | | * attribute. |
| | | */ |
| | | public VirtualAttributeCfgDefn.ConflictBehavior |
| | | getConflictBehavior() |
| | | { |
| | | return conflictBehavior; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether this virtual attribute rule applies to the |
| | | * provided entry, taking into account the eligibility requirements |
| | | * defined in the rule. |
| | | * |
| | | * @param entry The entry for which to make the determination. |
| | | * |
| | | * @return {@code true} if this virtual attribute rule may be used |
| | | * to generate values for the entry, or {@code false} if |
| | | * not. |
| | | */ |
| | | public boolean appliesToEntry(Entry entry) |
| | | { |
| | | // We'll do this in order of expense so that the checks which are |
| | | // potentially most expensive are done last. First, check to see |
| | | // if real values should override virtual ones and if so whether |
| | | // the entry already has virtual values. |
| | | if ((conflictBehavior == VirtualAttributeCfgDefn.ConflictBehavior. |
| | | REAL_OVERRIDES_VIRTUAL) && |
| | | entry.hasAttribute(attributeType)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | // If there are any base DNs defined, then the entry must be below |
| | | // one of them. |
| | | DN entryDN = entry.getDN(); |
| | | if (! baseDNs.isEmpty()) |
| | | { |
| | | boolean found = false; |
| | | for (DN dn : baseDNs) |
| | | { |
| | | if (entryDN.isDescendantOf(dn)) |
| | | { |
| | | found = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (! found) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // If there are any search filters defined, then the entry must |
| | | // match one of them. |
| | | if (! filters.isEmpty()) |
| | | { |
| | | boolean found = false; |
| | | for (SearchFilter filter : filters) |
| | | { |
| | | try |
| | | { |
| | | if (filter.matchesEntry(entry)) |
| | | { |
| | | found = true; |
| | | break; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (! found) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // If there are any group memberships defined, then the entry must |
| | | // be a member of one of them. |
| | | if (! groupDNs.isEmpty()) |
| | | { |
| | | boolean found = false; |
| | | for (DN dn : groupDNs) |
| | | { |
| | | try |
| | | { |
| | | Group group = |
| | | DirectoryServer.getGroupManager().getGroupInstance(dn); |
| | | if ((group != null) && group.isMember(entry)) |
| | | { |
| | | found = true; |
| | | break; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (! found) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // If we've gotten here, then the rule is applicable. |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a string representation of this virtual attribute rule. |
| | | * |
| | | * @return A string representation of this virutal attribute rule. |
| | | */ |
| | | public String toString() |
| | | { |
| | | StringBuilder buffer = new StringBuilder(); |
| | | toString(buffer); |
| | | return buffer.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Appends a string representation of this virtual attribute rule to |
| | | * the provided buffer. |
| | | * |
| | | * @param buffer The buffer to which the information should be |
| | | * written. |
| | | */ |
| | | public void toString(StringBuilder buffer) |
| | | { |
| | | buffer.append("VirtualAttributeRule(attrType="); |
| | | buffer.append(attributeType.getNameOrOID()); |
| | | buffer.append(", providerDN=\""); |
| | | buffer.append(provider.getClass().getName()); |
| | | |
| | | buffer.append("\", baseDNs={"); |
| | | if (! baseDNs.isEmpty()) |
| | | { |
| | | buffer.append("\""); |
| | | Iterator<DN> iterator = baseDNs.iterator(); |
| | | buffer.append(iterator.next()); |
| | | |
| | | while (iterator.hasNext()) |
| | | { |
| | | buffer.append("\", \""); |
| | | buffer.append(iterator.next()); |
| | | } |
| | | |
| | | buffer.append("\""); |
| | | } |
| | | |
| | | buffer.append("}, groupDNs={"); |
| | | if (! groupDNs.isEmpty()) |
| | | { |
| | | buffer.append("\""); |
| | | Iterator<DN> iterator = groupDNs.iterator(); |
| | | buffer.append(iterator.next()); |
| | | |
| | | while (iterator.hasNext()) |
| | | { |
| | | buffer.append("\", \""); |
| | | buffer.append(iterator.next()); |
| | | } |
| | | |
| | | buffer.append("\""); |
| | | } |
| | | |
| | | buffer.append("}, filters={"); |
| | | if (! filters.isEmpty()) |
| | | { |
| | | buffer.append("\""); |
| | | Iterator<SearchFilter> iterator = filters.iterator(); |
| | | buffer.append(iterator.next()); |
| | | |
| | | while (iterator.hasNext()) |
| | | { |
| | | buffer.append("\", \""); |
| | | buffer.append(iterator.next()); |
| | | } |
| | | |
| | | buffer.append("\""); |
| | | } |
| | | |
| | | buffer.append("}, conflictBehavior="); |
| | | buffer.append(conflictBehavior); |
| | | buffer.append(")"); |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | public final class LDIFWriter |
| | | { |
| | | |
| | | |
| | | // FIXME -- Add support for generating a hash when writing the data. |
| | | // FIXME -- Add support for signing the hash that is generated. |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * The OID for the real attributes only control. |
| | | */ |
| | | public static final String OID_REAL_ATTRS_ONLY = "2.16.840.1.113730.3.4.17"; |
| | | |
| | | |
| | | |
| | | /** |
| | | * The OID for the subtree delete control. |
| | | */ |
| | | public static final String OID_SUBTREE_DELETE_CONTROL = |
| | |
| | | |
| | | |
| | | |
| | | /** |
| | | * The OID for the virtual attributes only control. |
| | | */ |
| | | public static final String OID_VIRTUAL_ATTRS_ONLY = |
| | | "2.16.840.1.113730.3.4.19"; |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * The block length in bytes used when generating an HMAC-MD5 digest. |
| | |
| | | } |
| | | |
| | | // The add operation changes the attributes, so let's duplicate the entry. |
| | | Entry duplicateEntry = testEntry.duplicate(); |
| | | Entry duplicateEntry = testEntry.duplicate(false); |
| | | |
| | | AddOperation addOperation = |
| | | connection.processAdd(duplicateEntry.getDN(), |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.Collections; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | | import org.testng.annotations.Test; |
| | | |
| | | 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.types.Attribute; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ByteStringFactory; |
| | | import org.opends.server.types.ConditionResult; |
| | | import org.opends.server.types.Control; |
| | | import org.opends.server.types.DereferencePolicy; |
| | | import org.opends.server.types.DN; |
| | | 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 static org.testng.Assert.*; |
| | | |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A set of test cases for the entryDN virtual attribute provider. |
| | | */ |
| | | public class EntryDNVirtualAttributeProviderTestCase |
| | | extends ExtensionsTestCase |
| | | { |
| | | // The attribute type for the entryDN attribute. |
| | | private AttributeType entryDNType; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Ensures that the Directory Server is running. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @BeforeClass() |
| | | public void startServer() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.startServer(); |
| | | |
| | | entryDNType = DirectoryServer.getAttributeType("entrydn", false); |
| | | assertNotNull(entryDNType); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a set of entry DNs for use in testing the entryDN virtual |
| | | * attribute. |
| | | * |
| | | * @return A set of entry DNs for use in testing the entryDN 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") } |
| | | }; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code getEntry} method for the specified entry to ensure that |
| | | * the entry returned includes the entryDN 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(entryDNType)); |
| | | |
| | | List<Attribute> attrList = e.getAttribute(entryDNType); |
| | | assertNotNull(attrList); |
| | | assertFalse(attrList.isEmpty()); |
| | | for (Attribute a : attrList) |
| | | { |
| | | assertTrue(a.hasValue()); |
| | | assertEquals(a.getValues().size(), 1); |
| | | assertTrue(a.hasValue(new AttributeValue(entryDNType, |
| | | entryDN.toNormalizedString()))); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the entryDN 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(entryDNType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the entryDN 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(entryDNType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the entryDN 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(entryDNType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the entryDN 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(entryDNType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the entryDN attribute is included when the entryDN 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 testSearchEntryDNAttr(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("entrydn"); |
| | | |
| | | 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(entryDNType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the entryDN 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 testSearchExcludeEntryDNAttr(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(entryDNType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the entryDN attribute is included when the entryDN attribute is |
| | | * specifically requested and the entryDN 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 = "testEntryDNs") |
| | | public void testSearchEntryDNAttrInMatchingFilter(DN entryDN) |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); |
| | | |
| | | SearchFilter filter = |
| | | SearchFilter.createFilterFromString("(entryDN=" + entryDN.toString() + |
| | | ")"); |
| | | LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); |
| | | attrList.add("entrydn"); |
| | | |
| | | 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(entryDNType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * no entries are returned when the entryDN 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 testSearchEntryDNAttrInNonMatchingFilter(DN entryDN) |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); |
| | | |
| | | SearchFilter filter = |
| | | SearchFilter.createFilterFromString("(entryDN=cn=Not A Match)"); |
| | | LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); |
| | | attrList.add("entrydn"); |
| | | |
| | | 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 entryDN attribute is not included when the entryDN 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 testSearchEntryDNAttrRealAttrsOnly(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("entrydn"); |
| | | |
| | | LinkedList<Control> requestControls = new LinkedList<Control>(); |
| | | requestControls.add(new Control(OID_REAL_ATTRS_ONLY, true)); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | InternalSearchOperation searchOperation = |
| | | new InternalSearchOperation(conn, conn.nextOperationID(), |
| | | conn.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(entryDNType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the entryDN attribute is included when the entryDN 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 testSearchEntryDNAttrVirtualAttrsOnly(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("entrydn"); |
| | | |
| | | LinkedList<Control> requestControls = new LinkedList<Control>(); |
| | | requestControls.add(new Control(OID_VIRTUAL_ATTRS_ONLY, true)); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | InternalSearchOperation searchOperation = |
| | | new InternalSearchOperation(conn, conn.nextOperationID(), |
| | | conn.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(entryDNType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code isMultiValued} method. |
| | | */ |
| | | @Test() |
| | | public void testIsMultiValued() |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | assertFalse(provider.isMultiValued()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code getValues} method for an entry. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testGetValues() |
| | | throws Exception |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = provider.getValues(entry, rule); |
| | | assertNotNull(values); |
| | | assertEquals(values.size(), 1); |
| | | assertTrue(values.contains(new AttributeValue(entryDNType, "o=test"))); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, 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 |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | assertTrue(provider.hasValue(entry, rule, |
| | | new AttributeValue(entryDNType, "o=test"))); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | assertFalse(provider.hasValue(entry, rule, |
| | | new AttributeValue(entryDNType, "o=not test"))); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code hasAnyValue} method with an empty set of values. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testHasAnyValueEmptySet() |
| | | throws Exception |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, 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 |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); |
| | | values.add(new AttributeValue(entryDNType, "o=test")); |
| | | |
| | | 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 |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); |
| | | values.add(new AttributeValue(entryDNType, "o=not test")); |
| | | |
| | | 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 |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(3); |
| | | values.add(new AttributeValue(entryDNType, "o=test")); |
| | | values.add(new AttributeValue(entryDNType, "o=not test")); |
| | | values.add(new AttributeValue(entryDNType, "o=not test either")); |
| | | |
| | | 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 |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(3); |
| | | values.add(new AttributeValue(entryDNType, "o=not test")); |
| | | values.add(new AttributeValue(entryDNType, "o=not test either")); |
| | | values.add(new AttributeValue(entryDNType, "o=still not test")); |
| | | |
| | | assertFalse(provider.hasAnyValue(entry, rule, values)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code matchesSubstring} method to ensure that it returns a |
| | | * result of "undefined". |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testMatchesSubstring() |
| | | throws Exception |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedList<ByteString> subAny = new LinkedList<ByteString>(); |
| | | subAny.add(ByteStringFactory.create("=")); |
| | | |
| | | assertEquals(provider.matchesSubstring(entry, rule, null, subAny, null), |
| | | ConditionResult.UNDEFINED); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code greaterThanOrEqualTo} method to ensure that it returns a |
| | | * result of "undefined". |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testGreaterThanOrEqualTo() |
| | | throws Exception |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | AttributeValue value = new AttributeValue(entryDNType, "o=test2"); |
| | | assertEquals(provider.greaterThanOrEqualTo(entry, rule, value), |
| | | ConditionResult.UNDEFINED); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code lessThanOrEqualTo} method to ensure that it returns a |
| | | * result of "undefined". |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testLessThanOrEqualTo() |
| | | throws Exception |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | AttributeValue value = new AttributeValue(entryDNType, "o=test2"); |
| | | assertEquals(provider.lessThanOrEqualTo(entry, rule, value), |
| | | ConditionResult.UNDEFINED); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code approximatelyEqualTo} method to ensure that it returns a |
| | | * result of "undefined". |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testApproximatelyEqualTo() |
| | | throws Exception |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | AttributeValue value = new AttributeValue(entryDNType, "o=test2"); |
| | | assertEquals(provider.approximatelyEqualTo(entry, rule, value), |
| | | ConditionResult.UNDEFINED); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a set of filters for use in testing searchability. The returned |
| | | * data will actually include three elements: |
| | | * <OL> |
| | | * <LI>The string representation of the search filter to use</LI> |
| | | * <LI>An indication of whether it should be searchable</LI> |
| | | * <LI>An indication of whether a minimal o=test entry should match</LI> |
| | | * </OL> |
| | | * |
| | | * @return A set of filters for use in testing searchability. |
| | | */ |
| | | @DataProvider(name = "testFilters") |
| | | public Object[][] getTestFilters() |
| | | { |
| | | return new Object[][] |
| | | { |
| | | new Object[] { "(entryDN=o=test)", true, true }, |
| | | new Object[] { "(entryDN=o=not test)", true, false }, |
| | | new Object[] { "(o=test)", false, false }, |
| | | new Object[] { "(entryDN=*)", false, false }, |
| | | new Object[] { "(&(objectClass=*)(entryDN=o=test))", true, true }, |
| | | new Object[] { "(&(entryDN=o=test)(entryDN=o=not test))", true, false }, |
| | | new Object[] { "(|(objectClass=*)(entryDN=o=test))", false, false }, |
| | | new Object[] { "(|(entryDN=o=test)(entryDN=o=not test))", true, true }, |
| | | new Object[] { "(&(|(entryDN=o=test)(entryDN=o=not test))" + |
| | | "(&(objectClass=top)(|(objectClass=organization)" + |
| | | "(objectClass=domain)))" + |
| | | "(|(o=test)(o=not test)))", true, true } |
| | | }; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code isSearchable} method with the provided information. |
| | | * |
| | | * @param filterString The string representation of the search filter to use |
| | | * for the test. |
| | | * @param isSearchable Indicates whether a search with the given filter |
| | | * should be considered searchable. |
| | | * @param shouldMatch Indicates whether the provided filter should match |
| | | * a minimal o=test entry. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test(dataProvider = "testFilters") |
| | | public void testIsSearchable(String filterString, boolean isSearchable, |
| | | boolean shouldMatch) |
| | | throws Exception |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | SearchFilter filter = SearchFilter.createFilterFromString(filterString); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | InternalSearchOperation searchOperation = |
| | | new InternalSearchOperation(conn, conn.nextOperationID(), |
| | | conn.nextMessageID(), null, |
| | | DN.decode("o=test"), |
| | | SearchScope.WHOLE_SUBTREE, |
| | | DereferencePolicy.NEVER_DEREF_ALIASES, 0, |
| | | 0, false, filter, null, null); |
| | | |
| | | assertEquals(provider.isSearchable(rule, searchOperation), isSearchable); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code processSearch} method with the provided information. |
| | | * |
| | | * @param filterString The string representation of the search filter to use |
| | | * for the test. |
| | | * @param isSearchable Indicates whether a search with the given filter |
| | | * should be considered searchable. |
| | | * @param shouldMatch Indicates whether the provided filter should match |
| | | * a minimal o=test entry. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test(dataProvider = "testFilters") |
| | | public void testProcessSearch(String filterString, boolean isSearchable, |
| | | boolean shouldMatch) |
| | | throws Exception |
| | | { |
| | | if (! isSearchable) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | SearchFilter filter = SearchFilter.createFilterFromString(filterString); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | InternalSearchOperation searchOperation = |
| | | new InternalSearchOperation(conn, conn.nextOperationID(), |
| | | conn.nextMessageID(), null, |
| | | DN.decode("o=test"), |
| | | SearchScope.WHOLE_SUBTREE, |
| | | DereferencePolicy.NEVER_DEREF_ALIASES, 0, |
| | | 0, false, filter, null, null); |
| | | provider.processSearch(rule, searchOperation); |
| | | |
| | | if (shouldMatch) |
| | | { |
| | | assertEquals(searchOperation.getSearchEntries().size(), 1); |
| | | } |
| | | else |
| | | { |
| | | assertEquals(searchOperation.getSearchEntries().size(), 0); |
| | | } |
| | | } |
| | | } |
| | | |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.Collections; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | | import org.testng.annotations.Test; |
| | | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.std.meta.VirtualAttributeCfgDefn; |
| | | import org.opends.server.core.DeleteOperation; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.protocols.internal.InternalClientConnection; |
| | | import org.opends.server.protocols.internal.InternalSearchOperation; |
| | | import org.opends.server.types.Attribute; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ByteStringFactory; |
| | | import org.opends.server.types.ConditionResult; |
| | | import org.opends.server.types.Control; |
| | | import org.opends.server.types.DereferencePolicy; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.Entry; |
| | | import org.opends.server.types.ResultCode; |
| | | import org.opends.server.types.SearchFilter; |
| | | import org.opends.server.types.SearchScope; |
| | | import org.opends.server.types.VirtualAttributeRule; |
| | | |
| | | import static org.testng.Assert.*; |
| | | |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A set of test cases for the isMemberOf virtual attribute provider. |
| | | */ |
| | | public class IsMemberOfVirtualAttributeProviderTestCase |
| | | extends ExtensionsTestCase |
| | | { |
| | | // The attribute type for the isMemberOf attribute. |
| | | private AttributeType isMemberOfType; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Ensures that the Directory Server is running. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @BeforeClass() |
| | | public void startServer() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.startServer(); |
| | | |
| | | isMemberOfType = DirectoryServer.getAttributeType("ismemberof", false); |
| | | assertNotNull(isMemberOfType); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests that the isMemberOf virtual attribute is properly generated for an |
| | | * entry that is a member of a static group based on the member attribute. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testStaticGroupMembershipMember() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: uid=test.user,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user", |
| | | "givenName: Test", |
| | | "sn: User", |
| | | "cn: Test User", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=Test Static Group,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Static Group", |
| | | "member: uid=test.user,ou=People,o=test"); |
| | | |
| | | Entry e = |
| | | DirectoryServer.getEntry(DN.decode("uid=test.user,ou=People,o=test")); |
| | | assertNotNull(e); |
| | | assertTrue(e.hasAttribute(isMemberOfType)); |
| | | for (Attribute a : e.getAttribute(isMemberOfType)) |
| | | { |
| | | assertEquals(a.getValues().size(), 1); |
| | | |
| | | assertTrue(a.hasValue()); |
| | | assertTrue(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=test static group,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=not a group,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, "invalid"))); |
| | | } |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | DeleteOperation deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test static group,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests that the isMemberOf virtual attribute is properly generated for an |
| | | * entry that is a member of a static group based on the uniqueMember |
| | | * attribute. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testStaticGroupMembershipUniqueMember() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: uid=test.user,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user", |
| | | "givenName: Test", |
| | | "sn: User", |
| | | "cn: Test User", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=Test Static Group,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfUniqueNames", |
| | | "cn: Test Static Group", |
| | | "uniqueMember: uid=test.user,ou=People,o=test"); |
| | | |
| | | Entry e = |
| | | DirectoryServer.getEntry(DN.decode("uid=test.user,ou=People,o=test")); |
| | | assertNotNull(e); |
| | | assertTrue(e.hasAttribute(isMemberOfType)); |
| | | for (Attribute a : e.getAttribute(isMemberOfType)) |
| | | { |
| | | assertEquals(a.getValues().size(), 1); |
| | | |
| | | assertTrue(a.hasValue()); |
| | | assertTrue(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=test static group,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=not a group,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, "invalid"))); |
| | | } |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | DeleteOperation deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test static group,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests that the isMemberOf virtual attribute is properly generated for an |
| | | * entry that is a member of a dynamic group. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testDynamicGroupMembership() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: uid=test.user,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user", |
| | | "givenName: Test", |
| | | "sn: User", |
| | | "cn: Test User", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=Test Dynamic Group,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfURLs", |
| | | "cn: Test Dynamic Group", |
| | | "memberURL: ldap:///ou=People,o=test??sub?(sn=user)"); |
| | | |
| | | Entry e = |
| | | DirectoryServer.getEntry(DN.decode("uid=test.user,ou=People,o=test")); |
| | | assertNotNull(e); |
| | | assertTrue(e.hasAttribute(isMemberOfType)); |
| | | for (Attribute a : e.getAttribute(isMemberOfType)) |
| | | { |
| | | assertEquals(a.getValues().size(), 1); |
| | | |
| | | assertTrue(a.hasValue()); |
| | | assertTrue(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=test dynamic group,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=not a group,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, "invalid"))); |
| | | } |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | DeleteOperation deleteOperation = |
| | | conn.processDelete( |
| | | DN.decode("cn=test dynamic group,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests that the isMemberOf virtual attribute is properly generated for an |
| | | * entry that is a member of multiple static groups. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testMultipleStaticGroups() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: uid=test.user,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user", |
| | | "givenName: Test", |
| | | "sn: User", |
| | | "cn: Test User", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: uid=test.user2,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user2", |
| | | "givenName: Test", |
| | | "sn: User2", |
| | | "cn: Test User2", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=Test Group 1,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Group 1", |
| | | "member: uid=test.user,ou=People,o=test", |
| | | "", |
| | | "dn: cn=Test Group 2,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Group 2", |
| | | "member: uid=test.user2,ou=People,o=test", |
| | | "", |
| | | "dn: cn=Test Group 3,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Group 3", |
| | | "member: uid=test.user,ou=People,o=test", |
| | | "member: uid=test.user2,ou=People,o=test"); |
| | | |
| | | Entry e = |
| | | DirectoryServer.getEntry(DN.decode("uid=test.user,ou=People,o=test")); |
| | | assertNotNull(e); |
| | | assertTrue(e.hasAttribute(isMemberOfType)); |
| | | for (Attribute a : e.getAttribute(isMemberOfType)) |
| | | { |
| | | assertEquals(a.getValues().size(), 2); |
| | | |
| | | assertTrue(a.hasValue()); |
| | | assertTrue(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=test group 1,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=test group 2,ou=groups,o=test"))); |
| | | assertTrue(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=test group 3,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=not a group,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, "invalid"))); |
| | | } |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | DeleteOperation deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 1,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | |
| | | deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 2,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | |
| | | deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 3,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests that the isMemberOf virtual attribute is properly generated for an |
| | | * entry that is a member of multiple static and dynamic groups. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testMultipleGroups() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: uid=test.user,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user", |
| | | "givenName: Test", |
| | | "sn: User", |
| | | "cn: Test User", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: uid=test.user2,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user2", |
| | | "givenName: Test", |
| | | "sn: User2", |
| | | "cn: Test User2", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=Test Group 1,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Group 1", |
| | | "member: uid=test.user,ou=People,o=test", |
| | | "", |
| | | "dn: cn=Test Group 2,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Group 2", |
| | | "member: uid=test.user2,ou=People,o=test", |
| | | "", |
| | | "dn: cn=Test Group 3,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Group 3", |
| | | "member: uid=test.user,ou=People,o=test", |
| | | "member: uid=test.user2,ou=People,o=test", |
| | | "", |
| | | "dn: cn=Test Group 4,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfURLs", |
| | | "cn: Test Group 4", |
| | | "memberURL: ldap:///o=test??sub?(uid=test.user)", |
| | | "", |
| | | "dn: cn=Test Group 5,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfURLs", |
| | | "cn: Test Group 5", |
| | | "memberURL: ldap:///o=test??sub?(uid=test.user1)", |
| | | "", |
| | | "dn: cn=Test Group 6,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfURLs", |
| | | "cn: Test Group 6", |
| | | "memberURL: ldap:///o=test??sub?(givenName=test)"); |
| | | |
| | | Entry e = |
| | | DirectoryServer.getEntry(DN.decode("uid=test.user,ou=People,o=test")); |
| | | assertNotNull(e); |
| | | assertTrue(e.hasAttribute(isMemberOfType)); |
| | | for (Attribute a : e.getAttribute(isMemberOfType)) |
| | | { |
| | | assertEquals(a.getValues().size(), 4); |
| | | |
| | | assertTrue(a.hasValue()); |
| | | assertTrue(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=test group 1,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=test group 2,ou=groups,o=test"))); |
| | | assertTrue(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=test group 3,ou=groups,o=test"))); |
| | | assertTrue(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=test group 4,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=test group 5,ou=groups,o=test"))); |
| | | assertTrue(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=test group 6,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, |
| | | "cn=not a group,ou=groups,o=test"))); |
| | | assertFalse(a.hasValue(new AttributeValue(isMemberOfType, "invalid"))); |
| | | } |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | DeleteOperation deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 1,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | |
| | | deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 2,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | |
| | | deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 3,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | |
| | | deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 4,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | |
| | | deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 5,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | |
| | | deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 6,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code isMultiValued} method. |
| | | */ |
| | | @Test() |
| | | public void testIsMultiValued() |
| | | { |
| | | IsMemberOfVirtualAttributeProvider provider = |
| | | new IsMemberOfVirtualAttributeProvider(); |
| | | assertTrue(provider.isMultiValued()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code hasAnyValue} method with an empty set of values. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testHasAnyValueEmptySet() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: uid=test.user,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user", |
| | | "givenName: Test", |
| | | "sn: User", |
| | | "cn: Test User", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=Test Static Group,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Static Group", |
| | | "member: uid=test.user,ou=People,o=test"); |
| | | |
| | | Entry e = |
| | | DirectoryServer.getEntry(DN.decode("uid=test.user,ou=People,o=test")); |
| | | |
| | | IsMemberOfVirtualAttributeProvider provider = |
| | | new IsMemberOfVirtualAttributeProvider(); |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(isMemberOfType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | assertFalse(provider.hasAnyValue(e, rule, |
| | | Collections.<AttributeValue>emptySet())); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | DeleteOperation deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test static group,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: uid=test.user,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user", |
| | | "givenName: Test", |
| | | "sn: User", |
| | | "cn: Test User", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=Test Static Group,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Static Group", |
| | | "member: uid=test.user,ou=People,o=test"); |
| | | |
| | | Entry e = |
| | | DirectoryServer.getEntry(DN.decode("uid=test.user,ou=People,o=test")); |
| | | |
| | | IsMemberOfVirtualAttributeProvider provider = |
| | | new IsMemberOfVirtualAttributeProvider(); |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(isMemberOfType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(); |
| | | values.add(new AttributeValue(isMemberOfType, |
| | | "cn=test static group,ou=groups,o=test")); |
| | | |
| | | assertTrue(provider.hasAnyValue(e, rule, values)); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | DeleteOperation deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test static group,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: uid=test.user,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user", |
| | | "givenName: Test", |
| | | "sn: User", |
| | | "cn: Test User", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=Test Static Group,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Static Group", |
| | | "member: uid=test.user,ou=People,o=test"); |
| | | |
| | | Entry e = |
| | | DirectoryServer.getEntry(DN.decode("uid=test.user,ou=People,o=test")); |
| | | |
| | | IsMemberOfVirtualAttributeProvider provider = |
| | | new IsMemberOfVirtualAttributeProvider(); |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(isMemberOfType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(); |
| | | values.add(new AttributeValue(isMemberOfType, |
| | | "cn=test dynamic group,ou=groups,o=test")); |
| | | |
| | | assertFalse(provider.hasAnyValue(e, rule, values)); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | DeleteOperation deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test static group,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: uid=test.user,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user", |
| | | "givenName: Test", |
| | | "sn: User", |
| | | "cn: Test User", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=Test Static Group,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Static Group", |
| | | "member: uid=test.user,ou=People,o=test"); |
| | | |
| | | Entry e = |
| | | DirectoryServer.getEntry(DN.decode("uid=test.user,ou=People,o=test")); |
| | | |
| | | IsMemberOfVirtualAttributeProvider provider = |
| | | new IsMemberOfVirtualAttributeProvider(); |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(isMemberOfType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(); |
| | | values.add(new AttributeValue(isMemberOfType, |
| | | "cn=test static group,ou=groups,o=test")); |
| | | values.add(new AttributeValue(isMemberOfType, |
| | | "cn=test dynamic group,ou=groups,o=test")); |
| | | |
| | | assertTrue(provider.hasAnyValue(e, rule, values)); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | DeleteOperation deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test static group,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: uid=test.user,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user", |
| | | "givenName: Test", |
| | | "sn: User", |
| | | "cn: Test User", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=Test Static Group,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Static Group", |
| | | "member: uid=test.user,ou=People,o=test"); |
| | | |
| | | Entry e = |
| | | DirectoryServer.getEntry(DN.decode("uid=test.user,ou=People,o=test")); |
| | | |
| | | IsMemberOfVirtualAttributeProvider provider = |
| | | new IsMemberOfVirtualAttributeProvider(); |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(isMemberOfType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(); |
| | | values.add(new AttributeValue(isMemberOfType, |
| | | "cn=test nonstatic group,ou=groups,o=test")); |
| | | values.add(new AttributeValue(isMemberOfType, |
| | | "cn=test dynamic group,ou=groups,o=test")); |
| | | |
| | | assertFalse(provider.hasAnyValue(e, rule, values)); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | DeleteOperation deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test static group,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code matchesSubstring} method to ensure that it returns a |
| | | * result of "undefined". |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testMatchesSubstring() |
| | | throws Exception |
| | | { |
| | | IsMemberOfVirtualAttributeProvider provider = |
| | | new IsMemberOfVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(isMemberOfType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedList<ByteString> subAny = new LinkedList<ByteString>(); |
| | | subAny.add(ByteStringFactory.create("=")); |
| | | |
| | | assertEquals(provider.matchesSubstring(entry, rule, null, subAny, null), |
| | | ConditionResult.UNDEFINED); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code greaterThanOrEqualTo} method to ensure that it returns a |
| | | * result of "undefined". |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testGreaterThanOrEqualTo() |
| | | throws Exception |
| | | { |
| | | IsMemberOfVirtualAttributeProvider provider = |
| | | new IsMemberOfVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(isMemberOfType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | AttributeValue value = new AttributeValue(isMemberOfType, "o=test2"); |
| | | assertEquals(provider.greaterThanOrEqualTo(entry, rule, value), |
| | | ConditionResult.UNDEFINED); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code lessThanOrEqualTo} method to ensure that it returns a |
| | | * result of "undefined". |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testLessThanOrEqualTo() |
| | | throws Exception |
| | | { |
| | | IsMemberOfVirtualAttributeProvider provider = |
| | | new IsMemberOfVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(isMemberOfType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | AttributeValue value = new AttributeValue(isMemberOfType, "o=test2"); |
| | | assertEquals(provider.lessThanOrEqualTo(entry, rule, value), |
| | | ConditionResult.UNDEFINED); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code approximatelyEqualTo} method to ensure that it returns a |
| | | * result of "undefined". |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testApproximatelyEqualTo() |
| | | throws Exception |
| | | { |
| | | IsMemberOfVirtualAttributeProvider provider = |
| | | new IsMemberOfVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(isMemberOfType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | AttributeValue value = new AttributeValue(isMemberOfType, "o=test2"); |
| | | assertEquals(provider.approximatelyEqualTo(entry, rule, value), |
| | | ConditionResult.UNDEFINED); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a set of filters for use in testing searchability. The returned |
| | | * data will actually include three elements: |
| | | * <OL> |
| | | * <LI>The string representation of the search filter to use</LI> |
| | | * <LI>An indication of whether it should be searchable</LI> |
| | | * <LI>An indication of whether the uid=test.user,ou=People,o=test entry |
| | | * should match</LI> |
| | | * </OL> |
| | | * |
| | | * @return A set of filters for use in testing searchability. |
| | | */ |
| | | @DataProvider(name = "testFilters") |
| | | public Object[][] getTestFilters() |
| | | { |
| | | return new Object[][] |
| | | { |
| | | new Object[] { "(isMemberOf=*)", false, false }, |
| | | new Object[] { "(isMemberOf=cn*)", false, false }, |
| | | new Object[] { "(isMemberOf=invalid)", true, false }, |
| | | new Object[] { "(&(isMemberOf=invalid1)(isMemberOf=invalid2))", |
| | | true, false }, |
| | | new Object[] { "(isMemberOf>=cn=Test Group 1,ou=Groups,o=test)", |
| | | false, false }, |
| | | new Object[] { "(isMemberOf<=cn=Test Group 1,ou=Groups,o=test)", |
| | | false, false }, |
| | | new Object[] { "(isMemberOf~=cn=Test Group 1,ou=Groups,o=test)", |
| | | false, false }, |
| | | new Object[] { "(isMemberOf=cn=Test Group 1,ou=Groups,o=test)", |
| | | true, true }, |
| | | new Object[] { "(isMemberOf=cn=Test Group 2,ou=Groups,o=test)", |
| | | true, false }, |
| | | new Object[] { "(&(isMemberOf=cn=Test Group 1,ou=Groups,o=test)" + |
| | | "(givenName=test))", |
| | | true, true }, |
| | | new Object[] { "(&(isMemberOf=cn=Test Group 1,ou=Groups,o=test)" + |
| | | "(isMemberOf=invalid))", |
| | | true, false }, |
| | | new Object[] { "(&(isMemberOf=invalid)" + |
| | | "(isMemberOf=cn=Test Group 1,ou=Groups,o=test))", |
| | | true, false }, |
| | | new Object[] { "(&(isMemberOf=cn=Test Group 1,ou=Groups,o=test)" + |
| | | "(givenName=not test))", |
| | | true, false }, |
| | | new Object[] { "(&(isMemberOf=cn=Test Group 1,ou=Groups,o=test)" + |
| | | "(isMemberOf=cn=Test Group 2,ou=Groups,o=test))", |
| | | true, false }, |
| | | new Object[] { "(&(isMemberOf=cn=Test Group 1,ou=Groups,o=test)" + |
| | | "(isMemberOf=cn=Test Group 3,ou=Groups,o=test))", |
| | | true, true }, |
| | | new Object[] { "(&(isMemberOf=cn=Test Group 2,ou=Groups,o=test)" + |
| | | "(isMemberOf=cn=Test Group 4,ou=Groups,o=test))", |
| | | true, false }, |
| | | new Object[] { "(|(isMemberOf=cn=Test Group 1,ou=Groups,o=test)" + |
| | | "(isMemberOf=cn=Test Group 3,ou=Groups,o=test))", |
| | | false, false }, |
| | | }; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code isSearchable} method with the provided information. |
| | | * |
| | | * @param filterString The string representation of the search filter to use |
| | | * for the test. |
| | | * @param isSearchable Indicates whether a search with the given filter |
| | | * should be considered searchable. |
| | | * @param shouldMatch Indicates whether the provided filter should match |
| | | * a minimal o=test entry. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test(dataProvider = "testFilters") |
| | | public void testIsSearchable(String filterString, boolean isSearchable, |
| | | boolean shouldMatch) |
| | | throws Exception |
| | | { |
| | | IsMemberOfVirtualAttributeProvider provider = |
| | | new IsMemberOfVirtualAttributeProvider(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(isMemberOfType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | SearchFilter filter = SearchFilter.createFilterFromString(filterString); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | InternalSearchOperation searchOperation = |
| | | new InternalSearchOperation(conn, conn.nextOperationID(), |
| | | conn.nextMessageID(), null, |
| | | DN.decode("o=test"), |
| | | SearchScope.WHOLE_SUBTREE, |
| | | DereferencePolicy.NEVER_DEREF_ALIASES, 0, |
| | | 0, false, filter, null, null); |
| | | |
| | | assertEquals(provider.isSearchable(rule, searchOperation), isSearchable); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code processSearch} method with the provided information. |
| | | * |
| | | * @param filterString The string representation of the search filter to use |
| | | * for the test. |
| | | * @param isSearchable Indicates whether a search with the given filter |
| | | * should be considered searchable. |
| | | * @param shouldMatch Indicates whether the provided filter should match |
| | | * a minimal o=test entry. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test(dataProvider = "testFilters") |
| | | public void testProcessSearch(String filterString, boolean isSearchable, |
| | | boolean shouldMatch) |
| | | throws Exception |
| | | { |
| | | if (! isSearchable) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | |
| | | TestCaseUtils.addEntries( |
| | | "dn: ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: People", |
| | | "", |
| | | "dn: uid=test.user,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user", |
| | | "givenName: Test", |
| | | "sn: User", |
| | | "cn: Test User", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: uid=test.user2,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user2", |
| | | "givenName: Test", |
| | | "sn: User2", |
| | | "cn: Test User2", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: uid=test.user3,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: test.user3", |
| | | "givenName: Test", |
| | | "sn: User3", |
| | | "cn: Test User3", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: organizationalUnit", |
| | | "ou: Groups", |
| | | "", |
| | | "dn: cn=Test Group 1,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Group 1", |
| | | "member: uid=test.user,ou=People,o=test", |
| | | "", |
| | | "dn: cn=Test Group 2,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Group 2", |
| | | "member: uid=test.user2,ou=People,o=test", |
| | | "", |
| | | "dn: cn=Test Group 3,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Group 3", |
| | | "member: uid=test.user,ou=People,o=test", |
| | | "member: uid=test.user2,ou=People,o=test", |
| | | "", |
| | | "dn: cn=Test Group 4,ou=Groups,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfNames", |
| | | "cn: Test Group 4", |
| | | "member: uid=test.user2,ou=People,o=test", |
| | | "member: uid=test.user3,ou=People,o=test"); |
| | | |
| | | Entry userEntry = |
| | | DirectoryServer.getEntry(DN.decode("uid=test.user,ou=People,o=test")); |
| | | assertNotNull(userEntry); |
| | | |
| | | IsMemberOfVirtualAttributeProvider provider = |
| | | new IsMemberOfVirtualAttributeProvider(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(isMemberOfType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | SearchFilter filter = SearchFilter.createFilterFromString(filterString); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | InternalSearchOperation searchOperation = |
| | | new InternalSearchOperation(conn, conn.nextOperationID(), |
| | | conn.nextMessageID(), null, |
| | | DN.decode("o=test"), |
| | | SearchScope.WHOLE_SUBTREE, |
| | | DereferencePolicy.NEVER_DEREF_ALIASES, 0, |
| | | 0, false, filter, null, null); |
| | | provider.processSearch(rule, searchOperation); |
| | | |
| | | boolean matchFound = false; |
| | | for (Entry e : searchOperation.getSearchEntries()) |
| | | { |
| | | if (e.getDN().equals(userEntry.getDN())) |
| | | { |
| | | if (matchFound) |
| | | { |
| | | fail("Multiple matches found for the same user."); |
| | | } |
| | | else |
| | | { |
| | | matchFound = true; |
| | | } |
| | | } |
| | | } |
| | | |
| | | assertEquals(matchFound, shouldMatch); |
| | | |
| | | DeleteOperation deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 1,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | |
| | | deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 2,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | |
| | | deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 3,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | |
| | | deleteOperation = |
| | | conn.processDelete(DN.decode("cn=test group 4,ou=groups,o=test")); |
| | | assertEquals(deleteOperation.getResultCode(), ResultCode.SUCCESS); |
| | | } |
| | | } |
| | | |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import java.util.Collections; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | | import org.testng.annotations.Test; |
| | | |
| | | 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.types.Attribute; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ByteStringFactory; |
| | | import org.opends.server.types.ConditionResult; |
| | | import org.opends.server.types.Control; |
| | | import org.opends.server.types.DereferencePolicy; |
| | | import org.opends.server.types.DN; |
| | | 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 static org.testng.Assert.*; |
| | | |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * A set of test cases for the subschemaSubentry virtual attribute provider. |
| | | */ |
| | | public class SubschemaSubentryVirtualAttributeProviderTestCase |
| | | extends ExtensionsTestCase |
| | | { |
| | | // The attribute type for the subschemaSubentry attribute. |
| | | private AttributeType subschemaSubentryType; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Ensures that the Directory Server is running. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @BeforeClass() |
| | | public void startServer() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.startServer(); |
| | | |
| | | subschemaSubentryType = |
| | | DirectoryServer.getAttributeType("subschemasubentry", false); |
| | | assertNotNull(subschemaSubentryType); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a set of entry DNs for use in testing the subschemaSubentry |
| | | * virtual attribute. |
| | | * |
| | | * @return A set of entry DNs for use in testing the subschemaSubentry |
| | | * 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") } |
| | | }; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code getEntry} method for the specified entry to ensure that |
| | | * the entry returned includes the subschemaSubentry 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(subschemaSubentryType)); |
| | | |
| | | List<Attribute> attrList = e.getAttribute(subschemaSubentryType); |
| | | assertNotNull(attrList); |
| | | assertFalse(attrList.isEmpty()); |
| | | for (Attribute a : attrList) |
| | | { |
| | | assertTrue(a.hasValue()); |
| | | assertEquals(a.getValues().size(), 1); |
| | | assertTrue(a.hasValue(new AttributeValue(subschemaSubentryType, |
| | | "cn=schema"))); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the subschemaSubentry 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(subschemaSubentryType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the subschemaSubentry 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(subschemaSubentryType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the subschemaSubentry 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(subschemaSubentryType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the subschemaSubentry 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(subschemaSubentryType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the subschemaSubentry 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 testSearchSubschemaSubentryAttr(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("subschemasubentry"); |
| | | |
| | | 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(subschemaSubentryType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the subschemaSubentry 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 testSearchExcludeSubschemaSubentryAttr(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(subschemaSubentryType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the subschemaSubentry attribute is included when that attribute is |
| | | * specifically requested and the subschemaSubentry 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 = "testEntryDNs") |
| | | public void testSearchSubschemaSubentryAttrInMatchingFilter(DN entryDN) |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); |
| | | |
| | | SearchFilter filter = |
| | | SearchFilter.createFilterFromString("(subschemaSubentry=cn=schema)"); |
| | | LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); |
| | | attrList.add("subschemaSubentry"); |
| | | |
| | | 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(subschemaSubentryType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * no entries are returned when the subschemaSubentry 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 testSearchSubschemaSubentryAttrInNonMatchingFilter(DN entryDN) |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); |
| | | |
| | | SearchFilter filter = |
| | | SearchFilter.createFilterFromString("(subschemaSubentry=cn=foo)"); |
| | | LinkedHashSet<String> attrList = new LinkedHashSet<String>(1); |
| | | attrList.add("subschemaSubentry"); |
| | | |
| | | 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 subschemaSubentry 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 testSearchSubschemaSubentryAttrRealAttrsOnly(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("subschemaSubentry"); |
| | | |
| | | LinkedList<Control> requestControls = new LinkedList<Control>(); |
| | | requestControls.add(new Control(OID_REAL_ATTRS_ONLY, true)); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | InternalSearchOperation searchOperation = |
| | | new InternalSearchOperation(conn, conn.nextOperationID(), |
| | | conn.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(subschemaSubentryType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Performs an internal search to retrieve the specified entry, ensuring that |
| | | * the subschemaSubentry 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 testSearchSubschemaSubentryAttrVirtualAttrsOnly(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("subschemaSubentry"); |
| | | |
| | | LinkedList<Control> requestControls = new LinkedList<Control>(); |
| | | requestControls.add(new Control(OID_VIRTUAL_ATTRS_ONLY, true)); |
| | | |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | InternalSearchOperation searchOperation = |
| | | new InternalSearchOperation(conn, conn.nextOperationID(), |
| | | conn.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(subschemaSubentryType)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code isMultiValued} method. |
| | | */ |
| | | @Test() |
| | | public void testIsMultiValued() |
| | | { |
| | | SubschemaSubentryVirtualAttributeProvider provider = |
| | | new SubschemaSubentryVirtualAttributeProvider(); |
| | | assertFalse(provider.isMultiValued()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code getValues} method for an entry. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testGetValues() |
| | | throws Exception |
| | | { |
| | | SubschemaSubentryVirtualAttributeProvider provider = |
| | | new SubschemaSubentryVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(subschemaSubentryType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = provider.getValues(entry, rule); |
| | | assertNotNull(values); |
| | | assertEquals(values.size(), 1); |
| | | assertTrue(values.contains(new AttributeValue(subschemaSubentryType, |
| | | "cn=schema"))); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | | { |
| | | SubschemaSubentryVirtualAttributeProvider provider = |
| | | new SubschemaSubentryVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(subschemaSubentryType, 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 |
| | | { |
| | | SubschemaSubentryVirtualAttributeProvider provider = |
| | | new SubschemaSubentryVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(subschemaSubentryType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | assertTrue(provider.hasValue(entry, rule, |
| | | new AttributeValue(subschemaSubentryType, |
| | | "cn=schema"))); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | | { |
| | | SubschemaSubentryVirtualAttributeProvider provider = |
| | | new SubschemaSubentryVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(subschemaSubentryType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | assertFalse(provider.hasValue(entry, rule, |
| | | new AttributeValue(subschemaSubentryType, |
| | | "cn=not schema"))); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code hasAnyValue} method with an empty set of values. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testHasAnyValueEmptySet() |
| | | throws Exception |
| | | { |
| | | SubschemaSubentryVirtualAttributeProvider provider = |
| | | new SubschemaSubentryVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(subschemaSubentryType, 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 |
| | | { |
| | | SubschemaSubentryVirtualAttributeProvider provider = |
| | | new SubschemaSubentryVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(subschemaSubentryType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); |
| | | values.add(new AttributeValue(subschemaSubentryType, "cn=schema")); |
| | | |
| | | 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 |
| | | { |
| | | SubschemaSubentryVirtualAttributeProvider provider = |
| | | new SubschemaSubentryVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(subschemaSubentryType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1); |
| | | values.add(new AttributeValue(subschemaSubentryType, "cn=not schema")); |
| | | |
| | | 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 |
| | | { |
| | | SubschemaSubentryVirtualAttributeProvider provider = |
| | | new SubschemaSubentryVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(subschemaSubentryType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(3); |
| | | values.add(new AttributeValue(subschemaSubentryType, "cn=schema")); |
| | | values.add(new AttributeValue(subschemaSubentryType, "cn=not schema")); |
| | | values.add(new AttributeValue(subschemaSubentryType, |
| | | "cn=not schema either")); |
| | | |
| | | 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 |
| | | { |
| | | SubschemaSubentryVirtualAttributeProvider provider = |
| | | new SubschemaSubentryVirtualAttributeProvider(); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | entry.processVirtualAttributes(); |
| | | |
| | | VirtualAttributeRule rule = |
| | | new VirtualAttributeRule(subschemaSubentryType, provider, |
| | | Collections.<DN>emptySet(), Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | VirtualAttributeCfgDefn.ConflictBehavior. |
| | | VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(3); |
| | | values.add(new AttributeValue(subschemaSubentryType, "cn=not schema")); |
| | | values.add(new AttributeValue(subschemaSubentryType, |
| | | "cn=not schema either")); |
| | | values.add(new AttributeValue(subschemaSubentryType, |
| | | "cn=still not schema")); |
| | | |
| | | assertFalse(provider.hasAnyValue(entry, rule, values)); |
| | | } |
| | | } |
| | | |
| | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.RDN; |
| | | import org.opends.server.types.SearchScope; |
| | | |
| | | import static org.testng.Assert.*; |
| | | |
| | |
| | | sigs.add(new String[] { "isAncestorOf", |
| | | "boolean", |
| | | "org.opends.server.types.DN" }); |
| | | sigs.add(new String[] { "matchesBaseAndScope", |
| | | "boolean", |
| | | "org.opends.server.types.DN", |
| | | "org.opends.server.types.SearchScope" }); |
| | | sigs.add(new String[] { "equals", |
| | | "boolean", |
| | | "java.lang.Object" }); |
| | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code matchesBaseAndScope} method with valid DN strings. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testMatchesBaseAndScope() |
| | | throws Exception |
| | | { |
| | | assertTrue(new LazyDN("").matchesBaseAndScope(DN.nullDN(), |
| | | SearchScope.BASE_OBJECT)); |
| | | assertTrue(new LazyDN("dc=example,dc=com").matchesBaseAndScope( |
| | | DN.decode("dc=example,dc=com"), SearchScope.BASE_OBJECT)); |
| | | assertTrue(new LazyDN("ou=People,dc=example,dc=com").matchesBaseAndScope( |
| | | DN.decode("dc=example,dc=com"), SearchScope.WHOLE_SUBTREE)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code matchesBaseAndScope} method with an invalid DN string. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test(expectedExceptions = { RuntimeException.class }) |
| | | public void testMatchesBaseandScopeInvalid() |
| | | throws Exception |
| | | { |
| | | new LazyDN("invalid").matchesBaseAndScope(DN.decode("dc=example,dc=com"), |
| | | SearchScope.WHOLE_SUBTREE); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code equals} method with valid DN strings. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | |
| | | assertTrue(checkChangelogQueueSize(CHANGELOG_QUEUE_SIZE)); |
| | | |
| | | // Create an Entry (add operation) that will be later used in the test. |
| | | Entry tmp = personEntry.duplicate(); |
| | | Entry tmp = personEntry.duplicate(false); |
| | | AddOperation addOp = new AddOperation(connection, |
| | | InternalClientConnection.nextOperationID(), InternalClientConnection |
| | | .nextMessageID(), null, tmp.getDN(), |
| | |
| | | */ |
| | | |
| | | // Create an Entry (add operation) that will be later used in the test. |
| | | Entry tmp = personEntry.duplicate(); |
| | | Entry tmp = personEntry.duplicate(false); |
| | | AddOperation addOp = new AddOperation(connection, |
| | | InternalClientConnection.nextOperationID(), InternalClientConnection |
| | | .nextMessageID(), null, tmp.getDN(), |
| | |
| | | while ((count> 0) && (found != exist)) |
| | | { |
| | | Thread.sleep(200); |
| | | |
| | | |
| | | found = DirectoryServer.entryExists(dn); |
| | | count--; |
| | | } |
| | | |
| | | |
| | | Lock lock = null; |
| | | for (int i=0; i < 3; i++) |
| | | { |
| | |
| | | break; |
| | | } |
| | | } |
| | | |
| | | |
| | | if (lock == null) |
| | | { |
| | | throw new Exception("could not lock entry " + dn); |
| | | } |
| | | |
| | | |
| | | try |
| | | { |
| | | Entry entry = DirectoryServer.getEntry(dn); |
| | | if (entry == null) |
| | | return null; |
| | | else |
| | | return entry.duplicate(); |
| | | return entry.duplicate(true); |
| | | } |
| | | finally |
| | | { |
| | |
| | | */ |
| | | |
| | | // Create an Entry (add operation) |
| | | Entry tmp = personEntry.duplicate(); |
| | | Entry tmp = personEntry.duplicate(false); |
| | | AddOperation addOp = new AddOperation(connection, |
| | | InternalClientConnection.nextOperationID(), InternalClientConnection |
| | | .nextMessageID(), null, tmp.getDN(), |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.types; |
| | | |
| | | |
| | | |
| | | import java.util.Collections; |
| | | import java.util.LinkedHashSet; |
| | | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | | import org.testng.annotations.Test; |
| | | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.std.meta. |
| | | VirtualAttributeCfgDefn.ConflictBehavior; |
| | | import org.opends.server.extensions.EntryDNVirtualAttributeProvider; |
| | | import org.opends.server.protocols.internal.InternalClientConnection; |
| | | |
| | | import static org.testng.Assert.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class provides a set of test cases for virtual attribute rules, which |
| | | * link a virtual attribute provider implementation with an attribute type and a |
| | | * set of criteria for identifying the entries with which that provider should |
| | | * be used. |
| | | */ |
| | | public class VirtualAttributeRuleTestCase |
| | | extends TypesTestCase |
| | | { |
| | | // The attribute type for the entryDN attribute. |
| | | private AttributeType entryDNType; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Ensures that the Directory Server is running. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @BeforeClass() |
| | | public void startServer() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.startServer(); |
| | | |
| | | entryDNType = DirectoryConfig.getAttributeType("entrydn", false); |
| | | assertNotNull(entryDNType); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a set of virtual attribute rules that may be used for testing |
| | | * purposes. The return data will also include a Boolean value indicating |
| | | * whether the rule would apply to a minimal "o=test" entry. |
| | | * |
| | | * @return A set of virtual attribute rules that may be used for testing |
| | | * purposes. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @DataProvider(name = "testRules") |
| | | public Object[][] getVirtualAttributeRules() |
| | | throws Exception |
| | | { |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | LinkedHashSet<DN> dnSet1 = new LinkedHashSet<DN>(1); |
| | | dnSet1.add(DN.decode("o=test")); |
| | | |
| | | LinkedHashSet<DN> dnSet2 = new LinkedHashSet<DN>(1); |
| | | dnSet2.add(DN.decode("dc=example,dc=com")); |
| | | |
| | | LinkedHashSet<DN> dnSet3 = new LinkedHashSet<DN>(2); |
| | | dnSet3.add(DN.decode("o=test")); |
| | | dnSet3.add(DN.decode("dc=example,dc=com")); |
| | | |
| | | |
| | | LinkedHashSet<DN> groupSet1 = new LinkedHashSet<DN>(1); |
| | | groupSet1.add(DN.decode("cn=Test Group,o=test")); |
| | | |
| | | LinkedHashSet<DN> groupSet2 = new LinkedHashSet<DN>(1); |
| | | groupSet2.add(DN.decode("cn=Example Group,o=test")); |
| | | |
| | | LinkedHashSet<DN> groupSet3= new LinkedHashSet<DN>(2); |
| | | groupSet3.add(DN.decode("cn=Test Group,o=test")); |
| | | groupSet3.add(DN.decode("cn=Example Group,o=test")); |
| | | |
| | | |
| | | LinkedHashSet<SearchFilter> filterSet1 = new LinkedHashSet<SearchFilter>(1); |
| | | filterSet1.add(SearchFilter.createFilterFromString("(objectClass=*)")); |
| | | |
| | | LinkedHashSet<SearchFilter> filterSet2 = new LinkedHashSet<SearchFilter>(1); |
| | | filterSet2.add(SearchFilter.createFilterFromString("(o=test)")); |
| | | |
| | | LinkedHashSet<SearchFilter> filterSet3 = new LinkedHashSet<SearchFilter>(1); |
| | | filterSet3.add(SearchFilter.createFilterFromString("(foo=bar)")); |
| | | |
| | | LinkedHashSet<SearchFilter> filterSet4 = new LinkedHashSet<SearchFilter>(2); |
| | | filterSet4.add(SearchFilter.createFilterFromString("(o=test)")); |
| | | filterSet4.add(SearchFilter.createFilterFromString("(foo=bar)")); |
| | | |
| | | return new Object[][] |
| | | { |
| | | new Object[] |
| | | { |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), |
| | | Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | ConflictBehavior.VIRTUAL_OVERRIDES_REAL), |
| | | true |
| | | }, |
| | | |
| | | new Object[] |
| | | { |
| | | new VirtualAttributeRule(entryDNType, provider, dnSet1, |
| | | Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | ConflictBehavior.VIRTUAL_OVERRIDES_REAL), |
| | | true |
| | | }, |
| | | |
| | | new Object[] |
| | | { |
| | | new VirtualAttributeRule(entryDNType, provider, dnSet2, |
| | | Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | ConflictBehavior.VIRTUAL_OVERRIDES_REAL), |
| | | false |
| | | }, |
| | | |
| | | new Object[] |
| | | { |
| | | new VirtualAttributeRule(entryDNType, provider, dnSet3, |
| | | Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | ConflictBehavior.VIRTUAL_OVERRIDES_REAL), |
| | | true |
| | | }, |
| | | |
| | | new Object[] |
| | | { |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), groupSet1, |
| | | Collections.<SearchFilter>emptySet(), |
| | | ConflictBehavior.VIRTUAL_OVERRIDES_REAL), |
| | | true |
| | | }, |
| | | |
| | | new Object[] |
| | | { |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), groupSet2, |
| | | Collections.<SearchFilter>emptySet(), |
| | | ConflictBehavior.VIRTUAL_OVERRIDES_REAL), |
| | | false |
| | | }, |
| | | |
| | | new Object[] |
| | | { |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), groupSet3, |
| | | Collections.<SearchFilter>emptySet(), |
| | | ConflictBehavior.VIRTUAL_OVERRIDES_REAL), |
| | | true |
| | | }, |
| | | |
| | | new Object[] |
| | | { |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), |
| | | Collections.<DN>emptySet(), filterSet1, |
| | | ConflictBehavior.VIRTUAL_OVERRIDES_REAL), |
| | | true |
| | | }, |
| | | |
| | | new Object[] |
| | | { |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), |
| | | Collections.<DN>emptySet(), filterSet2, |
| | | ConflictBehavior.VIRTUAL_OVERRIDES_REAL), |
| | | true |
| | | }, |
| | | |
| | | new Object[] |
| | | { |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), |
| | | Collections.<DN>emptySet(), filterSet3, |
| | | ConflictBehavior.VIRTUAL_OVERRIDES_REAL), |
| | | false |
| | | }, |
| | | |
| | | new Object[] |
| | | { |
| | | new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), |
| | | Collections.<DN>emptySet(), filterSet4, |
| | | ConflictBehavior.VIRTUAL_OVERRIDES_REAL), |
| | | true |
| | | }, |
| | | }; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the various getter methods in the virtual attribute rule class. |
| | | * |
| | | * @param rule The rule for which to perform the test. |
| | | * @param appliesToEntry Indicates whether the provided rule applies to a |
| | | * minimal "o=test" entry. |
| | | */ |
| | | @Test(dataProvider = "testRules") |
| | | public void testGetters(VirtualAttributeRule rule, boolean appliesToEntry) |
| | | { |
| | | assertEquals(rule.getAttributeType(), entryDNType); |
| | | assertEquals(rule.getProvider().getClass().getName(), |
| | | EntryDNVirtualAttributeProvider.class.getName()); |
| | | assertNotNull(rule.getBaseDNs()); |
| | | assertNotNull(rule.getGroupDNs()); |
| | | assertNotNull(rule.getFilters()); |
| | | assertNotNull(rule.getConflictBehavior()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code appliesToEntry} method. |
| | | * |
| | | * @param rule The rule for which to perform the test. |
| | | * @param appliesToEntry Indicates whether the provided rule applies to a |
| | | * minimal "o=test" entry. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test(dataProvider = "testRules") |
| | | public void testAppliesToEntry(VirtualAttributeRule rule, |
| | | boolean appliesToEntry) |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | addGroups(); |
| | | assertEquals(rule.appliesToEntry( |
| | | DirectoryConfig.getEntry(DN.decode("o=test"))), |
| | | appliesToEntry); |
| | | removeGroups(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code toString} method. |
| | | * |
| | | * @param rule The rule for which to perform the test. |
| | | * @param appliesToEntry Indicates whether the provided rule applies to a |
| | | * minimal "o=test" entry. |
| | | */ |
| | | @Test(dataProvider = "testRules") |
| | | public void testToString(VirtualAttributeRule rule, boolean appliesToEntry) |
| | | { |
| | | String ruleString = rule.toString(); |
| | | assertNotNull(ruleString); |
| | | assertTrue(ruleString.length() > 0); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds a group to the server in which the "o=test" entry is a member. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | private void addGroups() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.addEntries( |
| | | "dn: cn=Test Group,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfUniqueNames", |
| | | "cn: Test Group", |
| | | "uniqueMember: o=test", |
| | | "", |
| | | "dn: cn=Example Group,o=test", |
| | | "objectClass: top", |
| | | "objectClass: groupOfUniqueNames", |
| | | "cn: Example Group", |
| | | "uniqueMember: dc=example,dc=com"); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Removes the test group from the server. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | private void removeGroups() |
| | | throws Exception |
| | | { |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | conn.processDelete(DN.decode("cn=Test Group,o=Test")); |
| | | conn.processDelete(DN.decode("cn=Example Group,o=Test")); |
| | | } |
| | | } |
| | | |
| New file |
| | |
| | | /* |
| | | * 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 |
| | | * |
| | | * |
| | | * Portions Copyright 2007 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.types; |
| | | |
| | | |
| | | |
| | | import java.util.Collections; |
| | | import java.util.LinkedHashSet; |
| | | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | | import org.testng.annotations.Test; |
| | | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.std.meta. |
| | | VirtualAttributeCfgDefn.ConflictBehavior; |
| | | import org.opends.server.extensions.EntryDNVirtualAttributeProvider; |
| | | import org.opends.server.protocols.internal.InternalClientConnection; |
| | | |
| | | import static org.testng.Assert.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class provides a set of test cases for virtual attributes. |
| | | */ |
| | | public class VirtualAttributeTestCase |
| | | extends TypesTestCase |
| | | { |
| | | // The attribute type for the entryDN attribute. |
| | | private AttributeType entryDNType; |
| | | |
| | | // The virtual attribute instance that will be used for all the testing. |
| | | private VirtualAttribute virtualAttribute; |
| | | |
| | | // The virutal attribute rule that will be used for the testing. |
| | | private VirtualAttributeRule virtualAttributeRule; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Ensures that the Directory Server is running. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @BeforeClass() |
| | | public void startServer() |
| | | throws Exception |
| | | { |
| | | TestCaseUtils.startServer(); |
| | | |
| | | entryDNType = DirectoryConfig.getAttributeType("entrydn", false); |
| | | assertNotNull(entryDNType); |
| | | |
| | | EntryDNVirtualAttributeProvider provider = |
| | | new EntryDNVirtualAttributeProvider(); |
| | | |
| | | virtualAttributeRule = new VirtualAttributeRule(entryDNType, provider, |
| | | Collections.<DN>emptySet(), |
| | | Collections.<DN>emptySet(), |
| | | Collections.<SearchFilter>emptySet(), |
| | | ConflictBehavior.VIRTUAL_OVERRIDES_REAL); |
| | | |
| | | Entry entry = TestCaseUtils.makeEntry( |
| | | "dn: o=test", |
| | | "objectClass: top", |
| | | "objectClass: organization", |
| | | "o: test"); |
| | | |
| | | virtualAttribute = new VirtualAttribute(entryDNType, entry, |
| | | virtualAttributeRule); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the various getter methods for virtual attributes. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testGetters() |
| | | throws Exception |
| | | { |
| | | assertNotNull(virtualAttribute.getEntry()); |
| | | assertEquals(virtualAttribute.getEntry().getDN(), |
| | | DN.decode("o=test")); |
| | | |
| | | assertEquals(virtualAttribute.getVirtualAttributeRule(), |
| | | virtualAttributeRule); |
| | | |
| | | assertTrue(virtualAttribute.isVirtual()); |
| | | assertTrue(virtualAttribute.duplicate(true).isVirtual()); |
| | | assertTrue(virtualAttribute.duplicate(false).isVirtual()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the various methods that interact with the virtual values. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testValues() |
| | | throws Exception |
| | | { |
| | | LinkedHashSet<AttributeValue> values = virtualAttribute.getValues(); |
| | | assertEquals(values.size(), 1); |
| | | assertTrue(values.contains(new AttributeValue(entryDNType, "o=test"))); |
| | | |
| | | assertTrue(virtualAttribute.hasValue()); |
| | | |
| | | assertTrue(virtualAttribute.hasValue(new AttributeValue(entryDNType, |
| | | "o=test"))); |
| | | assertFalse(virtualAttribute.hasValue(new AttributeValue(entryDNType, |
| | | "o=not test"))); |
| | | |
| | | LinkedHashSet<AttributeValue> testValues = |
| | | new LinkedHashSet<AttributeValue>(); |
| | | testValues.add(new AttributeValue(entryDNType, "o=test")); |
| | | assertTrue(virtualAttribute.hasAllValues(testValues)); |
| | | assertTrue(virtualAttribute.hasAnyValue(testValues)); |
| | | |
| | | testValues.add(new AttributeValue(entryDNType, "o=not test")); |
| | | assertFalse(virtualAttribute.hasAllValues(testValues)); |
| | | assertTrue(virtualAttribute.hasAnyValue(testValues)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the various methods that apply to different kinds of matching. |
| | | * |
| | | * @throws Exception If an unexpected problem occurs. |
| | | */ |
| | | @Test() |
| | | public void testMatching() |
| | | throws Exception |
| | | { |
| | | assertEquals(virtualAttribute.matchesSubstring( |
| | | ByteStringFactory.create("o="), null, |
| | | ByteStringFactory.create("test")), |
| | | ConditionResult.UNDEFINED); |
| | | |
| | | AttributeValue assertionValue = new AttributeValue(entryDNType, "o=test"); |
| | | assertEquals(virtualAttribute.greaterThanOrEqualTo(assertionValue), |
| | | ConditionResult.UNDEFINED); |
| | | assertEquals(virtualAttribute.lessThanOrEqualTo(assertionValue), |
| | | ConditionResult.UNDEFINED); |
| | | assertEquals(virtualAttribute.approximatelyEqualTo(assertionValue), |
| | | ConditionResult.UNDEFINED); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code toString} method. |
| | | */ |
| | | @Test() |
| | | public void testToString() |
| | | { |
| | | String vattrString = virtualAttribute.toString(); |
| | | assertNotNull(vattrString); |
| | | assertTrue(vattrString.length() > 0); |
| | | } |
| | | } |
| | | |