Skip to content

Commit

Permalink
upgrade authentication module (apache#9)
Browse files Browse the repository at this point in the history
* upgrade rocksdb jni to 6.22.1.1
* flush() rocksdb when graph mode change from LOADING to NONE
* commit in batchAPI wait 10 seconds before return if server is busy
* standardize the format and length of user name and password
* upgrade authentication module and make the authentication in system graph
* fixed api test 

Co-authored-by: zhangyi51 <[email protected]>
Co-authored-by: janbox70 <[email protected]>
Co-authored-by: guoyonggang <[email protected]>
  • Loading branch information
4 people authored Aug 31, 2021
1 parent c6b44e3 commit a3b6b9d
Show file tree
Hide file tree
Showing 19 changed files with 104 additions and 57 deletions.
4 changes: 2 additions & 2 deletions hugegraph-api/src/main/java/com/baidu/hugegraph/api/API.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ public class API {
public static final String ACTION_ELIMINATE = "eliminate";
public static final String ACTION_CLEAR = "clear";

public static final String USER_NAME_PATTERN = "^[0-9a-zA-Z_]{6,18}$";
public static final String USER_NAME_PATTERN = "^[0-9a-zA-Z_]{5,16}$";
public static final String USER_PASSWORD_PATTERN =
"[a-zA-Z0-9_.,\\-()/=+?!*;@#:%\\[\\]\\\\${}^|~\\n\\r\\t ]{8,16}";
"[a-zA-Z0-9~!@#$%^&*()_+|<>,.?/:;'`\"\\[\\]{}\\\\]{5,16}";

private static final Meter succeedMeter =
MetricsUtil.registerMeter(API.class, "commit-succeed");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,14 @@ private static class JsonLogin implements Checkable {
public void checkCreate(boolean isBatch) {
E.checkArgument(!StringUtils.isEmpty(this.name) &&
this.name.matches(USER_NAME_PATTERN),
"The name is 6-18 characters and can only contain letters, numbers or underscores");
"The name is 5-16 characters " +
"and can only contain letters, " +
"numbers or underscores");
E.checkArgument(!StringUtils.isEmpty(this.password) &&
this.password.matches(USER_PASSWORD_PATTERN),
"The password is 8-16 characters, which can be letters, numbers or special symbols");
"The password is 5-16 characters, " +
"which can be letters, numbers or " +
"special symbols");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,14 @@ public HugeUser build() {
public void checkCreate(boolean isBatch) {
E.checkArgument(!StringUtils.isEmpty(this.name) &&
this.name.matches(USER_NAME_PATTERN),
"The name is 6-18 characters and can only contain letters, numbers or underscores");
"The name is 5-16 characters " +
"and can only contain letters, " +
"numbers or underscores");
E.checkArgument(!StringUtils.isEmpty(this.password) &&
this.password.matches(USER_PASSWORD_PATTERN),
"The password is 8-16 characters, which can be letters, numbers or special symbols");
"The password is 5-16 characters, " +
"which can be letters, numbers or " +
"special symbols");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,12 @@
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.*;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.DatatypeConverter;

import com.baidu.hugegraph.HugeGraph;
import com.baidu.hugegraph.StandardHugeGraph;
import org.apache.commons.lang3.StringUtils;
import org.apache.tinkerpop.gremlin.server.auth.AuthenticationException;
import org.glassfish.grizzly.http.server.Request;
Expand All @@ -56,7 +54,7 @@
import com.google.common.collect.ImmutableList;

@Provider
@PreMatching
/* @PreMatching */
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

Expand All @@ -70,6 +68,10 @@ public class AuthenticationFilter implements ContainerRequestFilter {
"versions"
);

private static final List<String> ANONYMOUS_API_LIST = ImmutableList.of(
"metrics/backend"
);

@Context
private javax.inject.Provider<GraphManager> managerProvider;

Expand All @@ -95,6 +97,24 @@ protected User authenticate(ContainerRequestContext context) {
return User.ANONYMOUS;
}

if (AuthenticationFilter.isAnonymousAPI(context)) {
// Return anonymous user if access anonymous api
return User.ANONYMOUS;
}

MultivaluedMap<String, String> pathParameters =
context.getUriInfo().getPathParameters();
if (pathParameters != null && pathParameters.size() > 0) {
List<String> parameters = pathParameters.get("graph");
if (parameters != null && parameters.size() > 0) {
HugeGraph target = manager.graph(parameters.get(0));
if (target != null && target instanceof StandardHugeGraph) {
// Return anonymous user if access standard hugeGraph
return User.ANONYMOUS;
}
}
}

// Get peer info
Request request = this.requestProvider.get();
String peer = null;
Expand Down Expand Up @@ -291,4 +311,18 @@ public static boolean isWhiteAPI(ContainerRequestContext context) {
}
return false;
}

public static boolean isAnonymousAPI(ContainerRequestContext context) {
String path = context.getUriInfo().getPath();

E.checkArgument(StringUtils.isNotEmpty(path),
"Invalid request uri '%s'", path);

for (String anonymousApi : ANONYMOUS_API_LIST) {
if (path.endsWith(anonymousApi)) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,20 @@ public String system() {
@Timed
@Path("backend")
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed({"admin", "$owner= $action=metrics_read"})
@RolesAllowed({"admin", "$owner= $action=metrics_read", "dynamic"})
public String backend(@Context GraphManager manager) {
Map<String, Map<String, Object>> results = InsertionOrderUtil.newMap();
for (String graph : manager.graphs()) {
HugeGraph g = manager.graph(graph);
Map<String, Object> metrics = InsertionOrderUtil.newMap();
metrics.put(BackendMetrics.BACKEND, g.backend());
try {
HugeGraph g = manager.graph(graph);
Map<String, Object> metrics = InsertionOrderUtil.newMap();
metrics.put(BackendMetrics.BACKEND, g.backend());
metrics.putAll(g.metadata(null, "metrics"));
results.put(graph, metrics);
} catch (Throwable e) {
metrics.put(BackendMetrics.EXCEPTION, e.toString());
// metrics.put(BackendMetrics.EXCEPTION, e.toString());
LOG.debug("Failed to get backend metrics", e);
}
results.put(graph, metrics);
}
return JsonUtil.toJson(results);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.net.InetAddress;
import java.util.Scanner;

import com.baidu.hugegraph.api.API;
import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang.StringUtils;
import org.apache.tinkerpop.gremlin.structure.util.GraphFactory;
Expand Down Expand Up @@ -77,7 +78,9 @@ private boolean requireInitAdminUser() {

private String inputPassword() {
String inputPrompt = "Please input the admin password:";
String notEmptyPrompt = "The admin password can't be empty";
String notEmptyPrompt = "The admin password is 5-16 characters, " +
"which can be letters, numbers or " +
"special symbols";
Console console = System.console();
while (true) {
String password = "";
Expand All @@ -90,7 +93,8 @@ private String inputPassword() {
Scanner scanner = new Scanner(System.in);
password = scanner.nextLine();
}
if (!password.isEmpty()) {
if (!password.isEmpty() &&
password.matches(API.USER_PASSWORD_PATTERN)) {
return password;
}
System.out.println(notEmptyPrompt);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ public static synchronized ServerOptions instance() {
"The name of graph used to store authentication information, " +
"like users, only for com.baidu.hugegraph.auth.StandardAuthenticator.",
disallowEmpty(),
"hugegraph"
"system"
);

public static final ConfigOption<String> AUTH_ADMIN_TOKEN =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public static synchronized AuthOptions instance() {
"The name of graph used to store authentication information, " +
"like users, only for com.baidu.hugegraph.auth.StandardAuthenticator.",
disallowEmpty(),
"hugegraph"
"system"
);

public static final ConfigOption<String> AUTH_ADMIN_TOKEN =
Expand Down
3 changes: 2 additions & 1 deletion hugegraph-dist/src/assembly/static/conf/gremlin-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ scriptEvaluationTimeout: 30000

channelizer: org.apache.tinkerpop.gremlin.server.channel.WsAndHttpChannelizer
graphs: {
hugegraph: conf/hugegraph.properties
hugegraph: conf/hugegraph.properties,
system: conf/system.properties
}
scriptEngines: {
gremlin-groovy: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ restserver.url=http://127.0.0.1:8080
#gremlinserver.url=http://127.0.0.1:8182

# graphs list with pair NAME:CONF_PATH
graphs=[hugegraph:conf/hugegraph.properties]
graphs=[hugegraph:conf/hugegraph.properties, system:conf/system.properties]

# The maximum thread ratio for batch writing, only take effect if the batch.max_write_threads is 0
batch.max_write_ratio=80
Expand All @@ -15,7 +15,7 @@ batch.max_write_threads=0
#auth.authenticator=

# for StandardAuthenticator mode
#auth.graph_store=hugegraph
auth.graph_store=system
# auth client config
#auth.remote_url=127.0.0.1:8899,127.0.0.1:8898,127.0.0.1:8897

Expand Down
1 change: 1 addition & 0 deletions hugegraph-dist/src/assembly/static/conf/system.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# gremlin entrance to create graph
# auth config: com.baidu.hugegraph.auth.HugeFactoryAuthProxy
gremlin.graph=com.baidu.hugegraph.auth.HugeFactoryAuthProxy

# cache config
Expand Down
2 changes: 1 addition & 1 deletion hugegraph-dist/src/assembly/travis/run-api-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mvn package -DskipTests

# config rest-server
sed -i 's/#auth.authenticator=/auth.authenticator=com.baidu.hugegraph.auth.StandardAuthenticator/' $REST_SERVER_CONF
sed -i 's/#auth.admin_token=/auth.admin_token=pa/' $REST_SERVER_CONF
sed -i 's/#auth.admin_token=/auth.admin_token=admin/' $REST_SERVER_CONF

# config hugegraph.properties
sed -i 's/gremlin.graph=.*/gremlin.graph=com.baidu.hugegraph.auth.HugeFactoryAuthProxy/' $CONF
Expand Down
2 changes: 1 addition & 1 deletion hugegraph-dist/src/assembly/travis/start-server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ fi
echo "schema.sync_deletion=true" >> $CONF

AGENT_JAR=${HOME_DIR}/${TRAVIS_DIR}/jacocoagent.jar
echo -e "pa" | $BIN/init-store.sh && $BIN/start-hugegraph.sh -j "-javaagent:${AGENT_JAR}=includes=*,port=36320,destfile=jacoco-it.exec,output=tcpserver" -v
echo -e "admin" | $BIN/init-store.sh && $BIN/start-hugegraph.sh -j "-javaagent:${AGENT_JAR}=includes=*,port=36320,destfile=jacoco-it.exec,output=tcpserver" -v
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public class BaseApiTest {
private static String BASE_URL = "http://127.0.0.1:8080";
private static String GRAPH = "hugegraph";
private static final String USERNAME = "admin";
private static final String PASSWORD = "pa";
private static final String PASSWORD = "admin";

private static final String URL_PREFIX = "graphs/" + GRAPH;
private static final String SCHEMA_PKS = "/schema/propertykeys";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ public void testScript() {
public void testClearAndInit() {
String body = "{"
+ "\"gremlin\":\""
+ "def auth = hugegraph.hugegraph().authManager();"
+ "def auth = system.hugegraph().authManager();"
+ "def admin = auth.findUser('admin');"
+ "hugegraph.clearBackend();"
+ "hugegraph.initBackend();"
+ "auth.createUser(admin);\","
+ "\","
+ "\"bindings\":{},"
+ "\"language\":\"gremlin-groovy\","
+ "\"aliases\":{\"g\":\"__g_hugegraph\"}}";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@

public class LoginApiTest extends BaseApiTest {

private static final String PATH = "graphs/hugegraph/auth";
private static final String USER_PATH = "graphs/hugegraph/auth/users";
private static final String PATH = "graphs/auth";
private static final String USER_PATH = "graphs/auth/users";
private String userId4Test;

@Before
public void setup() {
Response r = this.createUser("test", "test");
Response r = this.createUser("test1", "test1");
Map<String, Object> user = r.readEntity(
new GenericType<Map<String, Object>>(){});
this.userId4Test = (String) user.get("id");
Expand All @@ -59,14 +59,14 @@ public void teardown() {
public void testLogin() {
Response r;

r = this.login("test", "test");
r = this.login("test1", "test1");
String result = assertResponseStatus(200, r);
assertJsonContains(result, "token");

r = this.login("test", "pass");
r = this.login("test1", "pass1");
assertResponseStatus(401, r);

r = this.login("pass", "pass");
r = this.login("pass1", "pass1");
assertResponseStatus(401, r);
}

Expand All @@ -75,7 +75,7 @@ public void testLogout() {
Response r;
String result;

r = this.login("test", "test");
r = this.login("test1", "test1");
result = assertResponseStatus(200, r);
assertJsonContains(result, "token");

Expand All @@ -99,7 +99,7 @@ public void testVerify() {
Response r;
String result;

r = this.login("test", "test");
r = this.login("test1", "test1");
result = assertResponseStatus(200, r);
assertJsonContains(result, "token");

Expand All @@ -118,7 +118,7 @@ public void testVerify() {
result,
new TypeReference<Map<String, Object>>(){});
Assert.assertEquals(this.userId4Test, user.get("user_id"));
Assert.assertEquals("test", user.get("user_name"));
Assert.assertEquals("test1", user.get("user_name"));

String invalidToken = "eyJhbGciOiJIUzI1NiJ9.eyJ1caVyX25hbWUiOiJ0ZXN0IiwidXNlcl9pZCI6Ii02Mzp0ZXN0IiwiZXhwIjoxNjI0MzUzMjUyfQ.kYot-3mSGlfSbEMzxrTs84q8YanhTTxtsKPPG25CNxA";
headers = new MultivaluedHashMap<>();
Expand Down
Loading

0 comments on commit a3b6b9d

Please sign in to comment.