QQQ-14 Add secret handling in meta data; update to scrub values before insert/update

This commit is contained in:
2022-06-28 11:21:27 -05:00
parent ecd2736fe8
commit b4c3c8246f
6 changed files with 60 additions and 11 deletions

View File

@ -51,7 +51,7 @@
<dependency> <dependency>
<groupId>com.kingsrook.qqq</groupId> <groupId>com.kingsrook.qqq</groupId>
<artifactId>qqq-backend-core</artifactId> <artifactId>qqq-backend-core</artifactId>
<version>0.0.0-20220624.210809-12</version> <version>0.0.0-20220628.161829-14</version>
</dependency> </dependency>
<!-- 3rd party deps specifically for this module --> <!-- 3rd party deps specifically for this module -->

View File

@ -22,10 +22,12 @@
package com.kingsrook.qqq.backend.module.rdbms.actions; package com.kingsrook.qqq.backend.module.rdbms.actions;
import java.io.Serializable;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import com.kingsrook.qqq.backend.core.model.actions.AbstractQTableRequest; import com.kingsrook.qqq.backend.core.model.actions.AbstractQTableRequest;
import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.QFieldType;
import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
import com.kingsrook.qqq.backend.core.utils.StringUtils; import com.kingsrook.qqq.backend.core.utils.StringUtils;
import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager; import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager;
@ -82,4 +84,24 @@ public abstract class AbstractRDBMSAction
ConnectionManager connectionManager = new ConnectionManager(); ConnectionManager connectionManager = new ConnectionManager();
return connectionManager.getConnection((RDBMSBackendMetaData) qTableRequest.getBackend()); return connectionManager.getConnection((RDBMSBackendMetaData) qTableRequest.getBackend());
} }
/*******************************************************************************
** Handle obvious problems with values - like empty string for integer should be null.
**
*******************************************************************************/
protected Serializable scrubValue(QFieldMetaData field, Serializable value)
{
if("".equals(value))
{
QFieldType type = field.getType();
if(type.equals(QFieldType.INTEGER) || type.equals(QFieldType.DECIMAL) || type.equals(QFieldType.DATE) || type.equals(QFieldType.DATE_TIME))
{
value = null;
}
}
return (value);
}
} }

View File

