From 4ca3aeae275bca076f4b1302a12c4d70483b4670 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Thu, 21 Dec 2006 18:31:02 +0000
Subject: [PATCH] Add the base API that may be used for interacting with groups within the server.  This is a very bare-bones API at the moment and is primarily intended to allow development of code that depends on the ability to make membership determinations (e.g., the access control subsystem).  A more thorough API and specific implementations will be added later.

---
 opendj-sdk/opends/src/server/org/opends/server/api/ClientConnection.java      |   78 ++++++
 opendj-sdk/opends/src/server/org/opends/server/types/MemberList.java          |  116 +++++++++
 opendj-sdk/opends/src/server/org/opends/server/types/MembershipException.java |  186 +++++++++++++++
 opendj-sdk/opends/src/server/org/opends/server/api/Group.java                 |  318 ++++++++++++++++++++++++++
 4 files changed, 698 insertions(+), 0 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/api/ClientConnection.java b/opendj-sdk/opends/src/server/org/opends/server/api/ClientConnection.java
index 41fd2ca..b689c53 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/api/ClientConnection.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/api/ClientConnection.java
@@ -31,6 +31,7 @@
 import java.net.InetAddress;
 import java.nio.ByteBuffer;
 import java.util.Collection;
+import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.opends.server.api.plugin.IntermediateResponsePluginResult;
@@ -42,6 +43,7 @@
 import org.opends.server.types.AuthenticationInfo;
 import org.opends.server.types.CancelRequest;
 import org.opends.server.types.CancelResult;
+import org.opends.server.types.DirectoryException;
 import org.opends.server.types.DisconnectReason;
 import org.opends.server.types.IntermediateResponse;
 import org.opends.server.types.SearchResultEntry;
