/*
|
* CDDL HEADER START
|
*
|
* The contents of this file are subject to the terms of the
|
* Common Development and Distribution License, Version 1.0 only
|
* (the "License"). You may not use this file except in compliance
|
* with the License.
|
*
|
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
|
* or http://forgerock.org/license/CDDLv1.0.html.
|
* See the License for the specific language governing permissions
|
* and limitations under the License.
|
*
|
* When distributing Covered Code, include this CDDL HEADER in each
|
* file and include the License file at legal-notices/CDDLv1_0.txt.
|
* If applicable, add the following below this CDDL HEADER, with the
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
* information:
|
* Portions Copyright [yyyy] [name of copyright owner]
|
*
|
* CDDL HEADER END
|
*
|
*
|
* Copyright 2006-2010 Sun Microsystems, Inc.
|
* Portions Copyright 2011-2016 ForgeRock AS
|
*/
|
package org.opends.server.api;
|
|
import org.forgerock.i18n.LocalizableMessage;
|
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Set;
|
|
import org.opends.server.admin.std.server.GroupImplementationCfg;
|
import org.opends.server.core.ServerContext;
|
import org.forgerock.opendj.config.server.ConfigException;
|
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.Modification;
|
import org.opends.server.types.SearchFilter;
|
import org.forgerock.opendj.ldap.SearchScope;
|
|
/**
|
* This class defines the set of methods that must be implemented by a
|
* Directory Server group. It is expected that there will be a number
|
* of different types of groups (e.g., legacy static and dynamic
|
* groups, as well as enhanced groups and virtual static groups). The
|
* following operations may be performed on an OpenDS group:
|
* <UL>
|
* <LI>Determining whether a given user is a member of this
|
* group</LI>
|
* <LI>Determining the set of members for this group, optionally
|
* filtered based on some set of criteria.</LI>
|
* <LI>Retrieving or updating the set of nested groups for this
|
* group, if the underlying group type supports nesting).</LI>
|
* <LI>Updating the set of members for this group, if the underlying
|
* group type provides the ability to explicitly add or remove
|
* members.</LI>
|
* </UL>
|
*
|
* @param <T> The type of configuration handled by this group
|
* implementation.
|
*/
|
@org.opends.server.types.PublicAPI(
|
stability=org.opends.server.types.StabilityLevel.VOLATILE,
|
mayInstantiate=false,
|
mayExtend=true,
|
mayInvoke=true)
|
public abstract class Group<T extends GroupImplementationCfg>
|
{
|
/**
|
* Initializes a "shell" instance of this group implementation that
|
* may be used to identify and instantiate instances of this type of
|
* group in the directory data.
|
*
|
* @param configuration The configuration for this group
|
* implementation.
|
*
|
* @throws ConfigException If there is a problem with the provided
|
* configuration entry.
|
*
|
* @throws InitializationException If a problem occurs while
|
* attempting to initialize this
|
* group implementation that is
|
* not related to the server
|
* configuration.
|
*/
|
public abstract void initializeGroupImplementation(T configuration)
|
throws ConfigException, InitializationException;
|
|
|
|
/**
|
* Indicates whether the provided configuration is acceptable for
|
* this group implementation. It should be possible to call this
|
* method on an uninitialized group implementation instance in order
|
* to determine whether the group implementation would be able to
|
* use the provided configuration.
|
* <BR><BR>
|
* Note that implementations which use a subclass of the provided
|
* configuration class will likely need to cast the configuration
|
* to the appropriate subclass type.
|
*
|
* @param configuration The group implementation
|
* configuration for which to make the
|
* determination.
|
* @param unacceptableReasons A list that may be used to hold the
|
* reasons that the provided
|
* configuration is not acceptable.
|
*
|
* @return {@code true} if the provided configuration is acceptable
|
* for this group implementation, or {@code false} if not.
|
*/
|
public boolean isConfigurationAcceptable(
|
GroupImplementationCfg configuration,
|
List<LocalizableMessage> unacceptableReasons)
|
{
|
// This default implementation does not perform any special
|
// validation. It should be overridden by group implementations
|
// that wish to perform more detailed validation.
|
return true;
|
}
|
|
|
|
/**
|
* Performs any necessary finalization that may be needed whenever
|
* this group implementation is taken out of service within the
|
* Directory Server (e.g., if it is disabled or the server is
|
* shutting down).
|
*/
|
public void finalizeGroupImplementation()
|
{
|
// No implementation is required by default.
|
}
|
|
|
|
/**
|
* Creates a new group of this type based on the definition
|
* contained in the provided entry. This method must be designed so
|
* that it may be invoked on the "shell" instance created using the
|
* default constructor and initialized with the
|
* {@code initializeGroupImplementation} method.
|
*
|
* @param serverContext
|
* The server context.
|
* @param groupEntry The entry containing the definition for the
|
* group to be created.
|
*
|
* @return The group instance created from the definition in the
|
* provided entry.
|
*
|
* @throws DirectoryException If a problem occurs while trying to
|
* create the group instance.
|
*/
|
public abstract Group<T> newInstance(ServerContext serverContext, Entry groupEntry)
|
throws DirectoryException;
|
|
|
|
/**
|
* Retrieves a search filter that may be used to identify entries
|
* containing definitions for groups of this type in the Directory
|
* Server. This method must be designed so that it may be invoked
|
* on the "shell" instance created using the default constructor and
|
* initialized with the {@code initializeGroupImplementation}
|
* method.
|
*
|
* @return A search filter that may be used to identify entries
|
* containing definitions for groups of this type in the
|
* Directory Server.
|
*
|
* @throws DirectoryException If a problem occurs while trying to
|
* locate all of the applicable group
|
* definition entries.
|
*/
|
public abstract SearchFilter getGroupDefinitionFilter()
|
throws DirectoryException;
|
|
|
|
/**
|
* Indicates whether the provided entry contains a valid definition
|
* for this type of group.
|
*
|
* @param entry The entry for which to make the determination.
|
*
|
* @return {@code true} if the provided entry does contain a valid
|
* definition for this type of group, or {@code false} if
|
* it does not.
|
*/
|
public abstract boolean isGroupDefinition(Entry entry);
|
|
|
|
/**
|
* Retrieves the DN of the entry that contains the definition for
|
* this group.
|
*
|
* @return The DN of the entry that contains the definition for
|
* this group.
|
*/
|
public abstract DN getGroupDN();
|
|
|
|
/**
|
* Sets the DN of the entry that contains the definition for
|
* this group.
|
*
|
* @param groupDN The DN of the entry that contains the
|
* definition for this group.
|
*/
|
public abstract void setGroupDN(DN groupDN);
|
|
|
|
/**
|
* Indicates whether this group supports nesting other groups, such
|
* that the members of the nested groups will also be considered
|
* members of this group.
|
*
|
* @return {@code true} if this group supports nesting other
|
* groups, or {@code false} if it does not.
|
*/
|
public abstract boolean supportsNestedGroups();
|
|
|
|
/**
|
* Retrieves a list of the DNs of any nested groups whose members
|
* should be considered members of this group.
|
*
|
* @return A list of the DNs of any nested groups whose members
|
* should be considered members of this group.
|
*/
|
public abstract List<DN> getNestedGroupDNs();
|
|
|
|
/**
|
* Attempts to add the provided group DN as a nested group within
|
* this group. The change should be committed to persistent storage
|
* through an internal operation.
|
*
|
* @param nestedGroupDN The DN of the group that should be added
|
* to the set of nested groups for this
|
* group.
|
*
|
* @throws UnsupportedOperationException If this group does not
|
* support nesting.
|
*
|
* @throws DirectoryException If a problem occurs while attempting
|
* to nest the provided group DN.
|
*/
|
public abstract void addNestedGroup(DN nestedGroupDN)
|
throws UnsupportedOperationException, DirectoryException;
|
|
|
|
/**
|
* Attempts to remove the provided group as a nested group within
|
* this group. The change should be committed to persistent storage
|
* through an internal operation.
|
*
|
* @param nestedGroupDN The DN of the group that should be removed
|
* from the set of nested groups for this
|
* group.
|
*
|
* @throws UnsupportedOperationException If this group does not
|
* support nesting.
|
*
|
* @throws DirectoryException If a problem occurs while attempting
|
* to nest the provided group DN.
|
*/
|
public abstract void removeNestedGroup(DN nestedGroupDN)
|
throws UnsupportedOperationException, DirectoryException;
|
|
|
|
/**
|
* Indicates whether the user with the specified DN is a member of
|
* this group. Note that this is a point-in-time determination and
|
* the caller must not cache the result.
|
*
|
* @param userDN The DN of the user for which to make the
|
* determination.
|
*
|
* @return {@code true} if the specified user is currently a member
|
* of this group, or {@code false} if not.
|
*
|
* @throws DirectoryException If a problem occurs while attempting
|
* to make the determination.
|
*/
|
public boolean isMember(DN userDN) throws DirectoryException
|
{
|
return userDN != null && isMember(userDN, new HashSet<DN>());
|
}
|
|
|
|
/**
|
* Indicates whether the user with the specified DN is a member of
|
* this group. Note that this is a point-in-time determination and
|
* the caller must not cache the result. Also note that group
|
* implementations that support nesting should use this version of
|
* the method rather than the version that does not take a set of
|
* DNs when attempting to determine whether a nested group includes
|
* the target member.
|
*
|
* @param userDN The DN of the user for which to make the
|
* determination.
|
* @param examinedGroups A set of groups that have already been
|
* examined in the process of making the
|
* determination. This provides a mechanism
|
* to prevent infinite recursion due to
|
* circular references (e.g., two groups
|
* include each other as nested groups).
|
* Each time a group instance is checked,
|
* its DN should be added to the list, and
|
* any DN already contained in the list
|
* should be skipped.
|
*
|
* @return {@code true} if the specified user is currently a member
|
* of this group, or {@code false} if not.
|
*
|
* @throws DirectoryException If a problem occurs while attempting
|
* to make the determination.
|
*/
|
public abstract boolean isMember(DN userDN, Set<DN> examinedGroups)
|
throws DirectoryException;
|
|
|
|
/**
|
* Indicates whether the user described by the provided user entry
|
* is a member of this group. Note that this is a point-in-time
|
* determination and the caller must not cache the result.
|
*
|
* @param userEntry The entry for the user for which to make the
|
* determination.
|
*
|
* @return {@code true} if the specified user is currently a member
|
* of this group, or {@code false} if not.
|
*
|
* @throws DirectoryException If a problem occurs while attempting
|
* to make the determination.
|
*/
|
public boolean isMember(Entry userEntry)
|
throws DirectoryException
|
{
|
return isMember(userEntry, new HashSet<DN>());
|
}
|
|
|
|
/**
|
* Indicates whether the user described by the provided user entry
|
* is a member of this group. Note that this is a point-in-time
|
* determination and the caller must not cache the result. Also
|
* note that group implementations that support nesting should use
|
* this version of the method rather than the version that does not
|
* take a set of DNs when attempting to determine whether a nested
|
* group includes the target member.
|
*
|
* @param userEntry The entry for the user for which to make
|
* the determination.
|
* @param examinedGroups A set of groups that have already been
|
* examined in the process of making the
|
* determination. This provides a mechanism
|
* to prevent infinite recursion due to
|
* circular references (e.g., two groups
|
* include each other as nested groups).
|
* Each time a group instance is checked,
|
* its DN should be added to the list, and
|
* any DN already contained in the list
|
* should be skipped.
|
*
|
* @return {@code true} if the specified user is currently a member
|
* of this group, or {@code false} if not.
|
*
|
* @throws DirectoryException If a problem occurs while attempting
|
* to make the determination.
|
*/
|
public abstract boolean isMember(Entry userEntry,
|
Set<DN> examinedGroups)
|
throws DirectoryException;
|
|
|
|
/**
|
* Retrieves an iterator that may be used to cursor through the
|
* entries of the members contained in this group. Note that this
|
* is a point-in-time determination, and the caller must not cache
|
* the result. Further, the determination should only include this
|
* group and not members from nested groups.
|
*
|
* @return An iterator that may be used to cursor through the
|
* entries of the members contained in this group.
|
*
|
* @throws DirectoryException If a problem occurs while attempting
|
* to retrieve the set of members.
|
*/
|
public MemberList getMembers()
|
throws DirectoryException
|
{
|
return getMembers(null, null, null);
|
}
|
|
|
|
/**
|
* Retrieves an iterator that may be used to cursor through the
|
* entries of the members contained in this group. It may
|
* optionally retrieve a subset of the member entries based on a
|
* given set of criteria. Note that this is a point-in-time
|
* determination, and the caller must not cache the result.
|
*
|
* @param baseDN The base DN that should be used when determining
|
* whether a given entry will be returned. If this
|
* is {@code null}, then all entries will be
|
* considered in the scope of the criteria.
|
* @param scope The scope that should be used when determining
|
* whether a given entry will be returned. It must
|
* not be {@code null} if the provided base DN is
|
* not {@code null}. The scope will be ignored if
|
* no base DN is provided.
|
* @param filter The filter that should be used when determining
|
* whether a given entry will be returned. If this
|
* is {@code null}, then any entry in the scope of
|
* the criteria will be included in the results.
|
*
|
* @return An iterator that may be used to cursor through the
|
* entries of the members contained in this group.
|
*
|
* @throws DirectoryException If a problem occurs while attempting
|
* to retrieve the set of members.
|
*/
|
public abstract MemberList getMembers(DN baseDN, SearchScope scope,
|
SearchFilter filter)
|
throws DirectoryException;
|
|
|
|
/**
|
* Indicates whether it is possible to alter the member list for
|
* this group (e.g., in order to add members to the group or remove
|
* members from it).
|
*
|
* @return {@code true} if it is possible to add members to this
|
* group, or {@code false} if not.
|
*/
|
public abstract boolean mayAlterMemberList();
|
|
|
|
/**
|
* Attempt to make multiple changes to the group's member list.
|
*
|
* @param modifications The list of modifications being made to the group,
|
* which may include changes to non-member attributes.
|
* @throws UnsupportedOperationException If this group does not support
|
* altering the member list.
|
* @throws DirectoryException If a problem occurs while attempting to
|
* update the members.
|
*/
|
public abstract void updateMembers(List<Modification> modifications)
|
throws UnsupportedOperationException, DirectoryException;
|
|
|
|
/**
|
* Attempts to add the provided user as a member of this group. The
|
* change should be committed to persistent storage through an
|
* internal operation.
|
*
|
* @param userEntry The entry for the user to be added as a member
|
* of this group.
|
*
|
* @throws UnsupportedOperationException If this group does not
|
* support altering the
|
* member list.
|
*
|
* @throws DirectoryException If a problem occurs while attempting
|
* to add the provided user as a member
|
* of this group.
|
*/
|
public abstract void addMember(Entry userEntry)
|
throws UnsupportedOperationException, DirectoryException;
|
|
|
|
/**
|
* Attempts to remove the specified user as a member of this group.
|
* The change should be committed to persistent storage through an
|
* internal operation.
|
*
|
* @param userDN The DN of the user to remove as a member of this
|
* group.
|
*
|
* @throws UnsupportedOperationException If this group does not
|
* support altering the
|
* member list.
|
*
|
* @throws DirectoryException If a problem occurs while attempting
|
* to remove the provided user as a
|
* member of this group.
|
*/
|
public abstract void removeMember(DN userDN)
|
throws UnsupportedOperationException, DirectoryException;
|
|
|
|
/**
|
* Retrieves a string representation of this group.
|
*
|
* @return A string representation of this group.
|
*/
|
public String toString()
|
{
|
StringBuilder buffer = new StringBuilder();
|
toString(buffer);
|
return buffer.toString();
|
}
|
|
|
|
/**
|
* Appends a string representation of this group to the provided
|
* buffer.
|
*
|
* @param buffer The buffer to which the string representation
|
* should be appended.
|
*/
|
public abstract void toString(StringBuilder buffer);
|
}
|