Skip to content

Commit b960881

Browse files
Merge pull request #1156 from Adyen/automation/release
Release v22.0.0-beta
2 parents c99ba89 + c6d37d7 commit b960881

File tree

394 files changed

+11864
-3858
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

394 files changed

+11864
-3858
lines changed

Makefile

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ payment: smallServiceName=PaymentApi
2828
recurring: spec=RecurringService-v68
2929
recurring: smallServiceName=RecurringApi
3030
payout: spec=PayoutService-v68
31-
management: spec=ManagementService-v1
31+
management: spec=ManagementService-v3
3232
balanceplatform: spec=BalancePlatformService-v2
33-
transfers: spec=TransferService-v3
33+
transfers: spec=TransferService-v4
3434
legalentitymanagement: spec=LegalEntityService-v3
3535
# Classic Platforms
3636
marketpayaccount: spec=AccountService-v6
@@ -46,9 +46,9 @@ marketpaywebhooks: spec=MarketPayNotificationService-v6
4646
acswebhooks: spec=BalancePlatformAcsNotification-v1
4747
configurationwebhooks: spec=BalancePlatformConfigurationNotification-v1
4848
reportwebhooks: spec=BalancePlatformReportNotification-v1
49-
transferwebhooks: spec=BalancePlatformTransferNotification-v3
49+
transferwebhooks: spec=BalancePlatformTransferNotification-v4
5050
# Management Webhooks
51-
managementwebhooks: spec=ManagementNotificationService-v1
51+
managementwebhooks: spec=ManagementNotificationService-v3
5252
# Disputes
5353
disputes: spec=DisputeService-v30
5454
disputes: smallServiceName=DisputesApi
@@ -67,7 +67,8 @@ $(modelGen): target/spec $(openapi-generator-jar)
6767
--library $(library) \
6868
--global-property modelDocs=false \
6969
--global-property modelTests=false \
70-
--inline-schema-name-mappings DonationPaymentRequest_paymentMethod=CheckoutPaymentMethod \
70+
--inline-schema-name-mappings PaymentRequest_paymentMethod=CheckoutPaymentMethod \
71+
--inline-schema-name-mappings DonationPaymentRequest_paymentMethod=DonationPaymentMethod \
7172
--additional-properties=dateLibrary=java8 \
7273
--additional-properties=openApiNullable=false \
7374
--additional-properties=resourceClass=$(resourceClass)Resource
@@ -97,7 +98,8 @@ $(bigServices): target/spec $(openapi-generator-jar)
9798
--api-name-suffix Api \
9899
--global-property modelDocs=false \
99100
--global-property modelTests=false \
100-
--inline-schema-name-mappings DonationPaymentRequest_paymentMethod=CheckoutPaymentMethod \
101+
--inline-schema-name-mappings PaymentRequest_paymentMethod=CheckoutPaymentMethod \
102+
--inline-schema-name-mappings DonationPaymentRequest_paymentMethod=DonationPaymentMethod \
101103
--additional-properties=dateLibrary=java8 \
102104
--additional-properties=openApiNullable=false
103105
mv $(output)/$(models)/$@ $(models)/$@
@@ -124,7 +126,8 @@ $(singleFileServices): target/spec $(openapi-generator-jar)
124126
--api-name-suffix Api \
125127
--global-property modelDocs=false \
126128
--global-property modelTests=false \
127-
--inline-schema-name-mappings DonationPaymentRequest_paymentMethod=CheckoutPaymentMethod \
129+
--inline-schema-name-mappings PaymentRequest_paymentMethod=CheckoutPaymentMethod \
130+
--inline-schema-name-mappings DonationPaymentRequest_paymentMethod=DonationPaymentMethod \
128131
--additional-properties=dateLibrary=java8 \
129132
--additional-properties=openApiNullable=false \
130133
--additional-properties=smallServiceName=$(smallServiceName)

README.md

Lines changed: 67 additions & 24 deletions
Large diffs are not rendered by default.

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<groupId>com.adyen</groupId>
55
<artifactId>adyen-java-api-library</artifactId>
66
<packaging>jar</packaging>
7-
<version>21.6.0</version>
7+
<version>22.0.0-beta</version>
88
<name>Adyen Java API Library</name>
99
<description>Adyen API Client Library for Java</description>
1010
<url>https://github.com/adyen/adyen-java-api-library</url>

src/main/java/com/adyen/Client.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
package com.adyen;
22

33
import com.adyen.enums.Environment;
4-
import com.adyen.enums.Region;
54
import com.adyen.httpclient.AdyenHttpClient;
65
import com.adyen.httpclient.ClientInterface;
76

8-
import java.security.KeyStore;
7+
import javax.net.ssl.SSLContext;
98

