FINERACT-1724: Datatables query API fix - invalid tablename

This commit is contained in:
abraham.menyhart
2023-06-06 14:09:29 +02:00
committed by Adam Saghy
parent d87d483665
commit 500e7720b7
2 changed files with 24 additions and 0 deletions
@@ -196,6 +196,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
@Override
public List<JsonObject> queryDataTable(String datatable, final String columnFilter, String valueFilter, String resultColumns) {
asList(datatable, columnFilter, valueFilter, resultColumns).forEach(SQLInjectionValidator::validateDynamicQuery);
validateDatatable(datatable);
List<ResultsetColumnHeaderData> resultsetColumnHeaderData = genericDataService.fillResultsetColumnHeaders(datatable);
validateRequestParams(columnFilter, valueFilter, resultColumns, resultsetColumnHeaderData);
@@ -1859,6 +1860,14 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return applicationTableName;
}
private void validateDatatable(final String datatable) {
final String sql = "SELECT COUNT(application_table_name) FROM x_registered_table WHERE registered_table_name = ?";
final Integer count = jdbcTemplate.queryForObject(sql, Integer.class, datatable);
if (count == 0) {
throw new DatatableNotFoundException(datatable);
}
}
private String getFKField(final String applicationTableName) {
return applicationTableName.substring(2) + "_id";
}
@@ -33,6 +33,7 @@ import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableNotFoundException;
import org.apache.fineract.infrastructure.security.utils.SQLInjectionException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -84,6 +85,7 @@ public class ReadWriteNonCoreDataServiceImplTest {
@Test
public void testQueryDataTableSuccess() {
mockDatatableValidation();
SqlRowSet sqlRS = Mockito.mock(SqlRowSet.class);
when(jdbcTemplate.queryForRowSet(eq("select rc1,rc2 from table where cf1 = ?"), any(Object.class))).thenReturn(sqlRS);
when(sqlRS.next()).thenReturn(true).thenReturn(false);
@@ -107,13 +109,22 @@ public class ReadWriteNonCoreDataServiceImplTest {
@Test
public void testQueryDataTableValidationError() {
mockDatatableValidation();
when(genericDataService.fillResultsetColumnHeaders("table")).thenReturn(emptyList());
assertThrows(PlatformApiDataValidationException.class, () -> underTest.queryDataTable("table", "cf1", "vf1", "rc1,rc2"));
}
@Test
public void testDatatableValidationError() {
when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class), anyString())).thenReturn(0);
assertThrows(DatatableNotFoundException.class, () -> underTest.queryDataTable("table", "cf1", "vf1", "rc1,rc2"));
}
@ParameterizedTest
@MethodSource("provideParameters")
public void testQueryDataTableInvalidParameterError(String columnType, String errorMessage) {
mockDatatableValidation();
ResultsetColumnHeaderData cf1 = ResultsetColumnHeaderData.detailed("cf1", columnType, 10L, false, false, emptyList(), null, false,
false);
ResultsetColumnHeaderData rc1 = ResultsetColumnHeaderData.detailed("rc1", "text", 10L, false, false, emptyList(), null, false,
@@ -129,6 +140,10 @@ public class ReadWriteNonCoreDataServiceImplTest {
assertEquals(errorMessage, thrown.getErrors().get(0).getUserMessageGlobalisationCode());
}
private void mockDatatableValidation() {
when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class), anyString())).thenReturn(1);
}
private static Stream<Arguments> provideParameters() {
return Stream.of(Arguments.of("timestamp without time zone", "validation.msg.invalid.dateFormat.format"),
Arguments.of("INTEGER", "validation.msg.invalid.integer.format"),