This is an automated email from the ASF dual-hosted git repository.

technoboy pushed a commit to branch branch-2.10
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/branch-2.10 by this push:
     new 83d513f6749 [fix][proxy] Move status endpoint out of auth coverage 
(#21494)
83d513f6749 is described below

commit 83d513f6749535de68a20c580fbb6404338f4f5d
Author: Qiang Zhao <[email protected]>
AuthorDate: Wed Nov 1 22:19:17 2023 +0800

    [fix][proxy] Move status endpoint out of auth coverage (#21494)
---
 .../pulsar/proxy/server/ProxyServiceStarter.java   | 10 +++--
 .../org/apache/pulsar/proxy/server/WebServer.java  | 31 +++++++++++++--
 .../server/ProxyWithJwtAuthorizationTest.java      | 44 ++++++++++++++++++++--
 .../server/UnauthedAdminProxyHandlerTest.java      |  4 +-
 4 files changed, 76 insertions(+), 13 deletions(-)

diff --git 
a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyServiceStarter.java
 
b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyServiceStarter.java
index 6bbe6691be3..07460285e04 100644
--- 
a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyServiceStarter.java
+++ 
b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyServiceStarter.java
@@ -241,11 +241,13 @@ public class ProxyServiceStarter {
                                      ProxyConfiguration config,
                                      ProxyService service,
                                      BrokerDiscoveryProvider 
discoveryProvider) throws Exception {
+        // We can make 'status.html' publicly accessible without 
authentication since
+        // it does not contain any sensitive data.
+        server.addRestResource("/", VipStatus.ATTRIBUTE_STATUS_FILE_PATH, 
config.getStatusFilePath(),
+                VipStatus.class, false);
         if (config.isEnableProxyStatsEndpoints()) {
-            server.addRestResources("/", 
VipStatus.class.getPackage().getName(),
-                    VipStatus.ATTRIBUTE_STATUS_FILE_PATH, 
config.getStatusFilePath());
-            server.addRestResources("/proxy-stats", 
ProxyStats.class.getPackage().getName(),
-                    ProxyStats.ATTRIBUTE_PULSAR_PROXY_NAME, service);
+            server.addRestResource("/proxy-stats", 
ProxyStats.ATTRIBUTE_PULSAR_PROXY_NAME, service,
+                    ProxyStats.class);
             if (service != null) {
                 PrometheusMetricsServlet metricsServlet = 
service.getMetricsServlet();
                 if (metricsServlet != null) {
diff --git 
a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/WebServer.java 
b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/WebServer.java
index 4269ac3d966..0359cdd274b 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/WebServer.java
+++ b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/WebServer.java
@@ -185,15 +185,40 @@ public class WebServer {
         handlers.add(context);
     }
 
-    public void addRestResources(String basePath, String javaPackages, String 
attribute, Object attributeValue) {
+    /**
+     * Add a REST resource to the servlet context with authentication coverage.
+     *
+     * @see WebServer#addRestResource(String, String, Object, Class, boolean)
+     *
+     * @param basePath             The base path for the resource.
+     * @param attribute            An attribute associated with the resource.
+     * @param attributeValue       The value of the attribute.
+     * @param resourceClass        The class representing the resource.
+     */
+    public void addRestResource(String basePath, String attribute, Object 
attributeValue, Class<?> resourceClass) {
+        addRestResource(basePath, attribute, attributeValue, resourceClass, 
true);
+    }
+
+    /**
+     * Add a REST resource to the servlet context.
+     *
+     * @param basePath             The base path for the resource.
+     * @param attribute            An attribute associated with the resource.
+     * @param attributeValue       The value of the attribute.
+     * @param resourceClass        The class representing the resource.
+     * @param requireAuthentication A boolean indicating whether 
authentication is required for this resource.
+     */
+    public void addRestResource(String basePath, String attribute, Object 
attributeValue,
+                                Class<?> resourceClass, boolean 
requireAuthentication) {
         ResourceConfig config = new ResourceConfig();
-        config.packages("jersey.config.server.provider.packages", 
javaPackages);
+        config.register(resourceClass);
         config.register(JsonMapperProvider.class);
         ServletHolder servletHolder = new ServletHolder(new 
ServletContainer(config));
         servletHolder.setAsyncSupported(true);
         // This method has not historically checked for existing paths, so we 
don't check here either. The
         // method call is added to reduce code duplication.
-        addServlet(basePath, servletHolder, 
Collections.singletonList(Pair.of(attribute, attributeValue)), true, false);
+        addServlet(basePath, servletHolder, 
Collections.singletonList(Pair.of(attribute, attributeValue)),
+                requireAuthentication, false);
     }
 
     public int getExternalServicePort() {
diff --git 
a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyWithJwtAuthorizationTest.java
 
b/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyWithJwtAuthorizationTest.java
index 4e80ee2208e..83beebd95f0 100644
--- 
a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyWithJwtAuthorizationTest.java
+++ 
b/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/ProxyWithJwtAuthorizationTest.java
@@ -21,7 +21,6 @@ package org.apache.pulsar.proxy.server;
 import static org.mockito.Mockito.spy;
 
 import com.google.common.collect.Sets;
-
 import io.jsonwebtoken.Jwts;
 import io.jsonwebtoken.SignatureAlgorithm;
 import java.util.Base64;
@@ -31,17 +30,30 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import javax.crypto.SecretKey;
+import lombok.Cleanup;
 import org.apache.pulsar.broker.authentication.AuthenticationProviderToken;
 import org.apache.pulsar.broker.authentication.AuthenticationService;
 import org.apache.pulsar.broker.authentication.utils.AuthTokenUtils;
+import org.apache.pulsar.broker.resources.PulsarResources;
 import org.apache.pulsar.client.admin.PulsarAdmin;
-import org.apache.pulsar.client.api.*;
+import org.apache.pulsar.client.api.AuthenticationFactory;
+import org.apache.pulsar.client.api.ClientBuilder;
+import org.apache.pulsar.client.api.Consumer;
+import org.apache.pulsar.client.api.Message;
+import org.apache.pulsar.client.api.Producer;
+import org.apache.pulsar.client.api.ProducerConsumerBase;
+import org.apache.pulsar.client.api.PulsarClient;
+import org.apache.pulsar.client.api.PulsarClientException;
+import org.apache.pulsar.client.api.Schema;
 import org.apache.pulsar.client.impl.auth.AuthenticationToken;
 import org.apache.pulsar.common.configuration.PulsarConfigurationLoader;
 import org.apache.pulsar.common.policies.data.AuthAction;
 import org.apache.pulsar.common.policies.data.ClusterData;
 import org.apache.pulsar.common.policies.data.SubscriptionAuthMode;
 import org.apache.pulsar.common.policies.data.TenantInfoImpl;
+import org.apache.pulsar.metadata.impl.ZKMetadataStore;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
 import org.mockito.Mockito;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -49,8 +61,8 @@ import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
-
-import javax.crypto.SecretKey;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.core.Response;
 
 public class ProxyWithJwtAuthorizationTest extends ProducerConsumerBase {
     private static final Logger log = 
LoggerFactory.getLogger(ProxyWithJwtAuthorizationTest.class);
@@ -111,6 +123,7 @@ public class ProxyWithJwtAuthorizationTest extends 
ProducerConsumerBase {
         
proxyConfig.setBrokerClientAuthenticationPlugin(AuthenticationToken.class.getName());
         proxyConfig.setBrokerClientAuthenticationParameters(PROXY_TOKEN);
         proxyConfig.setAuthenticationProviders(providers);
+        proxyConfig.setStatusFilePath("./src/test/resources/vip_status.html");
 
         AuthenticationService authService =
                 new 
AuthenticationService(PulsarConfigurationLoader.convertFrom(proxyConfig));
@@ -397,6 +410,29 @@ public class ProxyWithJwtAuthorizationTest extends 
ProducerConsumerBase {
         log.info("-- Exiting {} test --", methodName);
     }
 
+    @Test
+    void testGetStatus() throws Exception {
+        log.info("-- Starting {} test --", methodName);
+        final PulsarResources resource = new PulsarResources(new 
ZKMetadataStore(mockZooKeeper),
+                new ZKMetadataStore(mockZooKeeperGlobal));
+        final AuthenticationService authService = new AuthenticationService(
+                PulsarConfigurationLoader.convertFrom(proxyConfig));
+        final WebServer webServer = new WebServer(proxyConfig, authService);
+        ProxyServiceStarter.addWebServerHandlers(webServer, proxyConfig, 
proxyService,
+                new BrokerDiscoveryProvider(proxyConfig, resource));
+        webServer.start();
+        @Cleanup
+        final Client client = javax.ws.rs.client.ClientBuilder
+                .newClient(new ClientConfig().register(LoggingFeature.class));
+        try {
+            final Response r = 
client.target(webServer.getServiceUri()).path("/status.html").request().get();
+            Assert.assertEquals(r.getStatus(), 
Response.Status.OK.getStatusCode());
+        } finally {
+            webServer.stop();
+        }
+        log.info("-- Exiting {} test --", methodName);
+    }
+
     private void createAdminClient() throws Exception {
         admin = 
spy(PulsarAdmin.builder().serviceHttpUrl(webServer.getServiceUri().toString())
                 
.authentication(AuthenticationFactory.token(ADMIN_TOKEN)).build());
diff --git 
a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/UnauthedAdminProxyHandlerTest.java
 
b/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/UnauthedAdminProxyHandlerTest.java
index 8bf19c61bc4..4ccf7e55eac 100644
--- 
a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/UnauthedAdminProxyHandlerTest.java
+++ 
b/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/UnauthedAdminProxyHandlerTest.java
@@ -86,8 +86,8 @@ public class UnauthedAdminProxyHandlerTest extends 
MockedPulsarServiceBaseTest {
         webServer.addServlet("/admin", servletHolder);
         webServer.addServlet("/lookup", servletHolder);
 
-        webServer.addRestResources("/", VipStatus.class.getPackage().getName(),
-                VipStatus.ATTRIBUTE_STATUS_FILE_PATH, 
proxyConfig.getStatusFilePath());
+        webServer.addRestResource("/", VipStatus.ATTRIBUTE_STATUS_FILE_PATH,
+                proxyConfig.getStatusFilePath(), VipStatus.class);
 
         // start web-service
         webServer.start();

Reply via email to