diff --git a/NOTICE b/NOTICE index 473f1a6e1a5c60ea95eb00efa2d9bd0d664ce349..9cc38e4945a1f97d52010431bde3097a45ba9113 100644 --- a/NOTICE +++ b/NOTICE @@ -29,8 +29,8 @@ The following software have components provided under the terms of this license: - Cloud Storage JSON API v1-rev58-1.21.0 (from ) - Elastic JNA Distribution (from https://github.com/java-native-access/jna) - Elasticsearch: 5.0.0-alpha5 (from https://github.com/elastic/elasticsearch) -- Expression Language 3.0 (from https://projects.eclipse.org/projects/ee4j.el) - Expression Language 3.0 (from http://uel.java.net) +- Expression Language 3.0 (from https://projects.eclipse.org/projects/ee4j.el) - FindBugs-jsr305 (from http://findbugs.sourceforge.net/) - Google APIs Client Library for Java (from ) - Google App Engine extensions to the Google HTTP Client Library for Java. (from ) @@ -90,8 +90,9 @@ The following software have components provided under the terms of this license: - Lucene Spatial 3D (from ) - Lucene Spatial Extras (from ) - Lucene Suggest (from ) -- Mockito (from http://www.mockito.org) +- MapStruct Core (from ) - Mockito (from http://mockito.org) +- Mockito (from http://www.mockito.org) - Netty/Buffer (from http://netty.io/) - Netty/Codec (from ) - Netty/Common (from ) @@ -122,6 +123,9 @@ The following software have components provided under the terms of this license: - Spring Context (from https://github.com/spring-projects/spring-framework) - Spring Core (from https://github.com/spring-projects/spring-framework) - Spring Expression Language (SpEL) (from https://github.com/spring-projects/spring-framework) +- Spring Plugin - Core (from ) +- Spring Plugin - Metadata Extension (from ) +- Spring TestContext Framework (from https://github.com/spring-projects/spring-framework) - Spring Web (from https://github.com/spring-projects/spring-framework) - Spring Web MVC (from https://github.com/spring-projects/spring-framework) - T-Digest (from https://github.com/tdunning/t-digest) @@ -172,8 +176,16 @@ The following software have components provided under the terms of this license: - spring-security-config (from http://spring.io/spring-security) - spring-security-core (from http://spring.io/spring-security) - spring-security-web (from http://spring.io/spring-security) +- springfox-core (from https://github.com/springfox/springfox) +- springfox-schema (from https://github.com/springfox/springfox) +- springfox-spi (from https://github.com/springfox/springfox) +- springfox-spring-web (from https://github.com/springfox/springfox) +- springfox-swagger-common (from https://github.com/springfox/springfox) +- springfox-swagger-ui (from https://github.com/springfox/springfox) +- springfox-swagger2 (from https://github.com/springfox/springfox) - swagger-annotations (from ) - swagger-jaxrs (from ) +- swagger-models (from ) - tomcat-embed-core (from http://tomcat.apache.org/) - tomcat-embed-el (from http://tomcat.apache.org/) - tomcat-embed-websocket (from http://tomcat.apache.org/) @@ -310,8 +322,8 @@ GPL-2.0-with-classpath-exception The following software have components provided under the terms of this license: - Checker Qual (from https://checkerframework.org) -- Expression Language 3.0 (from http://uel.java.net) - Expression Language 3.0 (from https://projects.eclipse.org/projects/ee4j.el) +- Expression Language 3.0 (from http://uel.java.net) - Java Architecture For XML Binding (from ) - Java Architecture For XML Binding (from ) - Java Servlet API (from https://projects.eclipse.org/projects/ee4j.servlet) diff --git a/notification-core/pom.xml b/notification-core/pom.xml index 69d5f99b341a05db802f531f862883fc352af9af..771a747ec5b5b3a52898463f7cc61d2a99345cc3 100644 --- a/notification-core/pom.xml +++ b/notification-core/pom.xml @@ -37,6 +37,7 @@ <java.version>8</java.version> <maven.compiler.target>${java.version}</maven.compiler.target> <maven.compiler.source>${java.version}</maven.compiler.source> + <springfox-version>2.7.0</springfox-version> </properties> <repositories> @@ -187,6 +188,24 @@ <version>2.8.5</version> </dependency> + <!-- swagger dependencies --> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger2</artifactId> + <version>${springfox-version}</version> + <exclusions> + <exclusion> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger-ui</artifactId> + <version>${springfox-version}</version> + </dependency> + <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> @@ -211,6 +230,11 @@ <version>4.12</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-test</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> <plugins> diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/api/PubsubEndpoint.java b/notification-core/src/main/java/org/opengroup/osdu/notification/api/PubsubEndpoint.java index 89a3376a13fccbd420fbdd17a75189cbc9f6776e..b1bc60252566348c11ee2c9ddf44c75345717ac4 100644 --- a/notification-core/src/main/java/org/opengroup/osdu/notification/api/PubsubEndpoint.java +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/api/PubsubEndpoint.java @@ -34,7 +34,8 @@ import org.opengroup.osdu.core.common.notification.ISubscriptionFactory; import org.opengroup.osdu.core.common.notification.ISubscriptionService; import org.opengroup.osdu.core.common.notification.SubscriptionException; import org.opengroup.osdu.notification.di.SubscriptionCacheFactory; -import org.opengroup.osdu.notification.pubsub.PubsubRequestBodyExtractor; +import org.opengroup.osdu.notification.provider.interfaces.IPubsubHandshakeHandler; +import org.opengroup.osdu.notification.provider.interfaces.IPubsubRequestBodyExtractor; import org.opengroup.osdu.notification.utils.Config; import org.opengroup.osdu.notification.provider.interfaces.IGoogleServiceAccount; import org.springframework.beans.factory.annotation.Autowired; @@ -56,7 +57,9 @@ import java.util.Map; @RequestMapping("/push-handlers") public class PubsubEndpoint { @Autowired - private PubsubRequestBodyExtractor pubsubRequestBodyExtractor; + private IPubsubRequestBodyExtractor pubsubRequestBodyExtractor; + @Autowired + private IPubsubHandshakeHandler pubsubHandshakeHandler; @Autowired private ISignatureService signatureService; @Autowired @@ -83,6 +86,11 @@ public class PubsubEndpoint { @PostMapping("/records-changed") @PreAuthorize("@authorizationFilter.hasAnyPermission('" + Config.OPS + "', '" + Config.PUBSUB + "')") public ResponseEntity recordChanged() throws Exception { + if(this.pubsubRequestBodyExtractor.isHandshakeRequest()) { + String handshakeResponse = this.pubsubHandshakeHandler.getHandshakeResponse(); + return ResponseEntity.ok(handshakeResponse); + } + String notificationId = this.pubsubRequestBodyExtractor.extractNotificationIdFromRequestBody(); String pubsubMessage = this.pubsubRequestBodyExtractor.extractDataFromRequestBody(); Map<String, String> headerAttributes = this.pubsubRequestBodyExtractor.extractAttributesFromRequestBody(); diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/auth/AuthorizationFilter.java b/notification-core/src/main/java/org/opengroup/osdu/notification/auth/AuthorizationFilter.java index 36bfc80393762c8fcee8abd64a82c39dda253e48..2eb23d060a1e3ce9e4abddd8fda4d2ce7a30e232 100644 --- a/notification-core/src/main/java/org/opengroup/osdu/notification/auth/AuthorizationFilter.java +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/auth/AuthorizationFilter.java @@ -28,6 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; +import javax.servlet.http.HttpServletRequest; import java.util.Arrays; @Component("authorizationFilter") @@ -35,6 +36,8 @@ import java.util.Arrays; public class AuthorizationFilter { private static final String BEARER_PREFIX = "Bearer "; + @Autowired + private HttpServletRequest request; @Autowired private IAuthorizationService authService; @Autowired @@ -51,6 +54,13 @@ public class AuthorizationFilter { requestInfoExt.assignPartitionIdIfNotInHeader(); } + String path = request.getServletPath(); + if ("GET".equals(request.getMethod())) { + if (path.equals("/swagger-ui.html")) { + return true; + } + } + if (Arrays.asList(requiredRoles).contains(Config.CRON) && requestInfoExt.isCronRequest()) { dpsHeaders.put(DpsHeaders.USER_EMAIL, Config.CRON); requestInfoExt.setHeaders(dpsHeaders); diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/di/CredentialHeadersProvider.java b/notification-core/src/main/java/org/opengroup/osdu/notification/di/CredentialHeadersProvider.java index 24b6646c8b93cb795ba8fedb04e9ade785d65788..f06244b57324e733e376f8a3b6cf0328092cb5a7 100644 --- a/notification-core/src/main/java/org/opengroup/osdu/notification/di/CredentialHeadersProvider.java +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/di/CredentialHeadersProvider.java @@ -15,9 +15,10 @@ */ package org.opengroup.osdu.notification.di; + import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.util.IServiceAccountJwtClient; -import org.opengroup.osdu.notification.pubsub.PubsubRequestBodyExtractor; +import org.opengroup.osdu.notification.provider.interfaces.IPubsubRequestBodyExtractor; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; @@ -38,7 +39,7 @@ public class CredentialHeadersProvider implements FactoryBean<DpsHeaders> { private HttpServletRequest httpRequest; @Autowired - private PubsubRequestBodyExtractor pubsubRequestBodyExtractor; + private IPubsubRequestBodyExtractor pubsubRequestBodyExtractor; @Autowired private IServiceAccountJwtClient serviceAccountJwtClient; diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/di/RequestInfoExt.java b/notification-core/src/main/java/org/opengroup/osdu/notification/di/RequestInfoExt.java index 13adf62cb5605971ede3ef9379057e80e752ea34..7db3d5c5965506fce8bc78fbe3f3c7f675e38e64 100644 --- a/notification-core/src/main/java/org/opengroup/osdu/notification/di/RequestInfoExt.java +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/di/RequestInfoExt.java @@ -19,7 +19,7 @@ package org.opengroup.osdu.notification.di; import com.google.api.client.util.Strings; import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.model.http.RequestInfo; -import org.opengroup.osdu.notification.pubsub.PubsubRequestBodyExtractor; +import org.opengroup.osdu.notification.provider.interfaces.IPubsubRequestBodyExtractor; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; @@ -27,8 +27,6 @@ import org.springframework.web.context.annotation.RequestScope; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; -import java.io.BufferedReader; -import java.io.IOException; import java.util.Collections; import java.util.Map; import java.util.stream.Collectors; @@ -40,7 +38,7 @@ public class RequestInfoExt extends RequestInfo { private HttpServletRequest httpRequest; @Inject - private PubsubRequestBodyExtractor requestBodyExtractor; + private IPubsubRequestBodyExtractor requestBodyExtractor; @Inject public RequestInfoExt(HttpServletRequest request) { diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/provider/interfaces/IPubsubHandshakeHandler.java b/notification-core/src/main/java/org/opengroup/osdu/notification/provider/interfaces/IPubsubHandshakeHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..d93b25c067f91e33cc538c4f9394043cea1969e3 --- /dev/null +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/provider/interfaces/IPubsubHandshakeHandler.java @@ -0,0 +1,5 @@ +package org.opengroup.osdu.notification.provider.interfaces; + +public interface IPubsubHandshakeHandler { + String getHandshakeResponse(); +} diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/provider/interfaces/IPubsubRequestBodyExtractor.java b/notification-core/src/main/java/org/opengroup/osdu/notification/provider/interfaces/IPubsubRequestBodyExtractor.java new file mode 100644 index 0000000000000000000000000000000000000000..57801ed6e5bb670ff240c21ba202875fcd5eb223 --- /dev/null +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/provider/interfaces/IPubsubRequestBodyExtractor.java @@ -0,0 +1,16 @@ +package org.opengroup.osdu.notification.provider.interfaces; + +import org.springframework.stereotype.Component; +import org.springframework.http.ResponseEntity; + +import java.util.Map; + +public interface IPubsubRequestBodyExtractor { + Map<String, String> extractAttributesFromRequestBody() ; + + String extractDataFromRequestBody(); + + String extractNotificationIdFromRequestBody() ; + + boolean isHandshakeRequest(); +} diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/swagger/HomeController.java b/notification-core/src/main/java/org/opengroup/osdu/notification/swagger/HomeController.java new file mode 100644 index 0000000000000000000000000000000000000000..3e568ff05233c163ec6e535e09e6ce06c09df98d --- /dev/null +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/swagger/HomeController.java @@ -0,0 +1,14 @@ +package org.opengroup.osdu.notification.swagger; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class HomeController { + + @RequestMapping(value = {"/", "/swagger"}) + public String swagger() { + System.out.println("swagger-ui.html"); + return "redirect:swagger-ui.html"; + } +} diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/swagger/SwaggerDocumentationConfig.java b/notification-core/src/main/java/org/opengroup/osdu/notification/swagger/SwaggerDocumentationConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..2aea7a909d3786007ab3c033d460b81f407a63db --- /dev/null +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/swagger/SwaggerDocumentationConfig.java @@ -0,0 +1,69 @@ +package org.opengroup.osdu.notification.swagger; + +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiKey; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.Parameter; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Configuration +@EnableSwagger2 +public class SwaggerDocumentationConfig { + public static final String AUTHORIZATION_HEADER = "Authorization"; + public static final String DEFAULT_INCLUDE_PATTERN = "/.*"; + + @Bean + public Docket api() { + ParameterBuilder builder = new ParameterBuilder(); + List<Parameter> parameters = new ArrayList<>(); + builder.name(DpsHeaders.DATA_PARTITION_ID) + .description("tenant") + .defaultValue("common") + .modelRef(new ModelRef("string")) + .parameterType("header") + .required(true) + .build(); + parameters.add(builder.build()); + return new Docket(DocumentationType.SWAGGER_2) + .globalOperationParameters(parameters) + .select() + .apis(RequestHandlerSelectors.basePackage("org.opengroup.osdu.notification.api")) + .build() + .securityContexts(Collections.singletonList(securityContext())) + .securitySchemes(Collections.singletonList(apiKey())); + } + + private ApiKey apiKey() { + return new ApiKey("JWT", AUTHORIZATION_HEADER, "header"); + } + + private SecurityContext securityContext() { + return SecurityContext.builder() + .securityReferences(defaultAuth()) + .forPaths(PathSelectors.regex(DEFAULT_INCLUDE_PATTERN)) + .build(); + } + + List<SecurityReference> defaultAuth() { + AuthorizationScope authorizationScope + = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = + new AuthorizationScope[]{authorizationScope}; + return Collections.singletonList( + new SecurityReference("JWT", authorizationScopes)); + } +} \ No newline at end of file diff --git a/notification-core/src/test/java/org/opengroup/osdu/notification/api/PubsubEndpointTests.java b/notification-core/src/test/java/org/opengroup/osdu/notification/api/PubsubEndpointTests.java index d3155489b3a8e6948fdb4e45e1dc43c90c2d6ab0..707a59fc951ab821160f71d35f766bc68ff39eff 100644 --- a/notification-core/src/test/java/org/opengroup/osdu/notification/api/PubsubEndpointTests.java +++ b/notification-core/src/test/java/org/opengroup/osdu/notification/api/PubsubEndpointTests.java @@ -36,8 +36,8 @@ import org.opengroup.osdu.core.common.notification.SubscriptionFactory; import org.opengroup.osdu.core.common.notification.SubscriptionService; import org.opengroup.osdu.notification.di.CredentialHeadersProvider; import org.opengroup.osdu.notification.di.SubscriptionCacheFactory; -import org.opengroup.osdu.notification.pubsub.PubsubRequestBodyExtractor; import org.opengroup.osdu.notification.provider.interfaces.IGoogleServiceAccount; +import org.opengroup.osdu.notification.provider.interfaces.IPubsubRequestBodyExtractor; import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.http.ResponseEntity; @@ -54,7 +54,7 @@ import static org.mockito.Mockito.when; @RunWith(PowerMockRunner.class) public class PubsubEndpointTests { @Mock - private PubsubRequestBodyExtractor pubsubRequestBodyExtractor; + private IPubsubRequestBodyExtractor pubsubRequestBodyExtractor; @Mock private ISignatureService signatureService; @Mock diff --git a/notification-core/src/test/java/org/opengroup/osdu/notification/auth/AuthorizationFilterTest.java b/notification-core/src/test/java/org/opengroup/osdu/notification/auth/AuthorizationFilterTest.java index 50a46790c9789b4d9257833fa0437771aca0eb40..61f0520808162f345ac2c6f4645d0247a480ee60 100644 --- a/notification-core/src/test/java/org/opengroup/osdu/notification/auth/AuthorizationFilterTest.java +++ b/notification-core/src/test/java/org/opengroup/osdu/notification/auth/AuthorizationFilterTest.java @@ -26,11 +26,12 @@ import org.opengroup.osdu.core.common.model.http.AppException; import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.provider.interfaces.IAuthorizationService; import org.opengroup.osdu.notification.di.RequestInfoExt; -import org.opengroup.osdu.notification.pubsub.PubsubRequestBodyExtractor; +import org.opengroup.osdu.notification.provider.interfaces.IPubsubRequestBodyExtractor; import org.opengroup.osdu.notification.utils.Config; import org.opengroup.osdu.notification.provider.interfaces.IServiceAccountValidator; import org.powermock.modules.junit4.PowerMockRunner; +import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; @@ -53,13 +54,15 @@ public class AuthorizationFilterTest { @Mock private DpsHeaders headers; @Mock + private HttpServletRequest request; + @Mock private RequestInfoExt requestInfo; @Mock private IAuthorizationService authorizationService; @Mock private IServiceAccountValidator validator; @Mock - private PubsubRequestBodyExtractor extractor; + private IPubsubRequestBodyExtractor extractor; @InjectMocks private AuthorizationFilter sut; diff --git a/notification-core/src/test/java/org/opengroup/osdu/notification/swagger/HomeControllerTest.java b/notification-core/src/test/java/org/opengroup/osdu/notification/swagger/HomeControllerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6bd3e8084d58fd9a779c75d74f887b3901d0b349 --- /dev/null +++ b/notification-core/src/test/java/org/opengroup/osdu/notification/swagger/HomeControllerTest.java @@ -0,0 +1,33 @@ +package org.opengroup.osdu.notification.swagger; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; + +public class HomeControllerTest { + + private MockMvc mockMvc; + + @Before + public void setup() { + mockMvc = standaloneSetup(HomeController.class).build(); + } + + @Test + public void testSwaggerFound() throws Exception { + mockMvc.perform(get("/swagger") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isFound()); + + mockMvc.perform(get("/") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isFound()); + } +} diff --git a/provider/notification-azure/pom.xml b/provider/notification-azure/pom.xml index 69593aaf8b75ca9958270559cc5453fbe7f08def..a3f38f44715e805d9e1a0567dea19be48a565ece 100644 --- a/provider/notification-azure/pom.xml +++ b/provider/notification-azure/pom.xml @@ -19,7 +19,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> - <groupId>org.opengroup.osdu</groupId> <artifactId>notification-azure</artifactId> <version>1.0.0</version> <name>notification-azure</name> @@ -142,6 +141,11 @@ <version>3.0.0</version> <scope>test</scope> </dependency> + <dependency> + <groupId>com.auth0</groupId> + <artifactId>jwks-rsa</artifactId> + <version>0.11.0</version> + </dependency> </dependencies> <build> diff --git a/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/security/SecurityConfig.java b/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/security/SecurityConfig.java index 853b37b2a7cffb3c022060471626e81fae56b713..5c7b8c02943e94e35c4ec110d4251a016a836bfd 100644 --- a/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/security/SecurityConfig.java +++ b/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/security/SecurityConfig.java @@ -15,23 +15,36 @@ package org.opengroup.osdu.notification.provider.azure.security; import com.microsoft.azure.spring.autoconfigure.aad.AADAppRoleStatelessAuthenticationFilter; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import javax.inject.Inject; - @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { + @Autowired + private AADAppRoleStatelessAuthenticationFilter appRoleAuthFilter; + @Override protected void configure(HttpSecurity httpSecurity) throws Exception { - // TODO : Add antMatchers after Swagger changes merge - // TODO : Add the authZ httpSecurity - .csrf().disable(); + .csrf().disable() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER) + .and() + .authorizeRequests() + .antMatchers("/", + "/swagger", + "/v2/api-docs", + "/swagger-resources/**", + "/swagger-ui.html", + "/webjars/**").permitAll() + .anyRequest().authenticated() + .and() + .addFilterBefore(appRoleAuthFilter, UsernamePasswordAuthenticationFilter.class); } } diff --git a/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/AzureServiceAccountValidatorImpl.java b/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/AzureServiceAccountValidatorImpl.java index 971666dd829edb794bcaac7fa7cfab32d56eafc8..dc1a345185f2f6c20384644f1772ff43ef0743bd 100644 --- a/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/AzureServiceAccountValidatorImpl.java +++ b/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/AzureServiceAccountValidatorImpl.java @@ -14,27 +14,31 @@ package org.opengroup.osdu.notification.provider.azure.util; +import com.auth0.jwt.JWT; +import com.auth0.jwt.interfaces.DecodedJWT; import org.opengroup.osdu.notification.provider.interfaces.IServiceAccountValidator; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; -@Component +@Service public class AzureServiceAccountValidatorImpl implements IServiceAccountValidator { + @Autowired + AppProperties appProperties; + @Override - public boolean isValidPublisherServiceAccount(String jwt) { - // TODO : Implement the service account verification for PubSub Role - // TODO : Also check the need and means to verify the other Roles. + public boolean isValidPublisherServiceAccount(String token) { + return isValidServiceAccount(token, this.appProperties.getAadClientID()); - // Marking it to return true, for the integration tests. - return true; } @Override - public boolean isValidServiceAccount(String jwt, String userIdentity, String... audiences) { - // TODO : Implement the service account verification for PubSub Role - // TODO : Also check the need and means to verify the other Roles. - - // Marking it to return true, for the integration tests. - return true; + public boolean isValidServiceAccount(String token, String userIdentity, String... audiences) { + // TODO : find out if this will be required to authZ, + // when we are are authZ through Entitlement Service. + // + // Tracking through a issue. + return false; } } diff --git a/provider/notification-azure/src/test/java/org/opengroup/osdu/notification/util/AzureServiceAccountValidatorImplTest.java b/provider/notification-azure/src/test/java/org/opengroup/osdu/notification/util/AzureServiceAccountValidatorImplTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0899d9a4c6275dc152c9bdce952a91449260d066 --- /dev/null +++ b/provider/notification-azure/src/test/java/org/opengroup/osdu/notification/util/AzureServiceAccountValidatorImplTest.java @@ -0,0 +1,58 @@ +// Copyright © Microsoft Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package org.opengroup.osdu.notification.util; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; +import org.opengroup.osdu.notification.provider.azure.util.AppProperties; +import org.opengroup.osdu.notification.provider.azure.util.AzureServiceAccountValidatorImpl; + +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class AzureServiceAccountValidatorImplTest { + private static String invalidAADClientID = "testInvalidAADClientID"; + private static String invalidJWT = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkdW1teUBkdW1teS5jb20iLCJpc3MiOiJkdW1teUBkdW1teS5jb20iLCJhdWQiOiJkdW1teS5kdW1teS5jb20iLCJpYXQiOjE1NTYxMzcyNzMsImV4cCI6MTU1NjIzMDk3OSwicHJvdmlkZXIiOiJkdW1teS5jb20iLCJjbGllbnQiOiJkdW1teS5jb20iLCJ1c2VyaWQiOiJkdW1teXRlc3Rlci5jb20iLCJlbWFpbCI6ImR1bW15dGVzdGVyLmNvbSIsImF1dGh6IjoiIiwibGFzdG5hbWUiOiJkdW1teSIsImZpcnN0bmFtZSI6ImR1bW15IiwiY291bnRyeSI6IiIsImNvbXBhbnkiOiIiLCJqb2J0aXRsZSI6IiIsInN1YmlkIjoiZHVtbXlpZCIsImlkcCI6ImR1bW15IiwiaGQiOiJkdW1teS5jb20iLCJkZXNpZCI6ImR1bW15aWQiLCJjb250YWN0X2VtYWlsIjoiZHVtbXlAZHVtbXkuY29tIiwianRpIjoiNGEyMWYyYzItZjU5Yy00NWZhLTk0MTAtNDNkNDdhMTg4ODgwIn0.nkiyKtfXXxAlC60iDjXuB2EAGDfZiVglP-CyU1T4etc"; + + @Mock + private AppProperties appProperties; + + @InjectMocks + @Spy + private AzureServiceAccountValidatorImpl sut; + + @Before + public void setup() { + when(this.appProperties.getAadClientID()).thenReturn(this.invalidAADClientID); + } + + @Test + public void should_returnFalse_isValidServiceAccount() { + // Set Up + boolean expected = false; + + // Act + boolean observed = this.sut.isValidPublisherServiceAccount(invalidJWT); + + // Assert + Assert.assertEquals(expected, observed); + } +} diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/PubsubHandshakeHandler.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/PubsubHandshakeHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..c282f83aaf997c430a6e41083bf2104196a8d0d8 --- /dev/null +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/PubsubHandshakeHandler.java @@ -0,0 +1,15 @@ +package org.opengroup.osdu.notification.provider.gcp.pubsub; + +import org.opengroup.osdu.notification.provider.interfaces.IPubsubHandshakeHandler; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +@Component +@Lazy +public class PubsubHandshakeHandler implements IPubsubHandshakeHandler { + + @Override + public String getHandshakeResponse() { + return null; + } +} \ No newline at end of file diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/pubsub/PubsubRequestBodyExtractor.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/PubsubRequestBodyExtractor.java similarity index 94% rename from notification-core/src/main/java/org/opengroup/osdu/notification/pubsub/PubsubRequestBodyExtractor.java rename to provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/PubsubRequestBodyExtractor.java index b8126d6c1e863bcf085a889d7e217d9e876ce785..8a11fb3b511b5754f9f83ce63950a0829b511413 100644 --- a/notification-core/src/main/java/org/opengroup/osdu/notification/pubsub/PubsubRequestBodyExtractor.java +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/PubsubRequestBodyExtractor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.opengroup.osdu.notification.pubsub; +package org.opengroup.osdu.notification.provider.gcp.pubsub; import com.google.common.base.Strings; import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; @@ -25,6 +25,7 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import org.opengroup.osdu.notification.provider.interfaces.IPubsubRequestBodyExtractor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; @@ -41,7 +42,7 @@ import java.util.stream.Stream; @Component @RequestScope -public class PubsubRequestBodyExtractor { +public class PubsubRequestBodyExtractor implements IPubsubRequestBodyExtractor { private static final String INVALID_PUBSUB_MESSAGE = "Invalid pubsub message"; private static final Gson GSON = new Gson(); private MessageContent messageContent; @@ -80,6 +81,10 @@ public class PubsubRequestBodyExtractor { return fullNotificationId[fullNotificationId.length - 1]; } + public boolean isHandshakeRequest() { + return false; + } + private MessageContent extractPubsubMessageFromRequestBody() { if (this.root == null) { this.root = this.extractRootJsonElementFromRequestBody(); diff --git a/testing/notification-test-azure/pom.xml b/testing/notification-test-azure/pom.xml index cacbfac57ce7ddc7df80265db50ad6c3b6d96241..698e9d30ba371972d4da541dc633971ea866c948 100644 --- a/testing/notification-test-azure/pom.xml +++ b/testing/notification-test-azure/pom.xml @@ -56,11 +56,7 @@ <artifactId>notification-test-core</artifactId> <version>1.0-SNAPSHOT</version> </dependency> - <dependency> - <groupId>org.opengroup.osdu</groupId> - <artifactId>os-core-common</artifactId> - <version>0.0.20</version> - </dependency> + <dependency> <groupId>org.opengroup.osdu</groupId> <artifactId>core-lib-azure</artifactId> diff --git a/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/util/AzureTestUtils.java b/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/util/AzureTestUtils.java index 0af4600be0963289de1c245817dcb34478dfde71..93bedd57a1bda315459e6c41dfb2851ad2bcae58 100644 --- a/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/util/AzureTestUtils.java +++ b/testing/notification-test-azure/src/test/java/org/opengroup/osdu/notification/util/AzureTestUtils.java @@ -13,42 +13,51 @@ public class AzureTestUtils extends TestUtils { @Override public synchronized String getOpsToken() throws Exception { if (Strings.isNullOrEmpty(opsToken)) { - opsToken = getToken(System.getProperty("INTEGRATION_TESTER", System.getenv("INTEGRATION_TESTER")), + noAccessToken = getToken("c4167fb6-c724-40e8-be11-2e20d1b7a92c",//System.getProperty("NO_DATA_ACCESS_TESTER", System.getenv("NO_DATA_ACCESS_TESTER")), + "muwCHobjuKlVzQwdUgMcta4w7mfQzAiW");//System.getProperty("NO_DATA_ACCESS_TESTER_SERVICEPRINCIPAL_SECRET", System.getenv("NO_DATA_ACCESS_TESTER_SERVICEPRINCIPAL_SECRET"))); + + /*opsToken = getToken(System.getProperty("INTEGRATION_TESTER", System.getenv("INTEGRATION_TESTER")), System.getProperty("TESTER_SERVICEPRINCIPAL_SECRET", System.getenv("TESTER_SERVICEPRINCIPAL_SECRET"))); - } + */} return "Bearer " + opsToken; } @Override public synchronized String getAdminToken() throws Exception { if (Strings.isNullOrEmpty(adminToken)) { - adminToken = getToken(System.getProperty("INTEGRATION_TESTER", System.getenv("INTEGRATION_TESTER")), + noAccessToken = getToken("c4167fb6-c724-40e8-be11-2e20d1b7a92c",//System.getProperty("NO_DATA_ACCESS_TESTER", System.getenv("NO_DATA_ACCESS_TESTER")), + "muwCHobjuKlVzQwdUgMcta4w7mfQzAiW");//System.getProperty("NO_DATA_ACCESS_TESTER_SERVICEPRINCIPAL_SECRET", System.getenv("NO_DATA_ACCESS_TESTER_SERVICEPRINCIPAL_SECRET"))); + + /*adminToken = getToken(System.getProperty("INTEGRATION_TESTER", System.getenv("INTEGRATION_TESTER")), System.getProperty("TESTER_SERVICEPRINCIPAL_SECRET", System.getenv("TESTER_SERVICEPRINCIPAL_SECRET"))); - } + */} return "Bearer " + adminToken; } @Override public synchronized String getEditorToken() throws Exception { if (Strings.isNullOrEmpty(editorToken)) { - editorToken = getToken(System.getProperty("INTEGRATION_TESTER", System.getenv("INTEGRATION_TESTER")), + noAccessToken = getToken("c4167fb6-c724-40e8-be11-2e20d1b7a92c",//System.getProperty("NO_DATA_ACCESS_TESTER", System.getenv("NO_DATA_ACCESS_TESTER")), + "muwCHobjuKlVzQwdUgMcta4w7mfQzAiW");//System.getProperty("NO_DATA_ACCESS_TESTER_SERVICEPRINCIPAL_SECRET", System.getenv("NO_DATA_ACCESS_TESTER_SERVICEPRINCIPAL_SECRET"))); + + /*editorToken = getToken(System.getProperty("INTEGRATION_TESTER", System.getenv("INTEGRATION_TESTER")), System.getProperty("TESTER_SERVICEPRINCIPAL_SECRET", System.getenv("TESTER_SERVICEPRINCIPAL_SECRET"))); - } + */} return "Bearer " + editorToken; } @Override public synchronized String getNoAccessToken() throws Exception { if (Strings.isNullOrEmpty(noAccessToken)) { - noAccessToken = getToken(System.getProperty("NO_DATA_ACCESS_TESTER", System.getenv("NO_DATA_ACCESS_TESTER")), - System.getProperty("NO_DATA_ACCESS_TESTER_SERVICEPRINCIPAL_SECRET", System.getenv("NO_DATA_ACCESS_TESTER_SERVICEPRINCIPAL_SECRET"))); + noAccessToken = getToken("c4167fb6-c724-40e8-be11-2e20d1b7a92c",//System.getProperty("NO_DATA_ACCESS_TESTER", System.getenv("NO_DATA_ACCESS_TESTER")), + "muwCHobjuKlVzQwdUgMcta4w7mfQzAiW");//System.getProperty("NO_DATA_ACCESS_TESTER_SERVICEPRINCIPAL_SECRET", System.getenv("NO_DATA_ACCESS_TESTER_SERVICEPRINCIPAL_SECRET"))); } return "Bearer " + noAccessToken; } private String getToken(String sp_id, String sp_secret) throws Exception { - String tenant_id = System.getProperty("AZURE_AD_TENANT_ID", System.getenv("AZURE_AD_TENANT_ID")); - String app_resource_id = System.getProperty("AZURE_AD_APP_RESOURCE_ID", System.getenv("AZURE_AD_APP_RESOURCE_ID")); + String tenant_id = "58975fd3-4977-44d0-bea8-37af0baac100";//System.getProperty("AZURE_AD_TENANT_ID", System.getenv("AZURE_AD_TENANT_ID")); + String app_resource_id = "dbf53e4d-f088-4379-87c3-d9b1496e77f8";//System.getProperty("AZURE_AD_APP_RESOURCE_ID", System.getenv("AZURE_AD_APP_RESOURCE_ID")); return new AzureServicePrincipal().getIdToken(sp_id, sp_secret, tenant_id, app_resource_id); } diff --git a/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/Config.java b/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/Config.java index 486680fb57ff6b14ed86a67b7f59014dcad00fdb..2358ad1467db40bb154c991bb9f2ae40ad7d8162 100644 --- a/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/Config.java +++ b/testing/notification-test-core/src/main/java/org/opengroup/osdu/notification/util/Config.java @@ -32,19 +32,19 @@ public class Config { private static Config config = new Config(); public static Config Instance() { - String env = getEnvironment(); + String env = "LOCAL";//getEnvironment(); config.ClientTenant = "nonexistenttenant"; config.IntegrationAudience = "245464679631-ktfdfpl147m1mjpbutl00b3cmffissgq.apps.googleusercontent.com"; config.OsduTenant = "opendes"; config.Topic = "records-changed"; - config.hmacSecretValue = System.getProperty("HMAC_SECRET", System.getenv("HMAC_SECRET")); + config.hmacSecretValue = "";//System.getProperty("HMAC_SECRET", System.getenv("HMAC_SECRET")); if (env.equalsIgnoreCase("LOCAL")) { //make sure to run register service on a different port. You can also choose to point to Register service that is running in cloud String registerUrl = "http://localhost:8081/"; //must have notification and register services running on different ports - config.HostUrl = "http://localhost:8080/"; + config.HostUrl = "http://localhost:8082/"; config.GSAPushUrl = registerUrl+"/test/gsa-challenge/"; config.HMACPushUrl = registerUrl+"/test/challenge/";