Skip to content
This repository was archived by the owner on Dec 19, 2023. It is now read-only.

Feat/voyager csrf header #627

Merged
merged 6 commits into from
May 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,3 @@ PLUGIN_JACOCO_VER=0.8.7
PLUGIN_SONARQUBE_VER=3.2.0
PLUGIN_NEXUS_STAGING_VER=0.30.0
PLUGIN_GOOGLE_JAVA_FORMAT_VER=0.9
###
org.gradle.daemon=true
2 changes: 1 addition & 1 deletion graphql-spring-boot-autoconfigure/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ dependencies {
testImplementation "org.springframework.boot:spring-boot-starter-web"
testImplementation "org.springframework.boot:spring-boot-starter-actuator"
testImplementation "org.springframework.boot:spring-boot-starter-webflux"
// testImplementation "org.springframework.boot:spring-boot-starter-security"
testImplementation "org.springframework.boot:spring-boot-starter-security"
testImplementation "org.springframework.security:spring-security-test"
testImplementation "io.projectreactor:reactor-core"
testImplementation "io.reactivex.rxjava2:rxjava"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package graphql.kickstart.autoconfigure.editor;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class EditorConstants {

public static final String CSRF_ATTRIBUTE_NAME = "_csrf";
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ public class AltairAutoConfiguration {

@Bean
@ConditionalOnProperty(value = "graphql.altair.enabled", havingValue = "true")
AltairController altairController() {
return new AltairController();
AltairController altairController(
AltairProperties altairProperties,
AltairOptions altairOptions,
AltairResources altairResources) {
return new AltairController(altairProperties, altairOptions, altairResources);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringSubstitutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.util.StreamUtils;
Expand All @@ -27,14 +27,15 @@
/** @author Moncef AOUDIA */
@Slf4j
@Controller
@RequiredArgsConstructor
public class AltairController {

private static final String CDN_JSDELIVR_NET_NPM = "//cdn.jsdelivr.net/npm/";
private static final String ALTAIR = "altair-static";
private final ObjectMapper objectMapper = new ObjectMapper();
@Autowired private AltairProperties altairProperties;
@Autowired private AltairOptions altairOptions;
@Autowired private AltairResources altairResources;
private final AltairProperties altairProperties;
private final AltairOptions altairOptions;
private final AltairResources altairResources;

private String template;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package graphql.kickstart.autoconfigure.editor.voyager;

import static graphql.kickstart.autoconfigure.editor.EditorConstants.CSRF_ATTRIBUTE_NAME;

import java.io.IOException;
import java.util.Map;
import lombok.RequiredArgsConstructor;
Expand All @@ -9,6 +11,7 @@
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestAttribute;

/** @author Max David Günther */
@Controller
Expand All @@ -18,10 +21,12 @@ public class ReactiveVoyagerController {
@Autowired private VoyagerIndexHtmlTemplate indexTemplate;

@GetMapping(path = "${graphql.voyager.mapping:/voyager}")
public ResponseEntity<String> voyager(@PathVariable Map<String, String> params)
public ResponseEntity<String> voyager(
final @RequestAttribute(value = CSRF_ATTRIBUTE_NAME, required = false) Object csrf,
@PathVariable Map<String, String> params)
throws IOException {
// no context path in spring-webflux
String indexHtmlContent = indexTemplate.fillIndexTemplate("", params);
String indexHtmlContent = indexTemplate.fillIndexTemplate("", csrf, params);
return ResponseEntity.ok()
.contentType(MediaType.valueOf("text/html; charset=UTF-8"))
.body(indexHtmlContent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
public class VoyagerAutoConfiguration {

@Bean
VoyagerController voyagerController() {
return new VoyagerController();
VoyagerController voyagerController(VoyagerIndexHtmlTemplate voyagerIndexHtmlTemplate) {
return new VoyagerController(voyagerIndexHtmlTemplate);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
package graphql.kickstart.autoconfigure.editor.voyager;

import static graphql.kickstart.autoconfigure.editor.EditorConstants.CSRF_ATTRIBUTE_NAME;

import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestAttribute;

/** @author Max David Günther */
@Controller
@RequiredArgsConstructor
public class VoyagerController {

@Autowired private VoyagerIndexHtmlTemplate indexTemplate;
private final VoyagerIndexHtmlTemplate indexTemplate;

@GetMapping(value = "${graphql.voyager.mapping:/voyager}")
public ResponseEntity<String> voyager(
HttpServletRequest request, @PathVariable Map<String, String> params) throws IOException {
HttpServletRequest request,
final @RequestAttribute(value = CSRF_ATTRIBUTE_NAME, required = false) Object csrf,
@PathVariable Map<String, String> params)
throws IOException {
String contextPath = request.getContextPath();
String indexHtmlContent = indexTemplate.fillIndexTemplate(contextPath, params);
String indexHtmlContent = indexTemplate.fillIndexTemplate(contextPath, csrf, params);
return ResponseEntity.ok()
.contentType(MediaType.valueOf("text/html; charset=UTF-8"))
.body(indexHtmlContent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package graphql.kickstart.autoconfigure.editor.voyager;

import static graphql.kickstart.autoconfigure.editor.EditorConstants.CSRF_ATTRIBUTE_NAME;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
Expand All @@ -21,9 +24,10 @@ public class VoyagerIndexHtmlTemplate {
private static final String FAVICON_APIS_GURU =
"//apis.guru/graphql-voyager/icons/favicon-16x16.png";

private final ObjectMapper objectMapper = new ObjectMapper();
private final VoyagerPropertiesConfiguration voyagerConfiguration;

public String fillIndexTemplate(String contextPath, Map<String, String> params)
public String fillIndexTemplate(String contextPath, Object csrf, Map<String, String> params)
throws IOException {
String template =
StreamUtils.copyToString(
Expand All @@ -34,6 +38,11 @@ public String fillIndexTemplate(String contextPath, Map<String, String> params)
String voyagerCdnVersion = voyagerConfiguration.getCdn().getVersion();

Map<String, String> replacements = new HashMap<>();
if (csrf != null) {
replacements.put(CSRF_ATTRIBUTE_NAME, objectMapper.writeValueAsString(csrf));
} else {
replacements.put(CSRF_ATTRIBUTE_NAME, "null");
}
replacements.put("graphqlEndpoint", constructGraphQlEndpoint(contextPath, params));
replacements.put("pageTitle", voyagerConfiguration.getPageTitle());
replacements.put("pageFavicon", getResourceUrl(basePath, "favicon.ico", FAVICON_APIS_GURU));
Expand Down
Loading