Skip to content

Commit 47b568c

Browse files
committed
XWIKI-23550: DBListClass should respect query limit
* Respect the query limit in DBListClass#getDBList. * Add a unit test.
1 parent 7d7a391 commit 47b568c

2 files changed

Lines changed: 70 additions & 1 deletion

File tree

xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/objects/classes/DBListClass.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
import org.slf4j.Logger;
3333
import org.slf4j.LoggerFactory;
3434
import org.xwiki.component.util.DefaultParameterizedType;
35+
import org.xwiki.query.Query;
3536
import org.xwiki.query.QueryBuilder;
37+
import org.xwiki.security.SecurityConfiguration;
3638
import org.xwiki.security.authorization.AuthorExecutor;
3739

3840
import com.xpn.xwiki.XWiki;
@@ -118,13 +120,20 @@ public List<ListItem> getDBList(XWikiContext context)
118120
List<ListItem> list = getCachedDBList(context);
119121
if (list == null) {
120122
try {
123+
SecurityConfiguration securityConfiguration = Utils.getComponent(SecurityConfiguration.class);
121124
DefaultParameterizedType dbListQueryBuilderType =
122125
new DefaultParameterizedType(null, QueryBuilder.class, DBListClass.class);
123126
QueryBuilder<DBListClass> dbListQueryBuilder = Utils.getComponent(dbListQueryBuilderType);
124127
// Execute the query with the rights of the class last author.
125128
AuthorExecutor authorExecutor = Utils.getComponent(AuthorExecutor.class);
126129
list = makeList(authorExecutor.call(() -> {
127-
return dbListQueryBuilder.build(this).execute();
130+
Query query = dbListQueryBuilder.build(this);
131+
int configuredLimit = securityConfiguration.getQueryItemsLimit();
132+
// Limit unlimited queries or queries with a high limit to the configured limit.
133+
if (configuredLimit > 0 && (query.getLimit() <= 0 || query.getLimit() > configuredLimit)) {
134+
query.setLimit(configuredLimit);
135+
}
136+
return query.execute();
128137
}, getOwnerDocument().getAuthorReference(), getDocumentReference()));
129138
} catch (Exception e) {
130139
LOGGER.warn("Failed to get the Database List values. Root cause is [{}].",

xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/objects/classes/DBListClassTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,18 @@
2121

2222
import java.util.ArrayList;
2323
import java.util.List;
24+
import java.util.concurrent.Callable;
2425

2526
import org.junit.jupiter.api.BeforeEach;
2627
import org.junit.jupiter.api.Test;
28+
import org.junit.jupiter.params.ParameterizedTest;
29+
import org.junit.jupiter.params.provider.CsvSource;
30+
import org.xwiki.model.reference.DocumentReference;
31+
import org.xwiki.query.Query;
32+
import org.xwiki.query.QueryBuilder;
33+
import org.xwiki.security.SecurityConfiguration;
34+
import org.xwiki.security.authorization.AuthorExecutor;
35+
import org.xwiki.test.junit5.mockito.MockComponent;
2736

2837
import com.xpn.xwiki.XWikiContext;
2938
import com.xpn.xwiki.doc.XWikiDocument;
@@ -34,7 +43,12 @@
3443

3544
import static org.junit.jupiter.api.Assertions.assertEquals;
3645
import static org.mockito.ArgumentMatchers.any;
46+
import static org.mockito.ArgumentMatchers.anyInt;
3747
import static org.mockito.Mockito.doAnswer;
48+
import static org.mockito.Mockito.mock;
49+
import static org.mockito.Mockito.never;
50+
import static org.mockito.Mockito.verify;
51+
import static org.mockito.Mockito.when;
3852

3953
/**
4054
* Unit tests for {@link DBListClass}.
@@ -48,6 +62,15 @@ class DBListClassTest
4862
@InjectMockitoOldcore
4963
private MockitoOldcore oldcore;
5064

65+
@MockComponent
66+
private QueryBuilder<DBListClass> queryBuilder;
67+
68+
@MockComponent
69+
private SecurityConfiguration securityConfiguration;
70+
71+
@MockComponent
72+
private AuthorExecutor authorExecutor;
73+
5174
@BeforeEach
5275
void before()
5376
{
@@ -399,4 +422,41 @@ void testReturnColWithInvalidQuery()
399422
assertEquals("-", dblc.returnCol("do something", true));
400423
assertEquals("-", dblc.returnCol("do something", false));
401424
}
425+
426+
@ParameterizedTest
427+
@CsvSource({
428+
"10, 20, false",
429+
"20, 10, true",
430+
"0, 0, false",
431+
"0, -1, false",
432+
"20, -1, false",
433+
"0, 20, true"
434+
})
435+
void getDBListLimit(int queryLimit, int configuredLimit, boolean setLimit) throws Exception
436+
{
437+
Query mockQuery = mock();
438+
when(mockQuery.getLimit()).thenReturn(queryLimit);
439+
when(mockQuery.execute()).thenReturn(List.of());
440+
when(this.securityConfiguration.getQueryItemsLimit()).thenReturn(configuredLimit);
441+
442+
when(this.authorExecutor.call(any(), any(), any())).then(invocation -> {
443+
Callable<?> callable = invocation.getArgument(0);
444+
return callable.call();
445+
});
446+
447+
XWikiDocument ownerDocument = new XWikiDocument(new DocumentReference("wiki", "space", "page"));
448+
DBListClass dbListClass = new DBListClass();
449+
dbListClass.setOwnerDocument(ownerDocument);
450+
451+
when(this.queryBuilder.build(dbListClass)).thenReturn(mockQuery);
452+
453+
dbListClass.getDBList(this.oldcore.getXWikiContext());
454+
455+
if (setLimit) {
456+
verify(mockQuery).setLimit(configuredLimit);
457+
} else {
458+
verify(mockQuery, never()).setLimit(anyInt());
459+
}
460+
verify(mockQuery).execute();
461+
}
402462
}

0 commit comments

Comments
 (0)