Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- **Build**: Spring Boot is 4.1.1 (`spring-boot-starter-webmvc` + `spring-boot-starter-restclient`).
- **Build**: Gradle wrapper is 8.14.6.
- **Build**: `setupGitHooks` is no longer a dependency of `build` (submodule-safe / opt-in via `./gradlew setupGitHooks`).
- **HTTP**: OkHttp is 5.5.0. The unsafe client does not follow redirects itself. Each hop selects the client for the `Location` host.
Expand Down
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ dependencies {
}

// Spring Boot Starters
implementation libs.spring.boot.starter.web
implementation libs.spring.boot.starter.webmvc
implementation libs.spring.boot.starter.restclient
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation libs.spring.boot.starter.jdbc
implementation libs.spring.boot.starter.actuator
Expand Down Expand Up @@ -66,6 +67,8 @@ dependencies {
testImplementation(libs.spring.boot.starter.test) {
exclude group: 'com.vaadin.external.google', module: 'android-json'
}
testImplementation libs.spring.boot.starter.webmvc.test
testImplementation libs.spring.boot.starter.jdbc.test

testImplementation libs.h2
}
Expand Down
7 changes: 5 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[versions]
# Spring Boot and related versions
spring-boot = "3.5.4"
spring-boot = "4.1.1"
spring-dependency-management = "1.1.7"

# Plugin versions
Expand All @@ -16,10 +16,13 @@ okhttp3 = "5.5.0"
handy-uri-templates = "2.1.8"

[libraries]
spring-boot-starter-web = { group = "org.springframework.boot", name = "spring-boot-starter-web" }
spring-boot-starter-webmvc = { group = "org.springframework.boot", name = "spring-boot-starter-webmvc" }
spring-boot-starter-restclient = { group = "org.springframework.boot", name = "spring-boot-starter-restclient" }
spring-boot-starter-jdbc = { group = "org.springframework.boot", name = "spring-boot-starter-jdbc" }
spring-boot-starter-actuator = { group = "org.springframework.boot", name = "spring-boot-starter-actuator" }
spring-boot-starter-test = { group = "org.springframework.boot", name = "spring-boot-starter-test" }
spring-boot-starter-webmvc-test = { group = "org.springframework.boot", name = "spring-boot-starter-webmvc-test" }
spring-boot-starter-jdbc-test = { group = "org.springframework.boot", name = "spring-boot-starter-jdbc-test" }
spring-boot-starter-tomcat = { group = "org.springframework.boot", name = "spring-boot-starter-tomcat" }
spring-boot-devtools = { group = "org.springframework.boot", name = "spring-boot-devtools" }
h2 = { group = "com.h2database", name = "h2", version.ref = "h2" }
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/sitmun/proxy/middleware/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import org.sitmun.proxy.middleware.mbtiles.MbtilesProperties;
import org.sitmun.proxy.middleware.protocols.wms.WmsCapabilitiesProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.boot.restclient.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.sitmun.proxy.middleware.controllers;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.sitmun.proxy.middleware.mbtiles.MbtilesDtos.ClientCreateRequest;
import org.sitmun.proxy.middleware.mbtiles.MbtilesProxyService;
import org.springframework.http.HttpHeaders;
Expand All @@ -13,6 +12,7 @@
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tools.jackson.databind.ObjectMapper;

@RestController
@RequestMapping("/proxy")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import static org.sitmun.proxy.middleware.dto.ProblemTypes.*;
import static org.springframework.http.MediaType.APPLICATION_PROBLEM_JSON;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import java.util.Optional;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;

