opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AbstractRequestHandler.java
@@ -25,6 +25,7 @@ import org.forgerock.json.resource.QueryResourceHandler; import org.forgerock.json.resource.QueryResponse; import org.forgerock.json.resource.ReadRequest; import org.forgerock.json.resource.Request; import org.forgerock.json.resource.RequestHandler; import org.forgerock.json.resource.ResourceException; import org.forgerock.json.resource.ResourceResponse; @@ -34,51 +35,63 @@ /** * An abstract base class from which request handlers may be easily implemented. The default implementation of each * method is to return the {@link ResourceException} passed in during construction. * method is to invoke the {@link #handleRequest(Context, Request)} method. */ abstract class AbstractRequestHandler implements RequestHandler { private final ResourceException defaultErrorResponse; AbstractRequestHandler(final ResourceException defaultErrorResponse) { this.defaultErrorResponse = defaultErrorResponse; public abstract class AbstractRequestHandler implements RequestHandler { /** Creates a new {@code AbstractRequestHandler}. */ protected AbstractRequestHandler() { // Nothing to do. } @Override public Promise<ActionResponse, ResourceException> handleAction(final Context context, final ActionRequest request) { return defaultErrorResponse.asPromise(); return handleRequest(context, request); } @Override public Promise<ResourceResponse, ResourceException> handleCreate(final Context context, final CreateRequest request) { return defaultErrorResponse.asPromise(); return handleRequest(context, request); } @Override public Promise<ResourceResponse, ResourceException> handleDelete(final Context context, final DeleteRequest request) { return defaultErrorResponse.asPromise(); return handleRequest(context, request); } @Override public Promise<ResourceResponse, ResourceException> handlePatch(final Context context, final PatchRequest request) { return defaultErrorResponse.asPromise(); return handleRequest(context, request); } @Override public Promise<QueryResponse, ResourceException> handleQuery(final Context context, final QueryRequest request, final QueryResourceHandler handler) { return defaultErrorResponse.asPromise(); return handleRequest(context, request); } @Override public Promise<ResourceResponse, ResourceException> handleRead(final Context context, final ReadRequest request) { return defaultErrorResponse.asPromise(); return handleRequest(context, request); } @Override public Promise<ResourceResponse, ResourceException> handleUpdate(final Context context, final UpdateRequest request) { return defaultErrorResponse.asPromise(); return handleRequest(context, request); } /** * Implement this method in order to provide a default behavior when processing requests. * * @param <V> * The type of response. * @param context * The request context. * @param request * The request. * @return A {@code Promise} containing the result of the operation. */ protected abstract <V> Promise<V, ResourceException> handleRequest(final Context context, final Request request); } opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReadOnlyRequestHandler.java
@@ -23,6 +23,7 @@ import org.forgerock.json.resource.QueryResourceHandler; import org.forgerock.json.resource.QueryResponse; import org.forgerock.json.resource.ReadRequest; import org.forgerock.json.resource.Request; import org.forgerock.json.resource.RequestHandler; import org.forgerock.json.resource.ResourceException; import org.forgerock.json.resource.ResourceResponse; @@ -36,7 +37,6 @@ private final RequestHandler delegate; ReadOnlyRequestHandler(final RequestHandler delegate) { super(new BadRequestException(ERR_READ_ONLY_ENDPOINT.get().toString())); this.delegate = delegate; } @@ -51,4 +51,9 @@ final Context context, final ReadRequest request) { return delegate.handleRead(context, request); } @Override protected <V> Promise<V, ResourceException> handleRequest(final Context context, final Request request) { return new BadRequestException(ERR_READ_ONLY_ENDPOINT.get().toString()).asPromise(); } } opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LdapHttpApplication.java
@@ -18,6 +18,8 @@ import static org.forgerock.http.handler.HttpClientHandler.OPTION_KEY_MANAGERS; import static org.forgerock.http.handler.HttpClientHandler.OPTION_TRUST_MANAGERS; import static org.forgerock.http.routing.RouteMatchers.newResourceApiVersionBehaviourManager; import static org.forgerock.http.routing.RouteMatchers.resourceApiVersionContextFilter; import static org.forgerock.json.JsonValueFunctions.duration; import static org.forgerock.json.JsonValueFunctions.enumConstant; import static org.forgerock.json.JsonValueFunctions.setOf; @@ -201,7 +203,8 @@ final Filter authorizationFilter = buildAuthorizationFilter(config.get("authorization").required()); return Handlers.chainOf(newHttpHandler(configureRest2Ldap(configDirectory)), new ErrorLoggerFilter(), authorizationFilter); authorizationFilter, resourceApiVersionContextFilter(newResourceApiVersionBehaviourManager())); } catch (final Exception e) { final LocalizableMessage errorMsg = ERR_FAIL_PARSE_CONFIGURATION.get(e.getLocalizedMessage()); logger.error(errorMsg, e); opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LdapJsonConfigurator.java
@@ -40,6 +40,7 @@ import static org.forgerock.opendj.rest2ldap.Rest2Ldap.*; import static org.forgerock.opendj.rest2ldap.Rest2ldapMessages.*; import static org.forgerock.opendj.rest2ldap.Utils.newJsonValueException; import static org.forgerock.util.Utils.joinAsString; import static org.forgerock.util.time.Duration.duration; import java.io.BufferedReader; @@ -64,14 +65,19 @@ import org.forgerock.i18n.LocalizedIllegalArgumentException; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.json.JsonValue; import org.forgerock.json.resource.BadRequestException; import org.forgerock.json.resource.Request; import org.forgerock.json.resource.RequestHandler; import org.forgerock.json.resource.ResourceException; import org.forgerock.json.resource.Router; import org.forgerock.opendj.ldap.ConnectionFactory; import org.forgerock.opendj.ldap.LDAPConnectionFactory; import org.forgerock.opendj.ldap.SSLContextBuilder; import org.forgerock.opendj.ldap.requests.BindRequest; import org.forgerock.opendj.ldap.requests.Requests; import org.forgerock.services.context.Context; import org.forgerock.util.Options; import org.forgerock.util.promise.Promise; import org.forgerock.util.time.Duration; /** Provides core factory methods and builders for constructing Rest2Ldap endpoints from JSON configuration. */ @@ -209,7 +215,6 @@ */ public static Router configureEndpoint(final File endpointDirectory, final Options options) throws IOException { final Router versionRouter = new Router(); final File[] endpointVersions = endpointDirectory.listFiles(new FileFilter() { @Override public boolean accept(final File pathname) { @@ -221,6 +226,8 @@ throw new LocalizedIllegalArgumentException(ERR_INVALID_ENDPOINT_DIRECTORY.get(endpointDirectory)); } final List<String> supportedVersions = new ArrayList<>(); boolean hasWildCardVersion = false; for (final File endpointVersion : endpointVersions) { final JsonValue mappingConfig = readJson(endpointVersion); final String version = mappingConfig.get("version").defaultTo("*").asString(); @@ -234,13 +241,24 @@ if (version.equals("*")) { versionRouter.setDefaultRoute(handler); hasWildCardVersion = true; } else { versionRouter.addRoute(version(version), handler); supportedVersions.add(version); } logger.debug(INFO_REST2LDAP_CREATING_ENDPOINT.get(endpointDirectory.getName(), version)); } if (!hasWildCardVersion) { versionRouter.setDefaultRoute(new AbstractRequestHandler() { @Override protected <V> Promise<V, ResourceException> handleRequest(Context context, Request request) { final String message = ERR_BAD_API_RESOURCE_VERSION.get(request.getResourceVersion(), joinAsString(", ", supportedVersions)) .toString(); return new BadRequestException(message).asPromise(); } }); } return versionRouter; } opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SubResourceCollection.java
@@ -41,6 +41,7 @@ import org.forgerock.json.resource.QueryResourceHandler; import org.forgerock.json.resource.QueryResponse; import org.forgerock.json.resource.ReadRequest; import org.forgerock.json.resource.Request; import org.forgerock.json.resource.RequestHandler; import org.forgerock.json.resource.ResourceException; import org.forgerock.json.resource.ResourceResponse; @@ -356,10 +357,6 @@ * URL template /collection/{id} then this handler processes requests against /collection. */ private final class CollectionHandler extends AbstractRequestHandler { private CollectionHandler() { super(new BadRequestException(ERR_UNSUPPORTED_REQUEST_AGAINST_COLLECTION.get().toString())); } @Override public Promise<ActionResponse, ResourceException> handleAction(final Context context, final ActionRequest request) { @@ -377,6 +374,11 @@ final QueryResourceHandler handler) { return collection(context).query(context, request, handler); } @Override protected <V> Promise<V, ResourceException> handleRequest(final Context context, final Request request) { return new BadRequestException(ERR_UNSUPPORTED_REQUEST_AGAINST_COLLECTION.get().toString()).asPromise(); } } /** opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SubResourceSingleton.java
@@ -35,6 +35,7 @@ import org.forgerock.json.resource.QueryResourceHandler; import org.forgerock.json.resource.QueryResponse; import org.forgerock.json.resource.ReadRequest; import org.forgerock.json.resource.Request; import org.forgerock.json.resource.RequestHandler; import org.forgerock.json.resource.ResourceException; import org.forgerock.json.resource.ResourceResponse; @@ -148,10 +149,6 @@ * both a singleton and also a collection of {child}. */ private final class InstanceHandler extends AbstractRequestHandler { private InstanceHandler() { super(new BadRequestException(ERR_UNSUPPORTED_REQUEST_AGAINST_SINGLETON.get().toString())); } @Override public Promise<ActionResponse, ResourceException> handleAction(final Context context, final ActionRequest request) { @@ -200,6 +197,11 @@ return singleton(context).update(context, null, request); } @Override protected <V> Promise<V, ResourceException> handleRequest(final Context context, final Request request) { return new BadRequestException(ERR_UNSUPPORTED_REQUEST_AGAINST_SINGLETON.get().toString()).asPromise(); } private <T> Function<ResourceException, T, ResourceException> convert404To400() { return SubResource.convert404To400(ERR_UNSUPPORTED_REQUEST_AGAINST_SINGLETON.get()); } opendj-rest2ldap/src/main/resources/org/forgerock/opendj/rest2ldap/rest2ldap.properties
@@ -138,3 +138,5 @@ INFO_REST2LDAP_CREATING_ENDPOINT_81=Rest2Ldap created endpoint '%s' version %s ERR_PASSWORD_RESET_SECURE_CONNECTION_82=Passwords can only be reset using a secure connection ERR_PASSWORD_RESET_USER_AUTHENTICATED_83=Passwords can only be reset by authenticated users ERR_BAD_API_RESOURCE_VERSION_84=The requested resource API version '%s' is unsupported. This endpoint only supports \ the following resource API version(s): %s opendj-server-legacy/src/main/java/org/opends/server/protocols/http/rest2ldap/AdminEndpoint.java
@@ -16,6 +16,10 @@ */ package org.opends.server.protocols.http.rest2ldap; import static org.forgerock.http.handler.Handlers.chainOf; import static org.forgerock.http.routing.RouteMatchers.newResourceApiVersionBehaviourManager; import static org.forgerock.http.routing.RouteMatchers.resourceApiVersionContextFilter; import static org.forgerock.http.routing.Version.version; import static org.forgerock.json.resource.http.CrestHttp.newHttpHandler; import static org.forgerock.opendj.ldap.schema.CoreSchema.getBooleanSyntax; import static org.forgerock.opendj.ldap.schema.CoreSchema.getIntegerSyntax; @@ -24,6 +28,7 @@ import static org.forgerock.opendj.rest2ldap.WritabilityPolicy.READ_ONLY; import static org.forgerock.opendj.rest2ldap.WritabilityPolicy.READ_WRITE; import static org.forgerock.util.Options.defaultOptions; import static org.opends.messages.ConfigMessages.ERR_BAD_ADMIN_API_RESOURCE_VERSION; import java.util.ArrayList; import java.util.Collection; @@ -35,8 +40,13 @@ import org.forgerock.http.HttpApplication; import org.forgerock.http.HttpApplicationException; import org.forgerock.http.io.Buffer; import org.forgerock.http.routing.Version; import org.forgerock.json.JsonPointer; import org.forgerock.json.resource.BadRequestException; import org.forgerock.json.resource.Request; import org.forgerock.json.resource.RequestHandler; import org.forgerock.json.resource.ResourceException; import org.forgerock.json.resource.Router; import org.forgerock.opendj.config.AbstractManagedObjectDefinition; import org.forgerock.opendj.config.AggregationPropertyDefinition; import org.forgerock.opendj.config.DefaultBehaviorProvider; @@ -55,6 +65,7 @@ import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.ldap.Functions; import org.forgerock.opendj.ldap.schema.Syntax; import org.forgerock.opendj.rest2ldap.AbstractRequestHandler; import org.forgerock.opendj.rest2ldap.ReferencePropertyMapper; import org.forgerock.opendj.rest2ldap.Resource; import org.forgerock.opendj.rest2ldap.Rest2Ldap; @@ -64,9 +75,11 @@ import org.forgerock.opendj.server.config.meta.GlobalCfgDefn; import org.forgerock.opendj.server.config.meta.RootCfgDefn; import org.forgerock.opendj.server.config.server.AdminEndpointCfg; import org.forgerock.services.context.Context; import org.forgerock.util.Factory; import org.forgerock.util.Function; import org.forgerock.util.promise.NeverThrowsException; import org.forgerock.util.promise.Promise; import org.opends.server.api.HttpEndpoint; import org.opends.server.core.ServerContext; import org.opends.server.types.InitializationException; @@ -76,6 +89,7 @@ */ public final class AdminEndpoint extends HttpEndpoint<AdminEndpointCfg> { private static final Version ADMIN_API_VERSION = version("1.0"); private static final String TYPE_PROPERTY = "_schema"; private static final String ADMIN_API = "admin-api"; private static final String MONITOR = "monitor"; @@ -165,7 +179,20 @@ final Rest2Ldap rest2Ldap = rest2Ldap(defaultOptions(), resources.values()); final RequestHandler handler = rest2Ldap.newRequestHandlerFor(ADMIN_API); return newHttpHandler(handler); final Router versionRouter = new Router(); versionRouter.addRoute(ADMIN_API_VERSION, handler); versionRouter.setDefaultRoute(new AbstractRequestHandler() { @Override protected <V> Promise<V, ResourceException> handleRequest(final Context context, final Request request) { final String message = ERR_BAD_ADMIN_API_RESOURCE_VERSION.get(request.getResourceVersion(), ADMIN_API_VERSION) .toString(); return new BadRequestException(message).asPromise(); } }); return chainOf(newHttpHandler(versionRouter), resourceApiVersionContextFilter(newResourceApiVersionBehaviourManager())); } private Resource buildResource(final AbstractManagedObjectDefinition<?, ?> mod) opendj-server-legacy/src/main/java/org/opends/server/protocols/http/rest2ldap/Rest2LdapEndpoint.java
@@ -15,6 +15,9 @@ */ package org.opends.server.protocols.http.rest2ldap; import static org.forgerock.http.handler.Handlers.chainOf; import static org.forgerock.http.routing.RouteMatchers.newResourceApiVersionBehaviourManager; import static org.forgerock.http.routing.RouteMatchers.resourceApiVersionContextFilter; import static org.forgerock.json.resource.http.CrestHttp.newHttpHandler; import static org.forgerock.opendj.rest2ldap.Rest2LdapJsonConfigurator.configureEndpoint; import static org.forgerock.util.Options.defaultOptions; @@ -76,7 +79,8 @@ final File endpointConfig = getFileForPath(configuration.getConfigDirectory(), serverContext); try { return newHttpHandler(configureEndpoint(endpointConfig, defaultOptions())); return chainOf(newHttpHandler(configureEndpoint(endpointConfig, defaultOptions())), resourceApiVersionContextFilter(newResourceApiVersionBehaviourManager())); } catch (IOException e) { opendj-server-legacy/src/messages/org/opends/messages/config.properties
@@ -851,3 +851,5 @@ an invalid URL %s: %s ERR_CONFIG_OAUTH2_CONFIG_ERROR_756=Unable to configure the authorization mechanism defined \ in %s: %s ERR_BAD_ADMIN_API_RESOURCE_VERSION_757=The requested admin API version '%s' is unsupported. This endpoint only \ supports the following admin API version(s): %s