From 392bde20d260cc00dbdf5c80d512f57ebc760c4e Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Mon, 16 Nov 2015 16:49:54 +0000
Subject: [PATCH] OPENDJ-2383 REST interface: Implement password modify action

---
 opendj-server-legacy/src/main/java/org/opends/server/protocols/http/LdapHttpApplication.java            |   17 +++++++-
 opendj-server-legacy/src/main/java/org/forgerock/opendj/adapter/server3x/Converters.java                |   43 +++++++++++++++++++--
 opendj-server-legacy/src/main/java/org/opends/server/protocols/http/SdkConnectionAdapter.java           |    7 ++-
 opendj-server-legacy/src/main/java/org/opends/server/protocols/http/CollectClientConnectionsFilter.java |    4 +
 4 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/forgerock/opendj/adapter/server3x/Converters.java b/opendj-server-legacy/src/main/java/org/forgerock/opendj/adapter/server3x/Converters.java
index 5923154..e6b1daa 100644
--- a/opendj-server-legacy/src/main/java/org/forgerock/opendj/adapter/server3x/Converters.java
+++ b/opendj-server-legacy/src/main/java/org/forgerock/opendj/adapter/server3x/Converters.java
@@ -25,7 +25,11 @@
  */
 package org.forgerock.opendj.adapter.server3x;
 
+import static com.forgerock.opendj.ldap.CoreMessages.*;
+import static com.forgerock.opendj.util.StaticUtils.*;
+
 import static org.forgerock.opendj.ldap.LdapException.*;
+import static org.opends.server.extensions.ExtensionsConstants.*;
 import static org.opends.server.util.CollectionUtils.*;
 
 import java.io.IOException;
@@ -51,6 +55,7 @@
 import org.forgerock.opendj.ldap.SearchScope;
 import org.forgerock.opendj.ldap.controls.Control;
 import org.forgerock.opendj.ldap.controls.GenericControl;
+import org.forgerock.opendj.ldap.responses.PasswordModifyExtendedResult;
 import org.forgerock.opendj.ldap.responses.Responses;
 import org.forgerock.opendj.ldap.responses.Result;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
@@ -70,10 +75,9 @@
 import org.opends.server.types.LDAPException;
 import org.opends.server.types.Operation;
 import org.opends.server.types.SearchFilter;
+import org.opends.server.util.ServerConstants;
 
-/**
- * Common utility methods.
- */
+/** Common utility methods. */
 public final class Converters {
 
     /** Prevent instantiation. */
@@ -691,18 +695,47 @@
         return getResponseResult(operation, newSDKResult(operation));
     }
 
