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();