Skip to content

Commit

Permalink
Merge remote-tracking branch 'base/master' into pd-store-dev
Browse files Browse the repository at this point in the history
# Conflicts:
#	hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/version/CoreVersion.java
#	pom.xml
  • Loading branch information
Pengzna committed Apr 3, 2024
2 parents 4a87bb4 + 27cf52b commit 1a33a73
Show file tree
Hide file tree
Showing 50 changed files with 878 additions and 306 deletions.
5 changes: 3 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ charset = utf-8
end_of_line = lf
insert_final_newline = true

[*.{java,xml,py}]
[*.{java, xml, py}]
indent_style = space
indent_size = 4

[*.{java,xml}]
[*.{java, xml}]
# Ignore the IDEA unsupported warning & it works well (indeed)
continuation_indent_size = 8
5 changes: 3 additions & 2 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ For example:

<!-- DO NOT REMOVE THIS SECTION. CHECK THE PROPER BOX ONLY. -->

- [ ] Nope
- [ ] Dependencies (add/update license info) <!-- Don't forget to add/update the info in "LICENSE" & "NOTICE" files (both in root & dist module) -->
- [ ] Dependencies ([add/update license](https://hugegraph.apache.org/docs/contribution-guidelines/contribute/#321-check-licenses) info & [regenerate_dependencies](../hugegraph-server/hugegraph-dist/scripts/dependency/regenerate_known_dependencies.sh)) <!-- Don't forget to add/update the info in "LICENSE" & "NOTICE" files (both in root & dist module) -->
- [ ] Modify configurations
- [ ] The public API
- [ ] Other affects (typed here)
- [ ] Nope


## Documentation Status

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/check-dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
dependency-check:
runs-on: ubuntu-latest
env:
USE_STAGE: 'false' # Whether to include the stage repository.
USE_STAGE: 'true' # Whether to include the stage repository.
SCRIPT_DEPENDENCY: hugegraph-server/hugegraph-dist/scripts/dependency
steps:
- name: Checkout source
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ on:

jobs:
build:
# TODO: we need test & replace it to ubuntu-24.04 or ubuntu-latest
runs-on: ubuntu-20.04
env:
USE_STAGE: 'false' # Whether to include the stage repository.
USE_STAGE: 'true' # Whether to include the stage repository.
TRAVIS_DIR: hugegraph-server/hugegraph-dist/src/assembly/travis
REPORT_DIR: target/site/jacoco
BACKEND: ${{ matrix.BACKEND }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
jobs:
analyze:
env:
USE_STAGE: 'false' # Whether to include the stage repository.
USE_STAGE: 'true' # Whether to include the stage repository.
name: Analyze
runs-on: ubuntu-latest
permissions:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/licence-checker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
check-license:
runs-on: ubuntu-latest
env:
USE_STAGE: 'false' # Whether to include the stage repository.
USE_STAGE: 'true' # Whether to include the stage repository.
steps:
- uses: actions/checkout@v4

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,6 @@ hs_err_pid*
.mtj.tmp/
# blueJ files
*.ctxt

# docker volumes ignore
hugegraph-server/hugegraph-dist/docker/data/
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
## What is Apache HugeGraph?

[HugeGraph](https://hugegraph.apache.org/) is a fast-speed and highly-scalable [graph database](https://en.wikipedia.org/wiki/Graph_database).
Billions of vertices and edges can be easily stored into and queried from HugeGraph due to its excellent OLTP ability. As compliance to [Apache TinkerPop 3](https://tinkerpop.apache.org/) framework, various complicated graph queries can be accomplished through [Gremlin](https://tinkerpop.apache.org/gremlin.html)(a powerful graph traversal language).
Billions of vertices and edges can be easily stored into and queried from HugeGraph due to its excellent OLTP ability.
As compliance to [Apache TinkerPop 3](https://tinkerpop.apache.org/) framework, various complicated graph queries can be
achieved through [Gremlin](https://tinkerpop.apache.org/gremlin.html)(a powerful graph traversal language).


## Features
Expand All @@ -34,13 +36,14 @@ Billions of vertices and edges can be easily stored into and queried from HugeGr

We can use `docker run -itd --name=graph -p 8080:8080 hugegraph/hugegraph` to quickly start an inner
HugeGraph server with `RocksDB` (in backgrounds) for **test/dev**.
You can visit [doc page](https://hugegraph.apache.org/docs/quickstart/hugegraph-server/#3-deploy) or the [README](hugegraph-server/hugegraph-dist/docker/READEME.md) for more details.
You can visit [doc page](https://hugegraph.apache.org/docs/quickstart/hugegraph-server/#3-deploy) or
the [README](hugegraph-server/hugegraph-dist/docker/READEME.md) for more details. ([Docker Compose](./hugegraph-server/hugegraph-dist/docker/example))

> Note:
>
> 1. The docker image of hugegraph is a convenience release, but not **official distribution** artifacts. You can find more details from [ASF Release Distribution Policy](https://infra.apache.org/release-distribution.html#dockerhub).
>
> 2. Recommand to use `release tag`(like `1.2.0`) for the stable version. Use `latest` tag to experience the newest functions in development.
> 2. Recommend to use `release tag`(like `1.2.0`) for the stable version. Use `latest` tag to experience the newest functions in development.
### 2. Download Way

Expand All @@ -56,12 +59,11 @@ The project [doc page](https://hugegraph.apache.org/docs/) contains more informa
and provides detailed documentation for users. (Structure / Usage / API / Configs...)

And here are links of other **HugeGraph** component/repositories:
1. [hugegraph-toolchain](https://github.com/apache/incubator-hugegraph-toolchain) (graph tools **[loader](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-loader)/[dashboard](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-hubble)/[tool](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-tools)/[client](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-client)**)
2. [hugegraph-computer](https://github.com/apache/incubator-hugegraph-computer) (integrated **graph computing** system)
3. [hugegraph-commons](https://github.com/apache/incubator-hugegraph-commons) (**common & rpc** libs)
4. [hugegraph-website](https://github.com/apache/incubator-hugegraph-doc) (**doc & website** code)


1. [hugegraph-toolchain](https://github.com/apache/hugegraph-toolchain) (graph tools **[loader](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-loader)/[dashboard](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-hubble)/[tool](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-tools)/[client](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-client)**)
2. [hugegraph-computer](https://github.com/apache/hugegraph-computer) (integrated **graph computing** system)
3. [hugegraph-commons](https://github.com/apache/hugegraph-commons) (**common & rpc** libs)
4. [hugegraph-website](https://github.com/apache/hugegraph-doc) (**doc & website** code)
5. [hugegraph-ai](https://github.com/apache/incubator-hugegraph-ai) (integrated **Graph AI/LLM/KG** system)

## License

Expand Down
6 changes: 6 additions & 0 deletions hugegraph-server/hugegraph-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@
<artifactId>arthas-packaging</artifactId>
<version>${arthas.version}</version>
</dependency>
<dependency>
<groupId>org.gridkit.jvmtool</groupId>
<artifactId>sjk-core</artifactId>
<version>0.22</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,9 @@ public String login(@Context GraphManager manager, @PathParam("graph") String gr
checkCreatingBody(jsonLogin);

try {
String token = manager.authManager()
.loginUser(jsonLogin.name, jsonLogin.password);
String token = manager.authManager().loginUser(jsonLogin.name, jsonLogin.password);
HugeGraph g = graph(manager, graph);
return manager.serializer(g)
.writeMap(ImmutableMap.of("token", token));
return manager.serializer(g).writeMap(ImmutableMap.of("token", token));
} catch (AuthenticationException e) {
throw new NotAuthorizedException(e.getMessage(), e);
}
Expand All @@ -86,8 +84,7 @@ public String login(@Context GraphManager manager, @PathParam("graph") String gr
@Status(Status.OK)
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON_WITH_CHARSET)
public void logout(@Context GraphManager manager,
@PathParam("graph") String graph,
public void logout(@Context GraphManager manager, @PathParam("graph") String graph,
@HeaderParam(HttpHeaders.AUTHORIZATION) String auth) {
E.checkArgument(StringUtils.isNotEmpty(auth),
"Request header Authorization must not be null");
Expand All @@ -107,10 +104,8 @@ public void logout(@Context GraphManager manager,
@Status(Status.OK)
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON_WITH_CHARSET)
public String verifyToken(@Context GraphManager manager,
@PathParam("graph") String graph,
@HeaderParam(HttpHeaders.AUTHORIZATION)
String token) {
public String verifyToken(@Context GraphManager manager, @PathParam("graph") String graph,
@HeaderParam(HttpHeaders.AUTHORIZATION) String token) {
E.checkArgument(StringUtils.isNotEmpty(token),
"Request header Authorization must not be null");
LOG.debug("Graph [{}] get user: {}", graph, token);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
import java.io.IOException;
import java.net.URI;

import org.apache.hugegraph.auth.HugeAuthenticator;
import org.apache.hugegraph.config.HugeConfig;
import org.apache.hugegraph.config.ServerOptions;
import org.apache.hugegraph.core.GraphManager;
import org.apache.hugegraph.metrics.MetricsUtil;
import org.apache.hugegraph.util.Log;
import org.slf4j.Logger;
Expand Down Expand Up @@ -55,6 +57,9 @@ public class AccessLogFilter implements ContainerResponseFilter {
@Context
private jakarta.inject.Provider<HugeConfig> configProvider;

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

public static boolean needRecordLog(ContainerRequestContext context) {
// TODO: add test for 'path' result ('/gremlin' or 'gremlin')
String path = context.getUriInfo().getPath();
Expand Down Expand Up @@ -114,6 +119,13 @@ public void filter(ContainerRequestContext requestContext,
executeTime, null, method, path, uri.getQuery());
}
}

// Unset the context in "HugeAuthenticator", need distinguish Graph/Auth server lifecycle
GraphManager manager = managerProvider.get();
// TODO: transfer Authorizer if we need after.
if (manager.requireAuthentication()) {
manager.unauthorize(requestContext.getSecurityContext());
}
}

private boolean statusOk(int status) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@
import org.apache.tinkerpop.gremlin.server.auth.AuthenticationException;
import org.glassfish.grizzly.http.server.Request;
import org.glassfish.grizzly.utils.Charsets;
import org.gridkit.jvmtool.cmd.AntPathMatcher;
import org.slf4j.Logger;

import com.alipay.remoting.util.StringUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

import jakarta.annotation.Priority;
import jakarta.ws.rs.BadRequestException;
Expand All @@ -70,14 +71,15 @@ public class AuthenticationFilter implements ContainerRequestFilter {

private static final Logger LOG = Log.logger(AuthenticationFilter.class);

private static final List<String> WHITE_API_LIST = ImmutableList.of(
"auth/login",
private static final AntPathMatcher MATCHER = new AntPathMatcher();
private static final Set<String> FIXED_WHITE_API_SET = ImmutableSet.of(
"versions",
"openapi.json"
);
/** Remove auth/login API from whitelist */
private static final Set<String> FLEXIBLE_WHITE_API_SET = ImmutableSet.of();

private static String whiteIpStatus;

private static Boolean enabledWhiteIpCheck;
private static final String STRING_WHITE_IP_LIST = "whiteiplist";
private static final String STRING_ENABLE = "enable";

Expand All @@ -92,7 +94,7 @@ public class AuthenticationFilter implements ContainerRequestFilter {

@Override
public void filter(ContainerRequestContext context) throws IOException {
if (AuthenticationFilter.isWhiteAPI(context)) {
if (isWhiteAPI(context)) {
return;
}
User user = this.authenticate(context);
Expand All @@ -105,7 +107,7 @@ protected User authenticate(ContainerRequestContext context) {
E.checkState(manager != null, "Context GraphManager is absent");

if (!manager.requireAuthentication()) {
// Return anonymous user with admin role if disable authentication
// Return anonymous user with an admin role if disable authentication
return User.ANONYMOUS;
}

Expand All @@ -119,11 +121,12 @@ protected User authenticate(ContainerRequestContext context) {
}

// Check whiteIp
if (whiteIpStatus == null) {
whiteIpStatus = this.configProvider.get().get(WHITE_IP_STATUS);
if (enabledWhiteIpCheck == null) {
String whiteIpStatus = this.configProvider.get().get(WHITE_IP_STATUS);
enabledWhiteIpCheck = Objects.equals(whiteIpStatus, STRING_ENABLE);
}

if (Objects.equals(whiteIpStatus, STRING_ENABLE) && request != null) {
if (enabledWhiteIpCheck && request != null) {
peer = request.getRemoteAddr() + ":" + request.getRemotePort();
path = request.getRequestURI();

Expand All @@ -132,38 +135,32 @@ protected User authenticate(ContainerRequestContext context) {
boolean whiteIpEnabled = manager.authManager().getWhiteIpStatus();
if (!path.contains(STRING_WHITE_IP_LIST) && whiteIpEnabled &&
!whiteIpList.contains(remoteIp)) {
throw new ForbiddenException(
String.format("Remote ip '%s' is not permitted",
remoteIp));
throw new ForbiddenException(String.format("Remote ip '%s' is not permitted",
remoteIp));
}
}

Map<String, String> credentials = new HashMap<>();
// Extract authentication credentials
String auth = context.getHeaderString(HttpHeaders.AUTHORIZATION);
if (auth == null) {
throw new NotAuthorizedException(
"Authentication credentials are required",
"Missing authentication credentials");
throw new NotAuthorizedException("Authentication credentials are required",
"Missing authentication credentials");
}

if (auth.startsWith(BASIC_AUTH_PREFIX)) {
auth = auth.substring(BASIC_AUTH_PREFIX.length());
auth = new String(DatatypeConverter.parseBase64Binary(auth),
Charsets.ASCII_CHARSET);
auth = new String(DatatypeConverter.parseBase64Binary(auth), Charsets.ASCII_CHARSET);
String[] values = auth.split(":");
if (values.length != 2) {
throw new BadRequestException(
"Invalid syntax for username and password");
throw new BadRequestException("Invalid syntax for username and password");
}

final String username = values[0];
final String password = values[1];

if (StringUtils.isEmpty(username) ||
StringUtils.isEmpty(password)) {
throw new BadRequestException(
"Invalid syntax for username and password");
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
throw new BadRequestException("Invalid syntax for username and password");
}

credentials.put(HugeAuthenticator.KEY_USERNAME, username);
Expand All @@ -172,8 +169,7 @@ protected User authenticate(ContainerRequestContext context) {
String token = auth.substring(BEARER_TOKEN_PREFIX.length());
credentials.put(HugeAuthenticator.KEY_TOKEN, token);
} else {
throw new BadRequestException(
"Only HTTP Basic or Bearer authentication is supported");
throw new BadRequestException("Only HTTP Basic or Bearer authentication is supported");
}

credentials.put(HugeAuthenticator.KEY_ADDRESS, peer);
Expand All @@ -183,8 +179,7 @@ protected User authenticate(ContainerRequestContext context) {
try {
return manager.authenticate(credentials);
} catch (AuthenticationException e) {
throw new NotAuthorizedException("Authentication failed",
e.getMessage());
throw new NotAuthorizedException("Authentication failed", e.getMessage());
}
}

Expand Down Expand Up @@ -248,7 +243,7 @@ private boolean matchPermission(String required) {
requiredPerm = RequiredPerm.fromPermission(required);

/*
* Replace owner value(it may be a variable) if the permission
* Replace owner value (it may be a variable) if the permission
* format like: "$owner=$graph $action=vertex_write"
*/
String owner = requiredPerm.owner();
Expand All @@ -264,8 +259,7 @@ private boolean matchPermission(String required) {

if (LOG.isDebugEnabled()) {
LOG.debug("Verify permission {} {} for user '{}' with role {}",
requiredPerm.action().string(),
requiredPerm.resourceObject(),
requiredPerm.action().string(), requiredPerm.resourceObject(),
this.user.username(), this.user.role());
}

Expand All @@ -274,9 +268,8 @@ private boolean matchPermission(String required) {

if (!valid && LOG.isInfoEnabled() &&
!required.equals(HugeAuthenticator.USER_ADMIN)) {
LOG.info("User '{}' is denied to {} {}",
this.user.username(), requiredPerm.action().string(),
requiredPerm.resourceObject());
LOG.info("User '{}' is denied to {} {}", this.user.username(),
requiredPerm.action().string(), requiredPerm.resourceObject());
}
return valid;
}
Expand Down Expand Up @@ -314,9 +307,12 @@ public boolean equals(Object obj) {

public static boolean isWhiteAPI(ContainerRequestContext context) {
String path = context.getUriInfo().getPath();
if (FIXED_WHITE_API_SET.contains(path)) {
return true;
}

for (String whiteApi : WHITE_API_LIST) {
if (path.endsWith(whiteApi)) {
for (String whiteApi : FLEXIBLE_WHITE_API_SET) {
if (MATCHER.match(whiteApi, path)) {
return true;
}
}
Expand Down
Loading

0 comments on commit 1a33a73

Please sign in to comment.