Skip to content

Commit

Permalink
Merge pull request #18 from bunq/release/1.12.0
Browse files Browse the repository at this point in the history
Merge branch 'release/1.12.0'
  • Loading branch information
nickvandegroes authored Sep 17, 2019
2 parents 023a737 + 0bfe327 commit 2548c77
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 5 deletions.
6 changes: 5 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
// https://mvnrepository.com/artifact/commons-cli/commons-cli
compile group: 'commons-cli', name: 'commons-cli', version: '1.2'
compile 'com.github.bunq:sdk_java:1.10.+'
compile 'com.github.bunq:sdk_java:1.12.+'
}

compileJava {
options.compilerArgs << '-Xlint:unchecked'
}

jar {
Expand Down
22 changes: 22 additions & 0 deletions go-tinker
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,28 @@ USAGE="\
┌───────────────────────┬─────────────────────────────────────────────────┐
│ │ Run │
├───────────────────────┼─────────────────────────────────────────────────┤
│ 🔐 Create PSD2 Provider! │ ${ANSI_FORMAT_VERBOSE}java -jar tinker/tinker.jar CreatePsd2Configuration${ANSI_FORMAT_CLEAR}
│ │ │
│ │ ${ANSI_FORMAT_DIM}Required parameters:${ANSI_FORMAT_CLEAR}
│ │ ${ANSI_FORMAT_DIM}--env [SANDBOX/PRODUCTION]${ANSI_FORMAT_CLEAR}
│ │ ${ANSI_FORMAT_DIM}--certificate [path]${ANSI_FORMAT_CLEAR}
│ │ ${ANSI_FORMAT_DIM}--chain [path]${ANSI_FORMAT_CLEAR}
│ │ ${ANSI_FORMAT_DIM}--key [path]${ANSI_FORMAT_CLEAR}
├───────────────────────┼─────────────────────────────────────────────────┤
│ 🔒 Create PSD2 OAuth Client │ ${ANSI_FORMAT_VERBOSE}java -jar tinker/tinker.jar CreateOauthClient${ANSI_FORMAT_CLEAR}
│ │ │
│ │ ${ANSI_FORMAT_DIM}Required parameters:${ANSI_FORMAT_CLEAR}
│ │ ${ANSI_FORMAT_DIM}--context [path]${ANSI_FORMAT_CLEAR}
│ │ ${ANSI_FORMAT_DIM}--redirect [uri]${ANSI_FORMAT_CLEAR}
├───────────────────────┼─────────────────────────────────────────────────┤
│ 🔓 Test PSD2 OAuth │ ${ANSI_FORMAT_VERBOSE}java -jar tinker/tinker.jar TestOauth${ANSI_FORMAT_CLEAR}
│ │ │
│ │ ${ANSI_FORMAT_DIM}Required parameters:${ANSI_FORMAT_CLEAR}
│ │ ${ANSI_FORMAT_DIM}--env [SANDBOX/PRODUCTION]${ANSI_FORMAT_CLEAR}
│ │ ${ANSI_FORMAT_DIM}--code [authcode]${ANSI_FORMAT_CLEAR}
│ │ ${ANSI_FORMAT_DIM}--configuration [path]${ANSI_FORMAT_CLEAR}
│ │ ${ANSI_FORMAT_DIM}--redirect [uri]${ANSI_FORMAT_CLEAR}
├───────────────────────┼─────────────────────────────────────────────────┤
│ ✅ Show Overview │ ${ANSI_FORMAT_VERBOSE}java -jar tinker/tinker.jar UserOverview${ANSI_FORMAT_CLEAR}
├───────────────────────┼─────────────────────────────────────────────────┤
│ 🔼 Make a payment │ ${ANSI_FORMAT_VERBOSE}java -jar tinker/tinker.jar MakePayment${ANSI_FORMAT_CLEAR}
Expand Down
2 changes: 1 addition & 1 deletion gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
Expand Down
2 changes: 1 addition & 1 deletion gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DEFAULT_JVM_OPTS="-Xmx64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
Expand Down
100 changes: 100 additions & 0 deletions src/main/java/com/bunq/tinker/CreateOauthClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package com.bunq.tinker;

import com.bunq.sdk.context.ApiContext;
import com.bunq.sdk.context.ApiEnvironmentType;
import com.bunq.sdk.context.BunqContext;
import com.bunq.sdk.exception.BunqException;
import com.bunq.sdk.json.BunqGsonBuilder;
import com.bunq.sdk.model.core.OauthAuthorizationUri;
import com.bunq.sdk.model.core.OauthResponseType;
import com.bunq.sdk.model.generated.endpoint.OauthCallbackUrl;
import com.bunq.sdk.model.generated.endpoint.OauthClient;
import com.bunq.sdk.model.generated.object.Certificate;
import com.bunq.sdk.security.SecurityUtils;
import com.bunq.tinker.utils.ITinker;
import com.google.gson.stream.JsonReader;
import org.apache.commons.cli.*;

import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;

public class CreateOauthClient implements ITinker {
/**
* API constants.
*/
protected static final String OPTION_CONTEXT = "context";
protected static final String OPTION_REDIRECT_URI = "redirect";

/**
* File constants.
*/
protected static final String FILE_OAUTH_CONFIGURATION = "oauth.conf";

/**
* Error constants.
*/
protected static final String ERROR_MISSING_MANDATORY_OPTION = "Missing mandatory option.";

@Override
public void run(String[] args) throws Exception {
Options options = new Options();
options.addOption(new Option("", OPTION_CONTEXT, true, ""));
options.addOption(new Option("", OPTION_REDIRECT_URI, true, ""));

CommandLineParser parser = new BasicParser();
CommandLine allOption = parser.parse(options, args);

assertMandatoryOptions(allOption);

BunqContext.loadApiContext(
ApiContext.restore(allOption.getOptionValue(OPTION_CONTEXT))
);

OauthClient oauthClient;
File oauthFile = new File(FILE_OAUTH_CONFIGURATION);
if (oauthFile.exists()) {
oauthClient = createOauthClientFromFile(oauthFile.getPath());
} else {
Integer oauthClientId = OauthClient.create().getValue();

OauthCallbackUrl.create(oauthClientId, allOption.getOptionValue(OPTION_REDIRECT_URI));
oauthClient = OauthClient.get(oauthClientId).getValue();

String serializedClient = BunqGsonBuilder.buildDefault().create().toJson(oauthClient);
FileWriter fileWriter = new FileWriter(FILE_OAUTH_CONFIGURATION);

fileWriter.write(serializedClient);
fileWriter.close();
}

OauthAuthorizationUri authorizationUri = OauthAuthorizationUri.create(
OauthResponseType.CODE,
allOption.getOptionValue(OPTION_REDIRECT_URI),
oauthClient
);

System.out.println(" | Created OAuth client!");
System.out.println(" | Point your user to the following URL to obtain an auth code:");
System.out.println(" | " + authorizationUri.getAuthorizationUri());
}

/**
*/
private void assertMandatoryOptions(CommandLine allOption)
{
if (allOption.hasOption(OPTION_CONTEXT) &&
allOption.hasOption(OPTION_REDIRECT_URI)) {
return;
}
throw new BunqException(ERROR_MISSING_MANDATORY_OPTION);
}


private OauthClient createOauthClientFromFile(String path) throws IOException
{
return OauthClient.fromJsonReader(
new JsonReader(new InputStreamReader(new FileInputStream(path)))
);
}
}
78 changes: 78 additions & 0 deletions src/main/java/com/bunq/tinker/CreatePsd2Configuration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.bunq.tinker;

import com.bunq.sdk.context.ApiContext;
import com.bunq.sdk.context.ApiEnvironmentType;
import com.bunq.sdk.exception.BunqException;
import com.bunq.sdk.model.generated.object.Certificate;
import com.bunq.sdk.security.SecurityUtils;
import com.bunq.tinker.libs.SharedLib;
import com.bunq.tinker.utils.ITinker;
import org.apache.commons.cli.*;

import java.util.ArrayList;

public class CreatePsd2Configuration implements ITinker {
/**
* API constants.
*/
protected static final String API_DEVICE_DESCRIPTION = "##### YOUR DEVICE DESCRIPTION #####";

/**
* Option constants.
*/
protected static final String OPTION_ENVIRONMENT = "env";
protected static final String OPTION_CERTIFICATE = "certificate";
protected static final String OPTION_CERTIFICATE_CHAIN = "chain";
protected static final String OPTION_PRIVATE_KEY = "key";

/**
* File constants.
*/
protected static final String FILE_CONTEXT = "bunq-psd2.conf";

/**
* Error constants.
*/
protected static final String ERROR_MISSING_MANDATORY_OPTION = "Missing mandatory option.";

@Override
public void run(String[] args) throws Exception {

Options options = new Options();
options.addOption(new Option("", OPTION_CERTIFICATE, true, ""));
options.addOption(new Option("", OPTION_CERTIFICATE_CHAIN, true, ""));
options.addOption(new Option("", OPTION_PRIVATE_KEY, true, ""));

CommandLineParser parser = new BasicParser();
CommandLine allOption = parser.parse(options, args);

assertMandatoryOptions(allOption);

ApiContext apiContext = ApiContext.createForPsd2(
SharedLib.determineEnvironmentType(allOption),
SecurityUtils.getCertificateFromFile(allOption.getOptionValue(OPTION_CERTIFICATE)),
SecurityUtils.getPrivateKeyFromFile(allOption.getOptionValue(OPTION_PRIVATE_KEY)),
new Certificate[]{
SecurityUtils.getCertificateFromFile(allOption.getOptionValue(OPTION_CERTIFICATE_CHAIN))
},
API_DEVICE_DESCRIPTION,
new ArrayList<String>()
);

apiContext.save(FILE_CONTEXT);

System.out.println(" | PSD2 configuration created. Saved as bunq-psd.conf!");
}

/**
*/
private void assertMandatoryOptions(CommandLine allOption)
{
if (allOption.hasOption(OPTION_CERTIFICATE) &&
allOption.hasOption(OPTION_CERTIFICATE_CHAIN) &&
allOption.hasOption(OPTION_PRIVATE_KEY)) {
return;
}
throw new BunqException(ERROR_MISSING_MANDATORY_OPTION);
}
}
92 changes: 92 additions & 0 deletions src/main/java/com/bunq/tinker/TestOauth.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.bunq.tinker;

import com.bunq.sdk.context.ApiContext;
import com.bunq.sdk.context.ApiEnvironmentType;
import com.bunq.sdk.context.BunqContext;
import com.bunq.sdk.exception.BunqException;
import com.bunq.sdk.model.core.OauthAccessToken;
import com.bunq.sdk.model.core.OauthGrantType;
import com.bunq.sdk.model.generated.endpoint.OauthClient;
import com.bunq.tinker.libs.SharedLib;
import com.bunq.tinker.utils.ITinker;
import com.google.gson.stream.JsonReader;
import org.apache.commons.cli.*;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class TestOauth implements ITinker {
/**
* Option constants.
*/
private static final String OPTION_AUTH_CODE = "code";
private static final String OPTION_CLIENT_CONFIGURATION = "configuration";
private static final String OPTION_REDIRECT = "redirect";

/**
* API constants.
*/
protected static final String API_DEVICE_DESCRIPTION = "##### YOUR DEVICE DESCRIPTION #####";

/**
* Error constants.
*/
protected static final String ERROR_MISSING_MANDATORY_OPTION = "Missing mandatory option.";

@Override
public void run(String[] args) throws Exception {
Options options = new Options();
options.addOption(new Option("", OPTION_AUTH_CODE, true, ""));
options.addOption(new Option("", OPTION_CLIENT_CONFIGURATION, true, ""));
options.addOption(new Option("", OPTION_REDIRECT, true, ""));

CommandLineParser parser = new BasicParser();
CommandLine allOption = parser.parse(options, args);

assertMandatoryOptions(allOption);

OauthAccessToken accessToken = OauthAccessToken.create(
OauthGrantType.AUTHORIZATION_CODE,
allOption.getOptionValue(OPTION_AUTH_CODE),
allOption.getOptionValue(OPTION_REDIRECT),
createOauthClientFromFile(allOption.getOptionValue(OPTION_CLIENT_CONFIGURATION))
);

ApiContext apiContext = createApiContextByOauthToken(
accessToken,
SharedLib.determineEnvironmentType(allOption)
);
BunqContext.loadApiContext(apiContext);

(new UserOverview()).run(new String[]{});
}

/**
*/
private void assertMandatoryOptions(CommandLine allOption)
{
if (allOption.hasOption(OPTION_CLIENT_CONFIGURATION) &&
allOption.hasOption(OPTION_REDIRECT) &&
allOption.hasOption(OPTION_AUTH_CODE)) {
return;
}
throw new BunqException(ERROR_MISSING_MANDATORY_OPTION);
}

private OauthClient createOauthClientFromFile(String path) throws IOException
{
return OauthClient.fromJsonReader(
new JsonReader(new InputStreamReader(new FileInputStream(path)))
);
}

private static ApiContext createApiContextByOauthToken(OauthAccessToken token, ApiEnvironmentType environmentType)
{
return ApiContext.create(
environmentType,
token.getToken(),
API_DEVICE_DESCRIPTION
);
}
}
8 changes: 6 additions & 2 deletions src/main/java/com/bunq/tinker/utils/TinkerRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ public static void main(String[] args) throws Exception {

String className = args[0];
Class classObject = Class.forName(PACKAGE_TINKER_PREFIX + className);
ITinker tinker = (ITinker) classObject.newInstance();

tinker.run(args);
try {
ITinker tinker = (ITinker) classObject.getConstructor().newInstance();
tinker.run(args);
} catch (NoSuchMethodException exception) {
System.out.println("Couldn\'t start " + className + ". Class is missing or invalid.");
}
}
}

0 comments on commit 2548c77

Please sign in to comment.