This is an automated email from the ASF dual-hosted git repository.
imbajin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hugegraph-toolchain.git
The following commit(s) were added to refs/heads/master by this push:
new 3b385c3d2 fix(client): support graph-scoped legacy user auth paths
(#760)
3b385c3d2 is described below
commit 3b385c3d2f1c04f7fa4b4534b4b1ec220627bfb5
Author: looksaw <[email protected]>
AuthorDate: Fri Sep 4 23:43:41 2026 +0800
fix(client): support graph-scoped legacy user auth paths (#760)
- centralize legacy graph path detection in AuthAPI
- reuse list validation for legacy user lookup
- throw a clear exception when the user is absent
- cover missing users and graphless fallback
---------
Co-authored-by: imbajin <[email protected]>
---
.../org/apache/hugegraph/api/auth/AuthAPI.java | 20 ++++
.../org/apache/hugegraph/api/auth/UserAPI.java | 14 +++
.../org/apache/hugegraph/driver/AuthManager.java | 2 +-
.../org/apache/hugegraph/unit/AuthApiPathTest.java | 116 +++++++++++++++++++++
.../org/apache/hugegraph/unit/UnitTestSuite.java | 1 +
5 files changed, 152 insertions(+), 1 deletion(-)
diff --git
a/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/AuthAPI.java
b/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/AuthAPI.java
index 43ee21fdd..282c6a831 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/AuthAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/AuthAPI.java
@@ -24,18 +24,38 @@ import org.apache.hugegraph.structure.auth.AuthElement;
public abstract class AuthAPI extends API {
private static final String PATH = "graphspaces/%s/auth/%s";
+ private static final String LEGACY_PATH = "graphs/%s/auth/%s";
private static final String USER_PATH = "auth/%s";
+ private final boolean legacyGraphScoped;
+
public AuthAPI(RestClient client) {
super(client);
+ this.legacyGraphScoped = false;
this.path(USER_PATH, this.type());
}
public AuthAPI(RestClient client, String graphSpace) {
super(client);
+ this.legacyGraphScoped = false;
this.path(PATH, graphSpace, this.type());
}
+ public AuthAPI(RestClient client, String graphSpace, String graph) {
+ super(client);
+ this.legacyGraphScoped = !client.isSupportGs() &&
+ graph != null && !graph.isEmpty();
+ if (this.legacyGraphScoped) {
+ this.path(LEGACY_PATH, graph, this.type());
+ } else {
+ this.path(PATH, graphSpace, this.type());
+ }
+ }
+
+ protected boolean legacyGraphScoped() {
+ return this.legacyGraphScoped;
+ }
+
public static String formatEntityId(Object id) {
if (id == null) {
return null;
diff --git
a/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/UserAPI.java
b/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/UserAPI.java
index ff43a01c9..2b390a7c6 100644
--- a/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/UserAPI.java
+++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/auth/UserAPI.java
@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map;
import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.rest.ClientException;
import org.apache.hugegraph.rest.RestResult;
import org.apache.hugegraph.structure.auth.User;
import org.apache.hugegraph.structure.auth.User.UserRole;
@@ -34,6 +35,10 @@ public class UserAPI extends AuthAPI {
super(client, graphSpace);
}
+ public UserAPI(RestClient client, String graphSpace, String graph) {
+ super(client, graphSpace, graph);
+ }
+
@Override
protected String type() {
return HugeType.USER.string();
@@ -70,6 +75,15 @@ public class UserAPI extends AuthAPI {
}
public User getByName(String name) {
+ if (this.legacyGraphScoped()) {
+ List<User> users = this.list(-1);
+ for (User user : users) {
+ if (name.equals(user.name())) {
+ return user;
+ }
+ }
+ throw new ClientException("User '%s' does not exist", name);
+ }
Map<String, Object> params = ImmutableMap.of("name", name);
RestResult result = this.client.get(this.path(), params);
return result.readObject(User.class);
diff --git
a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/AuthManager.java
b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/AuthManager.java
index f8cc35216..42309cdb0 100644
---
a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/AuthManager.java
+++
b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/AuthManager.java
@@ -66,7 +66,7 @@ public class AuthManager {
this.targetAPI = new TargetAPI(client, graphSpace);
this.groupAPI = new GroupAPI(client);
this.graphSpaceGroupAPI = new GroupAPI(client, graphSpace);
- this.userAPI = new UserAPI(client, graphSpace);
+ this.userAPI = new UserAPI(client, graphSpace, graph);
this.accessAPI = new AccessAPI(client, graphSpace);
this.projectAPI = new ProjectAPI(client, graphSpace);
this.belongAPI = new BelongAPI(client, graphSpace);
diff --git
a/hugegraph-client/src/test/java/org/apache/hugegraph/unit/AuthApiPathTest.java
b/hugegraph-client/src/test/java/org/apache/hugegraph/unit/AuthApiPathTest.java
new file mode 100644
index 000000000..c1912e09e
--- /dev/null
+++
b/hugegraph-client/src/test/java/org/apache/hugegraph/unit/AuthApiPathTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.hugegraph.unit;
+
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
+
+import org.junit.Test;
+
+import org.apache.hugegraph.api.auth.UserAPI;
+import org.apache.hugegraph.client.RestClient;
+import org.apache.hugegraph.rest.ClientException;
+import org.apache.hugegraph.structure.auth.User;
+import org.apache.hugegraph.testutil.Assert;
+
+import com.sun.net.httpserver.HttpServer;
+
+public class AuthApiPathTest {
+
+ @Test
+ public void testLegacyServerUsesGraphScopedAuthPath() {
+ RestClient client = new RestClient("http://localhost", "", "", 1);
+ client.setSupportGs(false);
+
+ UserAPI api = new UserAPI(client, "DEFAULT", "hugegraph");
+
+ Assert.assertEquals("graphs/hugegraph/auth/users", api.path());
+ client.close();
+ }
+
+ @Test
+ public void testModernServerUsesGraphSpaceScopedAuthPath() {
+ RestClient client = new RestClient("http://localhost", "", "", 1);
+ client.setSupportGs(true);
+
+ UserAPI api = new UserAPI(client, "DEFAULT", "hugegraph");
+
+ Assert.assertEquals("graphspaces/DEFAULT/auth/users", api.path());
+ client.close();
+ }
+
+ @Test
+ public void testLegacyServerWithoutGraphUsesGraphSpaceScopedAuthPath() {
+ RestClient client = new RestClient("http://localhost", "", "", 1);
+ client.setSupportGs(false);
+
+ UserAPI api = new UserAPI(client, "DEFAULT", null);
+
+ Assert.assertEquals("graphspaces/DEFAULT/auth/users", api.path());
+ client.close();
+ }
+
+ @Test
+ public void testLegacyGetByNameReadsAllUsersFromWrapper() throws Exception
{
+ HttpServer server = HttpServer.create(new
InetSocketAddress("127.0.0.1",
+ 0), 0);
+ server.createContext("/graphs/hugegraph/auth/users", exchange -> {
+ boolean unlimited = "limit=-1".equals(
+ exchange.getRequestURI().getQuery());
+ StringBuilder content = new StringBuilder("{\"users\":[");
+ for (int i = 0; i < 100; i++) {
+ if (i > 0) {
+ content.append(',');
+ }
+ content.append("{\"id\":\"").append(i)
+ .append("\",\"user_name\":\"user_")
+ .append(i).append("\"}");
+ }
+ if (unlimited) {
+ content.append(",{\"id\":\"-30:admin\",")
+ .append("\"user_name\":\"admin\"}");
+ }
+ byte[] body = content.append("]}").toString()
+ .getBytes(StandardCharsets.UTF_8);
+ exchange.sendResponseHeaders(200, body.length);
+ try (OutputStream output = exchange.getResponseBody()) {
+ output.write(body);
+ }
+ });
+ server.start();
+
+ RestClient client = new RestClient(
+ "http://127.0.0.1:" + server.getAddress().getPort(),
+ "admin", "password", 1);
+ client.setSupportGs(false);
+ try {
+ UserAPI api = new UserAPI(client, "DEFAULT", "hugegraph");
+ User user = api.getByName("admin");
+ Assert.assertEquals("admin", user.name());
+ Assert.assertThrows(ClientException.class,
+ () -> api.getByName("missing"),
+ e -> Assert.assertContains(
+ "User 'missing' does not exist",
+ e.getMessage()));
+ } finally {
+ client.close();
+ server.stop(0);
+ }
+ }
+}
diff --git
a/hugegraph-client/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java
b/hugegraph-client/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java
index f48efbcec..97c32fc1e 100644
---
a/hugegraph-client/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java
+++
b/hugegraph-client/src/test/java/org/apache/hugegraph/unit/UnitTestSuite.java
@@ -28,6 +28,7 @@ import org.junit.runners.Suite;
PathSerializerTest.class,
RestResultTest.class,
RestClientStatusTest.class,
+ AuthApiPathTest.class,
BatchElementRequestTest.class,
PropertyKeyTest.class,
IndexLabelTest.class,