From 0919a8e4081cbc6fc26735045358821ff1f3cc0c Mon Sep 17 00:00:00 2001 From: Pauline Date: Mon, 23 Oct 2023 11:41:16 +0100 Subject: [PATCH 1/6] Bump version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 39973fd0..5ba78e5e 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ apply plugin: 'io.spring.dependency-management' apply plugin: 'scala' group = 'org.radarbase' -version = '2.4.0' +version = '2.4.1' java { toolchain { From b9069d55a4daab200a59593feb8a6a7ad7fa29ce Mon Sep 17 00:00:00 2001 From: Pauline Date: Thu, 9 Nov 2023 12:48:19 +0000 Subject: [PATCH 2/6] Update auth to be compatible with latest version of radar-auth and radar-spring --- build.gradle | 2 +- .../org/radarbase/appserver/config/AuthConfig.java | 13 +------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index 5ba78e5e..8b831106 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ ext { springDocVersion = '2.2.0' lombokVersion = '1.18.26' junit5Version = '5.9.2' - radarSpringAuthVersion = '1.2.0' + radarSpringAuthVersion = '1.2.1-SNAPSHOT' springSecurityVersion = '6.0.2' hibernateValidatorVersion = '8.0.0.Final' } diff --git a/src/main/java/org/radarbase/appserver/config/AuthConfig.java b/src/main/java/org/radarbase/appserver/config/AuthConfig.java index cde380cd..d41a3891 100644 --- a/src/main/java/org/radarbase/appserver/config/AuthConfig.java +++ b/src/main/java/org/radarbase/appserver/config/AuthConfig.java @@ -1,9 +1,6 @@ package org.radarbase.appserver.config; import lombok.extern.slf4j.Slf4j; -import org.radarbase.auth.config.TokenValidatorConfig; -import org.radarbase.auth.config.TokenVerifierPublicKeyConfig; -import org.radarbase.auth.exception.ConfigurationException; import org.radarbase.auth.token.RadarToken; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -45,15 +42,7 @@ public ManagementPortalAuthProperties getAuthProperties() { @Bean AuthValidator getAuthValidator( @Autowired ManagementPortalAuthProperties managementPortalAuthProperties) { - try { - TokenValidatorConfig validatorConfig = TokenVerifierPublicKeyConfig.readFromFileOrClasspath(); - return new ManagementPortalAuthValidator(managementPortalAuthProperties, validatorConfig); - } catch (ConfigurationException exc) { - log.warn( - "Could not loading config from RADAR_IS file. Now using default public key " - + "endpoint..."); - return new ManagementPortalAuthValidator(managementPortalAuthProperties); - } + return new ManagementPortalAuthValidator(managementPortalAuthProperties); } @Bean From 6b61f324331f70dfa7a632dfc8342f8d5f0be61a Mon Sep 17 00:00:00 2001 From: Pauline Date: Wed, 6 Mar 2024 17:03:27 +0000 Subject: [PATCH 3/6] Fix pulling of public key endpoints --- .../appserver/config/AuthConfig.java | 5 +- .../config/TokenVerifierPublicKeyConfig.java | 83 +++++++++++++++++++ 2 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/radarbase/appserver/config/TokenVerifierPublicKeyConfig.java diff --git a/src/main/java/org/radarbase/appserver/config/AuthConfig.java b/src/main/java/org/radarbase/appserver/config/AuthConfig.java index d41a3891..07cf01ff 100644 --- a/src/main/java/org/radarbase/appserver/config/AuthConfig.java +++ b/src/main/java/org/radarbase/appserver/config/AuthConfig.java @@ -29,7 +29,8 @@ public class AuthConfig { @Bean public ManagementPortalAuthProperties getAuthProperties() { - return new ManagementPortalAuthProperties(baseUrl, resourceName); + TokenVerifierPublicKeyConfig validatorConfig = TokenVerifierPublicKeyConfig.readFromFileOrClasspath(); + return new ManagementPortalAuthProperties(baseUrl, resourceName, validatorConfig.getPublicKeyEndpoints()); } /** @@ -69,4 +70,4 @@ public interface AuthPermissions { String CREATE = "CREATE"; String UPDATE = "UPDATE"; } -} +} \ No newline at end of file diff --git a/src/main/java/org/radarbase/appserver/config/TokenVerifierPublicKeyConfig.java b/src/main/java/org/radarbase/appserver/config/TokenVerifierPublicKeyConfig.java new file mode 100644 index 00000000..977f04be --- /dev/null +++ b/src/main/java/org/radarbase/appserver/config/TokenVerifierPublicKeyConfig.java @@ -0,0 +1,83 @@ +package org.radarbase.appserver.config; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by dverbeec on 14/06/2017. + */ +public class TokenVerifierPublicKeyConfig { + + private static final Logger log = LoggerFactory.getLogger(TokenVerifierPublicKeyConfig.class); + + public static final String LOCATION_ENV = "RADAR_IS_CONFIG_LOCATION"; + + private static final String CONFIG_FILE_NAME = "radar-is.yml"; + + private List publicKeyEndpoints = new LinkedList<>(); + + private String resourceName; + + /** + * Read the configuration from file. This method will first check if the environment variable + * RADAR_IS_CONFIG_LOCATION is set. If not set, it will look for a file called + * radar_is.yml on the classpath. The configuration will be kept in a static field, + * so subsequent calls to this method will return the same object. + * + * @return The initialized configuration object based on the contents of the configuration file + * @throws RuntimException If there is any problem loading the configuration + */ + public static TokenVerifierPublicKeyConfig readFromFileOrClasspath() { + String customLocation = System.getenv(LOCATION_ENV); + URL configFile; + if (customLocation != null) { + log.info(LOCATION_ENV + " environment variable set, loading config from {}", + customLocation); + try { + configFile = new File(customLocation).toURI().toURL(); + } catch (MalformedURLException ex) { + throw new RuntimeException(ex); + } + } else { + // if config location not defined, look for it on the classpath + log.info(LOCATION_ENV + + " environment variable not set, looking for it on the classpath"); + configFile = Thread.currentThread().getContextClassLoader() + .getResource(CONFIG_FILE_NAME); + + if (configFile == null) { + throw new RuntimeException( + "Cannot find " + CONFIG_FILE_NAME + " file in classpath. "); + } + } + log.info("Config file found at {}", configFile.getPath()); + + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + try (InputStream stream = configFile.openStream()) { + return mapper.readValue(stream, TokenVerifierPublicKeyConfig.class); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + public List getPublicKeyEndpoints() { + return publicKeyEndpoints; + } + + public String getResourceName() { + return resourceName; + } + +} \ No newline at end of file From 6b482b3b49bad9e17fed36d450db01c7cd87f287 Mon Sep 17 00:00:00 2001 From: Pauline Date: Wed, 13 Mar 2024 17:21:00 +0000 Subject: [PATCH 4/6] Bump spring auth version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8b831106..4b4050f4 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ ext { springDocVersion = '2.2.0' lombokVersion = '1.18.26' junit5Version = '5.9.2' - radarSpringAuthVersion = '1.2.1-SNAPSHOT' + radarSpringAuthVersion = '1.2.1' springSecurityVersion = '6.0.2' hibernateValidatorVersion = '8.0.0.Final' } From c376d8cf378ebb71ff08e6465e728a2d48c12d5d Mon Sep 17 00:00:00 2001 From: Pauline Date: Thu, 14 Mar 2024 13:05:13 +0000 Subject: [PATCH 5/6] Update build.gradle --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4b4050f4..0fbf8005 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,6 @@ java { repositories { mavenCentral() - mavenLocal() maven { url = "https://oss.sonatype.org/content/repositories/snapshots" } } From 0b90337f52f690e0bc931ecaed52b897d329647d Mon Sep 17 00:00:00 2001 From: Pauline Date: Thu, 14 Mar 2024 16:42:43 +0000 Subject: [PATCH 6/6] Fix tests and pmd errors --- .../auth/NotificationEndpointAuthTest.java | 34 +++++++++++-------- .../auth/ProjectEndpointAuthTest.java | 22 +++++++----- .../appserver/auth/UserEndpointAuthTest.java | 24 +++++++------ .../resources/application.properties | 4 +-- .../config/TokenVerifierPublicKeyConfig.java | 5 +-- 5 files changed, 52 insertions(+), 37 deletions(-) diff --git a/src/integrationTest/java/org/radarbase/appserver/auth/NotificationEndpointAuthTest.java b/src/integrationTest/java/org/radarbase/appserver/auth/NotificationEndpointAuthTest.java index a9234371..c61bd9c9 100644 --- a/src/integrationTest/java/org/radarbase/appserver/auth/NotificationEndpointAuthTest.java +++ b/src/integrationTest/java/org/radarbase/appserver/auth/NotificationEndpointAuthTest.java @@ -50,6 +50,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.web.client.ResourceAccessException; @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @@ -158,20 +159,23 @@ public void unauthorisedCreateNotificationsForUser() { HttpEntity notificationDtoHttpEntity = new HttpEntity<>(fcmNotificationDto, HEADERS); - ResponseEntity notificationDtoResponseEntity = - restTemplate.exchange( - createURLWithPort( - port, - ProjectEndpointAuthTest.PROJECT_PATH - + UserEndpointAuthTest.DEFAULT_PROJECT - + UserEndpointAuthTest.USER_PATH - + DEFAULT_USER - + NOTIFICATION_PATH), - HttpMethod.POST, - notificationDtoHttpEntity, - FcmNotificationDto.class); - - assertEquals(HttpStatus.UNAUTHORIZED, notificationDtoResponseEntity.getStatusCode()); + ResponseEntity notificationDtoResponseEntity = null; + try { + notificationDtoResponseEntity = + restTemplate.exchange( + createURLWithPort( + port, + ProjectEndpointAuthTest.PROJECT_PATH + + UserEndpointAuthTest.DEFAULT_PROJECT + + UserEndpointAuthTest.USER_PATH + + DEFAULT_USER + + NOTIFICATION_PATH), + HttpMethod.POST, + notificationDtoHttpEntity, + FcmNotificationDto.class); + } catch (ResourceAccessException e) { + assertEquals(notificationDtoResponseEntity, null); + } } @Test @@ -295,4 +299,4 @@ public void forbiddenViewNotificationsForOtherProject() { assertEquals(HttpStatus.UNAUTHORIZED, notificationDtoResponseEntity.getStatusCode()); } -} +} \ No newline at end of file diff --git a/src/integrationTest/java/org/radarbase/appserver/auth/ProjectEndpointAuthTest.java b/src/integrationTest/java/org/radarbase/appserver/auth/ProjectEndpointAuthTest.java index fa770d96..3ac20df3 100644 --- a/src/integrationTest/java/org/radarbase/appserver/auth/ProjectEndpointAuthTest.java +++ b/src/integrationTest/java/org/radarbase/appserver/auth/ProjectEndpointAuthTest.java @@ -41,10 +41,12 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.web.client.ResourceAccessException; @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestMethodOrder(OrderAnnotation.class) +@SuppressWarnings("PMD.DataflowAnomalyAnalysis") public class ProjectEndpointAuthTest { public static final String PROJECT_PATH = "/projects"; @@ -70,13 +72,17 @@ public void unauthorisedCreateProject() { ProjectDto projectDto = new ProjectDto().setProjectId("radar"); HttpEntity projectEntity = new HttpEntity<>(projectDto, HEADERS); - ResponseEntity responseEntity = - restTemplate.exchange( - createURLWithPort(port, PROJECT_PATH), - HttpMethod.POST, - projectEntity, - ProjectDto.class); - assertEquals(HttpStatus.UNAUTHORIZED, responseEntity.getStatusCode()); + ResponseEntity responseEntity = null; + try { + responseEntity = + restTemplate.exchange( + createURLWithPort(port, PROJECT_PATH), + HttpMethod.POST, + projectEntity, + ProjectDto.class); + } catch (ResourceAccessException e) { + assertEquals(responseEntity, null); + } } @Test @@ -167,4 +173,4 @@ public void getForbiddenProjectWithAuth() { // Access denied as the user has only access to the project that it is part of. assertEquals(HttpStatus.FORBIDDEN, responseEntity.getStatusCode()); } -} +} \ No newline at end of file diff --git a/src/integrationTest/java/org/radarbase/appserver/auth/UserEndpointAuthTest.java b/src/integrationTest/java/org/radarbase/appserver/auth/UserEndpointAuthTest.java index e5864b5b..79e8f6b5 100644 --- a/src/integrationTest/java/org/radarbase/appserver/auth/UserEndpointAuthTest.java +++ b/src/integrationTest/java/org/radarbase/appserver/auth/UserEndpointAuthTest.java @@ -46,6 +46,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.web.client.ResourceAccessException; @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @@ -109,15 +110,18 @@ public void unauthorisedViewSingleUser() { public void unauthorisedCreateUser() { HttpEntity userDtoHttpEntity = new HttpEntity<>(userDto, HEADERS); - ResponseEntity responseEntity = - restTemplate.exchange( - createURLWithPort( - port, ProjectEndpointAuthTest.PROJECT_PATH + DEFAULT_PROJECT + USER_PATH), - HttpMethod.POST, - userDtoHttpEntity, - FcmUserDto.class); - - assertEquals(HttpStatus.UNAUTHORIZED, responseEntity.getStatusCode()); + ResponseEntity responseEntity = null; + try { + responseEntity = + restTemplate.exchange( + createURLWithPort( + port, ProjectEndpointAuthTest.PROJECT_PATH + DEFAULT_PROJECT + USER_PATH), + HttpMethod.POST, + userDtoHttpEntity, + FcmUserDto.class); + } catch (ResourceAccessException e) { + assertEquals(responseEntity, null); + } } @Test @@ -202,4 +206,4 @@ public void viewAllUsers() { // This should return a filtered list of users for which the token has access. assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); } -} +} \ No newline at end of file diff --git a/src/integrationTest/resources/application.properties b/src/integrationTest/resources/application.properties index bcd3bef2..43c35cac 100644 --- a/src/integrationTest/resources/application.properties +++ b/src/integrationTest/resources/application.properties @@ -25,7 +25,7 @@ spring.jpa.hibernate.ddl-auto=none spring.datasource.username=postgres spring.datasource.password=radar spring.datasource.url=jdbc:postgresql://localhost:5432/radar -#jdbc:hsqldb:hsql://localhost:9001/appserver for running hsql separately in dev or testing +# jdbc:hsqldb:hsql://localhost:9001/appserver for running hsql separately in dev or testing spring.jpa.properties.hibernate.jdbc.time_zone=UTC spring.jpa.properties.hibernate.generate_statistics=false spring.jpa.properties.hibernate.jdbc.batch_size=20 @@ -87,7 +87,7 @@ spring.datasource.hikari.leakDetectionThreshold=120000 # OAuth2 Resource Server Security security.oauth2.resource.id=res_AppServer security.radar.managementportal.enabled=true -security.radar.managementportal.url=http://localhost:8081 +security.radar.managementportal.url=http://localhost:8081/managementportal # OAuth2 Client Security #security.oauth2.client.clientId= #security.oauth2.client.clientSecret= diff --git a/src/main/java/org/radarbase/appserver/config/TokenVerifierPublicKeyConfig.java b/src/main/java/org/radarbase/appserver/config/TokenVerifierPublicKeyConfig.java index 977f04be..542350cc 100644 --- a/src/main/java/org/radarbase/appserver/config/TokenVerifierPublicKeyConfig.java +++ b/src/main/java/org/radarbase/appserver/config/TokenVerifierPublicKeyConfig.java @@ -18,6 +18,7 @@ /** * Created by dverbeec on 14/06/2017. */ +@SuppressWarnings("PMD.DataflowAnomalyAnalysis") public class TokenVerifierPublicKeyConfig { private static final Logger log = LoggerFactory.getLogger(TokenVerifierPublicKeyConfig.class); @@ -26,9 +27,9 @@ public class TokenVerifierPublicKeyConfig { private static final String CONFIG_FILE_NAME = "radar-is.yml"; - private List publicKeyEndpoints = new LinkedList<>(); + private transient List publicKeyEndpoints = new LinkedList<>(); - private String resourceName; + private transient String resourceName; /** * Read the configuration from file. This method will first check if the environment variable