mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Yannick Lecaillez
29.48.2016 9020a676bbe359cb158e96761ef6f1a3c32c80e5
opendj-server-legacy/src/main/java/org/forgerock/opendj/adapter/server3x/Adapters.java
@@ -17,6 +17,8 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import org.forgerock.opendj.ldap.AbstractSynchronousConnection;
import org.forgerock.opendj.ldap.ByteString;
@@ -51,17 +53,19 @@
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.util.promise.Promise;
import org.forgerock.util.promise.PromiseImpl;
import org.opends.server.core.AddOperation;
import org.opends.server.core.BindOperation;
import org.opends.server.core.CompareOperation;
import org.opends.server.core.DeleteOperation;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ExtendedOperation;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchListener;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.internal.Requests;
import org.opends.server.types.AuthenticationInfo;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.OperationType;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchResultReference;
@@ -69,7 +73,6 @@
import static org.forgerock.opendj.adapter.server3x.Converters.*;
import static org.forgerock.opendj.ldap.ByteString.*;
import static org.forgerock.opendj.ldap.LdapException.*;
import static org.forgerock.util.promise.Promises.*;
/** This class provides a connection factory and an adapter for the OpenDJ 2.x server. */
public final class Adapters {
@@ -90,33 +93,6 @@
    }
    /**
     * Returns a new anonymous connection factory.
     *
     * @return A new anonymous connection factory.
     */
    public static ConnectionFactory newAnonymousConnectionFactory() {
        InternalClientConnection icc = new InternalClientConnection(new AuthenticationInfo());
        return newConnectionFactory(icc);
    }
    /**
     * Returns a new connection factory for a specified user.
     *
     * @param userDN
     *            The specified user's DN.
     * @return a new connection factory.
     */
    public static ConnectionFactory newConnectionFactoryForUser(final DN userDN) {
        InternalClientConnection icc = null;
        try {
            icc = new InternalClientConnection(userDN);
        } catch (DirectoryException e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
        return newConnectionFactory(icc);
    }
    /**
     * Returns a new connection factory.
     *
     * @param icc
@@ -125,7 +101,6 @@
     */
    public static ConnectionFactory newConnectionFactory(final InternalClientConnection icc) {
        return new ConnectionFactory() {
            @Override
            public void close() {
                // Nothing to do.
@@ -133,8 +108,30 @@
            @Override
            public Promise<Connection, LdapException> getConnectionAsync() {
                // TODO change the path...
                return newResultPromise(newConnection(icc));
                final PromiseImpl<Connection, LdapException> promise = PromiseImpl.create();
                try
                {
                  DirectoryServer.getWorkQueue().submitOperation(new AsyncOperation<>(icc, new Runnable()
                  {
                    @Override
                    public void run()
                    {
                      try
                      {
                        promise.handleResult(getConnection());
                      }
                      catch (LdapException e)
                      {
                        promise.handleException(e);
                      }
                    }
                  }));
                }
                catch (DirectoryException e)
                {
                  promise.handleException(LdapException.newLdapException(e.getResultCode()));
                }
                return promise;
            }
            @Override
@@ -144,214 +141,234 @@
        };
    }
    /**
     * Returns a new root connection.
     *
     * @return A new root connection.
     */
    public static Connection newRootConnection() {
        return newConnection(InternalClientConnection.getRootConnection());
    }
    /**
     * Returns a new connection for an anonymous user.
     *
     * @return A new connection.
     */
    public static Connection newAnonymousConnection() {
        return newConnection(new InternalClientConnection(new AuthenticationInfo()));
    }
    /**
     * Returns a new connection for a specified user.
     *
     * @param dn
     *            The DN of the user.
     * @return A new connection for a specified user.
     * @throws LdapException
     *             If no such object.
     */
    public static Connection newConnectionForUser(final DN dn) throws LdapException {
        try {
            return newConnection(new InternalClientConnection(dn));
        } catch (DirectoryException e) {
            throw newLdapException(Responses.newResult(ResultCode.NO_SUCH_OBJECT));
        }
    }
    private static Connection newConnection(final InternalClientConnection icc) {
        return new AbstractSynchronousConnection() {
      return new AbstractSynchronousConnection() {
            @Override
            public Result search(final SearchRequest request, final SearchResultHandler handler)
                    throws LdapException {
                InternalSearchListener internalSearchListener = new InternalSearchListener() {
          @Override
          public Result search(final SearchRequest request, final SearchResultHandler handler)
                  throws LdapException {
              InternalSearchListener internalSearchListener = new InternalSearchListener() {
                    @Override
                    public void handleInternalSearchReference(
                            InternalSearchOperation searchOperation,
                            SearchResultReference searchReference) throws DirectoryException {
                        handler.handleReference(from(searchReference));
                    }
                  @Override
                  public void handleInternalSearchReference(
                          InternalSearchOperation searchOperation,
                          SearchResultReference searchReference) throws DirectoryException {
                      handler.handleReference(from(searchReference));
                  }
                    @Override
                    public void handleInternalSearchEntry(InternalSearchOperation searchOperation,
                            SearchResultEntry searchEntry) throws DirectoryException {
                        handler.handleEntry(from(searchEntry));
                    }
                };
                  @Override
                  public void handleInternalSearchEntry(InternalSearchOperation searchOperation,
                          SearchResultEntry searchEntry) throws DirectoryException {
                      handler.handleEntry(from(searchEntry));
                  }
              };
                final SearchFilter filter = toSearchFilter(request.getFilter());
                final org.opends.server.protocols.internal.SearchRequest sr =
                    Requests.newSearchRequest(request.getName(), request.getScope(), filter)
                        .setDereferenceAliasesPolicy(request.getDereferenceAliasesPolicy())
                        .setSizeLimit(request.getSizeLimit())
                        .setTimeLimit(request.getTimeLimit())
                        .setTypesOnly(request.isTypesOnly())
                        .addAttribute(request.getAttributes())
                        .addControl(to(request.getControls()));
                return getResponseResult(icc.processSearch(sr, internalSearchListener));
            }
              final SearchFilter filter = toSearchFilter(request.getFilter());
              final org.opends.server.protocols.internal.SearchRequest sr =
                  Requests.newSearchRequest(request.getName(), request.getScope(), filter)
                      .setDereferenceAliasesPolicy(request.getDereferenceAliasesPolicy())
                      .setSizeLimit(request.getSizeLimit())
                      .setTimeLimit(request.getTimeLimit())
                      .setTypesOnly(request.isTypesOnly())
                      .addAttribute(request.getAttributes())
                      .addControl(to(request.getControls()));
              return getResponseResult(icc.processSearch(sr, internalSearchListener));
          }
            @Override
            public void removeConnectionEventListener(ConnectionEventListener listener) {
                // Internal client connection don't have any connection events.
            }
          @Override
          public void removeConnectionEventListener(ConnectionEventListener listener) {
              // Internal client connection don't have any connection events.
          }
            @Override
            public Result modifyDN(final ModifyDNRequest request) throws LdapException {
                return getResponseResult(icc.processModifyDN(request));
            }
          @Override
          public Result modifyDN(final ModifyDNRequest request) throws LdapException {
              return getResponseResult(icc.processModifyDN(request));
          }
            @Override
            public Result modify(final ModifyRequest request) throws LdapException {
                return getResponseResult(icc.processModify(request));
            }
          @Override
          public Result modify(final ModifyRequest request) throws LdapException {
              return getResponseResult(icc.processModify(request));
          }
            @Override
            public boolean isValid() {
                // Always true.
                return true;
            }
          @Override
          public boolean isValid() {
              // Always true.
              return true;
          }
            @Override
            public boolean isClosed() {
                return false;
            }
          @Override
          public boolean isClosed() {
              return false;
          }
            @Override
            public <R extends ExtendedResult> R extendedRequest(final ExtendedRequest<R> request,
                    final IntermediateResponseHandler handler) throws LdapException {
          @Override
          public <R extends ExtendedResult> R extendedRequest(final ExtendedRequest<R> request,
                  final IntermediateResponseHandler handler) throws LdapException {
                final ExtendedOperation extendedOperation =
                        icc.processExtendedOperation(request.getOID(), request.getValue(),
                                to(request.getControls()));
              final ExtendedOperation extendedOperation =
                      icc.processExtendedOperation(request.getOID(), request.getValue(),
                              to(request.getControls()));
                final Result result = getResponseResult(extendedOperation);
                final GenericExtendedResult genericExtendedResult =
                        Responses.newGenericExtendedResult(result.getResultCode())
                                .setDiagnosticMessage(result.getDiagnosticMessage()).setMatchedDN(
                                        result.getMatchedDN()).setValue(
                                        extendedOperation.getResponseValue().toByteString());
                try {
                    R extendedResult =
                            request.getResultDecoder().decodeExtendedResult(genericExtendedResult,
                                    new DecodeOptions());
                    for (final Control control : result.getControls()) {
                        extendedResult.addControl(control);
                    }
                    return extendedResult;
              final Result result = getResponseResult(extendedOperation);
              final GenericExtendedResult genericExtendedResult =
                      Responses.newGenericExtendedResult(result.getResultCode())
                              .setDiagnosticMessage(result.getDiagnosticMessage()).setMatchedDN(
                                      result.getMatchedDN()).setValue(
                                      extendedOperation.getResponseValue().toByteString());
              try {
                  R extendedResult =
                          request.getResultDecoder().decodeExtendedResult(genericExtendedResult,
                                  new DecodeOptions());
                  for (final Control control : result.getControls()) {
                      extendedResult.addControl(control);
                  }
                  return extendedResult;
                } catch (DecodeException e) {
                    DN matchedDN = extendedOperation.getMatchedDN();
                    return request.getResultDecoder().newExtendedErrorResult(
                            extendedOperation.getResultCode(),
                            matchedDN != null ? matchedDN.toString() : null,
                            extendedOperation.getErrorMessage().toString());
                }
            }
              } catch (DecodeException e) {
                  DN matchedDN = extendedOperation.getMatchedDN();
                  return request.getResultDecoder().newExtendedErrorResult(
                          extendedOperation.getResultCode(),
                          matchedDN != null ? matchedDN.toString() : null,
                          extendedOperation.getErrorMessage().toString());
              }
          }
            @Override
            public Result delete(final DeleteRequest request) throws LdapException {
                final DeleteOperation deleteOperation =
                        icc.processDelete(valueOfObject(request.getName()), to(request.getControls()));
                return getResponseResult(deleteOperation);
            }
          @Override
          public Result delete(final DeleteRequest request) throws LdapException {
              final DeleteOperation deleteOperation =
                      icc.processDelete(valueOfObject(request.getName()), to(request.getControls()));
              return getResponseResult(deleteOperation);
          }
            @Override
            public CompareResult compare(final CompareRequest request) throws LdapException {
                final CompareOperation compareOperation =
                        icc.processCompare(valueOfObject(request.getName()),
                                request.getAttributeDescription().toString(),
                                request.getAssertionValue(), to(request.getControls()));
          @Override
          public CompareResult compare(final CompareRequest request) throws LdapException {
              final CompareOperation compareOperation =
                      icc.processCompare(valueOfObject(request.getName()),
                              request.getAttributeDescription().toString(),
                              request.getAssertionValue(), to(request.getControls()));
                CompareResult result = Responses.newCompareResult(compareOperation.getResultCode());
                return getResponseResult(compareOperation, result);
            }
              CompareResult result = Responses.newCompareResult(compareOperation.getResultCode());
              return getResponseResult(compareOperation, result);
          }
            @Override
            public void close(final UnbindRequest request, final String reason) {
                // no implementation in open-ds.
            }
          @Override
          public void close(final UnbindRequest request, final String reason) {
              // no implementation in open-ds.
          }
            @Override
            public BindResult bind(final BindRequest request) throws LdapException {
                BindOperation bindOperation = null;
                if (request instanceof SimpleBindRequest) {
                    bindOperation =
                            icc.processSimpleBind(valueOfUtf8(request.getName()),
                                    ByteString.wrap(((SimpleBindRequest) request).getPassword()),
                                    to(request.getControls()));
                } else if (request instanceof SASLBindRequest) {
                    String serverName = null;
                    try {
                        serverName = InetAddress.getByName(null).getCanonicalHostName();
                    } catch (UnknownHostException e) {
                        // nothing to do.
                    }
                    BindClient bindClient = request.createBindClient(serverName);
                    do {
                        final GenericBindRequest genericBindRequest = bindClient.nextBindRequest();
                        bindOperation =
                                icc.processSASLBind(
                                        valueOfUtf8(request.getName()),
                                        ((SASLBindRequest) request).getSASLMechanism(),
                                        getCredentials(genericBindRequest.getAuthenticationValue()),
                                        to(request.getControls()));
                    } while (bindOperation.getResultCode() == ResultCode.SASL_BIND_IN_PROGRESS);
          @Override
          public BindResult bind(final BindRequest request) throws LdapException {
              BindOperation bindOperation = null;
              if (request instanceof SimpleBindRequest) {
                  bindOperation =
                          icc.processSimpleBind(valueOfUtf8(request.getName()),
                                  ByteString.wrap(((SimpleBindRequest) request).getPassword()),
                                  to(request.getControls()));
              } else if (request instanceof SASLBindRequest) {
                  String serverName = null;
                  try {
                      serverName = InetAddress.getByName(null).getCanonicalHostName();
                  } catch (UnknownHostException e) {
                      // nothing to do.
                  }
                  BindClient bindClient = request.createBindClient(serverName);
                  do {
                      final GenericBindRequest genericBindRequest = bindClient.nextBindRequest();
                      bindOperation =
                              icc.processSASLBind(
                                      valueOfUtf8(request.getName()),
                                      ((SASLBindRequest) request).getSASLMechanism(),
                                      getCredentials(genericBindRequest.getAuthenticationValue()),
                                      to(request.getControls()));
                  } while (bindOperation.getResultCode() == ResultCode.SASL_BIND_IN_PROGRESS);
                    bindClient.dispose();
                  bindClient.dispose();
                } else { // not supported
                    throw newLdapException(Responses.newResult(ResultCode.AUTH_METHOD_NOT_SUPPORTED));
                }
                BindResult result = Responses.newBindResult(bindOperation.getResultCode());
                result.setServerSASLCredentials(bindOperation.getSASLCredentials());
              } else { // not supported
                  throw newLdapException(Responses.newResult(ResultCode.AUTH_METHOD_NOT_SUPPORTED));
              }
              BindResult result = Responses.newBindResult(bindOperation.getResultCode());
              result.setServerSASLCredentials(bindOperation.getSASLCredentials());
                if (result.isSuccess()) {
                    return result;
                } else {
                    throw newLdapException(result);
                }
            }
              if (result.isSuccess()) {
                  return result;
              } else {
                  throw newLdapException(result);
              }
          }
            @Override
            public void addConnectionEventListener(ConnectionEventListener listener) {
                // Internal client connection don't have any connection events.
            }
          @Override
          public void addConnectionEventListener(ConnectionEventListener listener) {
              // Internal client connection don't have any connection events.
          }
            @Override
            public Result add(final AddRequest request) throws LdapException {
                final AddOperation addOperation =
                        icc.processAdd(valueOfObject(request.getName()), to(request
                                .getAllAttributes()), to(request.getControls()));
                return getResponseResult(addOperation);
            }
          @Override
          public Result add(final AddRequest request) throws LdapException {
              final AddOperation addOperation =
                      icc.processAdd(valueOfObject(request.getName()), to(request
                              .getAllAttributes()), to(request.getControls()));
              return getResponseResult(addOperation);
          }
            @Override
            public String toString() {
                return icc.toString();
            }
        };
          @Override
          public String toString() {
              return icc.toString();
          }
      };
  }
  /**
   * This operation is hack to be able to execute a {@link Runnable} in a
   * Directory Server's worker thread.
   */
  private static final class AsyncOperation<V> extends org.opends.server.types.AbstractOperation
  {
    private final Runnable runnable;
    AsyncOperation(InternalClientConnection icc, Runnable runnable)
    {
      super(icc, icc.nextOperationID(), icc.nextMessageID(), Collections.<org.opends.server.types.Control> emptyList());
      this.setInternalOperation(true);
      this.runnable = runnable;
    }
    @Override
    public void run()
    {
      runnable.run();
    }
    @Override
    public OperationType getOperationType()
    {
      return null;
    }
    @Override
    public List<org.opends.server.types.Control> getResponseControls()
    {
      return Collections.emptyList();
    }
    @Override
    public void addResponseControl(org.opends.server.types.Control control)
    {
    }
    @Override
    public void removeResponseControl(org.opends.server.types.Control control)
    {
    }
    @Override
    public DN getProxiedAuthorizationDN()
    {
      return null;
    }
    @Override
    public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
    {
    }
    @Override
    public void toString(StringBuilder buffer)
    {
      buffer.append(AsyncOperation.class.getSimpleName());
    }
  }
}