diff --git a/timbuctoo-instancev4/pom.xml b/timbuctoo-instancev4/pom.xml
index 4214a7261e..534da32422 100644
--- a/timbuctoo-instancev4/pom.xml
+++ b/timbuctoo-instancev4/pom.xml
@@ -265,7 +265,7 @@
com.graphql-java
graphql-java
- 11.0
+ 20.0
diff --git a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/datastores/implementations/bdb/BdbSchemaStore.java b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/datastores/implementations/bdb/BdbSchemaStore.java
index 6ab4efdea6..17738d4b3f 100644
--- a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/datastores/implementations/bdb/BdbSchemaStore.java
+++ b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/datastores/implementations/bdb/BdbSchemaStore.java
@@ -11,7 +11,6 @@
import nl.knaw.huygens.timbuctoo.v5.dataset.ImportStatus;
import nl.knaw.huygens.timbuctoo.v5.dataset.OptimizedPatchListener;
import nl.knaw.huygens.timbuctoo.v5.datastores.quadstore.dto.ChangeType;
-import nl.knaw.huygens.timbuctoo.v5.datastores.quadstore.dto.CursorQuad;
import nl.knaw.huygens.timbuctoo.v5.datastores.quadstore.dto.Direction;
import nl.knaw.huygens.timbuctoo.v5.datastores.quadstore.dto.QuadGraphs;
import nl.knaw.huygens.timbuctoo.v5.datastores.schemastore.SchemaStore;
diff --git a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/dropwizard/endpoints/GraphQl.java b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/dropwizard/endpoints/GraphQl.java
index 6bb8a1b2c3..5fea906675 100644
--- a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/dropwizard/endpoints/GraphQl.java
+++ b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/dropwizard/endpoints/GraphQl.java
@@ -3,17 +3,14 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.sleepycat.je.DatabaseException;
import graphql.ExecutionResult;
import graphql.GraphQL;
import graphql.GraphQLException;
import graphql.schema.GraphQLSchema;
import nl.knaw.huygens.timbuctoo.util.UriHelper;
import nl.knaw.huygens.timbuctoo.v5.dataset.DataSetRepository;
-import nl.knaw.huygens.timbuctoo.v5.dataset.exceptions.RdfProcessingFailedException;
import nl.knaw.huygens.timbuctoo.v5.dropwizard.contenttypes.SerializerWriter;
import nl.knaw.huygens.timbuctoo.v5.dropwizard.contenttypes.SerializerWriterRegistry;
-import nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.dto.RootData;
import nl.knaw.huygens.timbuctoo.v5.graphql.security.PermissionBasedFieldVisibility;
import nl.knaw.huygens.timbuctoo.v5.graphql.security.UserPermissionCheck;
import nl.knaw.huygens.timbuctoo.v5.graphql.serializable.SerializerExecutionStrategy;
@@ -35,6 +32,8 @@
import javax.ws.rs.core.StreamingOutput;
import javax.ws.rs.core.UriBuilder;
import java.net.URI;
+import java.time.Duration;
+import java.time.Instant;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -44,7 +43,6 @@
import static graphql.ExecutionInput.newExecutionInput;
import static nl.knaw.huygens.timbuctoo.util.JsonBuilder.jsn;
import static nl.knaw.huygens.timbuctoo.util.JsonBuilder.jsnO;
-import static nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.dto.ContextData.contextData;
@Path("/v5/graphql")
public class GraphQl {
@@ -58,8 +56,7 @@ public class GraphQl {
public GraphQl(Supplier graphqlGetter, SerializerWriterRegistry serializerWriterRegistry,
UserValidator userValidator, UriHelper uriHelper, PermissionFetcher permissionFetcher,
- DataSetRepository dataSetRepository)
- throws DatabaseException, RdfProcessingFailedException {
+ DataSetRepository dataSetRepository) {
this.graphqlGetter = graphqlGetter;
this.serializerWriterRegistry = serializerWriterRegistry;
this.userValidator = userValidator;
@@ -85,7 +82,7 @@ public Response postJson(JsonNode body, @QueryParam("query") String query,
} else {
queryFromBody = null;
}
- Map variables = null;
+ Map variables = null;
if (body.has("variables")) {
try {
variables = objectMapper.treeToValue(body.get("variables"), HashMap.class);
@@ -119,14 +116,13 @@ public Response get(@QueryParam("query") String query, @HeaderParam("accept") St
return executeGraphql(null, acceptHeader, acceptParam, query, null, null, authHeader);
}
-
public Response executeGraphql(String query, String acceptHeader, String acceptParam, String queryFromBody,
- Map variables, String operationName, String authHeader) {
+ Map variables, String operationName, String authHeader) {
final SerializerWriter serializerWriter;
if (acceptParam != null && !acceptParam.isEmpty()) {
acceptHeader = acceptParam; //Accept param overrules header because it's more under the user's control
}
- if (unSpecifiedAcceptHeader(acceptHeader)) {
+ if (acceptHeader == null || acceptHeader.isEmpty() || "*/*".equals(acceptHeader)) {
acceptHeader = MediaType.APPLICATION_JSON;
}
if (MediaType.APPLICATION_JSON.equals(acceptHeader)) {
@@ -166,14 +162,11 @@ public Response executeGraphql(String query, String acceptHeader, String acceptP
user = Optional.empty();
}
- UserPermissionCheck userPermissionCheck = new UserPermissionCheck(
- user,
- permissionFetcher
- );
-
- final GraphQLSchema transform = graphqlGetter
- .get()
- .transform(b -> b.fieldVisibility(new PermissionBasedFieldVisibility(userPermissionCheck,dataSetRepository)));
+ final UserPermissionCheck userPermissionCheck = new UserPermissionCheck(user, permissionFetcher);
+ final GraphQLSchema schema = graphqlGetter.get();
+ final GraphQLSchema transform = schema.transformWithoutTypes(sb ->
+ sb.codeRegistry(schema.getCodeRegistry().transform(crb ->
+ crb.fieldVisibility(new PermissionBasedFieldVisibility(userPermissionCheck, dataSetRepository)))));
final GraphQL.Builder builder = GraphQL.newGraphQL(transform);
if (serializerWriter != null) {
@@ -185,8 +178,8 @@ public Response executeGraphql(String query, String acceptHeader, String acceptP
try {
final ExecutionResult result = graphQl
.execute(newExecutionInput()
- .root(new RootData(user))
- .context(contextData(userPermissionCheck, user))
+ .root(new Object())
+ .graphQLContext(Map.of("userPermissionCheck", userPermissionCheck, "user", user))
.query(queryFromBody)
.operationName(operationName)
.variables(variables == null ? Collections.emptyMap() : variables)
@@ -219,10 +212,4 @@ public Response executeGraphql(String query, String acceptHeader, String acceptP
// throw e;
}
}
-
-
- public boolean unSpecifiedAcceptHeader(@HeaderParam("accept") String acceptHeader) {
- return acceptHeader == null || acceptHeader.isEmpty() || "*/*".equals(acceptHeader);
- }
-
}
diff --git a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/DirectiveRetriever.java b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/DirectiveRetriever.java
index 62ef7bbf6e..7064898a38 100644
--- a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/DirectiveRetriever.java
+++ b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/DirectiveRetriever.java
@@ -9,12 +9,11 @@
public class DirectiveRetriever {
public static Optional getDirectiveArgument(GraphQLObjectType parentType, String directiveName,
String argumentName) {
- // if (parentType.getDefinition().getDirectives(directiveName).isEmpty()) {
- // return Optional.empty();
- // }
+ if (parentType.getDefinition().getDirectives(directiveName).isEmpty()) {
+ return Optional.empty();
+ }
- // return Optional.of(parentType.getDefinition().getDirectives(directiveName).get(0))
- return Optional.ofNullable(parentType.getDefinition().getDirective(directiveName))
+ return Optional.of(parentType.getDefinition().getDirectives(directiveName).get(0))
.map(d -> d.getArgument(argumentName))
.map(v -> (StringValue) v.getValue())
.map(StringValue::getValue);
@@ -22,12 +21,11 @@ public static Optional getDirectiveArgument(GraphQLObjectType parentType
public static Optional getDirectiveArgument(GraphQLFieldDefinition field, String directiveName,
String argumentName) {
- // if (field.getDefinition().getDirectives(directiveName).isEmpty()) {
- // return Optional.empty();
- // }
- //
- // return Optional.of(field.getDefinition().getDirectives(directiveName).get(0))
- return Optional.ofNullable(field.getDefinition().getDirective(directiveName))
+ if (field.getDefinition().getDirectives(directiveName).isEmpty()) {
+ return Optional.empty();
+ }
+
+ return Optional.of(field.getDefinition().getDirectives(directiveName).get(0))
.map(d -> d.getArgument(argumentName))
.map(v -> (StringValue) v.getValue())
.map(StringValue::getValue);
diff --git a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/DataMetaDataListFetcher.java b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/DataMetaDataListFetcher.java
index b4a8c80fa9..37248d587b 100644
--- a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/DataMetaDataListFetcher.java
+++ b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/DataMetaDataListFetcher.java
@@ -3,16 +3,15 @@
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import nl.knaw.huygens.timbuctoo.v5.dataset.DataSetRepository;
-import nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.dto.ContextData;
import nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.dto.DataSetWithDatabase;
import nl.knaw.huygens.timbuctoo.v5.graphql.security.UserPermissionCheck;
import nl.knaw.huygens.timbuctoo.v5.graphql.security.UserPermissionCheck.OldGraphQlPermission;
-import nl.knaw.huygens.timbuctoo.v5.security.dto.Permission;
+import nl.knaw.huygens.timbuctoo.v5.security.dto.User;
+import java.util.Optional;
import java.util.stream.Stream;
public class DataMetaDataListFetcher implements DataFetcher {
-
private final DataSetRepository dataSetRepository;
public DataMetaDataListFetcher(DataSetRepository dataSetRepository) {
@@ -22,20 +21,19 @@ public DataMetaDataListFetcher(DataSetRepository dataSetRepository) {
@Override
public Object get(DataFetchingEnvironment env) {
return (Iterable) () -> {
- Stream dataSets = dataSetRepository.getDataSets()
- .stream()
- .map(dataSet -> new DataSetWithDatabase(dataSet,
- ((ContextData) env.getContext())
- .getUserPermissionCheck()));
+ Stream dataSets = dataSetRepository
+ .getDataSets()
+ .stream()
+ .map(dataSet -> new DataSetWithDatabase(dataSet, env.getGraphQlContext().get("userPermissionCheck")));
if (env.getArgument("ownOnly")) {
- String userId =
- ((ContextData) env.getContext()).getUser().map(u -> "u" + u.getPersistentId()).orElse(null);
+ Optional user = env.getGraphQlContext().get("user");
+ String userId = user.map(u -> "u" + u.getPersistentId()).orElse(null);
dataSets = dataSets.filter(d -> d.getOwnerId().equals(userId));
}
// translate
OldGraphQlPermission permission = OldGraphQlPermission.valueOf(env.getArgument("permission"));
- dataSets = dataSets.filter(d -> ((ContextData) env.getContext()).getUserPermissionCheck()
- .hasOldGraphQlPermission(d, permission));
+ UserPermissionCheck userPermissionCheck = env.getGraphQlContext().get("userPermissionCheck");
+ dataSets = dataSets.filter(d -> userPermissionCheck.hasOldGraphQlPermission(d, permission));
return dataSets.iterator();
};
diff --git a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/DataSetImportStatusFetcher.java b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/DataSetImportStatusFetcher.java
index 60f44b5581..43ca5328ab 100644
--- a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/DataSetImportStatusFetcher.java
+++ b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/DataSetImportStatusFetcher.java
@@ -7,7 +7,6 @@
import nl.knaw.huygens.timbuctoo.v5.dataset.dto.DataSet;
import nl.knaw.huygens.timbuctoo.v5.dataset.dto.DataSetMetaData;
import nl.knaw.huygens.timbuctoo.v5.dataset.dto.LogEntry;
-import nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.dto.ContextData;
import nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.dto.LogEntryImportStatus;
import nl.knaw.huygens.timbuctoo.v5.graphql.mutations.MutationHelpers;
import nl.knaw.huygens.timbuctoo.v5.security.dto.Permission;
@@ -29,11 +28,10 @@ public DataSetImportStatusFetcher(DataSetRepository dataSetRepository) {
@Override
public List get(DataFetchingEnvironment env) {
- User currentUser = env.getContext().getUser()
- .orElseThrow(() -> new RuntimeException("You are not logged in"));
+ Optional user = env.getGraphQlContext().get("user");
+ User currentUser = user.orElseThrow(() -> new RuntimeException("You are not logged in"));
DataSetMetaData dataSetMetaData = env.getSource();
-
MutationHelpers.checkPermission(env, dataSetMetaData, Permission.READ_IMPORT_STATUS);
DataSetMetaData input = env.getSource();
@@ -43,16 +41,16 @@ public List get(DataFetchingEnvironment env) {
input.getDataSetId()
);
- return dataSetOpt.map(dataSet -> dataSet.getImportManager().getLogList())
- .map(logList -> {
- final int[] num = new int[]{0};
- return logList.getEntries().stream().map(logEntry -> {
- Iterable unprocessedEntries = logList::getUnprocessed;
- boolean unprocessed = stream(unprocessedEntries.spliterator(), false)
- .anyMatch(unprocessedEntry -> unprocessedEntry.equals(logEntry));
- return new LogEntryImportStatus(logEntry, num[0]++, unprocessed);
- }).collect(toList());
- }).orElse(Lists.newArrayList());
+ return dataSetOpt
+ .map(dataSet -> dataSet.getImportManager().getLogList())
+ .map(logList -> {
+ final int[] num = new int[]{0};
+ return logList.getEntries().stream().map(logEntry -> {
+ Iterable unprocessedEntries = logList::getUnprocessed;
+ boolean unprocessed = stream(unprocessedEntries.spliterator(), false)
+ .anyMatch(unprocessedEntry -> unprocessedEntry.equals(logEntry));
+ return new LogEntryImportStatus(logEntry, num[0]++, unprocessed);
+ }).collect(toList());
+ }).orElse(Lists.newArrayList());
}
-
}
diff --git a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/ImportStatusFetcher.java b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/ImportStatusFetcher.java
index cab14c8ff4..e642a3f461 100644
--- a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/ImportStatusFetcher.java
+++ b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/ImportStatusFetcher.java
@@ -6,7 +6,6 @@
import nl.knaw.huygens.timbuctoo.v5.dataset.dto.DataSet;
import nl.knaw.huygens.timbuctoo.v5.dataset.dto.DataSetMetaData;
import nl.knaw.huygens.timbuctoo.v5.dataset.dto.LogEntry;
-import nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.dto.ContextData;
import nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.dto.LogEntryImportStatus;
import nl.knaw.huygens.timbuctoo.v5.graphql.mutations.MutationHelpers;
import nl.knaw.huygens.timbuctoo.v5.security.dto.Permission;
@@ -26,11 +25,10 @@ public ImportStatusFetcher(DataSetRepository dataSetRepository) {
@Override
public LogEntryImportStatus get(DataFetchingEnvironment env) {
- User currentUser = env.getContext().getUser()
- .orElseThrow(() -> new RuntimeException("You are not logged in"));
+ Optional user = env.getGraphQlContext().get("user");
+ User currentUser = user.orElseThrow(() -> new RuntimeException("You are not logged in"));
DataSetMetaData dataSetMetaData = env.getSource();
-
MutationHelpers.checkPermission(env, dataSetMetaData, Permission.READ_IMPORT_STATUS);
Optional dataSetOpt = dataSetRepository.getDataSet(
@@ -39,19 +37,19 @@ public LogEntryImportStatus get(DataFetchingEnvironment env) {
dataSetMetaData.getDataSetId()
);
- return dataSetOpt.map(dataSet -> dataSet.getImportManager().getLogList())
- .map(logList -> {
- int id = Integer.parseInt(env.getArgument("id"));
- List entries = logList.getEntries();
- if (entries.size() > id) {
- LogEntry logEntry = logList.getEntries().get(id);
- Iterable unprocessedEntries = logList::getUnprocessed;
- boolean unprocessed = stream(unprocessedEntries.spliterator(), false)
- .anyMatch(unprocessedEntry -> unprocessedEntry.equals(logEntry));
- return new LogEntryImportStatus(logEntry, id, unprocessed);
- }
- return null;
- }).orElseThrow(() -> new RuntimeException("No import status with id: " + env.getArgument("id")));
-
+ return dataSetOpt
+ .map(dataSet -> dataSet.getImportManager().getLogList())
+ .map(logList -> {
+ int id = Integer.parseInt(env.getArgument("id"));
+ List entries = logList.getEntries();
+ if (entries.size() > id) {
+ LogEntry logEntry = logList.getEntries().get(id);
+ Iterable unprocessedEntries = logList::getUnprocessed;
+ boolean unprocessed = stream(unprocessedEntries.spliterator(), false)
+ .anyMatch(unprocessedEntry -> unprocessedEntry.equals(logEntry));
+ return new LogEntryImportStatus(logEntry, id, unprocessed);
+ }
+ return null;
+ }).orElseThrow(() -> new RuntimeException("No import status with id: " + env.getArgument("id")));
}
}
diff --git a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/OtherDataSetFetcher.java b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/OtherDataSetFetcher.java
index 7b8b5bb2f3..61bb1a963a 100644
--- a/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/OtherDataSetFetcher.java
+++ b/timbuctoo-instancev4/src/main/java/nl/knaw/huygens/timbuctoo/v5/graphql/datafetchers/OtherDataSetFetcher.java
@@ -8,10 +8,10 @@
import nl.knaw.huygens.timbuctoo.v5.dataset.dto.DataSet;
import nl.knaw.huygens.timbuctoo.v5.datastores.quadstore.dto.CursorQuad;
import nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.berkeleydb.dto.LazyTypeSubjectReference;
-import nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.dto.ContextData;
import nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.dto.DataSetWithDatabase;
import nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.dto.SubjectGraphReference;
-import nl.knaw.huygens.timbuctoo.v5.graphql.datafetchers.dto.SubjectReference;
+import nl.knaw.huygens.timbuctoo.v5.graphql.security.UserPermissionCheck;
+import nl.knaw.huygens.timbuctoo.v5.security.dto.User;
import java.util.HashSet;
import java.util.List;
@@ -24,7 +24,6 @@
import static nl.knaw.huygens.timbuctoo.util.Tuple.tuple;
public class OtherDataSetFetcher implements DataFetcher> {
-
private final DataSetRepository repo;
public OtherDataSetFetcher(DataSetRepository repo) {
@@ -34,15 +33,16 @@ public OtherDataSetFetcher(DataSetRepository repo) {
@Override
public List