-    private static Result newSDKResult(final Operation operation) {
+    private static Result newSDKResult(final Operation operation) throws LdapException {
         ResultCode rc = operation.getResultCode();
         if (operation instanceof BindOperation) {
             return Responses.newBindResult(rc);
         } else if (operation instanceof CompareOperation) {
             return Responses.newCompareResult(rc);
         } else if (operation instanceof ExtendedOperation) {
-            return Responses.newGenericExtendedResult(rc);
+            ExtendedOperation extendedOperation = (ExtendedOperation) operation;
+            switch (extendedOperation.getRequestOID()) {
+            case ServerConstants.OID_PASSWORD_MODIFY_REQUEST:
+                PasswordModifyExtendedResult result = Responses.newPasswordModifyExtendedResult(rc);
+                ByteString generatedPwd = getGeneratedPassword(extendedOperation);
+                if (generatedPwd != null) {
+                    result.setGeneratedPassword(generatedPwd.toByteArray());
+                }
+                return result;
+
+            default:
+                return Responses.newGenericExtendedResult(rc);
+            }
         }
         return Responses.newResult(rc);
     }
 
+    private static ByteString getGeneratedPassword(ExtendedOperation op) throws LdapException {
+        // FIXME this code is duplicated with code in the SDK
+        // see PasswordModifyExtendedRequestImpl#ResultDecoder#decodeExtendedResult()
+        ByteString responseValue = op.getResponseValue();
+        if (responseValue != null) {
+            try {
+                ASN1Reader reader = ASN1.getReader(responseValue);
+                reader.readStartSequence();
+                return reader.readOctetString(TYPE_PASSWORD_MODIFY_GENERATED_PASSWORD);
+            } catch (IOException e) {
+                throw LdapException.newLdapException(ResultCode.PROTOCOL_ERROR,
+                        ERR_EXTOP_PASSMOD_CANNOT_DECODE_REQUEST.get(getExceptionMessage(e)), e);
+            }
+        }
+        return null;
+    }
+
     /**
      * Converts from <code>byte[]</code> to OpenDJ server {@link ByteString}.
      *
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/CollectClientConnectionsFilter.java b/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/CollectClientConnectionsFilter.java
index 77ed319..5ea8110 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/CollectClientConnectionsFilter.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/CollectClientConnectionsFilter.java
@@ -55,6 +55,7 @@
 import org.forgerock.opendj.rest2ldap.AuthenticatedConnectionContext;
 import org.forgerock.opendj.rest2ldap.Rest2LDAP;
 import org.forgerock.services.context.Context;
+import org.forgerock.services.context.SecurityContext;
 import org.forgerock.util.AsyncFunction;
 import org.forgerock.util.promise.NeverThrowsException;
 import org.forgerock.util.promise.Promise;
@@ -230,7 +231,8 @@
         clientConnection.setAuthUser(userName);
         try
         {
-          return doFilter(context, request, next, connection);
+          SecurityContext securityContext = new SecurityContext(context, userName, null);
+          return doFilter(securityContext, request, next, connection);
         }
         catch (Exception e)
         {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/LdapHttpApplication.java b/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/LdapHttpApplication.java
index 4206a8a..0850d8c 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/LdapHttpApplication.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/LdapHttpApplication.java
@@ -43,9 +43,13 @@
 import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.forgerock.json.JsonValue;
 import org.forgerock.json.resource.CollectionResourceProvider;
+import org.forgerock.json.resource.ConnectionFactory;
 import org.forgerock.json.resource.RequestHandler;
+import org.forgerock.json.resource.ResourceException;
+import org.forgerock.json.resource.Resources;
 import org.forgerock.json.resource.Router;
 import org.forgerock.json.resource.http.CrestHttp;
+import org.forgerock.json.resource.http.HttpContextFactory;
 import org.forgerock.opendj.ldap.SearchScope;
 import org.forgerock.opendj.rest2ldap.AuthorizationPolicy;
 import org.forgerock.opendj.rest2ldap.Rest2LDAP;
@@ -63,7 +67,6 @@
   /** Http Handler which sets a connection to an OpenDJ server. */
   private static class LdapHttpHandler implements Handler
   {
-
     private final Handler delegate;
 
     /**
@@ -75,7 +78,15 @@
      */
     public LdapHttpHandler(final JsonValue configuration)
     {
-      delegate = CrestHttp.newHttpHandler(createRouter(configuration));
+      ConnectionFactory connectionFactory = Resources.newInternalConnectionFactory(createRouter(configuration));
+      delegate = CrestHttp.newHttpHandler(connectionFactory, new HttpContextFactory()
+      {
+        @Override
+        public Context createContext(Context parentContext, Request request) throws ResourceException
+        {
+          return parentContext;
+        }
+      });
     }
 
     private RequestHandler createRouter(final JsonValue configuration)
@@ -93,12 +104,12 @@
       }
       return router;
     }
+
     @Override
     public final Promise<Response, NeverThrowsException> handle(final Context context, final Request request)
     {
       return delegate.handle(context, request);
     }
-
   }
 
   private HTTPConnectionHandler connectionHandler;
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/SdkConnectionAdapter.java b/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/SdkConnectionAdapter.java
index f7e2e23..aa03002 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/SdkConnectionAdapter.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/SdkConnectionAdapter.java
@@ -323,9 +323,10 @@
       IntermediateResponseHandler intermediateResponseHandler)
   {
     final int messageID = nextMessageID.getAndIncrement();
-    return enqueueOperation(new ExtendedOperationBasis(this.clientConnection, messageID, messageID,
-        to(request.getControls()), request.getOID(),
-        request.getValue()));
+    ExtendedOperation op = new ExtendedOperationBasis(
+        clientConnection, messageID, messageID, to(request.getControls()), request.getOID(), request.getValue());
+    op.setAuthorizationEntry(clientConnection.getAuthenticationInfo().getAuthorizationEntry());
+    return enqueueOperation(op);
   }
 
   /**

--
Gitblit v1.10.0