public final class ProxyProblemResponses {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package org.sitmun.proxy.middleware.mbtiles;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Optional;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;

/** Decodes JWT payload claims without verifying the signature (backend verifies). */
@Component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import static org.sitmun.proxy.middleware.dto.ProxyProblemResponses.proxyInvalidRequest;
import static org.sitmun.proxy.middleware.protocols.http.HttpRequestExecutor.isForwardableResponseHeader;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -30,6 +29,7 @@
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import tools.jackson.databind.ObjectMapper;

@Service
@Slf4j
Expand Down Expand Up @@ -167,7 +167,7 @@ public ResponseEntity<?> file(int appId, int terId, String authorization, String
copyHeader(upstream, headers, HttpHeaders.CONTENT_TYPE);
copyHeader(upstream, headers, HttpHeaders.CONTENT_LENGTH);
copyHeader(upstream, headers, HttpHeaders.CONTENT_DISPOSITION);
if (!headers.containsKey(HttpHeaders.CONTENT_TYPE)) {
if (!headers.containsHeader(HttpHeaders.CONTENT_TYPE)) {
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
}
StreamingResponseBody stream =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.sitmun.proxy.middleware.mbtiles;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
Expand All @@ -14,6 +13,7 @@
import org.sitmun.proxy.middleware.protocols.http.HttpRequestExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tools.jackson.databind.ObjectMapper;

/**
* Calls the configured MBTiles service. Never forwards client Authorization or proxy key headers.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import static org.sitmun.proxy.middleware.dto.ProxyProblemResponses.backendUnavailable;
import static org.sitmun.proxy.middleware.dto.ProxyProblemResponses.emptyBackendConfiguration;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Locale;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -28,6 +27,7 @@
import org.springframework.util.StringUtils;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import tools.jackson.databind.ObjectMapper;

@Service
@Slf4j
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -19,9 +18,9 @@
import org.sitmun.proxy.middleware.test.fixtures.AuthorizationProxyFixtures;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
Expand All @@ -31,6 +30,7 @@
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.web.client.RestTemplate;
import tools.jackson.databind.ObjectMapper;

@SpringBootTest
@AutoConfigureMockMvc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.StandardCharsets;
import java.time.Clock;
import java.time.Duration;
Expand All @@ -35,13 +34,14 @@
import org.sitmun.proxy.middleware.mbtiles.MbtilesRequestValidator;
import org.sitmun.proxy.middleware.mbtiles.MbtilesUpstreamClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import tools.jackson.databind.ObjectMapper;

@WebMvcTest(controllers = MbtilesProxyController.class)
@Import({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import org.junit.jupiter.api.Test;
import org.sitmun.proxy.middleware.service.RequestConfigurationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import static org.assertj.core.api.Assertions.assertThat;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.StandardCharsets;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.client.HttpClientErrorException;
import tools.jackson.databind.ObjectMapper;

class ProxyProblemResponsesTest {

Expand Down Expand Up @@ -50,7 +50,7 @@ void hostileBackendProblemIdentityUsesLocalFallback(
var response = ProxyProblemResponses.backendAuthorizationFailure(exception, objectMapper);

assertThat(response.getStatusCode().value()).isEqualTo(status);
assertThat(response.getHeaders()).doesNotContainKey(HttpHeaders.WWW_AUTHENTICATE);
assertThat(response.getHeaders().headerNames()).doesNotContain(HttpHeaders.WWW_AUTHENTICATE);
assertThat(response.getBody()).isNotNull();
assertThat(response.getBody().getType()).isEqualTo(expectedType);
assertThat(response.getBody().getTitle()).isEqualTo(expectedTitle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.sitmun.proxy.middleware.test.fixtures.AuthorizationProxyFixtures.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.StandardCharsets;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.sitmun.proxy.middleware.service.RequestExecutorService;
import org.sitmun.proxy.middleware.service.UpstreamContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.json.JacksonTester;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import tools.jackson.databind.json.JsonMapper;

@SpringBootTest
@AutoConfigureTestDatabase
Expand All @@ -33,7 +33,7 @@ class ExecutionRequestExecutorServiceTest {

@BeforeAll
void setup() {
ObjectMapper objectMapper = new ObjectMapper();
JsonMapper objectMapper = new JsonMapper();
JacksonTester.initFields(this, objectMapper);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@
import static org.sitmun.proxy.middleware.protocols.http.HttpSecurityConstants.TYPE_HTTP;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.sitmun.proxy.middleware.dto.ConfigProxyDto;
import org.sitmun.proxy.middleware.dto.HttpSecurityDto;
import org.sitmun.proxy.middleware.protocols.wms.WmsPayloadDto;
import tools.jackson.databind.json.JsonMapper;

@DisplayName("HttpContextSecurity / HttpSecurityDto contract")
class HttpContextSecurityContractTest {

private final ObjectMapper objectMapper = new ObjectMapper().findAndRegisterModules();
private final JsonMapper objectMapper = new JsonMapper();

@Test
@DisplayName("HttpSecurityDto is HttpContextSecurity and holds http/basic vs apiKey field shapes")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ void shouldSanitizeUpstreamAuthorizationFailuresAsBadGateway(int upstreamStatus)
// Then
assertThat(result.getStatusCode().value()).isEqualTo(502);
assertThat(UpstreamContentType.current()).isEqualTo("application/problem+json");
assertThat(result.getHeaders()).doesNotContainKey(HttpHeaders.WWW_AUTHENTICATE);
assertThat(result.getHeaders().headerNames()).doesNotContain(HttpHeaders.WWW_AUTHENTICATE);
assertThat(result.getBody()).isInstanceOf(ProblemDetail.class);
ProblemDetail problem = (ProblemDetail) result.getBody();
assertThat(problem.getType())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import org.sitmun.proxy.middleware.service.RequestExecutorService;
import org.sitmun.proxy.middleware.service.UpstreamContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockHttpServletRequest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.sitmun.proxy.middleware.test.fixtures.AuthorizationProxyFixtures.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import okhttp3.MediaType;
import okhttp3.Protocol;
Expand All @@ -22,14 +21,15 @@
import org.sitmun.proxy.middleware.test.interceptors.HostnameCheck;
import org.sitmun.proxy.middleware.test.interceptors.QueryCheck;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.json.JacksonTester;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import tools.jackson.databind.json.JsonMapper;

@SpringBootTest
@AutoConfigureTestDatabase
Expand All @@ -46,7 +46,7 @@ class ExecutionRequestExecutorServiceTest {

@BeforeAll
void setup() {
ObjectMapper objectMapper = new ObjectMapper();
JsonMapper objectMapper = new JsonMapper();
JacksonTester.initFields(this, objectMapper);
}

Expand Down Expand Up @@ -141,7 +141,7 @@ void upstreamAuthorizationFailureThroughDecoratorChain(int upstreamStatus) {
requestExecutorService.executeRequest("https://proxy.example/proxy/1/2/WMS/3", payload);

assertThat(response.getStatusCode().value()).isEqualTo(502);
assertThat(response.getHeaders()).doesNotContainKey(HttpHeaders.WWW_AUTHENTICATE);
assertThat(response.getHeaders().headerNames()).doesNotContain(HttpHeaders.WWW_AUTHENTICATE);
assertThat(response.getBody()).isInstanceOf(ProblemDetail.class);
var problem = (ProblemDetail) response.getBody();
assertThat(problem.getType())
Expand Down
Loading
Loading