#2007 - Encrypted fields unable to be mapped when using DtoQuery

This commit is contained in:
rob bygrave
2020-05-12 20:25:56 +12:00
parent 8980a3b6fd
commit 293700acc0
5 changed files with 85 additions and 16 deletions
@@ -102,7 +102,7 @@ public final class DtoQueryRequest<T> extends AbstractSqlQueryRequest {
@SuppressWarnings("unchecked")
public T readNextBean() throws SQLException {
dataReader.resetColumnPosition();
return (T)plan.readRow(dataReader);
return (T) plan.readRow(dataReader);
}
private DtoMappingRequest mappingRequest() throws SQLException {
@@ -110,19 +110,29 @@ public final class DtoQueryRequest<T> extends AbstractSqlQueryRequest {
}
private DtoColumn[] readMeta() throws SQLException {
ResultSetMetaData metaData = resultSet.getMetaData();
int cols = metaData.getColumnCount();
DtoColumn[] meta = new DtoColumn[cols];
for (int i = 0; i < cols; i++) {
int pos = i+1;
int pos = i + 1;
String columnLabel = metaData.getColumnLabel(pos);
if (columnLabel == null) {
columnLabel = metaData.getColumnName(pos);
}
meta[i] = new DtoColumn(columnLabel);
meta[i] = new DtoColumn(parseColumn(columnLabel));
}
return meta;
}
static String parseColumn(String columnLabel) {
if (columnLabel.startsWith("_e_")) {
// encrypted column alias in the form _e_<tableAlias>_<column>
final int pos = columnLabel.indexOf("_", 3);
if (pos > -1) {
return columnLabel.substring(pos + 1);
}
}
return columnLabel;
}
}
@@ -542,12 +542,11 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
return dbEncryptFunction.getDecryptSql(propertyName);
}
public String getDecryptSql() {
return dbEncryptFunction.getDecryptSql(this.getDbColumn());
}
private String getDecryptSql(String tableAlias) {
return dbEncryptFunction.getDecryptSql(tableAlias + "." + this.getDbColumn());
/**
* Return the SQL for the column including decryption function and column alias.
*/
private String getDecryptSqlWithColumnAlias(String tableAlias) {
return dbEncryptFunction.getDecryptSql(tableAlias + "." + this.getDbColumn()) + " _e_" + tableAlias + "_" + this.getDbColumn();
}
@Override
@@ -600,8 +599,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
}
if (dbEncrypted) {
String decryptSql = getDecryptSql(ctx.peekTableAlias());
ctx.appendRawColumn(decryptSql);
ctx.appendRawColumn(getDecryptSqlWithColumnAlias(ctx.peekTableAlias()));
ctx.addEncryptedProp(this);
} else {
@@ -328,11 +328,9 @@ class DefaultDbSqlContext implements DbSqlContext {
}
@Override
public void appendRawColumn(String rawcolumnWithTableAlias) {
public void appendRawColumn(String rawColumnWithAlias) {
sb.append(COMMA);
sb.append(rawcolumnWithTableAlias);
appendColumnAlias();
sb.append(rawColumnWithAlias);
}
@Override
@@ -0,0 +1,20 @@
package io.ebeaninternal.server.core;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class DtoQueryRequestTest {
@Test
public void testParse() {
assertEquals("foo", DtoQueryRequest.parseColumn("foo"));
assertEquals("bar", DtoQueryRequest.parseColumn("_e_t0_bar"));
assertEquals("baz", DtoQueryRequest.parseColumn("_e_t42_baz"));
assertEquals("e_t42_nope", DtoQueryRequest.parseColumn("e_t42_nope"));
assertEquals("_f_t42_nope", DtoQueryRequest.parseColumn("_f_t42_nope"));
}
}
@@ -55,6 +55,49 @@ public class TestEncrypt extends BaseTestCase {
assertThat(loggedSql.get(1)).contains("left join e_basicenc t1 on t1.id = t0.other_id");
}
@Test
public void asDto() {
DB.find(EBasicEncrypt.class).delete();
EBasicEncrypt e = new EBasicEncrypt();
e.setName("name2");
e.setDescription("descEncrypted2");
e.setDob(new Date(System.currentTimeMillis() - 100000));
DB.save(e);
final EDto dto = DB.find(EBasicEncrypt.class)
.select("name, description")
.asDto(EDto.class)
.findOne();
assertThat(dto).isNotNull();
assertThat(dto.getName()).isEqualTo("name2");
assertThat(dto.getDescription()).isEqualTo("descEncrypted2");
}
public static class EDto {
String name;
String description;
public EDto(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
@Test
@ForPlatform(Platform.H2)
public void test() {