@@ -909,6 +911,82 @@
 
 
   /**
+   * Indicates whether the user associated with this client connection
+   * should be considered a member of the specified group, optionally
+   * evaluated within the context of the provided operation.  If an
+   * operation is given, then the determination should be made based
+   * on the authorization identity for that operation.  If the
+   * operation is {@code null}, then the determination should be made
+   * based on the authorization identity for this client connection.
+   * Note that this is a point-in-time determination and the caller
+   * must not cache the result.
+   *
+   * @param  group      The group for which to make the determination.
+   * @param  operation  The operation to use to obtain the
+   *                    authorization identity for which to make the
+   *                    determination, or {@code null} if the
+   *                    authorization identity should be obtained from
+   *                    this client connection.
+   *
+   * @return  {@code true} if the target user is currently a member of
+   *          the specified group, or {@code false} if not.
+   *
+   * @throws  DirectoryException  If a problem occurs while attempting
+   *                             to make the determination.
+   */
+  public boolean isMemberOf(Group group, Operation operation)
+         throws DirectoryException
+  {
+    assert debugEnter(CLASS_NAME, "isMemberOf", String.valueOf(group),
+                      String.valueOf(operation));
+
+    if (operation == null)
+    {
+      return group.isMember(authenticationInfo.getAuthorizationDN());
+    }
+    else
+    {
+      return group.isMember(operation.getAuthorizationDN());
+    }
+  }
+
+
+
+  /**
+   * Retrieves the set of groups in which the user associated with
+   * this client connection may be considered to be a member.  If an
+   * operation is provided, then the determination should be made
+   * based on the authorization identity for that operation.  If the
+   * operation is {@code null}, then it should be made based on the
+   * authorization identity for this client connection.  Note that
+   * this is a point-in-time determination and the caller must not
+   * cache the result.
+   *
+   * @param  operation  The operation to use to obtain the
+   *                    authorization identity for which to retrieve
+   *                    the associated groups, or {@code null} if the
+   *                    authorization identity should be obtained from
+   *                    this client connection.
+   *
+   * @return  The set of groups in which the target user is currently
+   *          a member.
+   *
+   * @throws  DirectoryException  If a problem occurs while attempting
+   *                              to make the determination.
+   */
+  public Set<Group> getGroups(Operation operation)
+         throws DirectoryException
+  {
+    assert debugEnter(CLASS_NAME, "getGroups",
+                      String.valueOf(operation));
+
+    // NYI -- Add a mechanism for making this determination.
+    return java.util.Collections.<Group>emptySet();
+  }
+
+
+
+  /**
    * Retrieves a string representation of this client connection.
    *
    * @return  A string representation of this client connection.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/api/Group.java b/opendj-sdk/opends/src/server/org/opends/server/api/Group.java
new file mode 100644
index 0000000..5cab90a
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/api/Group.java
@@ -0,0 +1,318 @@
+/*
+ * 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 Sun Microsystems, Inc.
+ */
+package org.opends.server.api;
+
+
+
+import java.util.List;
+
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.DN;
+import org.opends.server.types.Entry;
+import org.opends.server.types.MemberList;
+import org.opends.server.types.SearchFilter;
+import org.opends.server.types.SearchScope;
+
+import static org.opends.server.loggers.Debug.*;
+
+
+
+/**
+ * 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>
+ */
+public abstract class Group
+{
+  /**
+   * The fully-qualified name of this class for debugging purposes.
+   */
+  private static final String CLASS_NAME =
+       "org.opends.server.api.Group";
+
+
+
+  /**
+   * 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();
+
+
+
+  /**
+   * 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 abstract boolean isMember(DN userDN)
+         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 abstract boolean isMember(Entry userEntry)
+         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.
+   *
+   * @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
+  {
+    assert debugEnter(CLASS_NAME, "getMembers");
+
+    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();
+
+
+
+  /**
+   * 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()
+  {
+    assert debugEnter(CLASS_NAME, "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);
+}
+
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/MemberList.java b/opendj-sdk/opends/src/server/org/opends/server/types/MemberList.java
new file mode 100644
index 0000000..52e94cf
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/MemberList.java
@@ -0,0 +1,116 @@
+/*
+ * 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 Sun Microsystems, Inc.
+ */
+package org.opends.server.types;
+
+
+
+import static org.opends.server.loggers.Debug.*;
+
+
+
+/**
+ * This class defines a mechanism that may be used to iterate over the
+ * members of a group.  It uses an interface that is similar to that
+ * of {@code java.util.Iterator}, but is specific to group membership
+ * and that provides the ability to throw an exception when attempting
+ * to retrieve the next member (e.g., if the group contains a
+ * malformed DN or references a member that doesn't exist).
+ */
+public abstract class MemberList
+{
+  /**
+   * The fully-qualified name of this class for debugging purposes.
+   */
+  private static final String CLASS_NAME =
+       "org.opends.server.types.MemberList";
+
+
+
+  /**
+   * Indicates whether the group contains any more members.
+   *
+   * @return  {@code true} if the group has at least one more member,
+   *          or {@code false} if not.
+   */
+  public abstract boolean hasMoreMembers();
+
+
+
+  /**
+   * Retrieves the DN of the next group member.
+   *
+   * @return  The DN of the next group member, or {@code null} if
+   *          there are no more members.
+   *
+   * @throws  MembershipException  If a problem occurs while
+   *                               attempting to retrieve the next
+   *                               member DN.
+   */
+  public DN nextMemberDN()
+         throws MembershipException
+  {
+    assert debugEnter(CLASS_NAME, "nextMemberDN");
+
+    Entry e = nextMemberEntry();
+    if (e == null)
+    {
+      return null;
+    }
+    else
+    {
+      return e.getDN();
+    }
+  }
+
+
+
+  /**
+   * Retrieves the entry for the next group member.
+   *
+   * @return  The entry for the next group member, or {@code null} if
+   *          there are no more members.
+   *
+   * @throws  MembershipException  If a problem occurs while
+   *                               attempting to retrieve the next
+   *                               entry.
+   */
+  public abstract Entry nextMemberEntry()
+         throws MembershipException;
+
+
+
+  /**
+   * Indicates that this member list is no longer required and that
+   * the server may clean up any resources that may have been used in
+   * the course of processing.  This method must be called if the
+   * caller wishes to stop iterating across the member list before the
+   * end has been reached, although it will not be necessary if the
+   * call to {@code hasMoreMembers} returns {@code false}.
+   */
+  public abstract void close();
+}
+
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/MembershipException.java b/opendj-sdk/opends/src/server/org/opends/server/types/MembershipException.java
new file mode 100644
index 0000000..358cf1c
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/MembershipException.java
@@ -0,0 +1,186 @@
+/*
+ * 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 Sun Microsystems, Inc.
+ */
+package org.opends.server.types;
+
+
+
+import static org.opends.server.loggers.Debug.*;
+
+
+
+/**
+ * This class defines an exception that may be thrown if a problem
+ * occurs while attempting to iterate across the members of a group.
+ */
+public class MembershipException
+       extends Exception
+{
+  /**
+   * The fully-qualified name of this class for debugging purposes.
+   */
+  private static final String CLASS_NAME =
+       "org.opends.server.types.MembershipException";
+
+
+
+  /**
+   * The serial version identifier required to satisfy the compiler
+   * because this class extends <CODE>java.lang.Exception</CODE>,
+   * which implements the <CODE>java.io.Serializable</CODE> interface.
+   * This value was generated using the <CODE>serialver</CODE>
+   * command-line utility included with the Java SDK.
+   */
+  private static final long serialVersionUID = -7312072056288770065L;
+
+
+
+  /**
+   * Indicates whether it is possible to continue iterating through
+   * the list of group members.
+   */
+  private final boolean continueIterating;
+
+
+
+  /**
+   * The unique identifier for the error message.
+   */
+  private final int errorMessageID;
+
+
+
+  /**
+   * The error message for this membership exception.
+   */
+  private final String errorMessage;
+
+
+
+  /**
+   * Creates a new membership exception with the provided information.
+   *
+   * @param  errorMessageID     The unique identifier for the error
+   *                            message.
+   * @param  errorMessage       The error message for this membership
+   *                            exception.
+   * @param  continueIterating  Indicates whether it is possible to
+   *                            continue iterating through the list of
+   *                            group members.
+   */
+  public MembershipException(int errorMessageID, String errorMessage,
+                             boolean continueIterating)
+  {
+    super(errorMessage);
+
+    assert debugConstructor(CLASS_NAME,
+                            String.valueOf(errorMessageID),
+                            String.valueOf(errorMessage),
+                            String.valueOf(continueIterating));
+
+    this.errorMessageID    = errorMessageID;
+    this.errorMessage      = errorMessage;
+    this.continueIterating = continueIterating;
+  }
+
+
+
+  /**
+   * Creates a new membership exception with the provided information.
+   *
+   * @param  errorMessageID     The unique identifier for the error
+   *                            message.
+   * @param  errorMessage       The error message for this membership
+   *                            exception.
+   * @param  continueIterating  Indicates whether it is possible to
+   *                            continue iterating through the list of
+   *                            group members.
+   * @param  cause              The underlying cause for this
+   *                            membership exception.
+   */
+  public MembershipException(int errorMessageID, String errorMessage,
+                             boolean continueIterating,
+                             Throwable cause)
+  {
+    super(errorMessage, cause);
+
+    assert debugConstructor(CLASS_NAME,
+                            String.valueOf(errorMessageID),
+                            String.valueOf(errorMessage),
+                            String.valueOf(continueIterating),
+                            String.valueOf(cause));
+
+    this.errorMessageID    = errorMessageID;
+    this.errorMessage      = errorMessage;
+    this.continueIterating = continueIterating;
+  }
+
+
+
+  /**
+   * Retrieves the unique identifier for the error message.
+   *
+   * @return  The unique identifier for the error message.
+   */
+  public final int getErrorMessageID()
+  {
+    assert debugEnter(CLASS_NAME, "getErrorMessageID");
+
+    return errorMessageID;
+  }
+
+
+
+  /**
+   * Retrieves the error message for this membership exception.
+   *
+   * @return  The error message for this membership exception.
+   */
+  public final String getErrorMessage()
+  {
+    assert debugEnter(CLASS_NAME, "getErrorMessage");
+
+    return errorMessage;
+  }
+
+
+
+  /**
+   * Indicates whether it is possible to continue iterating through
+   * the list of group members.
+   *
+   * @return  {@code true} if it is possible to continue iterating
+   *          through the list of group members, or {@code false} if
+   *          not.
+   */
+  public final boolean continueIterating()
+  {
+    assert debugEnter(CLASS_NAME, "continueIterating");
+
+    return continueIterating;
+  }
+}
+

--
Gitblit v1.10.0