diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java index 3b8ba67aa..06f2f0521 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java @@ -196,6 +196,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ @Override public List queryDataTable(String datatable, final String columnFilter, String valueFilter, String resultColumns) { asList(datatable, columnFilter, valueFilter, resultColumns).forEach(SQLInjectionValidator::validateDynamicQuery); + validateDatatable(datatable); List 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"; } diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImplTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImplTest.java index fb1bc4b25..b3216baf7 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImplTest.java +++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImplTest.java @@ -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 provideParameters() { return Stream.of(Arguments.of("timestamp without time zone", "validation.msg.invalid.dateFormat.format"), Arguments.of("INTEGER", "validation.msg.invalid.integer.format"),