diff --git a/plugin/ignite-plugin/src/main/scala/org/finos/vuu/feature/ignite/filter/SqlFilterColumnValueParser.scala b/plugin/ignite-plugin/src/main/scala/org/finos/vuu/feature/ignite/filter/SqlFilterColumnValueParser.scala index 8e54b7d7fb..7428c70558 100644 --- a/plugin/ignite-plugin/src/main/scala/org/finos/vuu/feature/ignite/filter/SqlFilterColumnValueParser.scala +++ b/plugin/ignite-plugin/src/main/scala/org/finos/vuu/feature/ignite/filter/SqlFilterColumnValueParser.scala @@ -108,13 +108,11 @@ private class ColumnValueParser(private val mapper: SchemaMapper, * This adds a limitation on what can be passed to the filters in order to prevent SQL injection attacks. */ private def checkForSqlInjection(v: String): Either[ErrorMessage, String] = { - val isSingleQuotedAndNotContainsAnyOtherSingleQuotes = v.matches("^'[^']+'$") - val isNotQuotedAndContainsOnlyDigits = v.matches("[0-9]+([.][0-9]+)?") + val isSingleQuotedStringWithoutAnyOtherSingleQuotes = v.matches("^'[^']+'$") + val isNumber = v.matches("[0-9]+([.][0-9]+)?") + val isBoolean = v.matches("(?i)(true)|(false)") - if ( - isSingleQuotedAndNotContainsAnyOtherSingleQuotes || - isNotQuotedAndContainsOnlyDigits - ) { + if (isSingleQuotedStringWithoutAnyOtherSingleQuotes || isNumber || isBoolean) { Right(v) } else { logger.warn(s"Potential SQL injection noticed with $v") diff --git a/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/IgniteTestStore.scala b/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/IgniteTestStore.scala index 6690c04ca3..01dcf1f8b4 100644 --- a/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/IgniteTestStore.scala +++ b/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/IgniteTestStore.scala @@ -65,6 +65,7 @@ object IgniteTestStore { fields.put("price", classOf[Double].getName) fields.put("quantity", classOf[Int].getName) fields.put("rating", classOf[Char].getName) + fields.put("isFilled", classOf[Boolean].getName) fields.put("createdAt", classOf[Date].getName) fields.put("updatedAt", classOf[LocalDate].getName) fields.put("totalFill", classOf[BigDecimal].getName) diff --git a/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/TestInput.scala b/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/TestInput.scala index f2e96e91e5..30c53bb7b4 100644 --- a/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/TestInput.scala +++ b/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/TestInput.scala @@ -6,7 +6,7 @@ import java.time.LocalDate object TestInput { def createTestOrderEntity(id: Int, ric: String, parentId: Int = 1, price: Double = 10.4, quantity: Int = 100, - rating: Char = 'A', createdAt: Date = Date.valueOf("2024-02-10"), + rating: Char = 'A', isFilled: Boolean = true, createdAt: Date = Date.valueOf("2024-02-10"), updatedAt: LocalDate = LocalDate.of(2024, 2, 15), totalFill: BigDecimal = new BigDecimal(10_000.3333)): TestOrderEntity = TestOrderEntity( @@ -16,6 +16,7 @@ object TestInput { price = price, quantity = quantity, rating = rating, + isFilled = isFilled, createdAt = createdAt, updatedAt = updatedAt, totalFill = totalFill diff --git a/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/TestOrderEntity.scala b/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/TestOrderEntity.scala index 8536f6b922..7b9601ded6 100644 --- a/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/TestOrderEntity.scala +++ b/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/TestOrderEntity.scala @@ -10,6 +10,7 @@ case class TestOrderEntity(parentId: Int, price: Double, quantity: Int, rating: Char, + isFilled: Boolean, createdAt: Date, updatedAt: LocalDate, totalFill: BigDecimal) {} @@ -23,9 +24,10 @@ object TestOrderEntity{ price = cols.get(3).asInstanceOf[Double], quantity = cols.get(4).asInstanceOf[Int], rating = cols.get(5).asInstanceOf[Char], - createdAt = cols.get(6).asInstanceOf[Date], - updatedAt = cols.get(7).asInstanceOf[LocalDate], - totalFill = cols.get(8).asInstanceOf[BigDecimal] + isFilled = cols.get(6).asInstanceOf[Boolean], + createdAt = cols.get(7).asInstanceOf[Date], + updatedAt = cols.get(8).asInstanceOf[LocalDate], + totalFill = cols.get(9).asInstanceOf[BigDecimal], ) } } diff --git a/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/filter/IgniteSqlFilteringTest.scala b/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/filter/IgniteSqlFilteringTest.scala index e9a8cabec2..7bc752a6a5 100644 --- a/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/filter/IgniteSqlFilteringTest.scala +++ b/plugin/ignite-plugin/src/test/scala/org/finos/vuu/feature/ignite/filter/IgniteSqlFilteringTest.scala @@ -225,6 +225,14 @@ class IgniteSqlFilteringTest extends IgniteTestsBase { assertEquavalent(filterResult.toArray, Array(testOrder1)) } + Scenario("Support comparison to BOOLEAN") { + givenOrderExistInIgnite(testOrder1, testOrder2, testOrder3) + + val filterResult = applyFilter("isFilled = false") + + assertEquavalent(filterResult.toArray, Array.empty) + } + Scenario("Support mapped column name") { givenOrderExistInIgnite(testOrder1, testOrder2, testOrder3) @@ -295,6 +303,14 @@ class IgniteSqlFilteringTest extends IgniteTestsBase { assertEquavalent(filterResult.toArray, Array(testOrder2, testOrder3)) } + Scenario("Support comparison to BOOLEAN") { + givenOrderExistInIgnite(testOrder1, testOrder2, testOrder3) + + val filterResult = applyFilter("isFilled != false") + + assertEquavalent(filterResult.toArray, Array(testOrder1, testOrder2, testOrder3)) + } + Scenario("Support mapped column name") { givenOrderExistInIgnite(testOrder1, testOrder2, testOrder3) @@ -552,6 +568,7 @@ class IgniteSqlFilteringTest extends IgniteTestsBase { "quantity" -> "quantity", "parentId" -> "parentOrderId", "rating" -> "rating", + "isFilled" -> "isFilled", "createdAt" -> "createdAt", "updatedAt" -> "updatedAt", "totalFill" -> "fill", @@ -564,6 +581,7 @@ class IgniteSqlFilteringTest extends IgniteTestsBase { ("quantity", classOf[Int]), ("parentOrderId", classOf[Int]), ("rating", classOf[String]), + ("isFilled", classOf[Boolean]), ("createdAt", classOf[Long]), ("updatedAt", classOf[Long]), ("fill", classOf[Double]), @@ -578,9 +596,10 @@ class IgniteSqlFilteringTest extends IgniteTestsBase { SchemaField("quantity", classOf[Int], 4), SchemaField("price", classOf[Double], 5), SchemaField("rating", classOf[Char], 6), - SchemaField("createdAt", classOf[Date], 7), - SchemaField("updatedAt", classOf[LocalDate], 8), - SchemaField("totalFill", classOf[BigDecimal], 8) + SchemaField("isFilled", classOf[Boolean], 7), + SchemaField("createdAt", classOf[Date], 8), + SchemaField("updatedAt", classOf[LocalDate], 9), + SchemaField("totalFill", classOf[BigDecimal], 10) ) }