From c3ae08be943ecf6da940af70735920a0ed70f41e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michae=CC=88l=20van=20de=20Giessen?= Date: Wed, 20 Jun 2018 08:23:13 +0200 Subject: [PATCH] formatting feedback, java7 (bunq/sdk_java#93) --- .../java/com/bunq/sdk/http/ApiClient.java | 7 +- .../com/bunq/sdk/http/BunqBasicHeader.java | 55 +++++++++++----- .../java/com/bunq/sdk/http/BunqHeader.java | 64 +++++++++++++------ .../com/bunq/sdk/http/BunqRequestBuilder.java | 14 +++- .../com/bunq/sdk/security/SecurityUtils.java | 62 +++++++++--------- .../com/bunq/sdk/http/BunqHeaderTest.java | 60 +++++++++++------ .../endpoint/AttachmentPublicTest.java | 12 ++-- .../model/generated/endpoint/AvatarTest.java | 8 +-- 8 files changed, 184 insertions(+), 98 deletions(-) diff --git a/src/main/java/com/bunq/sdk/http/ApiClient.java b/src/main/java/com/bunq/sdk/http/ApiClient.java index 2b16eda1..7ed201b9 100644 --- a/src/main/java/com/bunq/sdk/http/ApiClient.java +++ b/src/main/java/com/bunq/sdk/http/ApiClient.java @@ -238,7 +238,7 @@ private void setDefaultHeaders(BunqRequestBuilder httpEntity) { BunqHeader.userAgent.addTo(httpEntity); BunqHeader.language.addTo(httpEntity); BunqHeader.region.addTo(httpEntity); - BunqHeader.clientRequestId.addTo(httpEntity,UUID.randomUUID().toString()); + BunqHeader.clientRequestId.addTo(httpEntity, UUID.randomUUID().toString()); BunqHeader.geolocation.addTo(httpEntity); } @@ -256,8 +256,8 @@ private void setSessionHeaders(BunqRequestBuilder requestBuilder) { String sessionToken = apiContext.getSessionToken(); if (sessionToken != null) { - BunqHeader.clientAuthentication.addTo(requestBuilder,sessionToken); - BunqHeader.clientSignature.addTo(requestBuilder,generateSignature(requestBuilder)); + BunqHeader.clientAuthentication.addTo(requestBuilder, sessionToken); + BunqHeader.clientSignature.addTo(requestBuilder, generateSignature(requestBuilder)); } } @@ -285,6 +285,7 @@ private BunqResponseRaw createBunqResponseRaw(Response response) */ private static String getResponseId(Response response) { Map headerMap = getHeadersMap(response); + return BunqHeader.clientResponseId.getOrDefault(headerMap); } diff --git a/src/main/java/com/bunq/sdk/http/BunqBasicHeader.java b/src/main/java/com/bunq/sdk/http/BunqBasicHeader.java index 247f17d7..b2672c7c 100644 --- a/src/main/java/com/bunq/sdk/http/BunqBasicHeader.java +++ b/src/main/java/com/bunq/sdk/http/BunqBasicHeader.java @@ -2,23 +2,23 @@ import okhttp3.Response; -import java.util.Optional; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; public class BunqBasicHeader { + /** + * String format constants for signing data + */ private static final String DELIMITER_HEADER_NAME_AND_VALUE = ": "; private static final String NEWLINE = "\n"; private final BunqHeader name; private final String value; - public static BunqBasicHeader get(BunqHeader header,Response response) { - return new BunqBasicHeader(header,response.header(header.getHeader())); - } - - public static Optional get(String header, String value) { - return BunqHeader.parse(header).map(h->new BunqBasicHeader(h,value)); + public static BunqBasicHeader get(BunqHeader header, Response response) { + return new BunqBasicHeader(header, response.header(header.getHeader())); } public BunqBasicHeader(BunqHeader name, String value) { @@ -35,13 +35,36 @@ public String getValue() { } private String forSigning() { - return getName().getHeader()+DELIMITER_HEADER_NAME_AND_VALUE+getValue(); + return getName().getHeader() + DELIMITER_HEADER_NAME_AND_VALUE + getValue(); } - public static String collectForSigning(Stream headers) { - return headers - .map(BunqBasicHeader::forSigning) - .sorted() - .collect(Collectors.joining(NEWLINE)); + public static String collectForSigning( + Collection headers, + BunqHeader exclude, + Collection includes) { + List headersForSigning = new ArrayList(); + + for (BunqBasicHeader header:headers) { + if (!header.getName().isBunq() && !includes.contains(header.getName())) { + continue; + } + + if (exclude != null && exclude.equals(header.getName())) { + continue; + } + + headersForSigning.add(header.forSigning()); + } + + Collections.sort(headersForSigning); + + StringBuffer stringBuffer = new StringBuffer(); + + for (String header:headersForSigning) { + stringBuffer.append(header); + stringBuffer.append(NEWLINE); + } + + return stringBuffer.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/bunq/sdk/http/BunqHeader.java b/src/main/java/com/bunq/sdk/http/BunqHeader.java index 865d18f9..519df850 100644 --- a/src/main/java/com/bunq/sdk/http/BunqHeader.java +++ b/src/main/java/com/bunq/sdk/http/BunqHeader.java @@ -1,12 +1,11 @@ package com.bunq.sdk.http; +import java.util.Collection; import java.util.Map; -import java.util.Optional; -import java.util.stream.Stream; public enum BunqHeader { attachmentDescription("X-Bunq-Attachment-Description"), - cacheControl("Cache-Control","no-cache"), + cacheControl("Cache-Control", "no-cache"), contentType("Content-Type"), clientAuthentication("X-Bunq-Client-Authentication"), clientEncryptionHMAC("X-Bunq-Client-Encryption-Hmac"), @@ -14,12 +13,12 @@ public enum BunqHeader { clientEncryptionKey("X-Bunq-Client-Encryption-Key"), clientRequestId("X-Bunq-Client-Request-Id"), clientSignature("X-Bunq-Client-Signature"), - clientResponseId("X-Bunq-Client-Response-Id","Could not determine response id."), - geolocation("X-Bunq-Geolocation","0 0 0 0 000"), - language("X-Bunq-Language","en_US"), - region("X-Bunq-Region","nl_NL"), + clientResponseId("X-Bunq-Client-Response-Id", "Could not determine response id."), + geolocation("X-Bunq-Geolocation", "0 0 0 0 000"), + language("X-Bunq-Language", "en_US"), + region("X-Bunq-Region", "nl_NL"), serverSignature("X-Bunq-Server-Signature"), - userAgent("User-Agent","bunq-sdk-java/0.13.1"); + userAgent("User-Agent", "bunq-sdk-java/0.13.1"); private static final String PREFIX = "X-Bunq-"; @@ -27,7 +26,7 @@ public enum BunqHeader { private final String defaultValue; BunqHeader(String header) { - this(header,null); + this(header, null); } BunqHeader(String header, String defaultValue) { @@ -35,8 +34,14 @@ public enum BunqHeader { this.defaultValue = defaultValue; } - public static Optional parse(String value) { - return Stream.of(values()).filter(h->h.equals(value)).findAny(); + public static BunqHeader parse(String value) { + for (BunqHeader header:values()) { + if (header.equals(value)) { + return header; + } + } + + return null; } public String getHeader() { @@ -47,16 +52,24 @@ public String getDefaultValue() { return defaultValue; } - public void addTo(Map headers, String value) { - headers.put(getHeader(),value!=null?value:getDefaultValue()); + private String getOrDefault(String value) { + if (value != null) { + return value; + } + + return getDefaultValue(); + } + + public void addTo(Map headers, String value) { + headers.put(getHeader(), getOrDefault(value)); } public void addTo(BunqRequestBuilder requestBuilder) { - addTo(requestBuilder,null); + addTo(requestBuilder, null); } public void addTo(BunqRequestBuilder requestBuilder, String value) { - requestBuilder.addHeader(getHeader(),value!=null?value:getDefaultValue()); + requestBuilder.addHeader(getHeader(), getOrDefault(value)); } public boolean equals(String header) { @@ -67,8 +80,21 @@ public boolean isBunq() { return getHeader().startsWith(PREFIX); } - public String getOrDefault(Map headers) { - Optional key = headers.keySet().stream().filter(this::equals).findAny(); - return key.map(headers::get).orElse(getDefaultValue()); + private String findKey(Collection keys) { + for (String key:keys) { + if (this.equals(key)) { + return key; + } + } + + return null; + } + + public String getOrDefault(Map headers) { + String key = findKey(headers.keySet()); + if (key != null && headers.get(key) != null) { + return headers.get(key); + } + return getDefaultValue(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/bunq/sdk/http/BunqRequestBuilder.java b/src/main/java/com/bunq/sdk/http/BunqRequestBuilder.java index 450dd1b5..a52dd82c 100644 --- a/src/main/java/com/bunq/sdk/http/BunqRequestBuilder.java +++ b/src/main/java/com/bunq/sdk/http/BunqRequestBuilder.java @@ -75,12 +75,21 @@ public BunqRequestBuilder url(URL url) { return (BunqRequestBuilder) super.url(url); } + private void addToAllHeader(String name, String value) { + BunqHeader header = BunqHeader.parse(name); + + if (header != null) { + this.allHeader.add(new BunqBasicHeader(header, value)); + } + } + /** * {@inheritDoc} */ @Override public BunqRequestBuilder header(String name, String value) { - BunqBasicHeader.get(name,value).ifPresent(this.allHeader::add); + addToAllHeader(name, value); + return (BunqRequestBuilder) super.header(name, value); } @@ -89,7 +98,8 @@ public BunqRequestBuilder header(String name, String value) { */ @Override public BunqRequestBuilder addHeader(String name, String value) { - BunqBasicHeader.get(name,value).ifPresent(this.allHeader::add); + addToAllHeader(name, value); + return (BunqRequestBuilder) super.addHeader(name, value); } diff --git a/src/main/java/com/bunq/sdk/security/SecurityUtils.java b/src/main/java/com/bunq/sdk/security/SecurityUtils.java index 7a4a7fcd..484ce31d 100644 --- a/src/main/java/com/bunq/sdk/security/SecurityUtils.java +++ b/src/main/java/com/bunq/sdk/security/SecurityUtils.java @@ -3,7 +3,10 @@ import com.bunq.sdk.context.ApiContext; import com.bunq.sdk.exception.BunqException; import com.bunq.sdk.exception.UncaughtExceptionError; -import com.bunq.sdk.http.*; +import com.bunq.sdk.http.BunqBasicHeader; +import com.bunq.sdk.http.BunqHeader; +import com.bunq.sdk.http.BunqRequestBuilder; +import com.bunq.sdk.http.HttpMethod; import okhttp3.Headers; import okhttp3.Response; import okio.BufferedSink; @@ -30,7 +33,12 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.List; +import java.util.Map; /** * Static lib containing methods for handling encryption. @@ -284,7 +292,7 @@ private static void addHeaderClientEncryptionKey(ApiContext apiContext, SecretKe cipher.init(Cipher.ENCRYPT_MODE, apiContext.getInstallationContext().getPublicKeyServer()); byte[] keyEncrypted = cipher.doFinal(key.getEncoded()); String keyEncryptedEncoded = Base64.getEncoder().encodeToString(keyEncrypted); - BunqHeader.clientEncryptionKey.addTo(customHeaders,keyEncryptedEncoded); + BunqHeader.clientEncryptionKey.addTo(customHeaders, keyEncryptedEncoded); } catch (GeneralSecurityException exception) { throw new BunqException(exception.getMessage()); } @@ -293,7 +301,7 @@ private static void addHeaderClientEncryptionKey(ApiContext apiContext, SecretKe private static void addHeaderClientEncryptionIv(byte[] initializationVector, Map customHeaders) { String initializationVectorEncoded = Base64.getEncoder().encodeToString(initializationVector); - BunqHeader.clientEncryptionIV.addTo(customHeaders,initializationVectorEncoded); + BunqHeader.clientEncryptionIV.addTo(customHeaders, initializationVectorEncoded); } private static byte[] encryptRequestBytes(byte[] requestBytes, SecretKey key, @@ -326,7 +334,7 @@ private static void addHeaderClientEncryptionHmac(byte[] requestBytes, bufferedSink.close(); byte[] hmac = mac.doFinal(); String hmacEncoded = Base64.getEncoder().encodeToString(hmac); - BunqHeader.clientEncryptionHMAC.addTo(customHeaders,hmacEncoded); + BunqHeader.clientEncryptionHMAC.addTo(customHeaders, hmacEncoded); } catch (GeneralSecurityException | IOException exception) { throw new BunqException(exception.getMessage()); } @@ -380,14 +388,11 @@ private static byte[] getEntityBodyBytes(BunqRequestBuilder requestBuilder) thro } private static String generateRequestHeadersSortedString(BunqRequestBuilder bunqRequestBuilder) { - return BunqBasicHeader.collectForSigning(bunqRequestBuilder.getAllHeader() - .stream() - .filter( - header -> - header.getName().isBunq() || - header.getName().equals(BunqHeader.cacheControl) || - header.getName().equals(BunqHeader.userAgent) - )); + return BunqBasicHeader.collectForSigning( + bunqRequestBuilder.getAllHeader(), + null, + Arrays.asList(BunqHeader.cacheControl, BunqHeader.userAgent) + ); } /** @@ -462,9 +467,9 @@ public static void validateResponseSignature( response.headers() ); Signature signature = getSignatureInstance(); - BunqBasicHeader headerServerSignature = BunqBasicHeader.get(BunqHeader.serverSignature,response); + BunqBasicHeader serverSignature = BunqBasicHeader.get(BunqHeader.serverSignature, response); - byte[] serverSignatureBase64Bytes = headerServerSignature.getValue().getBytes(); + byte[] serverSignatureBase64Bytes = serverSignature.getValue().getBytes(); byte[] serverSignatureDecoded = Base64.getDecoder().decode(serverSignatureBase64Bytes); verifyDataSigned(signature, keyPublicServer, responseBytes, serverSignatureDecoded); } @@ -478,14 +483,15 @@ private static byte[] getResponseBytes( List allResponseHeader = new ArrayList<>(); for (int i = INDEX_FIRST; i < allHeader.names().size(); i++) { - Optional header = BunqBasicHeader.get(allHeader.name(i),allHeader.get(allHeader.name(i))); - if(header.isPresent() && !BunqHeader.serverSignature.equals(header.get().getName())) { - allResponseHeader.add(header.get()); + BunqHeader header = BunqHeader.parse(allHeader.name(i)); + + if (header != null && !BunqHeader.serverSignature.equals(header)) { + allResponseHeader.add(new BunqBasicHeader(header, allHeader.get(allHeader.name(i)))); } } try { - outputStream.write(getResponseHeadBytes(responseCode,allResponseHeader)); + outputStream.write(getResponseHeadBytes(responseCode, allResponseHeader)); outputStream.write(responseBodyBytes); } catch (IOException exception) { throw new UncaughtExceptionError(exception); @@ -494,20 +500,18 @@ private static byte[] getResponseBytes( return outputStream.toByteArray(); } - private static byte[] getResponseHeadBytes(int responseCode, List responseHeaders) { - String requestHeadString = responseCode + NEWLINE + - generateResponseHeadersSortedString(responseHeaders) + NEWLINE + NEWLINE; + private static byte[] getResponseHeadBytes(int code, List headers) { + String requestHeadString = code + NEWLINE + + generateResponseHeadersSortedString(headers) + NEWLINE + NEWLINE; return requestHeadString.getBytes(); } private static String generateResponseHeadersSortedString(List headers) { - return BunqBasicHeader.collectForSigning(headers - .stream() - .filter( - header -> - header.getName().isBunq() && - !header.getName().equals(BunqHeader.serverSignature) - )); + return BunqBasicHeader.collectForSigning( + headers, + BunqHeader.serverSignature, + Collections.emptyList() + ); } } diff --git a/src/test/java/com/bunq/sdk/http/BunqHeaderTest.java b/src/test/java/com/bunq/sdk/http/BunqHeaderTest.java index 244e92d6..ddaf0c78 100644 --- a/src/test/java/com/bunq/sdk/http/BunqHeaderTest.java +++ b/src/test/java/com/bunq/sdk/http/BunqHeaderTest.java @@ -1,49 +1,69 @@ package com.bunq.sdk.http; -import org.junit.Test; +import java.util.Collections; +import java.util.Map; +import java.util.HashMap; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; public class BunqHeaderTest { @Test public void parse() { // parse works case-insensitive - assertEquals(BunqHeader.clientResponseId,BunqHeader.parse("X-Bunq-Client-Response-Id").get()); - assertEquals(BunqHeader.clientResponseId,BunqHeader.parse("x-bunq-client-response-id").get()); + assertEquals(BunqHeader.clientResponseId, BunqHeader.parse("X-Bunq-Client-Response-Id")); + assertEquals(BunqHeader.clientResponseId, BunqHeader.parse("x-bunq-client-response-id")); } @Test public void isBunq() { - List nonBunqHeaders = Arrays.asList(BunqHeader.cacheControl,BunqHeader.contentType,BunqHeader.userAgent); + assertFalse(BunqHeader.cacheControl.isBunq()); + assertFalse(BunqHeader.contentType.isBunq()); + assertFalse(BunqHeader.userAgent.isBunq()); - assertEquals(nonBunqHeaders, Stream.of(BunqHeader.values()).filter(h->!h.isBunq()).collect(Collectors.toList())); + assertTrue(BunqHeader.attachmentDescription.isBunq()); + assertTrue(BunqHeader.clientAuthentication.isBunq()); + assertTrue(BunqHeader.clientEncryptionHMAC.isBunq()); + assertTrue(BunqHeader.clientEncryptionIV.isBunq()); + assertTrue(BunqHeader.clientEncryptionIV.isBunq()); + assertTrue(BunqHeader.clientEncryptionKey.isBunq()); + assertTrue(BunqHeader.clientRequestId.isBunq()); + assertTrue(BunqHeader.clientSignature.isBunq()); + assertTrue(BunqHeader.clientResponseId.isBunq()); + assertTrue(BunqHeader.geolocation.isBunq()); + assertTrue(BunqHeader.region.isBunq()); + assertTrue(BunqHeader.serverSignature.isBunq()); + assertTrue(BunqHeader.clientEncryptionKey.isBunq()); + assertTrue(BunqHeader.clientRequestId.isBunq()); } @Test public void getOrDefault() { BunqHeader h = BunqHeader.clientResponseId; - assertEquals("test-id",h.getOrDefault(Collections.singletonMap("x-bunq-client-response-id","test-id"))); - assertEquals("Could not determine response id.",h.getOrDefault(Collections.singletonMap("x-bunq-some-other-header","test-id"))); - assertEquals("Could not determine response id.",h.getOrDefault(Collections.emptyMap())); + assertEquals("test-id", + h.getOrDefault(Collections.singletonMap("x-bunq-client-response-id", "test-id"))); + assertEquals("Could not determine response id.", + h.getOrDefault(Collections.singletonMap("x-bunq-some-other-header", "test-id"))); + assertEquals("Could not determine response id.", + h.getOrDefault(Collections.emptyMap())); } @Test public void addToMap() { - Map headers = new HashMap<>(); + Map headers = new HashMap<>(); //sut - BunqHeader.language.addTo(headers,null); - BunqHeader.geolocation.addTo(headers,null); - BunqHeader.userAgent.addTo(headers,"test-agent"); + BunqHeader.language.addTo(headers, null); + BunqHeader.geolocation.addTo(headers, null); + BunqHeader.userAgent.addTo(headers, "test-agent"); // verify - assertEquals("en_US",headers.get("X-Bunq-Language")); - assertEquals("0 0 0 0 000",headers.get("X-Bunq-Geolocation")); - assertEquals("test-agent",headers.get("User-Agent")); + assertEquals("en_US", headers.get("X-Bunq-Language")); + assertEquals("0 0 0 0 000", headers.get("X-Bunq-Geolocation")); + assertEquals("test-agent", headers.get("User-Agent")); } -} \ No newline at end of file +} diff --git a/src/test/java/com/bunq/sdk/model/generated/endpoint/AttachmentPublicTest.java b/src/test/java/com/bunq/sdk/model/generated/endpoint/AttachmentPublicTest.java index 48eca29f..866d34d2 100644 --- a/src/test/java/com/bunq/sdk/model/generated/endpoint/AttachmentPublicTest.java +++ b/src/test/java/com/bunq/sdk/model/generated/endpoint/AttachmentPublicTest.java @@ -10,6 +10,7 @@ import java.io.File; import java.io.IOException; import java.util.HashMap; +import java.util.Map; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -37,11 +38,12 @@ private static byte[] getRequestBytes() { } private static String uploadFileAndGetUuid() { - HashMap customHeaders = new HashMap<>(); - BunqHeader.contentType.addTo(customHeaders,CONTENT_TYPE); - BunqHeader.attachmentDescription.addTo(customHeaders,ATTACHMENT_DESCRIPTION); - byte[] RequestBytes = getRequestBytes(); - return AttachmentPublic.create(customHeaders, RequestBytes).getValue(); + Map customHeaders = new HashMap<>(); + + BunqHeader.contentType.addTo(customHeaders, CONTENT_TYPE); + BunqHeader.attachmentDescription.addTo(customHeaders, ATTACHMENT_DESCRIPTION); + + return AttachmentPublic.create(customHeaders, getRequestBytes()).getValue(); } /** diff --git a/src/test/java/com/bunq/sdk/model/generated/endpoint/AvatarTest.java b/src/test/java/com/bunq/sdk/model/generated/endpoint/AvatarTest.java index 830fc020..65284c1b 100644 --- a/src/test/java/com/bunq/sdk/model/generated/endpoint/AvatarTest.java +++ b/src/test/java/com/bunq/sdk/model/generated/endpoint/AvatarTest.java @@ -54,9 +54,9 @@ public void createAvatarTest() { } private String uploadAvatar(byte[] file_contents) { - HashMap customHeaders = new HashMap<>(); - BunqHeader.attachmentDescription.addTo(customHeaders,ATTACHMENT_PATH_IN); - BunqHeader.contentType.addTo(customHeaders,CONTENT_TYPE); - return AttachmentPublic.create(customHeaders, file_contents).getValue(); + HashMap allCustomHeader = new HashMap<>(); + BunqHeader.attachmentDescription.addTo(allCustomHeader, ATTACHMENT_PATH_IN); + BunqHeader.contentType.addTo(allCustomHeader, CONTENT_TYPE); + return AttachmentPublic.create(allCustomHeader, file_contents).getValue(); } }