From 40c74b5c1aa2fedbaaa77a1f990a08f2a5ac928c Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Tue, 23 Jul 2024 15:21:58 +0200 Subject: [PATCH] Add FeatureService to v2 APIs --- .../server/ca/rest/v2/CAFeatureServlet.java | 20 +++++ .../server/ca/rest/v2/filters/EmptyACL.java | 2 +- .../ca/rest/v2/filters/EmptyAuthMethod.java | 2 +- .../server/rest/v2/FeatureServlet.java | 89 +++++++++++++++++++ 4 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/CAFeatureServlet.java create mode 100644 base/server/src/main/java/org/dogtagpki/server/rest/v2/FeatureServlet.java diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/CAFeatureServlet.java b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/CAFeatureServlet.java new file mode 100644 index 00000000000..6ddaabd6ba2 --- /dev/null +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/CAFeatureServlet.java @@ -0,0 +1,20 @@ +// +// Copyright Red Hat, Inc. +// +// SPDX-License-Identifier: GPL-2.0-or-later +// +package org.dogtagpki.server.ca.rest.v2; + +import javax.servlet.annotation.WebServlet; + +import org.dogtagpki.server.rest.v2.FeatureServlet; + +/** + * @author Marco Fargetta {@literal } + */ +@WebServlet( + name = "caFeature", + urlPatterns = "/v2/config/features/*") +public class CAFeatureServlet extends FeatureServlet { + private static final long serialVersionUID = 1L; +} diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/EmptyACL.java b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/EmptyACL.java index a34c8f3fbca..4d783951fde 100644 --- a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/EmptyACL.java +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/EmptyACL.java @@ -9,7 +9,7 @@ import org.dogtagpki.server.rest.v2.filters.ACLFilter; -@WebFilter(servletNames = {"caInfo", "caCert", "caCertRequest", "caJobs"}) +@WebFilter(servletNames = {"caInfo", "caCert", "caCertRequest", "caJobs", "caFeature"}) public class EmptyACL extends ACLFilter { private static final long serialVersionUID = 1L; diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/EmptyAuthMethod.java b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/EmptyAuthMethod.java index 80926c4024d..0f1ac2c6131 100644 --- a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/EmptyAuthMethod.java +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/EmptyAuthMethod.java @@ -9,7 +9,7 @@ import org.dogtagpki.server.rest.v2.filters.AuthMethodFilter; -@WebFilter(servletNames = {"caInfo", "caCert", "caCertRequest", "caJobs"}) +@WebFilter(servletNames = {"caInfo", "caCert", "caCertRequest", "caJobs", "caFeature"}) public class EmptyAuthMethod extends AuthMethodFilter { private static final long serialVersionUID = 1L; diff --git a/base/server/src/main/java/org/dogtagpki/server/rest/v2/FeatureServlet.java b/base/server/src/main/java/org/dogtagpki/server/rest/v2/FeatureServlet.java new file mode 100644 index 00000000000..69769cf7b0e --- /dev/null +++ b/base/server/src/main/java/org/dogtagpki/server/rest/v2/FeatureServlet.java @@ -0,0 +1,89 @@ +// +// Copyright Red Hat, Inc. +// +// SPDX-License-Identifier: GPL-2.0-or-later +// +package org.dogtagpki.server.rest.v2; + +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.netscape.certsrv.base.ResourceNotFoundException; +import com.netscape.certsrv.base.WebAction; +import com.netscape.certsrv.system.Feature; +import com.netscape.cmscore.apps.CMSEngine; +import com.netscape.cmscore.apps.EngineConfig; +import com.netscape.cmscore.base.ConfigStore; + +/** + * @author Marco Fargetta {@literal } + * @author alee + */ +public class FeatureServlet extends PKIServlet { + private static final long serialVersionUID = 1L; + public static final Logger logger = LoggerFactory.getLogger(FeatureServlet.class); + + @WebAction(method = HttpMethod.GET, paths = {""}) + public void listFeatures(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("FeatureServlet.listFeatures(): session: {}", session.getId()); + + CMSEngine engine = getEngine(); + EngineConfig config = engine.getConfig(); + + ConfigStore cs = config.getSubStore("features", ConfigStore.class); + ArrayList features = new ArrayList<>(); + Enumeration tags = cs.getSubStoreNames().elements(); + while (tags.hasMoreElements()) { + String tag = tags.nextElement(); + Feature feature = createFeature(cs, tag); + features.add(feature); + } + ObjectMapper mapper = new ObjectMapper(); + PrintWriter out = response.getWriter(); + out.println(mapper.writeValueAsString(features)); + } + + @WebAction(method = HttpMethod.GET, paths = {"{}"}) + public void getFeature(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("FeatureServlet.getFeature(): session: {}", session.getId()); + String[] pathElement = request.getPathInfo().substring(1).split("/"); + String featureId = pathElement[0]; + + CMSEngine engine = getEngine(); + EngineConfig config = engine.getConfig(); + ConfigStore cs = config.getSubStore("features", ConfigStore.class); + Enumeration tags = cs.getSubStoreNames().elements(); + while(tags.hasMoreElements()) { + String tag = tags.nextElement(); + if (tag.equals(featureId)) { + Feature feature = createFeature(cs, tag); + PrintWriter out = response.getWriter(); + out.println(feature.toJSON()); + return; + } + } + throw new ResourceNotFoundException("Feature " + featureId + " not supported"); + } + + private Feature createFeature(ConfigStore cs, String tag) { + Map props = cs.getSubStore(tag).getProperties(); + Feature feature = new Feature(); + feature.setId(tag); + feature.setEnabled(Boolean.parseBoolean(props.get("enabled"))); + feature.setDescription(props.get("description")); + feature.setVersion(props.get("version")); + return feature; + } +}