@ -22,6 +22,7 @@
package com.kingsrook.qqq.backend.module.rdbms.actions; package com.kingsrook.qqq.backend.module.rdbms.actions;
import java.io.Serializable;
import java.sql.Connection; import java.sql.Connection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -55,7 +56,7 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte
try try
{ {
InsertResult rs = new InsertResult(); InsertResult rs = new InsertResult();
QTableMetaData table = insertRequest.getTable(); QTableMetaData table = insertRequest.getTable();
List<QFieldMetaData> insertableFields = table.getFields().values().stream() List<QFieldMetaData> insertableFields = table.getFields().values().stream()
@ -69,9 +70,9 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte
.map(x -> "?") .map(x -> "?")
.collect(Collectors.joining(", ")); .collect(Collectors.joining(", "));
String tableName = getTableName(table); String tableName = getTableName(table);
StringBuilder sql = new StringBuilder("INSERT INTO ").append(tableName).append("(").append(columns).append(") VALUES"); StringBuilder sql = new StringBuilder("INSERT INTO ").append(tableName).append("(").append(columns).append(") VALUES");
List<Object> params = new ArrayList<>(); List<Object> params = new ArrayList<>();
int recordIndex = 0; int recordIndex = 0;
for(QRecord record : insertRequest.getRecords()) for(QRecord record : insertRequest.getRecords())
@ -83,7 +84,10 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte
sql.append("(").append(questionMarks).append(")"); sql.append("(").append(questionMarks).append(")");
for(QFieldMetaData field : insertableFields) for(QFieldMetaData field : insertableFields)
{ {
params.add(record.getValue(field.getName())); Serializable value = record.getValue(field.getName());
value = scrubValue(field, value);
params.add(value);
} }
} }
@ -95,14 +99,14 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte
// todo - non-serial-id style tables // todo - non-serial-id style tables
// todo - other generated values, e.g., createDate... maybe need to re-select? // todo - other generated values, e.g., createDate... maybe need to re-select?
Connection connection = getConnection(insertRequest); Connection connection = getConnection(insertRequest);
List<Integer> idList = QueryManager.executeInsertForGeneratedIds(connection, sql.toString(), params); List<Integer> idList = QueryManager.executeInsertForGeneratedIds(connection, sql.toString(), params);
List<QRecord> outputRecords = new ArrayList<>(); List<QRecord> outputRecords = new ArrayList<>();
rs.setRecords(outputRecords); rs.setRecords(outputRecords);
int index = 0; int index = 0;
for(QRecord record : insertRequest.getRecords()) for(QRecord record : insertRequest.getRecords())
{ {
Integer id = idList.get(index++); Integer id = idList.get(index++);
QRecord outputRecord = new QRecord(record); QRecord outputRecord = new QRecord(record);
outputRecord.setValue(table.getPrimaryKeyField(), id); outputRecord.setValue(table.getPrimaryKeyField(), id);
outputRecords.add(outputRecord); outputRecords.add(outputRecord);

View File

@ -45,6 +45,8 @@ import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
import com.kingsrook.qqq.backend.core.modules.interfaces.QueryInterface; import com.kingsrook.qqq.backend.core.modules.interfaces.QueryInterface;
import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager; import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/******************************************************************************* /*******************************************************************************
@ -52,6 +54,7 @@ import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
*******************************************************************************/ *******************************************************************************/
public class RDBMSQueryAction extends AbstractRDBMSAction implements QueryInterface public class RDBMSQueryAction extends AbstractRDBMSAction implements QueryInterface
{ {
private static final Logger LOG = LogManager.getLogger(RDBMSQueryAction.class);
/******************************************************************************* /*******************************************************************************
** **
@ -127,7 +130,7 @@ public class RDBMSQueryAction extends AbstractRDBMSAction implements QueryInterf
} }
catch(Exception e) catch(Exception e)
{ {
e.printStackTrace(); LOG.warn("Error executing query", e);
throw new QException("Error executing query", e); throw new QException("Error executing query", e);
} }
} }

View File

@ -22,6 +22,7 @@
package com.kingsrook.qqq.backend.module.rdbms.actions; package com.kingsrook.qqq.backend.module.rdbms.actions;
import java.io.Serializable;
import java.sql.Connection; import java.sql.Connection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -85,7 +86,9 @@ public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInte
List<Object> params = new ArrayList<>(); List<Object> params = new ArrayList<>();
for(QFieldMetaData field : updateableFields) for(QFieldMetaData field : updateableFields)
{ {
params.add(record.getValue(field.getName())); Serializable value = record.getValue(field.getName());
value = scrubValue(field, value);
params.add(value);
} }
params.add(record.getValue(table.getPrimaryKeyField())); params.add(record.getValue(table.getPrimaryKeyField()));

View File

@ -23,6 +23,7 @@ package com.kingsrook.qqq.backend.module.rdbms.model.metadata;
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.QSecretReader;
import com.kingsrook.qqq.backend.module.rdbms.RDBMSBackendModule; import com.kingsrook.qqq.backend.module.rdbms.RDBMSBackendModule;
@ -252,4 +253,20 @@ public class RDBMSBackendMetaData extends QBackendMetaData
this.password = password; this.password = password;
return (this); return (this);
} }
/*******************************************************************************
** Called by the QInstanceEnricher - to do backend-type-specific enrichments.
** Original use case is: reading secrets into fields (e.g., passwords).
*******************************************************************************/
@Override
public void enrich()
{
super.enrich();
QSecretReader secretReader = new QSecretReader();
username = secretReader.readSecret(username);
password = secretReader.readSecret(password);
}
} }