From d7bfdb69eb19db1711115b7a01c7afc2ec42e504 Mon Sep 17 00:00:00 2001 From: Tsukilc <153273766+Tsukilc@users.noreply.github.com> Date: Tue, 18 Nov 2025 21:44:34 +0800 Subject: [PATCH 1/4] fix(server): fix npe in non-auth mode --- .../org/apache/hugegraph/api/auth/ManagerAPI.java | 6 +++--- .../org/apache/hugegraph/api/profile/GraphsAPI.java | 2 +- .../apache/hugegraph/api/space/GraphSpaceAPI.java | 2 +- .../apache/hugegraph/auth/HugeGraphAuthProxy.java | 13 +++++++++++++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/ManagerAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/ManagerAPI.java index 6f5756b6dc..80b91d2731 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/ManagerAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/ManagerAPI.java @@ -73,7 +73,7 @@ public String createManager(@Context GraphManager manager, AuthManager authManager = manager.authManager(); validUser(authManager, user); - String creator = HugeGraphAuthProxy.getContext().user().username(); + String creator = HugeGraphAuthProxy.username(); switch (type) { case SPACE: validGraphSpace(manager, graphSpace); @@ -124,7 +124,7 @@ public void delete(@Context GraphManager manager, AuthManager authManager = manager.authManager(); validType(type); validUser(authManager, user); - String actionUser = HugeGraphAuthProxy.getContext().user().username(); + String actionUser = HugeGraphAuthProxy.username(); switch (type) { case SPACE: @@ -193,7 +193,7 @@ public String checkRole(@Context GraphManager manager, validType(type); AuthManager authManager = manager.authManager(); - String user = HugeGraphAuthProxy.getContext().user().username(); + String user = HugeGraphAuthProxy.username(); boolean result; switch (type) { diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/profile/GraphsAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/profile/GraphsAPI.java index 5f10da09e0..b7839ce053 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/profile/GraphsAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/profile/GraphsAPI.java @@ -199,7 +199,7 @@ public Object create(@Context GraphManager manager, } } - String creator = HugeGraphAuthProxy.getContext().user().username(); + String creator = HugeGraphAuthProxy.username(); if (StringUtils.isNotEmpty(clone)) { // Clone from existing graph diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/space/GraphSpaceAPI.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/space/GraphSpaceAPI.java index 4f12a59cfb..1471814cb0 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/space/GraphSpaceAPI.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/space/GraphSpaceAPI.java @@ -104,7 +104,7 @@ public String create(@Context GraphManager manager, jsonGraphSpace.checkCreate(false); - String creator = HugeGraphAuthProxy.getContext().user().username(); + String creator = HugeGraphAuthProxy.username(); GraphSpace exist = manager.graphSpace(jsonGraphSpace.name); E.checkArgument(exist == null, "The graph space '%s' has existed", jsonGraphSpace.name); diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java index c987aef4a8..190b0c0dbd 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java @@ -186,6 +186,11 @@ public static Context setAdmin() { public static Context getContext() { // Return task context first String taskContext = TaskManager.getContext(); + + if (taskContext == null) { + return null; + } + User user = User.fromJson(taskContext); if (user != null) { return new Context(user); @@ -953,6 +958,14 @@ public void updateTime(Date updateTime) { this.hugegraph.updateTime(updateTime); } + public static String username() { + Context context = HugeGraphAuthProxy.getContext(); + if (context == null) { + return "anonymous"; + } + return context.user.username(); + } + private Cache cache(String prefix, long capacity, long expiredTime) { String name = prefix + "-" + this.hugegraph.spaceGraphName(); From 6e6e23fd4b77c0f936f709121d5f12dd1c0b7f07 Mon Sep 17 00:00:00 2001 From: Tsukilc <153273766+Tsukilc@users.noreply.github.com> Date: Fri, 21 Nov 2025 19:30:57 +0800 Subject: [PATCH 2/4] fix(server): fix npe in non-auth mode --- .../java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java index 190b0c0dbd..cf390b886e 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeGraphAuthProxy.java @@ -187,10 +187,6 @@ public static Context getContext() { // Return task context first String taskContext = TaskManager.getContext(); - if (taskContext == null) { - return null; - } - User user = User.fromJson(taskContext); if (user != null) { return new Context(user); From ac0b87ebe8b8c36f8bef0cc07c15b980408c91da Mon Sep 17 00:00:00 2001 From: Tsukilc <153273766+Tsukilc@users.noreply.github.com> Date: Mon, 8 Dec 2025 12:58:44 +0800 Subject: [PATCH 3/4] fix(server): fix npe in non-auth mode --- .../unit/auth/HugeGraphAuthProxyTest.java | 198 ++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/auth/HugeGraphAuthProxyTest.java diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/auth/HugeGraphAuthProxyTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/auth/HugeGraphAuthProxyTest.java new file mode 100644 index 0000000000..1bff9b29d8 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/auth/HugeGraphAuthProxyTest.java @@ -0,0 +1,198 @@ +/* + * 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.auth; + +import java.lang.reflect.Method; + +import org.apache.hugegraph.auth.HugeAuthenticator; +import org.apache.hugegraph.auth.HugeGraphAuthProxy; +import org.apache.hugegraph.auth.RolePermission; +import org.apache.hugegraph.task.TaskManager; +import org.apache.hugegraph.testutil.Assert; +import org.apache.hugegraph.unit.BaseUnitTest; +import org.junit.After; +import org.junit.Test; + +public class HugeGraphAuthProxyTest extends BaseUnitTest { + + private static HugeGraphAuthProxy.Context setContext( + HugeGraphAuthProxy.Context context) { + try { + Method method = HugeGraphAuthProxy.class.getDeclaredMethod( + "setContext", + HugeGraphAuthProxy.Context.class); + method.setAccessible(true); + return (HugeGraphAuthProxy.Context) method.invoke(null, context); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @After + public void tearDown() { + // Clean up contexts after each test + HugeGraphAuthProxy.resetContext(); + TaskManager.resetContext(); + } + + @Test + public void testUsernameWithNullContext() { + // Ensure no context is set + HugeGraphAuthProxy.resetContext(); + TaskManager.resetContext(); + + // When context is null, username() should return "anonymous" + String username = HugeGraphAuthProxy.username(); + Assert.assertEquals("anonymous", username); + } + + @Test + public void testUsernameWithValidContext() { + // Create a user with a specific username + HugeAuthenticator.User user = new HugeAuthenticator.User( + "test_user", + RolePermission.admin() + ); + + // Set context with this user + HugeGraphAuthProxy.Context context = new HugeGraphAuthProxy.Context(user); + setContext(context); + + // username() should return the user's username + String username = HugeGraphAuthProxy.username(); + Assert.assertEquals("test_user", username); + } + + @Test + public void testUsernameWithAdminUser() { + // Test with ADMIN user + HugeAuthenticator.User adminUser = HugeAuthenticator.User.ADMIN; + HugeGraphAuthProxy.Context context = new HugeGraphAuthProxy.Context( + adminUser); + setContext(context); + + String username = HugeGraphAuthProxy.username(); + Assert.assertEquals("admin", username); + } + + @Test + public void testGetContextReturnsNull() { + // Ensure both TaskManager context and CONTEXTS are null + HugeGraphAuthProxy.resetContext(); + TaskManager.resetContext(); + + HugeGraphAuthProxy.Context context = HugeGraphAuthProxy.getContext(); + Assert.assertNull(context); + } + + @Test + public void testGetContextFromThreadLocal() { + // Set context via setContext (which sets CONTEXTS ThreadLocal) + HugeAuthenticator.User user = new HugeAuthenticator.User( + "thread_local_user", + RolePermission.admin() + ); + HugeGraphAuthProxy.Context expectedContext = new HugeGraphAuthProxy.Context( + user); + setContext(expectedContext); + + // Ensure TaskManager context is null + TaskManager.resetContext(); + + // getContext() should return the context from CONTEXTS ThreadLocal + HugeGraphAuthProxy.Context context = HugeGraphAuthProxy.getContext(); + Assert.assertNotNull(context); + Assert.assertEquals("thread_local_user", context.user().username()); + } + + @Test + public void testGetContextFromTaskManager() { + // Clear CONTEXTS ThreadLocal + HugeGraphAuthProxy.resetContext(); + + // Create a user and set it in TaskManager context + HugeAuthenticator.User user = new HugeAuthenticator.User( + "task_user", + RolePermission.admin() + ); + String userJson = user.toJson(); + TaskManager.setContext(userJson); + + // getContext() should return context from TaskManager + HugeGraphAuthProxy.Context context = HugeGraphAuthProxy.getContext(); + Assert.assertNotNull(context); + Assert.assertEquals("task_user", context.user().username()); + } + + @Test + public void testGetContextPrioritizesTaskManager() { + // Set both TaskManager context and CONTEXTS ThreadLocal + HugeAuthenticator.User taskUser = new HugeAuthenticator.User( + "task_user", + RolePermission.admin() + ); + String taskUserJson = taskUser.toJson(); + TaskManager.setContext(taskUserJson); + + HugeAuthenticator.User threadUser = new HugeAuthenticator.User( + "thread_user", + RolePermission.admin() + ); + HugeGraphAuthProxy.Context threadContext = new HugeGraphAuthProxy.Context( + threadUser); + setContext(threadContext); + + // getContext() should prioritize TaskManager context + HugeGraphAuthProxy.Context context = HugeGraphAuthProxy.getContext(); + Assert.assertNotNull(context); + Assert.assertEquals("task_user", context.user().username()); + } + + @Test + public void testGetContextWithNullTaskManagerJson() { + // Clear CONTEXTS ThreadLocal + HugeGraphAuthProxy.resetContext(); + + // Set null in TaskManager + TaskManager.setContext(null); + + // getContext() should return null + HugeGraphAuthProxy.Context context = HugeGraphAuthProxy.getContext(); + Assert.assertNull(context); + } + + @Test + public void testUsernameAfterResetContext() { + // Set a context first + HugeAuthenticator.User user = new HugeAuthenticator.User( + "temp_user", + RolePermission.admin() + ); + HugeGraphAuthProxy.Context context = new HugeGraphAuthProxy.Context(user); + setContext(context); + + // Verify it's set + Assert.assertEquals("temp_user", HugeGraphAuthProxy.username()); + + // Reset context + HugeGraphAuthProxy.resetContext(); + + // username() should now return "anonymous" + Assert.assertEquals("anonymous", HugeGraphAuthProxy.username()); + } +} From 4fd75c621153e08b9d9507480db95a1c52056bb6 Mon Sep 17 00:00:00 2001 From: Tsukilc <153273766+Tsukilc@users.noreply.github.com> Date: Fri, 19 Dec 2025 11:20:36 +0800 Subject: [PATCH 4/4] fix(server): fix npe in non-auth mode --- .../src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java index a0cb72aa6c..f9f20ab9e5 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java @@ -19,6 +19,7 @@ import org.apache.hugegraph.core.RoleElectionStateMachineTest; import org.apache.hugegraph.unit.api.filter.PathFilterTest; +import org.apache.hugegraph.unit.auth.HugeGraphAuthProxyTest; import org.apache.hugegraph.unit.cache.CacheManagerTest; import org.apache.hugegraph.unit.cache.CacheTest; import org.apache.hugegraph.unit.cache.CachedGraphTransactionTest; @@ -117,6 +118,7 @@ PageStateTest.class, SystemSchemaStoreTest.class, RoleElectionStateMachineTest.class, + HugeGraphAuthProxyTest.class, /* serializer */ BytesBufferTest.class,