109
public class Client {
1110
private ClientInterface httpClient;
1211
private Config config;
1312
public static final String LIB_NAME = "adyen-java-api-library";
14-
public static final String LIB_VERSION = "21.6.0";
13+
public static final String LIB_VERSION = "22.0.0-beta";
1514
public static final String TERMINAL_API_ENDPOINT_TEST = "https://terminal-api-test.adyen.com";
1615
public static final String TERMINAL_API_ENDPOINT_LIVE = "https://terminal-api-live.adyen.com";
1716

@@ -32,17 +31,12 @@ public Client(String username, String password, Environment environment, String
3231
* Use this constructor to create client for client certificate authentication along with API key.
3332
* Note: Client certificate authentication is only applicable for PAL and Checkout services in LIVE,
3433
* Other services will just use API key for authentication.
35-
* @param trustStore Trust store containing server certificate
36-
* @param clientKeyStore Client Key store containing client certificate and key
37-
* @param clientKeyStorePassword Password for client key store
34+
* @param sslContext {@link SSLContext} for client certificate authentication
3835
* @param apiKey Adyen API Key
39-
* @param region Data center region (EU/US/AU), default EU if not provided
4036
*/
41-
public Client(KeyStore trustStore, KeyStore clientKeyStore, String clientKeyStorePassword, String apiKey, Region region) {
37+
public Client(SSLContext sslContext, String apiKey) {
4238
this(apiKey, Environment.LIVE);
43-
this.config.setClientKeyStorePassword(clientKeyStorePassword);
44-
this.config.setClientKeyStore(clientKeyStore);
45-
this.config.setTrustKeyStore(trustStore);
39+
this.config.setSSLContext(sslContext);
4640
}
4741

4842
public Client(String username, String password, Environment environment, String liveEndpointUrlPrefix, String applicationName) {

src/main/java/com/adyen/Config.java

Lines changed: 27 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
package com.adyen;
22

33
import com.adyen.enums.Environment;
4-
import com.adyen.util.CertificateUtil;
54

6-
import java.io.FileNotFoundException;
7-
import java.io.IOException;
8-
import java.io.InputStream;
9-
import java.security.KeyStore;
10-
import java.security.KeyStoreException;
11-
import java.security.NoSuchAlgorithmException;
12-
import java.security.cert.Certificate;
13-
import java.security.cert.CertificateException;
5+
import javax.net.ssl.HostnameVerifier;
6+
import javax.net.ssl.SSLContext;
147

158
public class Config {
169
protected String username;
@@ -28,13 +21,9 @@ public class Config {
2821
//Terminal API Specific
2922
protected String terminalApiCloudEndpoint;
3023
protected String terminalApiLocalEndpoint;
31-
protected Certificate terminalCertificate;
32-
33-
// Client certificate authentication
34-
protected KeyStore trustKeyStore;
35-
protected KeyStore clientKeyStore;
36-
protected String clientKeyStorePassword;
3724
protected String liveEndpointUrlPrefix;
25+
protected SSLContext sslContext;
26+
protected HostnameVerifier hostnameVerifier;
3827

3928
public Config() {
4029
// do nothing
@@ -112,59 +101,37 @@ public void setReadTimeoutMillis(int readTimeoutMillis) {
112101
this.readTimeoutMillis = readTimeoutMillis;
113102
}
114103

115-
public Certificate getTerminalCertificate() {
116-
return terminalCertificate;
117-
}
118-
119-
public void setTerminalCertificate(Certificate terminalCertificate) {
120-
this.terminalCertificate = terminalCertificate;
121-
}
122-
123-
public void setTerminalCertificate(String terminalCertificatePath) throws FileNotFoundException, CertificateException {
124-
this.terminalCertificate = CertificateUtil.loadCertificate(terminalCertificatePath);
125-
}
126-
127-
public void setTerminalCertificate(InputStream terminalCertificateStream) throws CertificateException {
128-
this.terminalCertificate = CertificateUtil.loadCertificate(terminalCertificateStream);
129-
}
130-
131-
public KeyStore getTrustKeyStore() {
132-
return trustKeyStore;
133-
}
134-
135-
public void setTrustKeyStore(KeyStore trustKeyStore) {
136-
this.trustKeyStore = trustKeyStore;
137-
}
138-
139-
public void setTrustKeyStore(String trustKeyStorePath, String keyStoreType, String password) throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException {
140-
this.trustKeyStore = CertificateUtil.loadKeyStore(trustKeyStorePath, keyStoreType, password);
141-
}
142-
143-
public KeyStore getClientKeyStore() {
144-
return clientKeyStore;
104+
public String getLiveEndpointUrlPrefix() {
105+
return this.liveEndpointUrlPrefix;
145106
}
146-
147-
public void setClientKeyStore(KeyStore clientKeyStore) {
148-
this.clientKeyStore = clientKeyStore;
107+
public void setLiveEndpointUrlPrefix(String liveEndpointUrlPrefix) {
108+
this.liveEndpointUrlPrefix = liveEndpointUrlPrefix;
149109
}
150110

151-
public void setClientKeyStore(String clientKeyStorePath, String keyStoreType, String clientKeyStorePassword) throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException {
152-
this.clientKeyStorePassword = clientKeyStorePassword;
153-
this.clientKeyStore = CertificateUtil.loadKeyStore(clientKeyStorePath, keyStoreType, clientKeyStorePassword);
111+
public SSLContext getSSLContext() {
112+
return sslContext;
154113
}
155114

156-
public String getClientKeyStorePassword() {
157-
return clientKeyStorePassword;
115+
/**
116+
* Sets the {@link SSLContext} for the {@link com.adyen.httpclient.AdyenHttpClient}.
117+
*
118+
* @param sslContext The {@link SSLContext}
119+
*/
120+
public void setSSLContext(SSLContext sslContext) {
121+
this.sslContext = sslContext;
158122
}
159123

160-
public void setClientKeyStorePassword(String clientKeyStorePassword) {
161-
this.clientKeyStorePassword = clientKeyStorePassword;
124+
public HostnameVerifier getHostnameVerifier() {
125+
return hostnameVerifier;
162126
}
163127

164-
public String getLiveEndpointUrlPrefix() {
165-
return this.liveEndpointUrlPrefix;
166-
}
167-
public void setLiveEndpointUrlPrefix(String liveEndpointUrlPrefix) {
168-
this.liveEndpointUrlPrefix = liveEndpointUrlPrefix;
128+
/**
129+
* Sets the {@link HostnameVerifier} for the {@link com.adyen.httpclient.AdyenHttpClient}.
130+
*
131+
* @param hostnameVerifier The {@link HostnameVerifier}
132+
* @see com.adyen.httpclient.TerminalLocalAPIHostnameVerifier
133+
*/
134+
public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
135+
this.hostnameVerifier = hostnameVerifier;
169136
}
170137
}

src/main/java/com/adyen/httpclient/AdyenHttpClient.java

Lines changed: 7 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
import com.adyen.Client;
2424
import com.adyen.Config;
2525
import com.adyen.constants.ApiConstants;
26-
import com.adyen.enums.Environment;
2726
import com.adyen.model.RequestOptions;
28-
import com.adyen.terminal.security.TerminalCommonNameValidator;
2927
import org.apache.commons.codec.binary.Base64;
3028
import org.apache.hc.client5.http.classic.methods.HttpDelete;
3129
import org.apache.hc.client5.http.classic.methods.HttpGet;
@@ -41,22 +39,16 @@
4139
import org.apache.hc.core5.http.HttpHost;
4240
import org.apache.hc.core5.http.io.entity.StringEntity;
4341
import org.apache.hc.core5.net.URIBuilder;
42+
import org.apache.hc.core5.ssl.SSLContexts;
4443

4544
import javax.net.ssl.HostnameVerifier;
46-
import javax.net.ssl.KeyManagerFactory;
4745
import javax.net.ssl.SSLContext;
48-
import javax.net.ssl.SSLPeerUnverifiedException;
49-
import javax.net.ssl.TrustManager;
50-
import javax.net.ssl.TrustManagerFactory;
5146
import java.io.IOException;
5247
import java.net.InetSocketAddress;
5348
import java.net.Proxy;
5449
import java.net.URI;
5550
import java.net.URISyntaxException;
5651
import java.nio.charset.Charset;
57-
import java.security.GeneralSecurityException;
58-
import java.security.KeyStore;
59-
import java.security.cert.X509Certificate;
6052
import java.util.Map;
6153
import java.util.concurrent.TimeUnit;
6254

@@ -74,9 +66,6 @@
7466
public class AdyenHttpClient implements ClientInterface {
7567

7668
private static final String CHARSET = "UTF-8";
77-
private static final String TERMINAL_CERTIFICATE_ALIAS = "TerminalCertificate";
78-
private static final String SSL = "SSL";
79-
private static final String TLSV1_2 = "TLSv1.2";
8069
private Proxy proxy;
8170

8271
public Proxy getProxy() {
@@ -203,14 +192,13 @@ private URI createUri(String endpoint, Map<String, String> params) throws HTTPCl
203192
}
204193
}
205194

206-
private CloseableHttpClient createCloseableHttpClient(Config config) throws HTTPClientException {
207-
if (config.getClientKeyStore() != null && config.getTrustKeyStore() != null) {
208-
return createHttpClientWithSocketFactory(getClientCertificateAuthSSLContext(config));
195+
private CloseableHttpClient createCloseableHttpClient(Config config) {
196+
SSLContext sslContext = config.getSSLContext();
197+
if (sslContext == null) {
198+
sslContext = SSLContexts.createDefault();
209199
}
210-
if (config.getTerminalCertificate() != null) {
211-
return createHttpClientWithSocketFactory(getTerminalCertificateSocketFactory(config));
212-
}
213-
return HttpClients.createSystem();
200+
HostnameVerifier hostnameVerifier = config.getHostnameVerifier();
201+
return createHttpClientWithSocketFactory(new SSLConnectionSocketFactory(sslContext, hostnameVerifier));
214202
}
215203

216204
private CloseableHttpClient createHttpClientWithSocketFactory(SSLConnectionSocketFactory socketFactory) {
@@ -221,68 +209,6 @@ private CloseableHttpClient createHttpClientWithSocketFactory(SSLConnectionSocke
221209
.build();
222210
}
223211

224-
private SSLConnectionSocketFactory getTerminalCertificateSocketFactory(Config config) throws HTTPClientException {
225-
try {
226-
// Create new KeyStore for the terminal certificate
227-
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
228-
keyStore.load(null, null);
229-
keyStore.setCertificateEntry(TERMINAL_CERTIFICATE_ALIAS, config.getTerminalCertificate());
230-
231-
TrustManagerFactory trustFactory =
232-
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
233-
trustFactory.init(keyStore);
234-
TrustManager[] trustManagers = trustFactory.getTrustManagers();
235-
236-
// Install the terminal certificate trust manager
237-
SSLContext sc = SSLContext.getInstance(SSL);
238-
sc.init(null, trustManagers, new java.security.SecureRandom());
239-
240-
return new SSLConnectionSocketFactory(sc, createHostnameVerifier(config.getEnvironment()));
241-
} catch (GeneralSecurityException | IOException e) {
242-
throw new HTTPClientException("Error loading certificate from path", e);
243-
}
244-
}
245-
246-
private SSLConnectionSocketFactory getClientCertificateAuthSSLContext(Config config) throws HTTPClientException {
247-
try {
248-
char[] password = null;
249-
if (config.getClientKeyStorePassword() != null && !config.getClientKeyStorePassword().isEmpty()) {
250-
password = config.getClientKeyStorePassword().toCharArray();
251-
}
252-
253-
// Create a TrustManager that trusts the CAs in our Trust KeyStore
254-
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
255-
tmf.init(config.getTrustKeyStore());
256-
257-
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
258-
keyManagerFactory.init(config.getClientKeyStore(), password);
259-
260-
// Create an SSLContext that uses our TrustManager
261-
SSLContext context = SSLContext.getInstance(TLSV1_2);
262-
context.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);
263-
return new SSLConnectionSocketFactory(context);
264-
} catch (Exception e) {
265-
throw new HTTPClientException("Error creating SSL Context", e);
266-
}
267-
}
268-
269-
private HostnameVerifier createHostnameVerifier(final Environment environment) {
270-
return (host, session) -> {
271-
try {
272-
if (session.getPeerCertificates() != null && session.getPeerCertificates().length > 0) {
273-
// Assume the first certificate is the leaf, since chain will be ordered, according to Java documentation:
274-
// https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLSession.html#getPeerCertificates()
275-
X509Certificate certificate = (X509Certificate) session.getPeerCertificates()[0];
276-
return TerminalCommonNameValidator.validateCertificate(certificate, environment);
277-
}
278-
return false;
279-
} catch (SSLPeerUnverifiedException e) {
280-
e.printStackTrace();
281-
return false;
282-
}
283-
};
284-
}
285-
286212
/**
287213
* Sets content type
288214
*/
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.adyen.httpclient;
2+
3+
import com.adyen.enums.Environment;
4+
import com.adyen.terminal.security.TerminalCommonNameValidator;
5+
6+
import javax.net.ssl.HostnameVerifier;
7+
import javax.net.ssl.SSLPeerUnverifiedException;
8+
import javax.net.ssl.SSLSession;
9+
import java.security.cert.X509Certificate;
10+
11+
public final class TerminalLocalAPIHostnameVerifier implements HostnameVerifier {
12+
private final Environment environment;
13+
14+
public TerminalLocalAPIHostnameVerifier(Environment environment) {
15+
this.environment = environment;
16+
}
17+
18+
@Override
19+
public boolean verify(String hostname, SSLSession session) {
20+
try {
21+
if (session.getPeerCertificates() != null && session.getPeerCertificates().length > 0) {
22+
// Assume the first certificate is the leaf, since chain will be ordered, according to Java documentation:
23+
// https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLSession.html#getPeerCertificates()
24+
X509Certificate certificate = (X509Certificate) session.getPeerCertificates()[0];
25+
return TerminalCommonNameValidator.validateCertificate(certificate, environment);
26+
}
27+
return false;
28+
} catch (SSLPeerUnverifiedException e) {
29+
e.printStackTrace();
30+
return false;
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)