From 06c094a5a1d3623a1e6bb64d6d6decb615e47946 Mon Sep 17 00:00:00 2001 From: neelesh thakur <nthakur4@slb.com> Date: Fri, 17 Jul 2020 16:45:23 -0400 Subject: [PATCH] remove gcp dependency from core module --- notification-core/pom.xml | 51 ------------------- .../osdu/notification/api/PubsubEndpoint.java | 23 ++++----- .../auth/AuthorizationFilter.java | 17 +++---- .../notification/utils/IAppProperties.java | 8 +-- .../utils/IGoogleServiceAccount.java | 22 ++++++++ .../utils/ServiceAccountValidator.java | 2 + .../notification/api/PubsubEndpointTests.java | 42 +++++++-------- .../auth/AuthorizationFilterTest.java | 19 +++---- provider/notification-gcp/pom.xml | 2 +- .../provider/gcp}/Application.java | 6 +-- .../di/ServiceAccountJwtClientFactory.java | 4 +- .../gcp/security}/SecurityConfig.java | 2 +- .../gcp/{ => util}/AppProperties.java | 15 +----- .../gcp/util/GoogleServiceAccountImpl.java | 39 ++++++++++++++ .../GoogleServiceAccountValidatorImpl.java | 9 +++- .../util/ServiceAccountJwtGcpClientImpl.java | 26 +++++----- 16 files changed, 139 insertions(+), 148 deletions(-) create mode 100644 notification-core/src/main/java/org/opengroup/osdu/notification/utils/IGoogleServiceAccount.java rename {notification-core/src/main/java/org/opengroup/osdu/notification => provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp}/Application.java (84%) rename {notification-core/src/main/java/org/opengroup/osdu/notification => provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/security}/SecurityConfig.java (95%) rename provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/{ => util}/AppProperties.java (71%) create mode 100644 provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/GoogleServiceAccountImpl.java diff --git a/notification-core/pom.xml b/notification-core/pom.xml index 9837f7822..c033c18ae 100644 --- a/notification-core/pom.xml +++ b/notification-core/pom.xml @@ -63,11 +63,6 @@ <artifactId>os-core-common</artifactId> <version>0.0.20</version> </dependency> - <dependency> - <groupId>org.opengroup.osdu</groupId> - <artifactId>core-lib-gcp</artifactId> - <version>0.1.21</version> - </dependency> <dependency> <groupId>org.projectlombok</groupId> @@ -219,29 +214,6 @@ </dependency> </dependencies> <build> - <pluginManagement> - <plugins> - <plugin> - <groupId>org.whitesource</groupId> - <artifactId>whitesource-maven-plugin</artifactId> - <version>3.3.0</version> - <configuration> - <orgToken>${orgToken}</orgToken> - <wssUrl>https://app-eu.whitesourcesoftware.com/agent</wssUrl> - <aggregateModules>true</aggregateModules> - <product>DPS</product> - <aggregateProjectName>dps-search</aggregateProjectName> - <forceCheckAllDependencies>false</forceCheckAllDependencies> - <checkPolicies>false</checkPolicies> - <forceUpdate>true</forceUpdate> - <failOnError>true</failOnError> - <excludes> - <exclude>integration-tests</exclude> - </excludes> - </configuration> - </plugin> - </plugins> - </pluginManagement> <plugins> <plugin> <groupId>org.jacoco</groupId> @@ -268,29 +240,6 @@ </execution> </executions> </plugin> - <plugin> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-maven-plugin</artifactId> - <version>2.1.7.RELEASE</version> - <configuration> - <profiles> - <profile>local</profile> - </profiles> - </configuration> - <executions> - <execution> - <goals> - <goal>repackage</goal> - </goals> - <configuration> - <classifier>spring-boot</classifier> - <mainClass> - org.opengroup.osdu.notification.Application - </mainClass> - </configuration> - </execution> - </executions> - </plugin> </plugins> </build> </project> 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 0c68a510f..975d66958 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 @@ -22,18 +22,21 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import org.apache.http.HttpStatus; -import org.apache.http.impl.client.CloseableHttpClient; import org.opengroup.osdu.core.common.cryptographic.ISignatureService; import org.opengroup.osdu.core.common.http.HttpClient; import org.opengroup.osdu.core.common.http.HttpRequest; import org.opengroup.osdu.core.common.http.HttpResponse; import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.AppException; import org.opengroup.osdu.core.common.model.http.DpsHeaders; -import org.opengroup.osdu.core.gcp.GoogleIdToken.IGoogleIdTokenFactory; +import org.opengroup.osdu.core.common.model.notification.*; +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.core.common.model.http.AppException; import org.opengroup.osdu.notification.pubsub.PubsubRequestBodyExtractor; import org.opengroup.osdu.notification.utils.Config; +import org.opengroup.osdu.notification.utils.IGoogleServiceAccount; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -41,8 +44,6 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.annotation.RequestScope; -import org.opengroup.osdu.core.common.notification.*; -import org.opengroup.osdu.core.common.model.notification.*; import java.io.IOException; import java.util.HashMap; @@ -61,9 +62,7 @@ public class PubsubEndpoint { @Autowired private HttpClient httpClient; @Autowired - private IGoogleIdTokenFactory gsaTokenProvider; - @Autowired - private CloseableHttpClient closeableHttpClient; + private IGoogleServiceAccount gsaTokenProvider; @Autowired private JaxRsDpsLog log; @Autowired @@ -110,7 +109,7 @@ public class PubsubEndpoint { JsonElement root = jsonParser.parse(gsaSecretValue.getKey()); String keyString = root.getAsJsonObject().toString(); - String idToken = this.gsaTokenProvider.getGoogleIdToken(keyString, gsaSecretValue.getAudience(), this.closeableHttpClient); + String idToken = this.gsaTokenProvider.getIdToken(keyString, gsaSecretValue.getAudience()); pushUrl = endpoint; requestHeader.put("Authorization", idToken); } @@ -129,10 +128,10 @@ public class PubsubEndpoint { return ResponseEntity.ok(ACKNOWLEDGE); } - private Subscription getSubscriptionFromCache(String notificationId) throws Exception{ + private Subscription getSubscriptionFromCache(String notificationId) throws Exception { String subscriptionString = subscriptionCacheFactory.get(notificationId); try { - if(Strings.isNullOrEmpty(subscriptionString)) + if (Strings.isNullOrEmpty(subscriptionString)) subscriptionString = querySubscriptionAndUpdateCache(notificationId); ObjectMapper objectMapper = this.getObjectMapper(); Subscription subscription = objectMapper.readValue(subscriptionString, Subscription.class); @@ -146,7 +145,7 @@ public class PubsubEndpoint { } } - private String querySubscriptionAndUpdateCache(String notificationId) throws Exception{ + private String querySubscriptionAndUpdateCache(String notificationId) throws Exception { ISubscriptionService service = subscriptionFactory.create(headers); List<Subscription> subscriptionList = service.query(notificationId); 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 af351481b..c720b2d5c 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 @@ -18,11 +18,11 @@ package org.opengroup.osdu.notification.auth; import org.apache.commons.lang3.StringUtils; import org.opengroup.osdu.core.common.model.entitlements.AuthorizationResponse; +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.core.common.model.http.AppException; import org.opengroup.osdu.notification.utils.Config; -import org.opengroup.osdu.notification.utils.IAppProperties; import org.opengroup.osdu.notification.utils.ServiceAccountValidator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -30,15 +30,11 @@ import org.springframework.web.context.annotation.RequestScope; import java.util.Arrays; -import org.opengroup.osdu.core.common.provider.interfaces.IAuthorizationService; - @Component("authorizationFilter") @RequestScope public class AuthorizationFilter { private static final String BEARER_PREFIX = "Bearer "; - @Autowired - private IAppProperties config; @Autowired private IAuthorizationService authService; @Autowired @@ -46,23 +42,22 @@ public class AuthorizationFilter { @Autowired private ServiceAccountValidator validator; - public boolean hasAnyPermission(String... requiredRoles) { DpsHeaders dpsHeaders = requestInfoExt.getHeaders(); - if(StringUtils.isBlank(dpsHeaders.getAuthorization())) + if (StringUtils.isBlank(dpsHeaders.getAuthorization())) throw new AppException(302, "Redirect", "No credentials sent on request."); - if(StringUtils.isBlank(dpsHeaders.getPartitionId())){ + if (StringUtils.isBlank(dpsHeaders.getPartitionId())) { requestInfoExt.assignPartitionIdIfNotInHeader(); } - if(Arrays.asList(requiredRoles).contains(Config.CRON) && requestInfoExt.isCronRequest()) { + if (Arrays.asList(requiredRoles).contains(Config.CRON) && requestInfoExt.isCronRequest()) { dpsHeaders.put(DpsHeaders.USER_EMAIL, Config.CRON); requestInfoExt.setHeaders(dpsHeaders); return true; } else if (Arrays.asList(requiredRoles).contains(Config.PUBSUB)) { String jwt = dpsHeaders.getAuthorization().substring(BEARER_PREFIX.length()); - if(! this.validator.isValidServiceAccount(jwt, config.getPubSubServiceAccountEmail())) { + if (!this.validator.isValidPublisherServiceAccount(jwt)) { if (!this.authorizeWithEntitlements(requiredRoles)) { throw new AppException(401, "Invalid User Identity", "this user is not authorized for this operation"); } diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/utils/IAppProperties.java b/notification-core/src/main/java/org/opengroup/osdu/notification/utils/IAppProperties.java index 99c11a4db..16049cc10 100644 --- a/notification-core/src/main/java/org/opengroup/osdu/notification/utils/IAppProperties.java +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/utils/IAppProperties.java @@ -1,11 +1,7 @@ package org.opengroup.osdu.notification.utils; public interface IAppProperties { - public String getAuthorizeAPI(); + String getAuthorizeAPI(); - public String getRegisterAPI(); - - public String getPubSubServiceAccountEmail(); - - public String getGoogleAudiences(); + String getRegisterAPI(); } \ No newline at end of file diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/utils/IGoogleServiceAccount.java b/notification-core/src/main/java/org/opengroup/osdu/notification/utils/IGoogleServiceAccount.java new file mode 100644 index 000000000..ae067a8a9 --- /dev/null +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/utils/IGoogleServiceAccount.java @@ -0,0 +1,22 @@ +/* + * Copyright 2017-2020, Schlumberger + * + * 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.utils; + +public interface IGoogleServiceAccount { + + String getIdToken(String keyString, String audience); +} \ No newline at end of file diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/utils/ServiceAccountValidator.java b/notification-core/src/main/java/org/opengroup/osdu/notification/utils/ServiceAccountValidator.java index 8d6c7200d..1491eba4f 100644 --- a/notification-core/src/main/java/org/opengroup/osdu/notification/utils/ServiceAccountValidator.java +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/utils/ServiceAccountValidator.java @@ -17,5 +17,7 @@ package org.opengroup.osdu.notification.utils; public interface ServiceAccountValidator { + boolean isValidPublisherServiceAccount(String jwt); + boolean isValidServiceAccount(String jwt, String userIdentity, String... audiences); } 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 01892824c..67b9a4a81 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 @@ -17,7 +17,6 @@ package org.opengroup.osdu.notification.api; import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.http.impl.client.CloseableHttpClient; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -28,15 +27,20 @@ import org.opengroup.osdu.core.common.cryptographic.ISignatureService; import org.opengroup.osdu.core.common.http.HttpClient; import org.opengroup.osdu.core.common.http.HttpResponse; import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; -import org.opengroup.osdu.core.common.model.http.DpsHeaders; -import org.opengroup.osdu.core.gcp.GoogleIdToken.GoogleIdTokenProducer; -import org.opengroup.osdu.notification.di.*; import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.opengroup.osdu.core.common.model.notification.Subscription; +import org.opengroup.osdu.core.common.notification.ISubscriptionService; +import org.opengroup.osdu.core.common.notification.SubscriptionException; +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.utils.IGoogleServiceAccount; import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.http.ResponseEntity; -import org.opengroup.osdu.core.common.notification.*; -import org.opengroup.osdu.core.common.model.notification.*; + import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -56,13 +60,11 @@ public class PubsubEndpointTests { @Mock private HttpClient httpClient; @Mock - private CloseableHttpClient closeableHttpClient; - @Mock private DpsHeaders headers; @Mock private SubscriptionCacheFactory subscriptionCacheFactory; @Mock - private GoogleIdTokenProducer googleIdTokenProducer; + private IGoogleServiceAccount googleIdTokenProducer; @Mock private JaxRsDpsLog log; @InjectMocks @@ -82,13 +84,13 @@ public class PubsubEndpointTests { private HttpResponse response = new HttpResponse(); @Before - public void setup() throws Exception{ + public void setup() throws Exception { when(this.pubsubRequestBodyExtractor.extractNotificationIdFromRequestBody()).thenReturn(NOTIFICATION_ID); when(this.pubsubRequestBodyExtractor.extractDataFromRequestBody()).thenReturn(PUBSUB_MESSAGE); } @Test - public void should_return200_whenPubsubMessageValidAndSuccessCodeReturnedFromClient_hmac() throws Exception{ + public void should_return200_whenPubsubMessageValidAndSuccessCodeReturnedFromClient_hmac() throws Exception { response.setResponseCode(200); when(this.signatureService.getSignedSignature(any(), any())).thenReturn(SIGNED_SIGNATURE); @@ -101,10 +103,10 @@ public class PubsubEndpointTests { } @Test - public void should_return200_whenPubsubMessageValidAndSuccessCodeReturnedFromClient_gsa() throws Exception{ + public void should_return200_whenPubsubMessageValidAndSuccessCodeReturnedFromClient_gsa() throws Exception { response.setResponseCode(200); - when(this.googleIdTokenProducer.getGoogleIdToken(any(), any(), any())).thenReturn(GOOGLE_ID_TOKEN); + when(this.googleIdTokenProducer.getIdToken(any(), any())).thenReturn(GOOGLE_ID_TOKEN); when(this.httpClient.send(any())).thenReturn(response); when(this.subscriptionCacheFactory.get(any())).thenReturn(getGsaSubscription()); sut.setObjectMapper(new ObjectMapper()); @@ -115,7 +117,7 @@ public class PubsubEndpointTests { } @Test - public void should_return400_whenSendOutRequestButNoSuccessCodeReturned_hmac() throws Exception{ + public void should_return400_whenSendOutRequestButNoSuccessCodeReturned_hmac() throws Exception { response.setResponseCode(500); when(this.signatureService.getSignedSignature(any(), any())).thenReturn(SIGNED_SIGNATURE); @@ -129,10 +131,10 @@ public class PubsubEndpointTests { } @Test - public void should_return400_whenSendOutRequestButNoSuccessCodeReturned_gsa() throws Exception{ + public void should_return400_whenSendOutRequestButNoSuccessCodeReturned_gsa() throws Exception { response.setResponseCode(500); - when(this.googleIdTokenProducer.getGoogleIdToken(any(), any(), any())).thenReturn(GOOGLE_ID_TOKEN); + when(this.googleIdTokenProducer.getIdToken(any(), any())).thenReturn(GOOGLE_ID_TOKEN); when(this.httpClient.send(any())).thenReturn(response); when(this.subscriptionCacheFactory.get(any())).thenReturn(getGsaSubscription()); sut.setObjectMapper(new ObjectMapper()); @@ -181,7 +183,7 @@ public class PubsubEndpointTests { public void should_return200_whenSubscriptionGotFromRegistration() throws Exception { response.setResponseCode(200); - when(this.googleIdTokenProducer.getGoogleIdToken(any(), any(), any())).thenReturn(GOOGLE_ID_TOKEN); + when(this.googleIdTokenProducer.getIdToken(any(), any())).thenReturn(GOOGLE_ID_TOKEN); when(this.httpClient.send(any())).thenReturn(response); when(this.subscriptionCacheFactory.get(any())).thenReturn(null); @@ -203,7 +205,7 @@ public class PubsubEndpointTests { } @Test(expected = IllegalArgumentException.class) - public void should_throwException_whenErrorGeneratingSignature_hmac() throws Exception{ + public void should_throwException_whenErrorGeneratingSignature_hmac() throws Exception { IllegalArgumentException ex = new IllegalArgumentException("Error generating signed signature"); when(this.subscriptionCacheFactory.get(any())).thenReturn(getHmacSubscription()); @@ -214,7 +216,7 @@ public class PubsubEndpointTests { } private String getHmacSubscription() { - return "{\n" + + return "{\n" + "\t\"name\": \"testSubscription\",\n" + "\t\"description\": \"Description\",\n" + "\t\"topic\": \"records-changed\",\n" + @@ -230,7 +232,7 @@ public class PubsubEndpointTests { } private String getGsaSubscription() { - return "{\n" + + return "{\n" + "\t\"name\": \"testSubscription\",\n" + "\t\"description\": \"Description\",\n" + "\t\"topic\": \"records-changed\",\n" + 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 1851b3380..c73e87d11 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 @@ -16,21 +16,19 @@ package org.opengroup.osdu.notification.auth; -import org.opengroup.osdu.core.common.model.entitlements.AuthorizationResponse; -import org.opengroup.osdu.core.common.model.http.DpsHeaders; - -import org.opengroup.osdu.notification.di.RequestInfoExt; -import org.opengroup.osdu.core.common.model.http.AppException; -import org.opengroup.osdu.notification.pubsub.PubsubRequestBodyExtractor; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.opengroup.osdu.core.common.model.entitlements.AuthorizationResponse; +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.utils.Config; -import org.opengroup.osdu.notification.utils.IAppProperties; import org.opengroup.osdu.notification.utils.ServiceAccountValidator; -import org.opengroup.osdu.core.common.provider.interfaces.IAuthorizationService; import org.powermock.modules.junit4.PowerMockRunner; import java.util.HashMap; @@ -52,8 +50,6 @@ public class AuthorizationFilterTest { private static final String ROLE4 = "notification.pubsub"; private static final String TEST_PUBSUB_JWT = "Bearer test.jwt.token"; - @Mock - private IAppProperties config; @Mock private DpsHeaders headers; @Mock @@ -69,8 +65,6 @@ public class AuthorizationFilterTest { @Before public void setup() { - when(config.getPubSubServiceAccountEmail()).thenReturn("test@test.com"); - when(headers.getAuthorization()).thenReturn("Bearer 123456"); when(headers.getPartitionId()).thenReturn("tenant1"); when(requestInfo.getHeaders()).thenReturn(headers); @@ -114,6 +108,7 @@ public class AuthorizationFilterTest { public void should_authenticateRequest_when_isFromPubsubAndUserIdentityIsCorrect() { when(headers.getAuthorization()).thenReturn(TEST_PUBSUB_JWT); when(this.validator.isValidServiceAccount(any(), any())).thenReturn(true); + when(this.authorizationService.authorizeAny(any(), eq(ROLE4))).thenReturn(AuthorizationResponse.builder().user("test@test.com").build()); this.sut.hasAnyPermission(ROLE4); } diff --git a/provider/notification-gcp/pom.xml b/provider/notification-gcp/pom.xml index 829d68252..dd4841e73 100644 --- a/provider/notification-gcp/pom.xml +++ b/provider/notification-gcp/pom.xml @@ -133,7 +133,7 @@ <configuration> <classifier>spring-boot</classifier> <mainClass> - org.opengroup.osdu.notification.Application + org.opengroup.osdu.notification.provider.gcp.Application </mainClass> </configuration> </execution> diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/Application.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/Application.java similarity index 84% rename from notification-core/src/main/java/org/opengroup/osdu/notification/Application.java rename to provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/Application.java index 3ebf8660c..aeac0d84d 100644 --- a/notification-core/src/main/java/org/opengroup/osdu/notification/Application.java +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/Application.java @@ -14,17 +14,13 @@ * limitations under the License. */ -package org.opengroup.osdu.notification; +package org.opengroup.osdu.notification.provider.gcp; -import org.opengroup.osdu.core.common.model.http.DpsHeaders; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableAsync; -import javax.annotation.PostConstruct; - @SpringBootApplication @ComponentScan({"org.opengroup.osdu"}) @EnableAsync diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/di/ServiceAccountJwtClientFactory.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/di/ServiceAccountJwtClientFactory.java index 6d3546993..403523702 100644 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/di/ServiceAccountJwtClientFactory.java +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/di/ServiceAccountJwtClientFactory.java @@ -16,8 +16,8 @@ package org.opengroup.osdu.notification.provider.gcp.di; import org.opengroup.osdu.core.common.util.IServiceAccountJwtClient; +import org.opengroup.osdu.notification.provider.gcp.util.AppProperties; import org.opengroup.osdu.notification.provider.gcp.util.ServiceAccountJwtGcpClientImpl; -import org.opengroup.osdu.notification.utils.IAppProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.stereotype.Component; @@ -26,7 +26,7 @@ import org.springframework.stereotype.Component; public class ServiceAccountJwtClientFactory extends AbstractFactoryBean<IServiceAccountJwtClient> { @Autowired - private IAppProperties config; + private AppProperties config; @Override public IServiceAccountJwtClient createInstance() throws Exception { diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/SecurityConfig.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/security/SecurityConfig.java similarity index 95% rename from notification-core/src/main/java/org/opengroup/osdu/notification/SecurityConfig.java rename to provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/security/SecurityConfig.java index 497a36ae1..089c6fdae 100644 --- a/notification-core/src/main/java/org/opengroup/osdu/notification/SecurityConfig.java +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/security/SecurityConfig.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.opengroup.osdu.notification; +package org.opengroup.osdu.notification.provider.gcp.security; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/AppProperties.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/AppProperties.java similarity index 71% rename from provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/AppProperties.java rename to provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/AppProperties.java index 04d0d9b2d..19789adf6 100644 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/AppProperties.java +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/AppProperties.java @@ -14,17 +14,15 @@ * limitations under the License. */ -package org.opengroup.osdu.notification.provider.gcp; +package org.opengroup.osdu.notification.provider.gcp.util; -import com.google.common.base.Strings; -import org.opengroup.osdu.core.common.model.http.AppException; import org.opengroup.osdu.notification.utils.IAppProperties; import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; @Component public class AppProperties implements IAppProperties { + @Value("${app.entitlements}") private String authorizeAPI; @Value("${app.register}") @@ -54,13 +52,4 @@ public class AppProperties implements IAppProperties { public String getGoogleAudiences() { return this.googleAudience; } - - private static String getEnvironmentVariable(String propertyKey) { - String property = System.getProperty(propertyKey, System.getenv(propertyKey)); - if (Strings.isNullOrEmpty(property)) { - throw new AppException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Property is null or empty", - String.format("Property of %s is null or empty, check the property key again.", propertyKey)); - } - return property; - } } diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/GoogleServiceAccountImpl.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/GoogleServiceAccountImpl.java new file mode 100644 index 000000000..7dcf3ba66 --- /dev/null +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/GoogleServiceAccountImpl.java @@ -0,0 +1,39 @@ +/* + * Copyright 2017-2020, Schlumberger + * + * 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.provider.gcp.util; + +import lombok.SneakyThrows; +import org.apache.http.impl.client.CloseableHttpClient; +import org.opengroup.osdu.core.gcp.GoogleIdToken.IGoogleIdTokenFactory; +import org.opengroup.osdu.notification.utils.IGoogleServiceAccount; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class GoogleServiceAccountImpl implements IGoogleServiceAccount { + + @Autowired + private IGoogleIdTokenFactory googleIdTokenFactory; + @Autowired + private CloseableHttpClient closeableHttpClient; + + @SneakyThrows + @Override + public String getIdToken(String keyString, String audience) { + return this.googleIdTokenFactory.getGoogleIdToken(keyString, audience, this.closeableHttpClient); + } +} \ No newline at end of file diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/GoogleServiceAccountValidatorImpl.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/GoogleServiceAccountValidatorImpl.java index 82977fc27..2d70b3d3c 100644 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/GoogleServiceAccountValidatorImpl.java +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/GoogleServiceAccountValidatorImpl.java @@ -23,8 +23,6 @@ import com.google.api.client.json.jackson2.JacksonFactory; import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; import org.opengroup.osdu.notification.utils.ServiceAccountValidator; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; @Service @@ -36,8 +34,15 @@ public class GoogleServiceAccountValidatorImpl implements ServiceAccountValidato @Autowired private JaxRsDpsLog log; @Autowired + private AppProperties appConfig; + @Autowired private GoogleServiceAccountValidatorGenerator verifierGenerator; + @Override + public boolean isValidPublisherServiceAccount(String jwt) { + return isValidServiceAccount(jwt, this.appConfig.getPubSubServiceAccountEmail()); + } + @Override public boolean isValidServiceAccount(String jwt, String userIdentity, String... googleAudiences) { GoogleIdTokenVerifier verifier = this.verifierGenerator.getVerifier(this.netHttpTransport, this.jacksonFactory, googleAudiences); diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/ServiceAccountJwtGcpClientImpl.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/ServiceAccountJwtGcpClientImpl.java index 05368cdcd..e2ef422c3 100644 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/ServiceAccountJwtGcpClientImpl.java +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/ServiceAccountJwtGcpClientImpl.java @@ -10,9 +10,9 @@ import com.google.api.services.iam.v1.model.SignJwtRequest; import com.google.api.services.iam.v1.model.SignJwtResponse; import com.google.auth.http.HttpCredentialsAdapter; import com.google.auth.oauth2.GoogleCredentials; +import com.google.common.base.Strings; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import com.google.common.base.Strings; import org.apache.http.HttpHeaders; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; @@ -26,18 +26,20 @@ import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.opengroup.osdu.core.common.model.http.AppException; import org.opengroup.osdu.core.common.model.tenant.TenantInfo; -import org.opengroup.osdu.core.gcp.multitenancy.TenantFactory; import org.opengroup.osdu.core.common.util.IServiceAccountJwtClient; -import org.opengroup.osdu.notification.utils.IAppProperties; +import org.opengroup.osdu.core.gcp.multitenancy.TenantFactory; import java.io.IOException; import java.security.GeneralSecurityException; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class ServiceAccountJwtGcpClientImpl implements IServiceAccountJwtClient { - private IAppProperties config; + private AppProperties config; private static final String JWT_AUDIENCE = "https://www.googleapis.com/oauth2/v4/token"; private static final String SERVICE_ACCOUNT_NAME_FORMAT = "projects/%s/serviceAccounts/%s"; private static final JsonFactory JSON_FACTORY = new JacksonFactory(); @@ -47,7 +49,7 @@ public class ServiceAccountJwtGcpClientImpl implements IServiceAccountJwtClient private static ConcurrentHashMap<String, JwtValidity> jwtCache = new ConcurrentHashMap<>(); private Iam iam; - public ServiceAccountJwtGcpClientImpl(IAppProperties config) { + public ServiceAccountJwtGcpClientImpl(AppProperties config) { if (config == null) { throw new IllegalArgumentException("AppProperties is null when initializing jwt client."); } else { @@ -56,8 +58,8 @@ public class ServiceAccountJwtGcpClientImpl implements IServiceAccountJwtClient } public String getIdToken(String dataPartitionId) { - String googleAudience = config.getGoogleAudiences(); - String hostName = config.getRegisterAPI(); + String googleAudience = this.config.getGoogleAudiences(); + String hostName = this.config.getRegisterAPI(); if (Strings.isNullOrEmpty(dataPartitionId) || Strings.isNullOrEmpty(googleAudience) || Strings.isNullOrEmpty(hostName)) { throw new AppException(HttpStatus.SC_BAD_REQUEST, "data partition id, audiences or hostname are null", INVALID_INPUT); } @@ -65,11 +67,11 @@ public class ServiceAccountJwtGcpClientImpl implements IServiceAccountJwtClient // Check if there is already a valid jwt String key = dataPartitionId + googleAudience + hostName; String jwt = checkAndGetJwtIfValid(key); - if(!Strings.isNullOrEmpty(jwt)) + if (!Strings.isNullOrEmpty(jwt)) return jwt; TenantInfo tenantInfo = new TenantFactory().getTenantInfo(dataPartitionId); - if(tenantInfo == null) { + if (tenantInfo == null) { throw new AppException(HttpStatus.SC_BAD_REQUEST, "data partition id is invalid", INVALID_DATA_PARTITION); } long currentTime = System.currentTimeMillis() / 1000; @@ -139,7 +141,7 @@ public class ServiceAccountJwtGcpClientImpl implements IServiceAccountJwtClient // THIS METHOD IS ONLY TO ENABLE UNIT TESTING boolean reduceTenantExpiry(String dataPartitionId, String googleAudience, String hostName, long keepDifference) { JwtValidity jwtValidity = jwtCache.get(dataPartitionId + googleAudience + hostName); - if(jwtValidity == null) + if (jwtValidity == null) return false; long currentTime = System.currentTimeMillis() / 1000; @@ -161,7 +163,7 @@ public class ServiceAccountJwtGcpClientImpl implements IServiceAccountJwtClient long currentTime = System.currentTimeMillis() / 1000; // If exipring in less than 5 minutes then need to renew the token - if ( jwtValidity.expiryTime - 300 < currentTime) { + if (jwtValidity.expiryTime - 300 < currentTime) { jwtCache.remove(key); return null; } -- GitLab