You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2014/03/17 14:49:27 UTC
svn commit: r1578376 - in /cayenne/main/trunk:
cayenne-crypto/src/main/java/org/apache/cayenne/crypto/
cayenne-crypto/src/main/java/org/apache/cayenne/crypto/batch/
cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/
cayenne-crypto/src/test/...
Author: aadamchik
Date: Mon Mar 17 13:49:27 2014
New Revision: 1578376
URL: http://svn.apache.org/r1578376
Log:
CAY-1916 cayenne-crypto module that enables data encryption for certain model attributes
select decryption
Added:
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java
Modified:
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleBuilder.java
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/batch/CryptoBatchTranslatorFactoryDecorator.java
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Crypto_InRuntime_Test.java
cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/ColumnDescriptor.java
Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleBuilder.java?rev=1578376&r1=1578375&r2=1578376&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleBuilder.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleBuilder.java Mon Mar 17 13:49:27 2014
@@ -18,10 +18,12 @@
****************************************************************/
package org.apache.cayenne.crypto;
+import org.apache.cayenne.access.jdbc.reader.RowReaderFactory;
import org.apache.cayenne.access.translator.batch.BatchTranslatorFactory;
import org.apache.cayenne.crypto.batch.CryptoBatchTranslatorFactoryDecorator;
import org.apache.cayenne.crypto.cipher.CryptoHandler;
import org.apache.cayenne.crypto.map.ColumnMapper;
+import org.apache.cayenne.crypto.reader.CryptoRowReaderFactoryDecorator;
import org.apache.cayenne.di.Binder;
import org.apache.cayenne.di.Module;
@@ -81,8 +83,9 @@ public class CryptoModuleBuilder {
} else {
binder.bind(ColumnMapper.class).toInstance(columnMapper);
}
-
- binder.decorate(BatchTranslatorFactory.class).after(CryptoBatchTranslatorFactoryDecorator.class);
+
+ binder.decorate(BatchTranslatorFactory.class).before(CryptoBatchTranslatorFactoryDecorator.class);
+ binder.decorate(RowReaderFactory.class).before(CryptoRowReaderFactoryDecorator.class);
}
};
}
Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/batch/CryptoBatchTranslatorFactoryDecorator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/batch/CryptoBatchTranslatorFactoryDecorator.java?rev=1578376&r1=1578375&r2=1578376&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/batch/CryptoBatchTranslatorFactoryDecorator.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/batch/CryptoBatchTranslatorFactoryDecorator.java Mon Mar 17 13:49:27 2014
@@ -36,15 +36,15 @@ import org.apache.cayenne.query.BatchQue
*/
public class CryptoBatchTranslatorFactoryDecorator implements BatchTranslatorFactory {
- private CryptoHandler cipherService;
+ private CryptoHandler cryptoHandler;
private ColumnMapper columnMapper;
private BatchTranslatorFactory delegate;
public CryptoBatchTranslatorFactoryDecorator(@Inject BatchTranslatorFactory delegate,
- @Inject CryptoHandler cipherService, @Inject ColumnMapper columnMapper) {
+ @Inject CryptoHandler cryptoHandler, @Inject ColumnMapper columnMapper) {
this.columnMapper = columnMapper;
- this.cipherService = cipherService;
+ this.cryptoHandler = cryptoHandler;
this.delegate = delegate;
}
@@ -70,7 +70,7 @@ public class CryptoBatchTranslatorFactor
for (BatchParameterBinding b : bindings) {
if (columnMapper.isEncrypted(b.getAttribute())) {
- Object encrypted = cipherService.encrypt(b.getValue(), b.getAttribute().getType());
+ Object encrypted = cryptoHandler.encrypt(b.getValue(), b.getAttribute().getType());
b.setValue(encrypted);
}
}
Added: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java?rev=1578376&view=auto
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java (added)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java Mon Mar 17 13:49:27 2014
@@ -0,0 +1,113 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+package org.apache.cayenne.crypto.reader;
+
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cayenne.access.jdbc.ColumnDescriptor;
+import org.apache.cayenne.access.jdbc.RowDescriptor;
+import org.apache.cayenne.access.jdbc.reader.RowReader;
+import org.apache.cayenne.access.jdbc.reader.RowReaderFactory;
+import org.apache.cayenne.crypto.cipher.CryptoHandler;
+import org.apache.cayenne.crypto.map.ColumnMapper;
+import org.apache.cayenne.dba.DbAdapter;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.query.QueryMetadata;
+
+public class CryptoRowReaderFactoryDecorator implements RowReaderFactory {
+
+ private RowReaderFactory delegate;
+ private ColumnMapper columnMapper;
+ private CryptoHandler cryptoHandler;
+
+ public CryptoRowReaderFactoryDecorator(@Inject RowReaderFactory delegate, @Inject CryptoHandler cryptoHandler,
+ @Inject ColumnMapper columnMapper) {
+ this.delegate = delegate;
+ this.columnMapper = columnMapper;
+ this.cryptoHandler = cryptoHandler;
+ }
+
+ @Override
+ public RowReader<?> rowReader(RowDescriptor descriptor, QueryMetadata queryMetadata, DbAdapter adapter,
+ Map<ObjAttribute, ColumnDescriptor> attributeOverrides) {
+
+ List<ColumnDescriptor> encryptedColumns = null;
+
+ for (ColumnDescriptor cd : descriptor.getColumns()) {
+
+ DbAttribute attribute = cd.getAttribute();
+ if (attribute != null && columnMapper.isEncrypted(attribute)) {
+ if (encryptedColumns == null) {
+ encryptedColumns = new ArrayList<ColumnDescriptor>();
+ }
+
+ encryptedColumns.add(cd);
+ }
+ }
+
+ final RowReader<?> delegateReader = delegate.rowReader(descriptor, queryMetadata, adapter, attributeOverrides);
+
+ if (encryptedColumns == null) {
+ return delegateReader;
+ }
+
+ final int len = encryptedColumns.size();
+ final String[] labels = new String[len];
+ final int[] types = new int[len];
+
+ for (int i = 0; i < len; i++) {
+ labels[i] = encryptedColumns.get(i).getDataRowKey();
+ types[i] = encryptedColumns.get(i).getJdbcType();
+ }
+
+ return new RowReader<Object>() {
+ private Boolean canDecrypt;
+
+ @Override
+ public Object readRow(ResultSet resultSet) {
+ Object row = delegateReader.readRow(resultSet);
+
+ if (canDecrypt == null) {
+ canDecrypt = row instanceof Map;
+ }
+
+ if (canDecrypt) {
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ Map<String, Object> map = (Map) row;
+
+ for (int i = 0; i < len; i++) {
+ Object encrypted = map.get(labels[i]);
+
+ if (encrypted != null) {
+ map.put(labels[i], cryptoHandler.decrypt(encrypted, types[i]));
+ }
+ }
+ }
+
+ return row;
+ }
+ };
+ }
+
+}
Modified: cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Crypto_InRuntime_Test.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Crypto_InRuntime_Test.java?rev=1578376&r1=1578375&r2=1578376&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Crypto_InRuntime_Test.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Crypto_InRuntime_Test.java Mon Mar 17 13:49:27 2014
@@ -31,6 +31,7 @@ import org.apache.cayenne.crypto.db.Tabl
import org.apache.cayenne.crypto.map.PatternColumnMapper;
import org.apache.cayenne.crypto.unit.Rot13CryptoHandler;
import org.apache.cayenne.di.Module;
+import org.apache.cayenne.query.SelectQuery;
import org.apache.cayenne.test.jdbc.DBHelper;
import org.apache.cayenne.test.jdbc.TableHelper;
@@ -95,4 +96,21 @@ public class Crypto_InRuntime_Test exten
assertEquals(Rot13CryptoHandler.rotate("crypto_2"), cipherByPlain.get("b"));
}
+ public void test_SelectQuery() throws SQLException {
+
+ table1.insert(1, "plain_1", Rot13CryptoHandler.rotate("crypto_1"));
+ table1.insert(2, "plain_2", Rot13CryptoHandler.rotate("crypto_2"));
+ table1.insert(3, "plain_3", Rot13CryptoHandler.rotate("crypto_3"));
+
+ SelectQuery<Table1> select = SelectQuery.query(Table1.class);
+ select.addOrdering(Table1.PLAIN_STRING.asc());
+
+ List<Table1> result = runtime.newContext().select(select);
+
+ assertEquals(3, result.size());
+ assertEquals("crypto_1", result.get(0).getCryptoString());
+ assertEquals("crypto_2", result.get(1).getCryptoString());
+ assertEquals("crypto_3", result.get(2).getCryptoString());
+ }
+
}
Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/ColumnDescriptor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/ColumnDescriptor.java?rev=1578376&r1=1578375&r2=1578376&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/ColumnDescriptor.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/ColumnDescriptor.java Mon Mar 17 13:49:27 2014
@@ -37,6 +37,7 @@ import org.apache.cayenne.util.ToStringB
*/
public class ColumnDescriptor {
+ protected DbAttribute attribute;
protected String tableName;
protected String procedureName;
@@ -75,6 +76,8 @@ public class ColumnDescriptor {
*/
public ColumnDescriptor(DbAttribute attribute, String tableAlias) {
this(attribute.getName(), attribute.getType());
+
+ this.attribute = attribute;
this.namePrefix = tableAlias;
if (attribute.getEntity() != null) {
@@ -135,6 +138,17 @@ public class ColumnDescriptor {
}
/**
+ * Returns a DbAttribute for this column. Since columns descriptors can be
+ * initialized in a context where a DbAttribite is unknown, this method may
+ * return null.
+ *
+ * @since 3.2
+ */
+ public DbAttribute getAttribute() {
+ return attribute;
+ }
+
+ /**
* Returns true if another object is a ColumnDescriptor with the same name,
* name prefix, table and procedure names. Other fields are ignored in the
* equality test.