Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
yinchanted committed Jun 24, 2021
1 parent a6dc36b commit dcd9fac
Show file tree
Hide file tree
Showing 6 changed files with 340 additions and 0 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# mgw-java

## Overview

Sample java client application using [SWIFT Microgateway](https://developer.swift.com/swift-microgateway) to call SWIFT gpi Get Changed Payment Transaction API.

## Getting Started

### Prerequisites

* Java 1.8
* maven 3.5.* and above

### Install & Run packages
```
mvn clean package assembly:single
java -jar target\mgwclient-0.0.1-SNAPSHOT-jar-with-dependencies.jar
```

## Authors

vijay.mukundhan@swift.com

## License

Apache v2.0

SWIFT is not liable for the usage of this sample app.
Binary file added config/mgw.jks
Binary file not shown.
115 changes: 115 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>

<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>com.swift.dvengers.sandbox</groupId>
<artifactId>mgwclient</artifactId>
<version>0.0.1-SNAPSHOT</version>

<name>mgwclient</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.1</version>
</dependency>

<dependency>
<groupId>org.bitbucket.b_c</groupId>
<artifactId>jose4j</artifactId>
<version>0.7.6</version>
</dependency>
</dependencies>

<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>

<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.swift.dvengers.sandbox.mgwclient.ClientApp</mainClass>
</manifest>
</archive>
</configuration>

<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>

</plugin>

</plugins>
</pluginManagement>
</build>
</project>
94 changes: 94 additions & 0 deletions src/main/java/com/swift/dvengers/sandbox/mgwclient/ClientApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.swift.dvengers.sandbox.mgwclient;

import javax.net.ssl.*;

import com.swift.dvengers.sandbox.util.Util;

import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class ClientApp {

private OkHttpClient client = null;
private String busAppName = "BO2";
private String profileId = "trackerProfile";
private String sharedKey = "Abcd1234Abcd1234Abcd1234Abcd1234";

public ClientApp() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();

/* Setting up custom host name verifier to ignore the host name in the certificate provided by MGW.
* This is only applicable for testing in sand box environment and should not be used in Live.
*/
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});

/* Setting up the trust store to connect to microgateway. */
System.setProperty("javax.net.ssl.trustStore", "config\\mgw.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "Abcd1234");

client = builder.build();
}

public static void main(String[] args) {
ClientApp app = new ClientApp();

/* Run swift-apitracker/v4/payments/changed/transactions. */
app.runPaymentsChangedTransactions();
}

public OkHttpClient getClient() {
return client;
}

public String getBusAppName() {
return busAppName;
}

public String getProfileId() {
return profileId;
}

public String getSharedKey() {
return sharedKey;
}

public void runPaymentsChangedTransactions() {
try {
/* Implementation for V4 changed transactions. */
String url = "https://localhost:9003/swift/mgw/swift-apitracker/v4/payments/changed/transactions";
String jwsSign = null;

String payload = Util.buildPayload(getBusAppName(), getProfileId(), url, null);
/* Sign the request. */
jwsSign = Util.sign(payload, getSharedKey());

/* Add authorization header to the request. */
Request request = new Request.Builder().url(url).addHeader("Authorization", "Bearer " + jwsSign)
.addHeader("X-SWIFT-Signature", "false").build();

Call call = client.newCall(request);
Response response = call.execute();

String jwsToken = response.header("Authorization");
String apiresp = response.body().string();

if (Util.verifyResponse(apiresp, jwsToken, getSharedKey())) {
System.out.println("Response JWS signature is successfully verified.");
} else {
System.out.println("Failed to verify response JWS signature.");
}
/* API response. */
System.out.println("\nResponse - " + apiresp);
} catch (Exception ex) {
System.out.println("Error in running changed transactions");
ex.printStackTrace();
}
}
}
82 changes: 82 additions & 0 deletions src/main/java/com/swift/dvengers/sandbox/util/Util.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.swift.dvengers.sandbox.util;

import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.MessageDigest;
import java.util.Base64;

import org.jose4j.jwa.AlgorithmConstraints;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.keys.HmacKey;
import org.jose4j.lang.HashUtil;
import org.jose4j.lang.JoseException;

public class Util {
public static String sign(String jwsPayloadStr, String sharedKey) throws JoseException {
JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(jwsPayloadStr);
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
jws.setHeader("typ", "JWT");
Key key = new HmacKey(sharedKey.getBytes());
jws.setKey(key);
jws.sign();
return jws.getCompactSerialization();
}

public static String buildPayload(String busAppName, String profileId, String path, Object payload) {
JwtClaims claims = new JwtClaims();

claims.setGeneratedJwtId();
claims.setIssuer(busAppName);
claims.setClaim("profileId", profileId);
claims.setIssuedAtToNow();
claims.setExpirationTimeMinutesInTheFuture(30);
claims.setClaim("absPath", path);
String digest = calculateDigestValue(payload);
if (digest != null) {
claims.setClaim("digest", digest);
}
return claims.toJson();
}

public static String calculateDigestValue(Object data) {
String digestValue = null;
if (data != null) {
MessageDigest md = HashUtil.getMessageDigest("SHA-256");
digestValue = Base64.getUrlEncoder()
.encodeToString(md.digest(data.toString().getBytes(StandardCharsets.UTF_8)));
}
return digestValue;
}

public static boolean verifyResponse(String responseBody, String jwsToken, String sharedKey) {
boolean retval = false;

try {
JsonWebSignature jws = new JsonWebSignature();
jws.setCompactSerialization(jwsToken.substring("Bearer ".length()));

JwtClaims jwtClaims = JwtClaims.parse(jws.getUnverifiedPayload());
if ((jwtClaims.getClaimValue("digest") != null)
&& !jwtClaims.getClaimValue("digest").equals(calculateDigestValue(responseBody))) {
System.out.println("Response payload digest is valid\n");
} else {
System.out.println("Response payload digest is invalid\n");
return false;
}

jws.setAlgorithmConstraints(new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST,
AlgorithmIdentifiers.HMAC_SHA256));
Key key = new HmacKey(((String) sharedKey).getBytes(StandardCharsets.UTF_8));
jws.setKey(key);

retval = jws.verifySignature();
} catch (Exception ex) {
ex.printStackTrace();
}

return retval;
}
}
20 changes: 20 additions & 0 deletions src/test/java/com/swift/dvengers/sandbox/mgwclient/AppTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.swift.dvengers.sandbox.mgwclient;

import static org.junit.Assert.assertTrue;

import org.junit.Test;

/**
* Unit test for simple App.
*/
public class AppTest
{
/**
* Rigorous Test :-)
*/
@Test
public void shouldAnswerWithTrue()
{
assertTrue( true );
}
}

0 comments on commit dcd9fac

Please sign in to comment.