You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2022/11/16 14:50:49 UTC
[cayenne] 02/06: update CryptoModuleExtender
This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 11ea4681a14c743ce9294aa4bb78575cf472e1f4
Author: Mikhail Dzianishchyts <mi...@gmail.com>
AuthorDate: Wed Nov 16 12:31:09 2022 +0300
update CryptoModuleExtender
---
.../org/apache/cayenne/crypto/CryptoModule.java | 176 +++++---------
.../cayenne/crypto/CryptoModuleExtender.java | 253 +++++++--------------
...lderTest.java => CryptoModuleExtenderTest.java} | 7 +-
.../apache/cayenne/crypto/Runtime_AES128_Base.java | 24 +-
4 files changed, 158 insertions(+), 302 deletions(-)
diff --git a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModule.java b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModule.java
index 631b7b74e..d4e8de7a5 100644
--- a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModule.java
+++ b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModule.java
@@ -18,27 +18,13 @@
*/
package org.apache.cayenne.crypto;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.sql.Types;
-import java.time.Duration;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.Period;
-import java.util.Date;
-
import org.apache.cayenne.access.jdbc.reader.RowReaderFactory;
import org.apache.cayenne.access.translator.batch.BatchTranslatorFactory;
import org.apache.cayenne.configuration.DataMapLoader;
import org.apache.cayenne.crypto.batch.CryptoBatchTranslatorFactoryDecorator;
-import org.apache.cayenne.crypto.cipher.CipherFactory;
import org.apache.cayenne.crypto.cipher.DefaultCipherFactory;
import org.apache.cayenne.crypto.key.JceksKeySource;
-import org.apache.cayenne.crypto.key.KeySource;
-import org.apache.cayenne.crypto.map.ColumnMapper;
import org.apache.cayenne.crypto.map.CryptoDataMapLoader;
-import org.apache.cayenne.crypto.map.PatternColumnMapper;
import org.apache.cayenne.crypto.reader.CryptoRowReaderFactoryDecorator;
import org.apache.cayenne.crypto.transformer.DefaultTransformerFactory;
import org.apache.cayenne.crypto.transformer.TransformerFactory;
@@ -50,7 +36,6 @@ import org.apache.cayenne.crypto.transformer.value.BigDecimalConverter;
import org.apache.cayenne.crypto.transformer.value.BigIntegerConverter;
import org.apache.cayenne.crypto.transformer.value.BooleanConverter;
import org.apache.cayenne.crypto.transformer.value.ByteConverter;
-import org.apache.cayenne.crypto.transformer.value.BytesConverter;
import org.apache.cayenne.crypto.transformer.value.BytesToBytesConverter;
import org.apache.cayenne.crypto.transformer.value.DefaultValueTransformerFactory;
import org.apache.cayenne.crypto.transformer.value.DoubleConverter;
@@ -68,9 +53,18 @@ import org.apache.cayenne.crypto.transformer.value.Utf8StringConverter;
import org.apache.cayenne.crypto.transformer.value.UtilDateConverter;
import org.apache.cayenne.crypto.transformer.value.ValueTransformerFactory;
import org.apache.cayenne.di.Binder;
-import org.apache.cayenne.di.MapBuilder;
import org.apache.cayenne.di.Module;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Types;
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.Period;
+import java.util.Date;
+
/**
* Contains cryptography extensions for Cayenne.
*
@@ -82,65 +76,75 @@ public class CryptoModule implements Module {
private static final String DEFAULT_CIPHER_MODE = "CBC";
private static final String DEFAULT_CIPHER_PADDING = "PKCS5Padding";
// same as default keystore password in java...
+ // credentials are stored as char[] to potentially allow wiping them clean in memory...
private static final char[] DEFAULT_KEY_PASSWORD = "changeit".toCharArray();
private static final String DEFAULT_COLUMN_MAPPER_PATTERN = "^CRYPTO_";
/**
- * Returns a new extender that helps to build a custom module that provides required configuration for {@link CryptoModule}
+ * Returns a new extender that helps to build a custom module that provides required configuration for
+ * {@link CryptoModule}
* as well as custom strategies overriding the defaults defined here.
*
* @return a new extender that helps to build a custom module that provides required configuration for {@link CryptoModule}.
+ * @since 5.0
*/
- public static CryptoModuleExtender extend() {
- return new CryptoModuleExtender();
- }
-
- static MapBuilder<String> contributeProperties(Binder binder) {
- return binder.bindMap(String.class, CryptoConstants.PROPERTIES_MAP);
- }
-
- static MapBuilder<char[]> contributeCredentials(Binder binder) {
- return binder.bindMap(char[].class, CryptoConstants.CREDENTIALS_MAP);
- }
-
- @SuppressWarnings("unchecked")
- static MapBuilder<BytesConverter<?>> contributeDbToByteConverters(Binder binder) {
- MapBuilder mapBuilder = binder.bindMap(BytesConverter.class, DefaultValueTransformerFactory.DB_TO_BYTE_CONVERTERS_KEY);
- return (MapBuilder<BytesConverter<?>>) mapBuilder;
- }
-
- @SuppressWarnings("unchecked")
- static MapBuilder<BytesConverter<?>> contributeObjectToByteConverters(Binder binder) {
- MapBuilder mapBuilder = binder.bindMap(BytesConverter.class, DefaultValueTransformerFactory.OBJECT_TO_BYTE_CONVERTERS_KEY);
- return (MapBuilder<BytesConverter<?>>) mapBuilder;
+ public static CryptoModuleExtender extend(Binder binder) {
+ return new CryptoModuleExtender(binder);
}
@Override
public void configure(Binder binder) {
+ extend(binder)
+ .cipherAlgorithm(DEFAULT_CIPHER_ALGORITHM)
+ .cipherMode(DEFAULT_CIPHER_MODE)
+ .cipherPadding(DEFAULT_CIPHER_PADDING)
+ .cipherFactory(DefaultCipherFactory.class)
+
+ .keyStore((String) null, DEFAULT_KEY_PASSWORD, null)
+ .keySource(JceksKeySource.class)
+
+ .valueTransformerFactory(DefaultValueTransformerFactory.class)
+ .bytesTransformerFactory(DefaultBytesTransformerFactory.class)
+
+ .columnMapper(DEFAULT_COLUMN_MAPPER_PATTERN)
+
+ .objectToBytesConverter("byte[]", BytesToBytesConverter.INSTANCE)
+ .objectToBytesConverter(String.class, Utf8StringConverter.INSTANCE)
+
+ .objectToBytesConverter(Double.class, DoubleConverter.INSTANCE)
+ .objectToBytesConverter(Float.class, FloatConverter.INSTANCE)
+ .objectToBytesConverter(Long.class, LongConverter.INSTANCE)
+ .objectToBytesConverter(Integer.class, IntegerConverter.INSTANCE)
+ .objectToBytesConverter(Short.class, ShortConverter.INSTANCE)
+ .objectToBytesConverter(Byte.class, ByteConverter.INSTANCE)
+ .objectToBytesConverter(Boolean.class, BooleanConverter.INSTANCE)
+
+ .objectToBytesConverter(BigInteger.class, BigIntegerConverter.INSTANCE)
+ .objectToBytesConverter(BigDecimal.class, BigDecimalConverter.INSTANCE)
+ .objectToBytesConverter(Date.class, UtilDateConverter.INSTANCE)
+ .objectToBytesConverter(LocalDate.class, LocalDateConverter.INSTANCE)
+ .objectToBytesConverter(LocalTime.class, LocalTimeConverter.INSTANCE)
+ .objectToBytesConverter(LocalDateTime.class, LocalDateTimeConverter.INSTANCE)
+ .objectToBytesConverter(Duration.class, DurationConverter.INSTANCE)
+ .objectToBytesConverter(Period.class, PeriodConverter.INSTANCE)
+
+ .dbToBytesConverter(Types.BINARY, BytesToBytesConverter.INSTANCE)
+ .dbToBytesConverter(Types.BLOB, BytesToBytesConverter.INSTANCE)
+ .dbToBytesConverter(Types.VARBINARY, BytesToBytesConverter.INSTANCE)
+ .dbToBytesConverter(Types.LONGVARBINARY, BytesToBytesConverter.INSTANCE)
+
+ .dbToBytesConverter(Types.CHAR, Base64StringConverter.INSTANCE)
+ .dbToBytesConverter(Types.NCHAR, Base64StringConverter.INSTANCE)
+ .dbToBytesConverter(Types.CLOB, Base64StringConverter.INSTANCE)
+ .dbToBytesConverter(Types.NCLOB, Base64StringConverter.INSTANCE)
+ .dbToBytesConverter(Types.LONGVARCHAR, Base64StringConverter.INSTANCE)
+ .dbToBytesConverter(Types.LONGNVARCHAR, Base64StringConverter.INSTANCE)
+ .dbToBytesConverter(Types.VARCHAR, Base64StringConverter.INSTANCE)
+ .dbToBytesConverter(Types.NVARCHAR, Base64StringConverter.INSTANCE);
- contributeProperties(binder)
- .put(CryptoConstants.CIPHER_ALGORITHM, DEFAULT_CIPHER_ALGORITHM)
- .put(CryptoConstants.CIPHER_MODE, DEFAULT_CIPHER_MODE)
- .put(CryptoConstants.CIPHER_PADDING, DEFAULT_CIPHER_PADDING);
-
- // credentials are stored as char[] to potentially allow wiping them clean in memory...
- contributeCredentials(binder).put(CryptoConstants.KEY_PASSWORD, DEFAULT_KEY_PASSWORD);
-
- binder.bind(CipherFactory.class).to(DefaultCipherFactory.class);
binder.bind(TransformerFactory.class).to(DefaultTransformerFactory.class);
- binder.bind(ValueTransformerFactory.class).to(DefaultValueTransformerFactory.class);
-
- MapBuilder<BytesConverter<?>> dbToBytesBinder = contributeDbToByteConverters(binder);
- contributeDefaultDbConverters(dbToBytesBinder);
-
- MapBuilder<BytesConverter<?>> objectToBytesBinder = contributeObjectToByteConverters(binder);
- contributeDefaultObjectConverters(objectToBytesBinder);
- binder.bind(BytesTransformerFactory.class).to(DefaultBytesTransformerFactory.class);
- binder.bind(KeySource.class).to(JceksKeySource.class);
- binder.bind(ColumnMapper.class).toInstance(new PatternColumnMapper(DEFAULT_COLUMN_MAPPER_PATTERN));
binder.decorate(DataMapLoader.class).before(CryptoDataMapLoader.class);
-
binder.decorate(BatchTranslatorFactory.class).before(CryptoBatchTranslatorFactoryDecorator.class);
binder.bind(RowReaderFactory.class).to(CryptoRowReaderFactoryDecorator.class);
@@ -149,58 +153,4 @@ public class CryptoModule implements Module {
binder.decorate(ValueTransformerFactory.class).after(LazyValueTransformerFactory.class);
binder.decorate(BytesTransformerFactory.class).after(LazyBytesTransformerFactory.class);
}
-
- private static void contributeDefaultDbConverters(MapBuilder<BytesConverter<?>> mapBuilder) {
-
- mapBuilder.put(String.valueOf(Types.BINARY), BytesToBytesConverter.INSTANCE);
- mapBuilder.put(String.valueOf(Types.BLOB), BytesToBytesConverter.INSTANCE);
- mapBuilder.put(String.valueOf(Types.VARBINARY), BytesToBytesConverter.INSTANCE);
- mapBuilder.put(String.valueOf(Types.LONGVARBINARY), BytesToBytesConverter.INSTANCE);
-
- mapBuilder.put(String.valueOf(Types.CHAR), Base64StringConverter.INSTANCE);
- mapBuilder.put(String.valueOf(Types.NCHAR), Base64StringConverter.INSTANCE);
- mapBuilder.put(String.valueOf(Types.CLOB), Base64StringConverter.INSTANCE);
- mapBuilder.put(String.valueOf(Types.NCLOB), Base64StringConverter.INSTANCE);
- mapBuilder.put(String.valueOf(Types.LONGVARCHAR), Base64StringConverter.INSTANCE);
- mapBuilder.put(String.valueOf(Types.LONGNVARCHAR), Base64StringConverter.INSTANCE);
- mapBuilder.put(String.valueOf(Types.VARCHAR), Base64StringConverter.INSTANCE);
- mapBuilder.put(String.valueOf(Types.NVARCHAR), Base64StringConverter.INSTANCE);
- }
-
- private static void contributeDefaultObjectConverters(MapBuilder<BytesConverter<?>> mapBuilder) {
-
- mapBuilder.put("byte[]", BytesToBytesConverter.INSTANCE);
- mapBuilder.put(String.class.getName(), Utf8StringConverter.INSTANCE);
-
- mapBuilder.put(Double.class.getName(), DoubleConverter.INSTANCE);
- mapBuilder.put(Double.TYPE.getName(), DoubleConverter.INSTANCE);
-
- mapBuilder.put(Float.class.getName(), FloatConverter.INSTANCE);
- mapBuilder.put(Float.TYPE.getName(), FloatConverter.INSTANCE);
-
- mapBuilder.put(Long.class.getName(), LongConverter.INSTANCE);
- mapBuilder.put(Long.TYPE.getName(), LongConverter.INSTANCE);
-
- mapBuilder.put(Integer.class.getName(), IntegerConverter.INSTANCE);
- mapBuilder.put(Integer.TYPE.getName(), IntegerConverter.INSTANCE);
-
- mapBuilder.put(Short.class.getName(), ShortConverter.INSTANCE);
- mapBuilder.put(Short.TYPE.getName(), ShortConverter.INSTANCE);
-
- mapBuilder.put(Byte.class.getName(), ByteConverter.INSTANCE);
- mapBuilder.put(Byte.TYPE.getName(), ByteConverter.INSTANCE);
-
- mapBuilder.put(Boolean.class.getName(), BooleanConverter.INSTANCE);
- mapBuilder.put(Boolean.TYPE.getName(), BooleanConverter.INSTANCE);
-
- mapBuilder.put(Date.class.getName(), UtilDateConverter.INSTANCE);
- mapBuilder.put(BigInteger.class.getName(), BigIntegerConverter.INSTANCE);
- mapBuilder.put(BigDecimal.class.getName(), BigDecimalConverter.INSTANCE);
-
- mapBuilder.put(LocalDate.class.getName(), LocalDateConverter.INSTANCE);
- mapBuilder.put(LocalTime.class.getName(), LocalTimeConverter.INSTANCE);
- mapBuilder.put(LocalDateTime.class.getName(), LocalDateTimeConverter.INSTANCE);
- mapBuilder.put(Duration.class.getName(), DurationConverter.INSTANCE);
- mapBuilder.put(Period.class.getName(), PeriodConverter.INSTANCE);
- }
}
diff --git a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleExtender.java b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleExtender.java
index b3720e680..0adfb9213 100644
--- a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleExtender.java
+++ b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleExtender.java
@@ -24,15 +24,14 @@ import org.apache.cayenne.crypto.map.ColumnMapper;
import org.apache.cayenne.crypto.map.PatternColumnMapper;
import org.apache.cayenne.crypto.transformer.bytes.BytesTransformerFactory;
import org.apache.cayenne.crypto.transformer.value.BytesConverter;
+import org.apache.cayenne.crypto.transformer.value.DefaultValueTransformerFactory;
import org.apache.cayenne.crypto.transformer.value.ValueTransformerFactory;
+import org.apache.cayenne.di.Binder;
import org.apache.cayenne.di.MapBuilder;
-import org.apache.cayenne.di.Module;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
import java.util.Objects;
/**
@@ -42,91 +41,75 @@ import java.util.Objects;
*/
public class CryptoModuleExtender {
- private Class<? extends ValueTransformerFactory> valueTransformerFactoryType;
- private Class<? extends BytesTransformerFactory> bytesTransformerFactoryType;
+ private final Binder binder;
- private Map<String, BytesConverter<?>> extraObjectToBytes;
- private Map<Integer, BytesConverter<?>> extraDbToBytes;
+ private MapBuilder<String> properties;
+ private MapBuilder<char[]> credentials;
+ private MapBuilder<BytesConverter<?>> dbToByteConverters;
+ private MapBuilder<BytesConverter<?>> objectToByteConverters;
- private String columnMapperPattern;
- private ColumnMapper columnMapper;
- private Class<? extends ColumnMapper> columnMapperType;
-
- private String cipherAlgorithm;
- private String cipherMode;
- private Class<? extends CipherFactory> cipherFactoryType;
-
- private URL keyStoreUrl;
- private String keyStoreUrlString;
- private File keyStoreFile;
- private Class<? extends KeySource> keySourceType;
- private KeySource keySource;
-
- private String encryptionKeyAlias;
- private char[] keyPassword;
-
- private boolean compress;
- private boolean useHMAC;
-
- // use CryptoModule.builder() to create the builder...
- protected CryptoModuleExtender() {
- this.extraDbToBytes = new HashMap<>();
- this.extraObjectToBytes = new HashMap<>();
+ protected CryptoModuleExtender(Binder binder) {
+ this.binder = binder;
}
public CryptoModuleExtender cipherAlgorithm(String algorithm) {
- this.cipherAlgorithm = Objects.requireNonNull(algorithm);
+ contributeProperties(binder).put(CryptoConstants.CIPHER_ALGORITHM, algorithm);
return this;
}
public CryptoModuleExtender cipherMode(String mode) {
- this.cipherMode = Objects.requireNonNull(mode);
+ contributeProperties(binder).put(CryptoConstants.CIPHER_MODE, mode);
+ return this;
+ }
+
+ public CryptoModuleExtender cipherPadding(String padding) {
+ contributeProperties(binder).put(CryptoConstants.CIPHER_PADDING, padding);
return this;
}
public CryptoModuleExtender cipherFactory(Class<? extends CipherFactory> factoryType) {
- this.cipherFactoryType = Objects.requireNonNull(factoryType);
+ binder.bind(CipherFactory.class).to(factoryType);
+ return this;
+ }
+
+ public CryptoModuleExtender valueTransformerFactory(Class<? extends ValueTransformerFactory> factoryType) {
+ binder.bind(ValueTransformerFactory.class).to(factoryType);
return this;
}
- public CryptoModuleExtender valueTransformer(Class<? extends ValueTransformerFactory> factoryType) {
- this.valueTransformerFactoryType = Objects.requireNonNull(factoryType);
+ public CryptoModuleExtender bytesTransformerFactory(Class<? extends BytesTransformerFactory> factoryType) {
+ binder.bind(BytesTransformerFactory.class).to(factoryType);
return this;
}
public <T> CryptoModuleExtender objectToBytesConverter(Class<T> objectType, BytesConverter<T> converter) {
- extraObjectToBytes.put(objectType.getName(), Objects.requireNonNull(converter));
+ contributeObjectToByteConverters(binder).put(objectType.getName(), Objects.requireNonNull(converter));
return this;
}
- public CryptoModuleExtender dbToBytesConverter(int sqlType, BytesConverter<?> converter) {
- extraDbToBytes.put(sqlType, Objects.requireNonNull(converter));
+ // workaround for byte[]
+ CryptoModuleExtender objectToBytesConverter(String objectTypeName, BytesConverter<Object> converter) {
+ contributeObjectToByteConverters(binder).put(objectTypeName, Objects.requireNonNull(converter));
return this;
}
- public CryptoModuleExtender bytesTransformer(Class<? extends BytesTransformerFactory> factoryType) {
- this.bytesTransformerFactoryType = Objects.requireNonNull(factoryType);
+ public CryptoModuleExtender dbToBytesConverter(int sqlType, BytesConverter<?> converter) {
+ contributeDbToByteConverters(binder).put(String.valueOf(sqlType), Objects.requireNonNull(converter));
return this;
}
public CryptoModuleExtender columnMapper(Class<? extends ColumnMapper> columnMapperType) {
- this.columnMapperPattern = null;
- this.columnMapperType = Objects.requireNonNull(columnMapperType);
- this.columnMapper = null;
+ binder.bind(ColumnMapper.class).to(columnMapperType);
return this;
}
public CryptoModuleExtender columnMapper(ColumnMapper columnMapper) {
- this.columnMapperPattern = null;
- this.columnMapperType = null;
- this.columnMapper = Objects.requireNonNull(columnMapper);
+ binder.bind(ColumnMapper.class).toInstance(columnMapper);
return this;
}
public CryptoModuleExtender columnMapper(String pattern) {
- this.columnMapperPattern = Objects.requireNonNull(pattern);
- this.columnMapperType = null;
- this.columnMapper = null;
+ binder.bind(ColumnMapper.class).toInstance(new PatternColumnMapper(pattern));
return this;
}
@@ -135,13 +118,13 @@ public class CryptoModuleExtender {
* encryption by default.
*/
public CryptoModuleExtender encryptionKeyAlias(String encryptionKeyAlias) {
- this.encryptionKeyAlias = Objects.requireNonNull(encryptionKeyAlias);
+ contributeProperties(binder).put(CryptoConstants.ENCRYPTION_KEY_ALIAS, encryptionKeyAlias);
return this;
}
/**
* Configures keystore parameters. The KeyStore must be of "jceks" type and
- * contain all needed secret keys for the target database. Currently all
+ * contain all needed secret keys for the target database. Currently, all
* keys must be protected with the same password.
*
* @param file A file to load keystore from.
@@ -150,17 +133,17 @@ public class CryptoModuleExtender {
* encryption by default.
*/
public CryptoModuleExtender keyStore(File file, char[] passwordForAllKeys, String encryptionKeyAlias) {
- this.encryptionKeyAlias = encryptionKeyAlias;
- this.keyPassword = passwordForAllKeys;
- this.keyStoreUrl = null;
- this.keyStoreUrlString = null;
- this.keyStoreFile = Objects.requireNonNull(file);
- return this;
+ try {
+ String fileUrl = file.toURI().toURL().toExternalForm();
+ return keyStore(fileUrl, passwordForAllKeys, encryptionKeyAlias);
+ } catch (MalformedURLException e) {
+ throw new IllegalArgumentException("Invalid keyStore file", e);
+ }
}
/**
* Configures keystore parameters. The KeyStore must be of "jceks" type and
- * contain all needed secret keys for the target database. Currently all
+ * contain all needed secret keys for the target database. Currently, all
* keys must be protected with the same password.
*
* @param url A URL to load keystore from.
@@ -168,18 +151,13 @@ public class CryptoModuleExtender {
* @param encryptionKeyAlias The name of the key in the keystore that should be used for
* encryption by default.
*/
- public CryptoModuleExtender keyStore(String url, char[] passwordForAllKeys, String encryptionKeyAlias) {
- this.encryptionKeyAlias = encryptionKeyAlias;
- this.keyPassword = passwordForAllKeys;
- this.keyStoreUrl = null;
- this.keyStoreUrlString = Objects.requireNonNull(url);
- this.keyStoreFile = null;
- return this;
+ public CryptoModuleExtender keyStore(URL url, char[] passwordForAllKeys, String encryptionKeyAlias) {
+ return keyStore(url.toExternalForm(), passwordForAllKeys, encryptionKeyAlias);
}
/**
* Configures keystore parameters. The KeyStore must be of "jceks" type and
- * contain all needed secret keys for the target database. Currently all
+ * contain all needed secret keys for the target database. Currently, all
* keys must be protected with the same password.
*
* @param url A URL to load keystore from.
@@ -187,29 +165,26 @@ public class CryptoModuleExtender {
* @param encryptionKeyAlias The name of the key in the keystore that should be used for
* encryption by default.
*/
- public CryptoModuleExtender keyStore(URL url, char[] passwordForAllKeys, String encryptionKeyAlias) {
- this.encryptionKeyAlias = encryptionKeyAlias;
- this.keyPassword = passwordForAllKeys;
- this.keyStoreUrl = Objects.requireNonNull(url);
- this.keyStoreUrlString = null;
- this.keyStoreFile = null;
+ public CryptoModuleExtender keyStore(String url, char[] passwordForAllKeys, String encryptionKeyAlias) {
+ MapBuilder<String> propertiesBuilder = contributeProperties(binder);
+ propertiesBuilder.put(CryptoConstants.KEYSTORE_URL, url);
+ propertiesBuilder.put(CryptoConstants.ENCRYPTION_KEY_ALIAS, encryptionKeyAlias);
+ contributeCredentials(binder).put(CryptoConstants.KEY_PASSWORD, passwordForAllKeys);
return this;
}
- public CryptoModuleExtender keySource(Class<? extends KeySource> type) {
- this.keySourceType = Objects.requireNonNull(type);
- this.keySource = null;
+ public CryptoModuleExtender keySource(Class<? extends KeySource> keySourceType) {
+ binder.bind(KeySource.class).to(keySourceType);
return this;
}
public CryptoModuleExtender keySource(KeySource keySource) {
- this.keySourceType = null;
- this.keySource = Objects.requireNonNull(keySource);
+ binder.bind(KeySource.class).toInstance(keySource);
return this;
}
public CryptoModuleExtender compress() {
- this.compress = true;
+ contributeProperties(binder).put(CryptoConstants.COMPRESSION, "true");
return this;
}
@@ -217,109 +192,41 @@ public class CryptoModuleExtender {
* Enable authentication codes
*/
public CryptoModuleExtender useHMAC() {
- this.useHMAC = true;
+ contributeProperties(binder).put(CryptoConstants.USE_HMAC, "true");
return this;
}
- /**
- * Produces a module that can be used to start Cayenne runtime.
- */
- public Module module() {
-
- return binder -> {
-
- MapBuilder<String> props = CryptoModule.contributeProperties(binder);
-
- if (cipherAlgorithm != null) {
- props.put(CryptoConstants.CIPHER_ALGORITHM, cipherAlgorithm);
- }
-
- if (cipherMode != null) {
- props.put(CryptoConstants.CIPHER_MODE, cipherMode);
- }
-
- String keyStoreUrl = keyStoreUrl();
- if (keyStoreUrl != null) {
- props.put(CryptoConstants.KEYSTORE_URL, keyStoreUrl);
- }
-
- if (encryptionKeyAlias != null) {
- props.put(CryptoConstants.ENCRYPTION_KEY_ALIAS, encryptionKeyAlias);
- }
-
- if (compress) {
- props.put(CryptoConstants.COMPRESSION, "true");
- }
-
- if (useHMAC) {
- props.put(CryptoConstants.USE_HMAC, "true");
- }
-
- if (keyPassword != null) {
- CryptoModule.contributeCredentials(binder).put(CryptoConstants.KEY_PASSWORD, keyPassword);
- }
-
- if (cipherFactoryType != null) {
- binder.bind(CipherFactory.class).to(cipherFactoryType);
- }
-
- if (valueTransformerFactoryType != null) {
- binder.bind(ValueTransformerFactory.class).to(valueTransformerFactoryType);
- }
-
- if (!extraDbToBytes.isEmpty()) {
- MapBuilder<BytesConverter<?>> dbToBytesBinder = CryptoModule.contributeDbToByteConverters(binder);
- for (Map.Entry<Integer, BytesConverter<?>> extraConverter : extraDbToBytes.entrySet()) {
- dbToBytesBinder.put(extraConverter.getKey().toString(), extraConverter.getValue());
- }
- }
-
- if (!extraObjectToBytes.isEmpty()) {
- MapBuilder<BytesConverter<?>> objectToBytesBinder = CryptoModule.contributeObjectToByteConverters(binder);
- for (Map.Entry<String, BytesConverter<?>> extraConverter : extraObjectToBytes.entrySet()) {
- objectToBytesBinder.put(extraConverter.getKey(), extraConverter.getValue());
- }
- }
-
- if (bytesTransformerFactoryType != null) {
- binder.bind(BytesTransformerFactory.class).to(bytesTransformerFactoryType);
- }
-
- if (keySource != null) {
- binder.bind(KeySource.class).toInstance(keySource);
- } else if (keySourceType != null) {
- binder.bind(KeySource.class).to(keySourceType);
- }
-
- if (columnMapperPattern != null) {
- binder.bind(ColumnMapper.class).toInstance(new PatternColumnMapper(columnMapperPattern));
- } else if (columnMapperType != null) {
- binder.bind(ColumnMapper.class).to(columnMapperType);
- } else if (columnMapper != null) {
- binder.bind(ColumnMapper.class).toInstance(columnMapper);
- }
- };
+ private MapBuilder<String> contributeProperties(Binder binder) {
+ if (properties == null) {
+ properties = binder.bindMap(String.class, CryptoConstants.PROPERTIES_MAP);
+ }
+ return properties;
}
- protected String keyStoreUrl() {
- if (this.keyStoreUrl != null) {
- return this.keyStoreUrl.toExternalForm();
+ private MapBuilder<char[]> contributeCredentials(Binder binder) {
+ if (credentials == null) {
+ credentials = binder.bindMap(char[].class, CryptoConstants.CREDENTIALS_MAP);
}
+ return credentials;
+ }
- if (this.keyStoreUrlString != null) {
- return this.keyStoreUrlString;
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ private MapBuilder<BytesConverter<?>> contributeDbToByteConverters(Binder binder) {
+ if (dbToByteConverters == null) {
+ MapBuilder mapBuilder = binder.bindMap(BytesConverter.class,
+ DefaultValueTransformerFactory.DB_TO_BYTE_CONVERTERS_KEY);
+ dbToByteConverters = mapBuilder;
}
+ return dbToByteConverters;
+ }
- if (keyStoreFile != null) {
- try {
- return keyStoreFile.toURI().toURL().toExternalForm();
- } catch (MalformedURLException e) {
- throw new IllegalStateException("Invalid keyStore file", e);
- }
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ private MapBuilder<BytesConverter<?>> contributeObjectToByteConverters(Binder binder) {
+ if (objectToByteConverters == null) {
+ MapBuilder mapBuilder = binder.bindMap(BytesConverter.class,
+ DefaultValueTransformerFactory.OBJECT_TO_BYTE_CONVERTERS_KEY);
+ objectToByteConverters = mapBuilder;
}
-
- return null;
+ return objectToByteConverters;
}
-
-
}
diff --git a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleBuilderTest.java b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleExtenderTest.java
similarity index 89%
rename from cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleBuilderTest.java
rename to cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleExtenderTest.java
index 4e79817d9..20e03a900 100644
--- a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleBuilderTest.java
+++ b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleExtenderTest.java
@@ -32,14 +32,13 @@ import java.security.Key;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-public class CryptoModuleBuilderTest {
+public class CryptoModuleExtenderTest {
@Test
public void testBuild_KeySource() {
-
URL ksUrl = JceksKeySourceTest.class.getResource(JceksKeySourceTest.KS1_JCEKS);
- Module m = new CryptoModuleExtender().keyStore(ksUrl, JceksKeySourceTest.TEST_KEY_PASS, "k1")
- .valueTransformer(DefaultValueTransformerFactory.class).module();
+ Module m = b -> new CryptoModuleExtender(b).keyStore(ksUrl, JceksKeySourceTest.TEST_KEY_PASS, "k1")
+ .valueTransformerFactory(DefaultValueTransformerFactory.class);
Injector injector = DIBootstrap.createInjector(new CryptoModule(), m);
diff --git a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Runtime_AES128_Base.java b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Runtime_AES128_Base.java
index 8eb9b16d8..43c6873a3 100644
--- a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Runtime_AES128_Base.java
+++ b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Runtime_AES128_Base.java
@@ -66,18 +66,18 @@ public class Runtime_AES128_Base {
protected Module createCryptoModule(boolean compress, boolean useHMAC) {
URL keyStoreUrl = JceksKeySourceTest.class.getResource(JceksKeySourceTest.KS1_JCEKS);
- CryptoModuleExtender builder = CryptoModule
- .extend()
- .keyStore(keyStoreUrl, JceksKeySourceTest.TEST_KEY_PASS, "k3");
-
- if (compress) {
- builder.compress();
- }
- if(useHMAC) {
- builder.useHMAC();
- }
-
- return builder.module();
+ Module module = b -> {
+ CryptoModuleExtender moduleExtender = CryptoModule.extend(b)
+ .keyStore(keyStoreUrl, JceksKeySourceTest.TEST_KEY_PASS, "k3");
+ if (compress) {
+ moduleExtender.compress();
+ }
+ if(useHMAC) {
+ moduleExtender.useHMAC();
+ }
+ };
+
+ return module;
}
}