mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
Option (turned on by default, controlled via javalin metadata) to not allow query requests without a limit
This commit is contained in:
@ -1279,6 +1279,11 @@ public class QJavalinImplementation
|
||||
queryInput.getFilter().setLimit(limit);
|
||||
}
|
||||
|
||||
if(queryInput.getFilter() == null || queryInput.getFilter().getLimit() == null)
|
||||
{
|
||||
handleQueryNullLimit(context, queryInput);
|
||||
}
|
||||
|
||||
List<QueryJoin> queryJoins = processQueryJoinsParam(context);
|
||||
queryInput.setQueryJoins(queryJoins);
|
||||
|
||||
@ -1299,6 +1304,28 @@ public class QJavalinImplementation
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
private static void handleQueryNullLimit(Context context, QueryInput queryInput)
|
||||
{
|
||||
boolean allowed = javalinMetaData.getQueryWithoutLimitAllowed();
|
||||
if(!allowed)
|
||||
{
|
||||
if(queryInput.getFilter() == null)
|
||||
{
|
||||
queryInput.setFilter(new QQueryFilter());
|
||||
}
|
||||
|
||||
queryInput.getFilter().setLimit(javalinMetaData.getQueryWithoutLimitDefault());
|
||||
LOG.log(javalinMetaData.getQueryWithoutLimitLogLevel(), "Query request did not specify a limit, which is not allowed. Using default instead", null,
|
||||
logPair("defaultLimit", javalinMetaData.getQueryWithoutLimitDefault()),
|
||||
logPair("path", context.path()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
@ -23,6 +23,7 @@ package com.kingsrook.qqq.backend.javalin;
|
||||
|
||||
|
||||
import java.util.function.Function;
|
||||
import org.apache.logging.log4j.Level;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -36,6 +37,10 @@ public class QJavalinMetaData
|
||||
|
||||
private Function<QJavalinAccessLogger.LogEntry, Boolean> logFilter;
|
||||
|
||||
private boolean queryWithoutLimitAllowed = false;
|
||||
private Integer queryWithoutLimitDefault = 1000;
|
||||
private Level queryWithoutLimitLogLevel = Level.INFO;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -143,4 +148,97 @@ public class QJavalinMetaData
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for queryWithoutLimitAllowed
|
||||
*******************************************************************************/
|
||||
public boolean getQueryWithoutLimitAllowed()
|
||||
{
|
||||
return (this.queryWithoutLimitAllowed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for queryWithoutLimitAllowed
|
||||
*******************************************************************************/
|
||||
public void setQueryWithoutLimitAllowed(boolean queryWithoutLimitAllowed)
|
||||
{
|
||||
this.queryWithoutLimitAllowed = queryWithoutLimitAllowed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for queryWithoutLimitAllowed
|
||||
*******************************************************************************/
|
||||
public QJavalinMetaData withQueryWithoutLimitAllowed(boolean queryWithoutLimitAllowed)
|
||||
{
|
||||
this.queryWithoutLimitAllowed = queryWithoutLimitAllowed;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for queryWithoutLimitDefault
|
||||
*******************************************************************************/
|
||||
public Integer getQueryWithoutLimitDefault()
|
||||
{
|
||||
return (this.queryWithoutLimitDefault);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for queryWithoutLimitDefault
|
||||
*******************************************************************************/
|
||||
public void setQueryWithoutLimitDefault(Integer queryWithoutLimitDefault)
|
||||
{
|
||||
this.queryWithoutLimitDefault = queryWithoutLimitDefault;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for queryWithoutLimitDefault
|
||||
*******************************************************************************/
|
||||
public QJavalinMetaData withQueryWithoutLimitDefault(Integer queryWithoutLimitDefault)
|
||||
{
|
||||
this.queryWithoutLimitDefault = queryWithoutLimitDefault;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for queryWithoutLimitLogLevel
|
||||
*******************************************************************************/
|
||||
public Level getQueryWithoutLimitLogLevel()
|
||||
{
|
||||
return (this.queryWithoutLimitLogLevel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for queryWithoutLimitLogLevel
|
||||
*******************************************************************************/
|
||||
public void setQueryWithoutLimitLogLevel(Level queryWithoutLimitLogLevel)
|
||||
{
|
||||
this.queryWithoutLimitLogLevel = queryWithoutLimitLogLevel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for queryWithoutLimitLogLevel
|
||||
*******************************************************************************/
|
||||
public QJavalinMetaData withQueryWithoutLimitLogLevel(Level queryWithoutLimitLogLevel)
|
||||
{
|
||||
this.queryWithoutLimitLogLevel = queryWithoutLimitLogLevel;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
|
||||
import com.kingsrook.qqq.backend.core.logging.QCollectingLogger;
|
||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormat;
|
||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||
@ -45,6 +47,7 @@ import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.SleepUtils;
|
||||
import kong.unirest.HttpResponse;
|
||||
import kong.unirest.Unirest;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
@ -469,6 +472,101 @@ class QJavalinImplementationTest extends QJavalinTestBase
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** test a table query using an actual filter via POST, with no limit specified,
|
||||
** and with that not being allowed.
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void test_dataQueryWithFilterPOSTWithoutLimitNotAllowed() throws QInstanceValidationException
|
||||
{
|
||||
try
|
||||
{
|
||||
qJavalinImplementation.getJavalinMetaData()
|
||||
.withQueryWithoutLimitAllowed(false)
|
||||
.withQueryWithoutLimitDefault(3)
|
||||
.withQueryWithoutLimitLogLevel(Level.WARN);
|
||||
|
||||
QCollectingLogger collectingLogger = QLogger.activateCollectingLoggerForClass(QJavalinImplementation.class);
|
||||
|
||||
String filterJson = """
|
||||
{"criteria":[]}""";
|
||||
|
||||
HttpResponse<String> response = Unirest.post(BASE_URL + "/data/person/query")
|
||||
.field("filter", filterJson)
|
||||
.asString();
|
||||
|
||||
assertEquals(200, response.getStatus());
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||
assertTrue(jsonObject.has("records"));
|
||||
JSONArray records = jsonObject.getJSONArray("records");
|
||||
assertEquals(3, records.length());
|
||||
|
||||
assertThat(collectingLogger.getCollectedMessages())
|
||||
.anyMatch(m -> m.getLevel().equals(Level.WARN) && m.getMessage().contains("Query request did not specify a limit"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
QLogger.activateCollectingLoggerForClass(QJavalinImplementation.class);
|
||||
resetMetaDataQueryWithoutLimitSettings();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** test a table query using an actual filter via POST, with no limit specified,
|
||||
** but with that being allowed.
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void test_dataQueryWithFilterPOSTWithoutLimitAllowed() throws QInstanceValidationException
|
||||
{
|
||||
try
|
||||
{
|
||||
qJavalinImplementation.getJavalinMetaData()
|
||||
.withQueryWithoutLimitAllowed(true);
|
||||
|
||||
QCollectingLogger collectingLogger = QLogger.activateCollectingLoggerForClass(QJavalinImplementation.class);
|
||||
|
||||
String filterJson = """
|
||||
{"criteria":[]}""";
|
||||
|
||||
HttpResponse<String> response = Unirest.post(BASE_URL + "/data/person/query")
|
||||
.field("filter", filterJson)
|
||||
.asString();
|
||||
|
||||
assertEquals(200, response.getStatus());
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
|
||||
assertTrue(jsonObject.has("records"));
|
||||
JSONArray records = jsonObject.getJSONArray("records");
|
||||
assertEquals(6, records.length());
|
||||
|
||||
assertThat(collectingLogger.getCollectedMessages())
|
||||
.noneMatch(m -> m.getMessage().contains("Query request did not specify a limit"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
QLogger.activateCollectingLoggerForClass(QJavalinImplementation.class);
|
||||
resetMetaDataQueryWithoutLimitSettings();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
private void resetMetaDataQueryWithoutLimitSettings()
|
||||
{
|
||||
qJavalinImplementation.getJavalinMetaData()
|
||||
.withQueryWithoutLimitAllowed(false)
|
||||
.withQueryWithoutLimitDefault(1000)
|
||||
.withQueryWithoutLimitLogLevel(Level.INFO);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@ -1029,7 +1127,7 @@ class QJavalinImplementationTest extends QJavalinTestBase
|
||||
// filter use-case, with no values, should return options. //
|
||||
/////////////////////////////////////////////////////////////
|
||||
HttpResponse<String> response = Unirest.post(BASE_URL + "/data/pet/possibleValues/ownerPersonId?searchTerm=&useCase=filter").asString();
|
||||
JSONArray options = assertPossibleValueSuccessfulResponseAndGetOptionsArray(response);
|
||||
JSONArray options = assertPossibleValueSuccessfulResponseAndGetOptionsArray(response);
|
||||
assertNotNull(options);
|
||||
assertThat(options.length()).isGreaterThanOrEqualTo(5);
|
||||
|
||||
|
@ -102,7 +102,7 @@ public class QJavalinTestBase
|
||||
{
|
||||
qJavalinImplementation.stopJavalinServer();
|
||||
}
|
||||
qJavalinImplementation = new QJavalinImplementation(qInstance);
|
||||
qJavalinImplementation = new QJavalinImplementation(qInstance, new QJavalinMetaData());
|
||||
QJavalinProcessHandler.setAsyncStepTimeoutMillis(250);
|
||||
qJavalinImplementation.startJavalinServer(PORT);
|
||||
}
|
||||
|
Reference in New Issue
Block a user