imbajin commented on code in PR #3008:
URL: https://github.com/apache/hugegraph/pull/3008#discussion_r3142354568
##########
hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/profile/GraphsAPI.java:
##########
@@ -155,6 +296,60 @@ public void drop(@Context GraphManager manager,
manager.dropGraph(graphSpace, name, true);
}
+ @PUT
+ @Timed
+ @Path("{name}")
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON_WITH_CHARSET)
+ @RolesAllowed({"space"})
+ public Map<String, String> manage(@Context GraphManager manager,
+ @Parameter(description = "The graph
space name")
+ @PathParam("graphspace") String
graphSpace,
+ @Parameter(description = "The graph
name")
+ @PathParam("name") String name,
+ @Parameter(description = "Action map:
{'action':'update','update':{...}}")
+ Map<String, Object> actionMap) {
+ LOG.debug("Manage graph '{}' with action '{}'", name, actionMap);
+ E.checkArgument(actionMap != null && actionMap.size() == 2 &&
+ actionMap.containsKey(GRAPH_ACTION),
+ "Invalid request body '%s'", actionMap);
+ Object value = actionMap.get(GRAPH_ACTION);
+ E.checkArgument(value instanceof String,
+ "Invalid action type '%s', must be string",
+ value.getClass());
+ String action = (String) value;
+ switch (action) {
+ case UPDATE:
+ E.checkArgument(actionMap.containsKey(UPDATE),
+ "Please pass '%s' for graph update",
+ UPDATE);
+ value = actionMap.get(UPDATE);
+ E.checkArgument(value instanceof Map,
+ "The '%s' must be map, but got %s",
+ UPDATE, value.getClass());
+ @SuppressWarnings("unchecked")
+ Map<String, Object> graphMap = (Map<String, Object>) value;
+ String graphName = (String) graphMap.get("name");
+ E.checkArgument(graphName != null && graphName.equals(name),
+ "Different name in update body '%s' with path
'%s'",
+ graphName, name);
+ HugeGraph exist = graph(manager, graphSpace, name);
+ String nickname = (String) graphMap.get("nickname");
+ if (!Strings.isEmpty(nickname)) {
+ GraphManager.checkNickname(nickname);
+
E.checkArgument(!manager.isExistedGraphNickname(graphSpace, nickname) ||
+ nickname.equals(exist.nickname()),
+ "Nickname '%s' has already existed in
graphspace '%s'",
+ nickname, graphSpace);
+ exist.nickname(nickname);
Review Comment:
‼️ **Bug: nickname 更新未持久化,且 `isExistedGraphNickname` 在非 PD 模式下会 NPE**
两个问题:
1. `exist.nickname(nickname)` 只修改了内存中的 `StandardHugeGraph.nickname` 字段,没有调用
`metaManager.updateGraphConfig()` 写回存储。创建图时有完整的持久化链路(`GraphManager:1345` 设内存 →
`:1353` 写 metaManager),但这里的更新路径缺少持久化步骤,重启后 nickname 会丢失。
2. `manager.isExistedGraphNickname()` 内部调用
`metaManager.graphConfigs(graphSpace)` — 在非 PD(RocksDB 单机)模式下 MetaManager
未初始化,会抛 NPE。GraphsAPI 的端点在非 PD 模式下通过 `graphspace=DEFAULT` 正常使用,所以这里需要加
`isPDEnabled()` 分支做兼容(可参考 `GraphManager.graphs()` 的处理方式)。
##########
hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/profile/GraphsAPI.java:
##########
@@ -207,11 +402,14 @@ public Object create(@Context GraphManager manager,
if (StringUtils.isEmpty(clone)) {
// Only check required parameters when creating new graph, not
when cloning
E.checkArgument(configs != null, "Config parameters cannot be
null");
- String[] requiredKeys = {"backend", "serializer", "store"};
- for (String key : requiredKeys) {
- Object value = configs.get(key);
- E.checkArgument(value instanceof String &&
!StringUtils.isEmpty((String) value),
- "Required parameter '%s' is missing or empty",
key);
+ // Auto-fill defaults for PD/HStore mode when not provided
+ configs.putIfAbsent("backend", "hstore");
Review Comment:
‼️ **Bug: auto-fill `backend=hstore` 会导致非 PD 模式创建图失败**
GraphsAPI 的创建端点在非 PD(RocksDB 单机)模式下也会被调用(通过 `graphspace=DEFAULT`)。这里无条件填充
`backend=hstore` 会导致单机版用户创建图时使用错误的后端,应该加 PD 模式判断:
```suggestion
// Auto-fill defaults for PD/HStore mode when not provided
if (manager.isPDEnabled()) {
configs.putIfAbsent("backend", "hstore");
configs.putIfAbsent("serializer", "binary");
}
configs.putIfAbsent("store", name);
```
##########
hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/util/ConfigUtil.java:
##########
@@ -188,4 +192,18 @@ private static void validateGraphName(String graphName) {
"Graph name can only contain letters, numbers, hyphens
and underscores: %s",
graphName);
}
+
+ public static String writeConfigToString(HugeConfig config) {
+ // Always serialize config to a JSON object by iterating all keys,
+ // regardless of whether the config was loaded from a file or not.
+ // This ensures callers (e.g. GraphsAPI.listProfile) can safely parse
+ // the result via JsonUtil.fromJson() without format inconsistencies.
+ Map<String, Object> configMap = new HashMap<>();
+ Iterator<String> iterator = config.getKeys();
+ while (iterator.hasNext()) {
+ String key = iterator.next();
+ configMap.put(key, config.getProperty(key));
Review Comment:
‼️ **Security: 序列化全部配置项,可能泄露敏感信息**
`config.getKeys()` 会遍历所有配置键值对,包括可能包含密码、token 等敏感字段(如
`gremlin.server.password`、认证相关配置等)。该方法的返回值会通过 `GraphsAPI.listProfile()` 返回给前端展示。
建议做白名单过滤(只输出前端需要的字段),或者至少排除包含 `password`、`secret`、`token`、`credential` 等关键词的
key。
##########
hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/ManagerAPI.java:
##########
@@ -259,6 +262,41 @@ public String getRolesInGs(@Context GraphManager manager,
result));
}
+ @GET
+ @Timed
+ @Path("default")
+ @Consumes(APPLICATION_JSON)
+ public String checkDefaultRole(@Context GraphManager manager,
+ @QueryParam("graphspace") String graphSpace,
+ @QueryParam("role") String role,
+ @QueryParam("graph") String graph) {
+ LOG.debug("check if current user is default role: {} {} {}",
+ role, graphSpace, graph);
+ ensurePdModeEnabled(manager);
+ AuthManager authManager = manager.authManager();
+ String user = HugeGraphAuthProxy.username();
+
+ E.checkArgument(StringUtils.isNotEmpty(role) &&
+ StringUtils.isNotEmpty(graphSpace),
+ "Must pass graphspace and role params");
+
+ HugeDefaultRole defaultRole =
+ HugeDefaultRole.valueOf(role.toUpperCase());
Review Comment:
‼️ **Bug: `HugeDefaultRole.valueOf()` 未做异常处理,非法 role 值返回 500**
`valueOf(role.toUpperCase())` 在 role 值非法时会抛出 `IllegalArgumentException`,变成
HTTP 500 而不是 400。同一个 PR 中 `GraphSpaceAPI.setDefaultRole()` 已经用 try-catch
做了处理,这里应该保持一致:
```suggestion
HugeDefaultRole defaultRole;
try {
defaultRole = HugeDefaultRole.valueOf(role.toUpperCase());
} catch (IllegalArgumentException e) {
E.checkArgument(false, "Invalid role value '%s'", role);
defaultRole = null; // unreachable
}
```
--
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]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]