Commit c9620df0 authored by neelesh thakur's avatar neelesh thakur
Browse files

Merge branch 'gcp-dependency' into 'master'

remove gcp dependency from core module

See merge request !2
parents f54f1529 06c094a5
Pipeline #3654 passed with stages
in 8 minutes and 21 seconds
......@@ -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>
......@@ -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);
......
......@@ -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");
}
......
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
/*
* 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
......@@ -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);
}
......@@ -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" +
......
......@@ -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);
}
......
......@@ -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>
......
......@@ -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
......
......@@ -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 {
......
......@@ -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;
......
......@@ -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;
}
}
/*
* 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