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

vgalaxies pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-hugegraph.git


The following commit(s) were added to refs/heads/master by this push:
     new 8c1ee710d feat(server): LoginAPI support token_expire field  (#2754)
8c1ee710d is described below

commit 8c1ee710d6f7fae26cade37dcf4968b422b108d6
Author: John <sp...@apache.org>
AuthorDate: Mon May 5 11:49:12 2025 +0800

    feat(server): LoginAPI support token_expire field  (#2754)
    
    Co-authored-by: imbajin <j...@apache.org>
---
 .../org/apache/hugegraph/api/auth/LoginAPI.java    |   5 +-
 .../apache/hugegraph/auth/HugeGraphAuthProxy.java  | 193 +++++++++++----------
 .../org/apache/hugegraph/auth/AuthManager.java     |   2 +
 .../apache/hugegraph/auth/StandardAuthManager.java |  21 ++-
 .../java/org/apache/hugegraph/core/AuthTest.java   | 138 +++++++--------
 5 files changed, 188 insertions(+), 171 deletions(-)

diff --git 
a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/LoginAPI.java
 
b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/LoginAPI.java
index 50bf1a78d..5e1bdb636 100644
--- 
a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/LoginAPI.java
+++ 
b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/LoginAPI.java
@@ -70,7 +70,8 @@ public class LoginAPI extends API {
         checkCreatingBody(jsonLogin);
 
         try {
-            String token = manager.authManager().loginUser(jsonLogin.name, 
jsonLogin.password);
+            String token = manager.authManager()
+                                  .loginUser(jsonLogin.name, 
jsonLogin.password, jsonLogin.expire);
             HugeGraph g = graph(manager, graph);
             return manager.serializer(g).writeMap(ImmutableMap.of("token", 
token));
         } catch (AuthenticationException e) {
@@ -131,6 +132,8 @@ public class LoginAPI extends API {
         private String name;
         @JsonProperty("user_password")
         private String password;
+        @JsonProperty("token_expire")
+        private long expire;
 
         @Override
         public void checkCreate(boolean isBatch) {
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 63d391279..383504e80 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
@@ -110,15 +110,16 @@ import jakarta.ws.rs.NotAuthorizedException;
 
 public final class HugeGraphAuthProxy implements HugeGraph {
 
+    private static final Logger LOG = Log.logger(HugeGraphAuthProxy.class);
+    private static final ThreadLocal<Context> CONTEXTS = new 
InheritableThreadLocal<>();
+
     static {
         HugeGraph.registerTraversalStrategies(HugeGraphAuthProxy.class);
     }
 
-    private static final Logger LOG = Log.logger(HugeGraphAuthProxy.class);
     private final Cache<Id, UserWithRole> usersRoleCache;
     private final Cache<Id, RateLimiter> auditLimiters;
     private final double auditLogMaxRate;
-
     private final HugeGraph hugegraph;
     private final TaskSchedulerProxy taskScheduler;
     private final AuthManagerProxy authManager;
@@ -141,6 +142,40 @@ public final class HugeGraphAuthProxy implements HugeGraph 
{
         LOG.info("Audit log rate limit is {}/s", this.auditLogMaxRate);
     }
 
+    static Context setContext(Context context) {
+        Context old = CONTEXTS.get();
+        CONTEXTS.set(context);
+        return old;
+    }
+
+    static void resetContext() {
+        CONTEXTS.remove();
+    }
+
+    private static Context getContext() {
+        // Return task context first
+        String taskContext = TaskManager.getContext();
+        User user = User.fromJson(taskContext);
+        if (user != null) {
+            return new Context(user);
+        }
+
+        return CONTEXTS.get();
+    }
+
+    private static String getContextString() {
+        Context context = getContext();
+        if (context == null) {
+            return null;
+        }
+        return context.user().toJson();
+    }
+
+    static void logUser(User user, String path) {
+        LOG.info("User '{}' login from client [{}] with path '{}'",
+                 user.username(), user.client(), path);
+    }
+
     @Override
     public HugeGraph hugegraph() {
         this.verifyAdminPermission();
@@ -1016,6 +1051,61 @@ public final class HugeGraphAuthProxy implements 
HugeGraph {
         return result;
     }
 
+    static class Context {
+
+        private static final Context ADMIN = new Context(User.ADMIN);
+
+        private final User user;
+
+        public Context(User user) {
+            E.checkNotNull(user, "user");
+            this.user = user;
+        }
+
+        public static Context admin() {
+            return ADMIN;
+        }
+
+        public User user() {
+            return this.user;
+        }
+    }
+
+    static class ContextTask implements Runnable {
+
+        private final Runnable runner;
+        private final Context context;
+
+        public ContextTask(Runnable runner) {
+            this.context = getContext();
+            this.runner = runner;
+        }
+
+        @Override
+        public void run() {
+            setContext(this.context);
+            try {
+                this.runner.run();
+            } finally {
+                resetContext();
+            }
+        }
+    }
+
+    public static class ContextThreadPoolExecutor extends ThreadPoolExecutor {
+
+        public ContextThreadPoolExecutor(int corePoolSize, int maxPoolSize,
+                                         ThreadFactory threadFactory) {
+            super(corePoolSize, maxPoolSize, 0L, TimeUnit.MILLISECONDS,
+                  new LinkedBlockingQueue<>(), threadFactory);
+        }
+
+        @Override
+        public void execute(Runnable command) {
+            super.execute(new ContextTask(command));
+        }
+    }
+
     class TaskSchedulerProxy implements TaskScheduler {
 
         private final TaskScheduler taskScheduler;
@@ -1622,8 +1712,14 @@ public final class HugeGraphAuthProxy implements 
HugeGraph {
 
         @Override
         public String loginUser(String username, String password) {
+            return this.loginUser(username, password, -1L);
+        }
+
+        // TODO: the expire haven't been implemented yet
+        @Override
+        public String loginUser(String username, String password, long expire) 
{
             try {
-                return this.authManager.loginUser(username, password);
+                return this.authManager.loginUser(username, password, expire);
             } catch (AuthenticationException e) {
                 throw new NotAuthorizedException(e.getMessage(), e);
             }
@@ -1841,95 +1937,4 @@ public final class HugeGraphAuthProxy implements 
HugeGraph {
             return this.origin.toString();
         }
     }
-
-    private static final ThreadLocal<Context> CONTEXTS = new 
InheritableThreadLocal<>();
-
-    protected static Context setContext(Context context) {
-        Context old = CONTEXTS.get();
-        CONTEXTS.set(context);
-        return old;
-    }
-
-    protected static void resetContext() {
-        CONTEXTS.remove();
-    }
-
-    protected static Context getContext() {
-        // Return task context first
-        String taskContext = TaskManager.getContext();
-        User user = User.fromJson(taskContext);
-        if (user != null) {
-            return new Context(user);
-        }
-
-        return CONTEXTS.get();
-    }
-
-    protected static String getContextString() {
-        Context context = getContext();
-        if (context == null) {
-            return null;
-        }
-        return context.user().toJson();
-    }
-
-    protected static void logUser(User user, String path) {
-        LOG.info("User '{}' login from client [{}] with path '{}'",
-                 user.username(), user.client(), path);
-    }
-
-    static class Context {
-
-        private static final Context ADMIN = new Context(User.ADMIN);
-
-        private final User user;
-
-        public Context(User user) {
-            E.checkNotNull(user, "user");
-            this.user = user;
-        }
-
-        public User user() {
-            return this.user;
-        }
-
-        public static Context admin() {
-            return ADMIN;
-        }
-    }
-
-    static class ContextTask implements Runnable {
-
-        private final Runnable runner;
-        private final Context context;
-
-        public ContextTask(Runnable runner) {
-            this.context = getContext();
-            this.runner = runner;
-        }
-
-        @Override
-        public void run() {
-            setContext(this.context);
-            try {
-                this.runner.run();
-            } finally {
-                resetContext();
-            }
-        }
-    }
-
-    public static class ContextThreadPoolExecutor extends ThreadPoolExecutor {
-
-        public ContextThreadPoolExecutor(int corePoolSize, int maxPoolSize,
-                                         ThreadFactory threadFactory) {
-            super(corePoolSize, maxPoolSize, 0L, TimeUnit.MILLISECONDS,
-                  new LinkedBlockingQueue<>(), threadFactory);
-        }
-
-        @Override
-        public void execute(Runnable command) {
-            super.execute(new ContextTask(command));
-        }
-    }
 }
diff --git 
a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/AuthManager.java
 
b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/AuthManager.java
index 51c72fba4..a2c76d395 100644
--- 
a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/AuthManager.java
+++ 
b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/AuthManager.java
@@ -121,6 +121,8 @@ public interface AuthManager {
 
     String loginUser(String username, String password) throws 
AuthenticationException;
 
+    String loginUser(String username, String password, long expire) throws 
AuthenticationException;
+
     void logoutUser(String token);
 
     UserWithRole validateUser(String username, String password);
diff --git 
a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManager.java
 
b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManager.java
index 103c58afc..1ec2711d7 100644
--- 
a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManager.java
+++ 
b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/auth/StandardAuthManager.java
@@ -114,6 +114,13 @@ public class StandardAuthManager implements AuthManager {
         this.ipWhiteListEnabled = false;
     }
 
+    /**
+     * Maybe can define an proxy class to choose forward or call local
+     */
+    public static boolean isLocal(AuthManager authManager) {
+        return authManager instanceof StandardAuthManager;
+    }
+
     private <V> Cache<Id, V> cache(String prefix, long capacity,
                                    long expiredTime) {
         String name = prefix + "-" + this.graph.name();
@@ -636,6 +643,13 @@ public class StandardAuthManager implements AuthManager {
     @Override
     public String loginUser(String username, String password)
             throws AuthenticationException {
+        return this.loginUser(username, password, -1L);
+    }
+
+    // TODO: the expire haven't been implemented yet
+    @Override
+    public String loginUser(String username, String password, long expire)
+            throws AuthenticationException {
         HugeUser user = this.matchUser(username, password);
         if (user == null) {
             String msg = "Incorrect username or password";
@@ -717,13 +731,6 @@ public class StandardAuthManager implements AuthManager {
         this.ipWhiteListEnabled = status;
     }
 
-    /**
-     * Maybe can define an proxy class to choose forward or call local
-     */
-    public static boolean isLocal(AuthManager authManager) {
-        return authManager instanceof StandardAuthManager;
-    }
-
     public <R> R commit(Callable<R> callable) {
         this.groups.autoCommit(false);
         this.access.autoCommit(false);
diff --git 
a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/AuthTest.java
 
b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/AuthTest.java
index 1db7af924..60bfdace8 100644
--- 
a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/AuthTest.java
+++ 
b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/AuthTest.java
@@ -55,6 +55,63 @@ import com.google.common.collect.ImmutableSet;
 
 public class AuthTest extends BaseCoreTest {
 
+    private static Id makeProjectAndAddGraph(HugeGraph graph,
+                                             String projectName,
+                                             String graphName) {
+        HugeProject project = makeProject(projectName, "");
+        AuthManager authManager = graph.authManager();
+        Id projectId = authManager.createProject(project);
+        projectId = authManager.projectAddGraphs(projectId,
+                                                 ImmutableSet.of(graphName));
+        Assert.assertNotNull(projectId);
+        return projectId;
+    }
+
+    private static HugeProject makeProject(String name, String desc) {
+        HugeProject project = new HugeProject(name, desc);
+        project.creator("admin");
+        return project;
+    }
+
+    private static HugeUser makeUser(String name, String password) {
+        HugeUser user = new HugeUser(name);
+        user.password(password);
+        user.creator("admin");
+        return user;
+    }
+
+    private static HugeGroup makeGroup(String name) {
+        HugeGroup group = new HugeGroup(name);
+        group.creator("admin");
+        return group;
+    }
+
+    private static HugeTarget makeTarget(String name, String url) {
+        HugeTarget target = new HugeTarget(name, url);
+        target.creator("admin");
+        return target;
+    }
+
+    private static HugeTarget makeTarget(String name, String graph, String url,
+                                         List<HugeResource> ress) {
+        HugeTarget target = new HugeTarget(name, graph, url, ress);
+        target.creator("admin");
+        return target;
+    }
+
+    private static HugeBelong makeBelong(Id user, Id group) {
+        HugeBelong belong = new HugeBelong(user, group);
+        belong.creator("admin");
+        return belong;
+    }
+
+    private static HugeAccess makeAccess(Id group, Id target,
+                                         HugePermission permission) {
+        HugeAccess access = new HugeAccess(group, target, permission);
+        access.creator("admin");
+        return access;
+    }
+
     @After
     public void clearAll() {
         HugeGraph graph = graph();
@@ -301,7 +358,7 @@ public class AuthTest extends BaseCoreTest {
 
         group = authManager.getGroup(id);
         Assert.assertEquals("group1", group.name());
-        Assert.assertEquals(null, group.description());
+        Assert.assertNull(group.description());
         Assert.assertEquals(group.create(), group.update());
 
         Assert.assertEquals(ImmutableMap.of("group_name", "group1",
@@ -632,7 +689,7 @@ public class AuthTest extends BaseCoreTest {
         HugeBelong belong = authManager.getBelong(id1);
         Assert.assertEquals(user, belong.source());
         Assert.assertEquals(group1, belong.target());
-        Assert.assertEquals(null, belong.description());
+        Assert.assertNull(belong.description());
         Assert.assertEquals(belong.create(), belong.update());
 
         Map<String, Object> expected = new HashMap<>();
@@ -647,7 +704,7 @@ public class AuthTest extends BaseCoreTest {
         belong = authManager.getBelong(id2);
         Assert.assertEquals(user, belong.source());
         Assert.assertEquals(group2, belong.target());
-        Assert.assertEquals(null, belong.description());
+        Assert.assertNull(belong.description());
         Assert.assertEquals(belong.create(), belong.update());
 
         expected = new HashMap<>();
@@ -1321,11 +1378,11 @@ public class AuthTest extends BaseCoreTest {
         authManager.createUser(user);
 
         // Login
-        authManager.loginUser("test", "pass");
+        authManager.loginUser("test", "pass", 10080L);
 
         // Invalid username or password
         Assert.assertThrows(AuthenticationException.class, () -> {
-            authManager.loginUser("huge", "graph");
+            authManager.loginUser("huge", "graph", 10080L);
         }, e -> {
             Assert.assertContains("Incorrect username or password", 
e.getMessage());
         });
@@ -1338,7 +1395,7 @@ public class AuthTest extends BaseCoreTest {
         HugeUser user = makeUser("test", StringEncoding.hashPassword("pass"));
         Id userId = authManager.createUser(user);
 
-        String token = authManager.loginUser("test", "pass");
+        String token = authManager.loginUser("test", "pass", 10080L);
 
         UserWithRole userWithRole;
         userWithRole = authManager.validateUser(token);
@@ -1375,7 +1432,7 @@ public class AuthTest extends BaseCoreTest {
         Id userId = authManager.createUser(user);
 
         // Login
-        String token = authManager.loginUser("test", "pass");
+        String token = authManager.loginUser("test", "pass", 10080L);
 
         // Logout
         Cache<Id, String> tokenCache = Whitebox.getInternalState(authManager,
@@ -1500,79 +1557,22 @@ public class AuthTest extends BaseCoreTest {
 
         List<HugeProject> projects = authManager.listAllProject(1);
         Assert.assertNotNull(projects);
-        Assert.assertTrue(projects.size() == 1);
+        Assert.assertEquals(1, projects.size());
 
         projects = authManager.listAllProject(-1);
         Assert.assertNotNull(projects);
-        Assert.assertTrue(projects.size() == 3);
+        Assert.assertEquals(3, projects.size());
 
         projects = authManager.listAllProject(3);
         Assert.assertNotNull(projects);
-        Assert.assertTrue(projects.size() == 3);
+        Assert.assertEquals(3, projects.size());
 
         projects = authManager.listAllProject(4);
         Assert.assertNotNull(projects);
-        Assert.assertTrue(projects.size() == 3);
+        Assert.assertEquals(3, projects.size());
 
         projects = authManager.listAllProject(2);
         Assert.assertNotNull(projects);
-        Assert.assertTrue(projects.size() == 2);
-    }
-
-    private static Id makeProjectAndAddGraph(HugeGraph graph,
-                                             String projectName,
-                                             String graphName) {
-        HugeProject project = makeProject(projectName, "");
-        AuthManager authManager = graph.authManager();
-        Id projectId = authManager.createProject(project);
-        projectId = authManager.projectAddGraphs(projectId,
-                                                 ImmutableSet.of(graphName));
-        Assert.assertNotNull(projectId);
-        return projectId;
-    }
-
-    private static HugeProject makeProject(String name, String desc) {
-        HugeProject project = new HugeProject(name, desc);
-        project.creator("admin");
-        return project;
-    }
-
-    private static HugeUser makeUser(String name, String password) {
-        HugeUser user = new HugeUser(name);
-        user.password(password);
-        user.creator("admin");
-        return user;
-    }
-
-    private static HugeGroup makeGroup(String name) {
-        HugeGroup group = new HugeGroup(name);
-        group.creator("admin");
-        return group;
-    }
-
-    private static HugeTarget makeTarget(String name, String url) {
-        HugeTarget target = new HugeTarget(name, url);
-        target.creator("admin");
-        return target;
-    }
-
-    private static HugeTarget makeTarget(String name, String graph, String url,
-                                         List<HugeResource> ress) {
-        HugeTarget target = new HugeTarget(name, graph, url, ress);
-        target.creator("admin");
-        return target;
-    }
-
-    private static HugeBelong makeBelong(Id user, Id group) {
-        HugeBelong belong = new HugeBelong(user, group);
-        belong.creator("admin");
-        return belong;
-    }
-
-    private static HugeAccess makeAccess(Id group, Id target,
-                                         HugePermission permission) {
-        HugeAccess access = new HugeAccess(group, target, permission);
-        access.creator("admin");
-        return access;
+        Assert.assertEquals(2, projects.size());
     }
 }

Reply via email to