Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.hugegraph.api;

import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.Callable;
Expand Down Expand Up @@ -89,6 +90,13 @@ public class API {
private static final String STANDALONE_ERROR =
"GraphSpace management is not supported in standalone mode";

/**
* Shared date formatter for API response timestamps (thread-safe, reusable).
* Example output: {@code "2024-05-01 12:30:00"}
*/
protected static final DateTimeFormatter DATE_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

public static HugeGraph graph(GraphManager manager, String graphSpace,
String graph) {
HugeGraph g = manager.graph(graphSpace, graph);
Expand Down Expand Up @@ -282,6 +290,28 @@ public static void validPermission(boolean hasPermission, String user,
}
}

/**
* Returns {@code true} if the profile's {@code "name"} or {@code "nickname"}
* field starts with the given prefix. Returns {@code true} when prefix is
* null or empty (i.e. no filtering).
*
* <p>Used by {@code GraphsAPI.listProfile} and {@code GraphSpaceAPI.listProfile}
* to filter results by a user-supplied prefix string.
*
* @param profile a map containing at least a {@code "name"} key
* @param prefix the prefix to match against; ignored when blank
* @return whether the entry matches the prefix filter
*/
protected static boolean isPrefix(Map<String, Object> profile, String prefix) {
if (prefix == null || prefix.isEmpty()) {
return true;
}
String name = profile.get("name").toString();
Object nicknameObj = profile.get("nickname");
String nickname = nicknameObj != null ? nicknameObj.toString() : "";
return name.startsWith(prefix) || nickname.startsWith(prefix);
}

public static class ApiMeasurer {

public static final String EDGE_ITER = "edge_iterations";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import org.apache.hugegraph.api.API;
import org.apache.hugegraph.api.filter.StatusFilter;
import org.apache.hugegraph.auth.AuthManager;
import org.apache.hugegraph.auth.HugeDefaultRole;
import org.apache.hugegraph.auth.HugeGraphAuthProxy;
import org.apache.hugegraph.auth.HugePermission;
import org.apache.hugegraph.core.GraphManager;
Expand Down Expand Up @@ -259,6 +262,46 @@ 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);
Comment thread
Yeaury marked this conversation as resolved.
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;
try {
defaultRole = HugeDefaultRole.valueOf(role.toUpperCase());
} catch (IllegalArgumentException e) {
E.checkArgument(false, "Invalid role value '%s'", role);
defaultRole = null; // unreachable, satisfies compiler
}
boolean hasGraph = defaultRole.equals(HugeDefaultRole.OBSERVER);
E.checkArgument(!hasGraph || StringUtils.isNotEmpty(graph),
"Must set a graph for observer");

boolean result;
if (hasGraph) {
result = authManager.isDefaultRole(graphSpace, graph, user,
defaultRole);
} else {
result = authManager.isDefaultRole(graphSpace, user,
defaultRole);
}
return manager.serializer().writeMap(ImmutableMap.of("check", result));
}

private void validUser(AuthManager authManager, String user) {
E.checkArgument(authManager.findUser(user) != null ||
authManager.findGroup(user) != null,
Expand All @@ -274,7 +317,7 @@ private void validType(HugePermission type) {

private void validGraphSpace(GraphManager manager, String graphSpace) {
E.checkArgument(manager.graphSpace(graphSpace) != null,
"The graph space is not exist");
"The graph space '%s' does not exist", graphSpace);
}

private static class JsonManager implements Checkable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ private static class JsonUser implements Checkable {
@JsonProperty("user_password")
@Schema(description = "The user password", required = true)
private String password;
@JsonProperty("user_nickname")
@Schema(description = "The user nickname")
private String nickname;
@JsonProperty("user_phone")
@Schema(description = "The user phone number")
private String phone;
Expand All @@ -197,6 +200,9 @@ public HugeUser build(HugeUser user) {
if (this.password != null) {
user.password(StringEncoding.hashPassword(this.password));
}
if (this.nickname != null) {
user.nickname(this.nickname);
}
if (this.phone != null) {
user.phone(this.phone);
}
Expand All @@ -215,6 +221,7 @@ public HugeUser build(HugeUser user) {
public HugeUser build() {
HugeUser user = new HugeUser(this.name);
user.password(StringEncoding.hashPassword(this.password));
user.nickname(this.nickname);
user.phone(this.phone);
user.email(this.email);
user.avatar(this.avatar);
Expand All @@ -233,10 +240,12 @@ public void checkCreate(boolean isBatch) {
@Override
public void checkUpdate() {
E.checkArgument(!StringUtils.isEmpty(this.password) ||
this.nickname != null ||
this.phone != null ||
this.email != null ||
this.avatar != null,
"Expect one of user password/phone/email/avatar]");
this.avatar != null ||
this.description != null,
"Expect one of user password/nickname/phone/email/avatar/description");
}
}
}
Loading