Commit af81c79d authored by Alan Braz's avatar Alan Braz
Browse files

Merge branch 'ibm-impl-merge' into 'master'

Ibm impl merge

See merge request !20
parents 0a4efa6b d7eb3202
Pipeline #8175 passed with stages
in 13 minutes and 25 seconds
......@@ -5,3 +5,45 @@
**/out
**/*.iml
**/dependency-reduced-pom.xml
HELP.md
target/
bin/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/
.gradle/
### macOS ###
*.DS_Store
### Integration tests ###
.gradle
### Environment Configuration ###
*.env
......@@ -78,6 +78,7 @@
<module>notification-core</module>
<module>provider/notification-gcp</module>
<module>provider/notification-azure</module>
<module>provider/notification-ibm</module>
</modules>
<distributionManagement>
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2020 IBM Corp. All Rights Reserved.
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
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-ibm</artifactId>
<version>1.0.0</version>
<name>notification-ibm</name>
<description>IBM implementation for Notification service</description>
<packaging>jar</packaging>
<parent>
<groupId>org.opengroup.osdu</groupId>
<artifactId>os-notification</artifactId>
<version>1.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<properties>
<java.version>8</java.version>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.source>${java.version}</maven.compiler.source>
</properties>
<repositories>
<repository>
<id>${gitlab-server}</id>
<url>https://community.opengroup.org/api/v4/groups/17/-/packages/maven</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>${gitlab-server}</id>
<url>https://community.opengroup.org/api/v4/projects/143/packages/maven</url>
</repository>
<snapshotRepository>
<id>${gitlab-server}</id>
<url>https://community.opengroup.org/api/v4/projects/143/packages/maven</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<!-- <dependency>
<groupId>org.opengroup.osdu</groupId>
<artifactId>os-core-common</artifactId>
</dependency> -->
<dependency>
<groupId>org.opengroup.osdu</groupId>
<artifactId>os-core-lib-ibm</artifactId>
<version>0.3.6-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opengroup.osdu</groupId>
<artifactId>notification-core</artifactId>
<version>1.0.0</version>
</dependency>
<!-- unit test dependencies -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>spring-boot</classifier>
<mainClass>
org.opengroup.osdu.notification.provider.ibm.Application
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
/*
* 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.ibm;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@ComponentScan({"org.opengroup.osdu"})
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(new Class[] { Application.class} , args);
}
}
/*
* 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.ibm.di;
import org.opengroup.osdu.core.common.util.IServiceAccountJwtClient;
import org.opengroup.osdu.notification.provider.ibm.util.AppProperties;
import org.opengroup.osdu.notification.provider.ibm.util.ServiceAccountJwtIBMClientImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.stereotype.Component;
public class ServiceAccountJwtClientFactory extends AbstractFactoryBean<IServiceAccountJwtClient> {
@Override
public IServiceAccountJwtClient createInstance() throws Exception {
return new ServiceAccountJwtIBMClientImpl();
}
@Override
public Class<?> getObjectType() {
return IServiceAccountJwtClient.class;
}
}
package org.opengroup.osdu.notification.provider.ibm.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
package org.opengroup.osdu.notification.provider.ibm.pubsub;
import com.google.common.base.Strings;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.core.common.model.storage.MessageContent;
import org.opengroup.osdu.core.common.model.http.AppException;
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;
import org.springframework.web.context.annotation.RequestScope;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Component
@RequestScope
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;
private JsonObject root = null;
@Autowired
private HttpServletRequest request;
@Autowired
private JaxRsDpsLog log;
public Map<String, String> extractAttributesFromRequestBody() {
if (this.messageContent == null) {
this.messageContent = this.extractPubsubMessageFromRequestBody();
}
return this.messageContent.getAttributes();
}
public String extractDataFromRequestBody() {
if (this.messageContent == null) {
this.messageContent = this.extractPubsubMessageFromRequestBody();
}
return this.messageContent.getData();
}
public String extractNotificationIdFromRequestBody() {
if (this.root == null) {
this.root = this.extractRootJsonElementFromRequestBody();
}
JsonElement subscription = this.root.get("subscription");
if (subscription == null) {
throw new AppException(HttpStatus.BAD_REQUEST.value(), INVALID_PUBSUB_MESSAGE, "subscription object not found");
}
String[] fullNotificationId = subscription.getAsString().split("/");
return fullNotificationId[fullNotificationId.length - 1];
}
@Override
public boolean isHandshakeRequest() {
return false;
}
private MessageContent extractPubsubMessageFromRequestBody() {
if (this.root == null) {
this.root = this.extractRootJsonElementFromRequestBody();
}
JsonElement message = this.root.get("message");
if (message == null) {
throw new AppException(HttpStatus.BAD_REQUEST.value(), INVALID_PUBSUB_MESSAGE, "message object not found");
}
MessageContent content = GSON.fromJson(message.toString(), MessageContent.class);
Map<String, String> attributes = content.getAttributes();
if (attributes == null || attributes.isEmpty()) {
log.error("Incorrect Message: " + message.toString() );
throw new AppException(HttpStatus.BAD_REQUEST.value(), INVALID_PUBSUB_MESSAGE, "attribute map not found");
}
String data = content.getData();
if (Strings.isNullOrEmpty(data)) {
throw new AppException(HttpStatus.BAD_REQUEST.value(), INVALID_PUBSUB_MESSAGE, "data field not found");
}
Map<String, String> lowerCase = new HashMap<>();
attributes.forEach((key, value) -> lowerCase.put(key.toLowerCase(), value));
if (Strings.isNullOrEmpty(attributes.get("data-partition-id"))) {
throw new AppException(HttpStatus.BAD_REQUEST.value(), INVALID_PUBSUB_MESSAGE,
"No tenant information from pubsub message.");
}
content.setAttributes(lowerCase);
String decoded = new String(Base64.getDecoder().decode(data));
content.setData(decoded);
return content;
}
private JsonObject extractRootJsonElementFromRequestBody() {
try {
JsonParser jsonParser = new JsonParser();
BufferedReader reader = request.getReader();
Stream<String> lines = reader.lines();
String requestBody = lines.collect(Collectors.joining("\n"));
JsonElement rootElement = jsonParser.parse(requestBody);
if (!(rootElement instanceof JsonObject)) {
throw new AppException(HttpStatus.BAD_REQUEST.value(), "RequestBody is not JsonObject.",
"Request Body should be JsonObject to be processed.");
}
return rootElement.getAsJsonObject();
} catch (IOException e) {
throw new AppException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Request payload parsing error",
"Unable to parse request payload.", e);
}
}
}
/*
* 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.ibm.security;
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;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.httpBasic().disable()
.csrf().disable(); //disable default authN. AuthN handled by endpoints proxy
}
}
\ No newline at end of file
/**
* Copyright 2020 IBM Corp. All Rights Reserved.
*
* 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.ibm.util;
import org.opengroup.osdu.notification.provider.interfaces.IAppProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppProperties implements IAppProperties {
@Value("${app.entitlements}")
private String authorizeAPI;
@Value("${app.register}")
private String registerAPI;
@Value("${app.expireTime}")
private int expireTime;
@Value("${app.maxCacheSize}")
private int maxCacheSize;
public String getAuthorizeAPI() {
return authorizeAPI;
}
public String getRegisterAPI() {
return registerAPI;
}
}
/*
* 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.ibm.util;
import org.apache.http.impl.client.CloseableHttpClient;
//import org.opengroup.osdu.core.gcp.GoogleIdToken.IGoogleIdTokenFactory;
import org.opengroup.osdu.notification.provider.interfaces.IGoogleServiceAccount;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import lombok.SneakyThrows;
@Component
public class GoogleServiceAccountImpl implements IGoogleServiceAccount {
@SneakyThrows
@Override
public String getIdToken(String keyString, String audience) {
// TODO for GSA token validation check whether we have to impl
return "token";//this.googleIdTokenFactory.getGoogleIdToken(keyString, audience, this.closeableHttpClient);
}
}
\ No newline at end of file
/**
* Copyright 2020 IBM Corp. All Rights Reserved.
*
* 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.ibm.util;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.notification.provider.interfaces.IServiceAccountValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class IBMServiceAccountValidatorImpl implements IServiceAccountValidator {
@Override
public boolean isValidPublisherServiceAccount(String jwt) {
//call isValidServiceAccount()
// Check whether IBM have to implement the service account verification for PubSub Role
// Marking it to return true, for the integration tests.
return true;
}
@Override
public boolean isValidServiceAccount(String jwt, String userIdentity, String... googleAudiences) {
// Marking it to return true, for the integration tests.
return true;
}
}