Copilot commented on code in PR #11558:
URL: https://github.com/apache/gravitino/pull/11558#discussion_r3450490026


##########
lance/lance-rest-server/src/main/java/org/apache/gravitino/lance/service/LanceAuthenticationFilter.java:
##########
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.lance.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.gravitino.exceptions.UnauthorizedException;
+import org.apache.gravitino.server.authentication.AuthenticationFilter;
+import org.lance.namespace.model.ErrorResponse;
+
+/**
+ * An {@link AuthenticationFilter} subclass for the Lance REST server that:
+ *
+ * <ul>
+ *   <li>allows health check endpoints to bypass authentication;
+ *   <li>returns Lance-compatible JSON error responses on authentication 
failure instead of the
+ *       default HTML error pages.
+ * </ul>
+ *
+ * <p>The default {@link AuthenticationFilter} only whitelists /health, 
/api/health paths. This
+ * subclass additionally permits /lance/health and /lance/health/* so that 
Kubernetes probes and
+ * monitoring systems can reach the Lance health endpoint without credentials.
+ */
+public class LanceAuthenticationFilter extends AuthenticationFilter {
+
+  private static final ObjectMapper MAPPER = new ObjectMapper();
+
+  @Override
+  protected boolean isHealthCheckRequest(ServletRequest request) {
+    if (super.isHealthCheckRequest(request)) {
+      return true;
+    }
+
+    if (!(request instanceof HttpServletRequest)) {
+      return false;
+    }
+    String path = ((HttpServletRequest) request).getRequestURI();
+    if (path == null) {
+      return false;
+    }
+    return path.equals("/lance/health") || path.startsWith("/lance/health/");
+  }
+
+  @Override
+  protected void sendAuthErrorResponse(HttpServletResponse response, Exception 
exception)
+      throws IOException {
+    int status =
+        exception instanceof UnauthorizedException
+            ? HttpServletResponse.SC_UNAUTHORIZED
+            : HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+    String message = exception.getMessage();
+    if (message == null || message.isEmpty()) {
+      message = "Authentication failed";
+    }

Review Comment:
   For non-401 failures, returning `exception.getMessage()` to clients can leak 
internal details (e.g., stack/implementation information) in 500 responses. 
Consider returning a generic message for `SC_INTERNAL_SERVER_ERROR` (and 
logging the exception server-side), while keeping the more specific message for 
`UnauthorizedException` if desired.



##########
lance/lance-rest-server/src/main/java/org/apache/gravitino/lance/LanceRESTService.java:
##########
@@ -28,13 +28,17 @@
 import org.apache.gravitino.lance.common.config.LanceConfig;
 import org.apache.gravitino.lance.common.ops.LanceNamespaceBackend;
 import org.apache.gravitino.lance.common.ops.NamespaceWrapper;
+import org.apache.gravitino.lance.service.LanceAuthenticationFilter;
 import org.apache.gravitino.listener.EventBus;
 import org.apache.gravitino.listener.api.event.EventSource;
 import org.apache.gravitino.metrics.MetricsSystem;
 import org.apache.gravitino.metrics.source.MetricsSource;
 import org.apache.gravitino.server.web.HttpAuditFilter;
 import org.apache.gravitino.server.web.HttpServerMetricsSource;
-import org.apache.gravitino.server.web.JettyServer;
+import org.apache.gravitino.server.web.
+  
+  
+  ;

Review Comment:
   This import section is syntactically invalid and will fail compilation. 
Replace it with the intended import (likely `import 
org.apache.gravitino.server.web.JettyServer;`) and remove the stray 
blank/semicolon-only lines so the imports are valid Java.



##########
lance/lance-rest-server/src/test/java/org/apache/gravitino/lance/service/TestLanceAuthenticationFilter.java:
##########
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.lance.service;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.gravitino.exceptions.UnauthorizedException;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.lance.namespace.model.ErrorResponse;
+
+public class TestLanceAuthenticationFilter {
+
+  private static final ObjectMapper MAPPER = new ObjectMapper();
+
+  /** Exposes the protected {@code isHealthCheckRequest} method for white-box 
testing. */
+  private static class TestableFilter extends LanceAuthenticationFilter {
+    boolean isHealth(ServletRequest request) {
+      return isHealthCheckRequest(request);
+    }
+  }
+
+  @ParameterizedTest
+  @ValueSource(
+      strings = {
+        "/lance/health",
+        "/lance/health/live",
+        "/lance/health/ready",
+        "/health",
+        "/health/live",
+        "/health/ready",
+        "/health.html",
+        "/api/health",
+        "/api/health/live",
+        "/api/health/ready"
+      })

Review Comment:
   This test is asserting inherited whitelist behavior from 
`AuthenticationFilter` (e.g., `/health.html`) in addition to Lance-specific 
behavior. That makes the Lance test brittle if the base filter’s whitelist 
changes. Consider limiting this parameter set to the Lance-specific paths 
(`/lance/health...`) and covering base filter expectations in tests that are 
scoped to `AuthenticationFilter` (or only assert on behaviors that are part of 
its documented contract).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to