aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorOlli Tietäväinen <ollit@vaadin.com>2021-10-05 09:50:16 +0300
committerGitHub <noreply@github.com>2021-10-05 09:50:16 +0300
commitab775a32112ebfb7ae45f9c1efd6e85d43788f4b (patch)
tree20fa259f85285d8eed93b5b2c85b54a720bdcb91 /server
parent2b2028e22fabcf669008db1acfbfa33826809f10 (diff)
downloadvaadin-framework-ab775a32112ebfb7ae45f9c1efd6e85d43788f4b.tar.gz
vaadin-framework-ab775a32112ebfb7ae45f9c1efd6e85d43788f4b.zip
8.14 cherry-picks (#12418)
* Improve thread safety (#12395) See: https://vaadin.com/forum/thread/17522264/concurrentmodificationexception-in-vaadin-shared-on-karaf-4-2-x * Fix incompatible selenium version in test module. (#12397) * Fixed a dependency version in a karaf test module. (#12399) * Checkstyle tweaks to DateField widgets. (#12400) - Added and updated JavaDocs. - Updated comments. - Updated to use non-deprecated method calls. - Removed unnecessary warning suppressions. - Suppressed warnings for unavoidable deprecation. * fix: set Vaadin session attribute using lock in reinitializeSession (#12401) * Cherry picked unit test from Flow See https://github.com/vaadin/flow/pull/11538 * Fix missing import * Cherry pick fix from Flow * deprecate vaadin-snasphots repo (#12405) * deprecate vaadin-snasphots repo * Update chrome version to 93 * add more screenshots * fix: Add MPR UI id request parameter (#12412) * fix: Add MPR UI id request parameter Related-to https://github.com/vaadin/multiplatform-runtime/issues/85 * test: Remove redundant non-empty param test * test: Remove leftovers * fix: Init window.mprUiId earlier than window.vaadin * Add missing '=' * Update links shown by license checker (#12402) vaadin.com/pro does no longer have the info * fix: Add row limit to DataCommunicator row data requests (#12415) * Add row limit to DataCommunicator row data requests * Add missing constant * Add unit test * Add test for extending Grid * Fixed test Co-authored-by: Tatu Lund <tatu@vaadin.com> Co-authored-by: Anna Koskinen <Ansku@users.noreply.github.com> Co-authored-by: Zhe Sun <31067185+ZheSun88@users.noreply.github.com> Co-authored-by: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com>
Diffstat (limited to 'server')
-rw-r--r--server/src/main/java/com/vaadin/data/provider/DataCommunicator.java15
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinService.java18
-rw-r--r--server/src/main/resources/VAADIN/vaadinBootstrap.js6
-rw-r--r--server/src/test/java/com/vaadin/data/provider/DataCommunicatorTest.java8
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinServiceTest.java44
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java19
6 files changed, 106 insertions, 4 deletions
diff --git a/server/src/main/java/com/vaadin/data/provider/DataCommunicator.java b/server/src/main/java/com/vaadin/data/provider/DataCommunicator.java
index 0c1dafe09e..8d974c85d3 100644
--- a/server/src/main/java/com/vaadin/data/provider/DataCommunicator.java
+++ b/server/src/main/java/com/vaadin/data/provider/DataCommunicator.java
@@ -60,6 +60,7 @@ import elemental.json.JsonObject;
public class DataCommunicator<T> extends AbstractExtension {
private Registration dataProviderUpdateRegistration;
+ private static final int MAXIMUM_ALLOWED_ROWS = 500;
/**
* Simple implementation of collection data provider communication. All data
@@ -306,11 +307,25 @@ public class DataCommunicator<T> extends AbstractExtension {
*/
protected void onRequestRows(int firstRowIndex, int numberOfRows,
int firstCachedRowIndex, int cacheSize) {
+ if (numberOfRows > getMaximumAllowedRows()) {
+ throw new IllegalStateException(
+ "Client tried fetch more rows than allowed. This is denied to prevent denial of service.");
+ }
setPushRows(Range.withLength(firstRowIndex, numberOfRows));
markAsDirty();
}
/**
+ * Set the maximum allowed rows to be fetched in one query.
+ *
+ * @return Maximum allowed rows for one query.
+ * @since 8.14.1
+ */
+ protected int getMaximumAllowedRows() {
+ return MAXIMUM_ALLOWED_ROWS;
+ }
+
+ /**
* Triggered when rows have been dropped from the client side cache.
*
* @param keys
diff --git a/server/src/main/java/com/vaadin/server/VaadinService.java b/server/src/main/java/com/vaadin/server/VaadinService.java
index 888b82a3cb..25354074e1 100644
--- a/server/src/main/java/com/vaadin/server/VaadinService.java
+++ b/server/src/main/java/com/vaadin/server/VaadinService.java
@@ -1156,8 +1156,13 @@ public abstract class VaadinService implements Serializable {
if (value instanceof VaadinSession) {
// set flag to avoid cleanup
VaadinSession serviceSession = (VaadinSession) value;
- serviceSession.setAttribute(PRESERVE_UNBOUND_SESSION_ATTRIBUTE,
- Boolean.TRUE);
+ serviceSession.lock();
+ try {
+ serviceSession.setAttribute(
+ PRESERVE_UNBOUND_SESSION_ATTRIBUTE, Boolean.TRUE);
+ } finally {
+ serviceSession.unlock();
+ }
}
attrs.put(name, value);
}
@@ -1183,8 +1188,13 @@ public abstract class VaadinService implements Serializable {
serviceSession.getLockInstance());
service.storeSession(serviceSession, newSession);
- serviceSession.setAttribute(PRESERVE_UNBOUND_SESSION_ATTRIBUTE,
- null);
+ serviceSession.lock();
+ try {
+ serviceSession.setAttribute(
+ PRESERVE_UNBOUND_SESSION_ATTRIBUTE, null);
+ } finally {
+ serviceSession.unlock();
+ }
}
}
diff --git a/server/src/main/resources/VAADIN/vaadinBootstrap.js b/server/src/main/resources/VAADIN/vaadinBootstrap.js
index a6830f434b..82e7482216 100644
--- a/server/src/main/resources/VAADIN/vaadinBootstrap.js
+++ b/server/src/main/resources/VAADIN/vaadinBootstrap.js
@@ -365,6 +365,12 @@
params += '&v-wn=' + encodeURIComponent(window.name);
}
+ // This parameter is used in multiplatform-runtime as a key for
+ // storing the MPR UI content in the session
+ if (window.mprUiId) {
+ params += '&v-mui=' + encodeURIComponent(window.mprUiId);
+ }
+
// Detect touch device support
var supportsTouch = false;
try {
diff --git a/server/src/test/java/com/vaadin/data/provider/DataCommunicatorTest.java b/server/src/test/java/com/vaadin/data/provider/DataCommunicatorTest.java
index c187c91471..ed681f298d 100644
--- a/server/src/test/java/com/vaadin/data/provider/DataCommunicatorTest.java
+++ b/server/src/test/java/com/vaadin/data/provider/DataCommunicatorTest.java
@@ -314,4 +314,12 @@ public class DataCommunicatorTest {
assertTrue("DataCommunicator should be marked as dirty",
ui.getConnectorTracker().isDirty(communicator));
}
+
+
+ @Test(expected = IllegalStateException.class)
+ public void requestTooMuchRowsFail() {
+ TestDataCommunicator communicator = new TestDataCommunicator();
+ communicator.onRequestRows(0, communicator.getMaximumAllowedRows() + 10,
+ 0, 0);
+ }
}
diff --git a/server/src/test/java/com/vaadin/server/VaadinServiceTest.java b/server/src/test/java/com/vaadin/server/VaadinServiceTest.java
index f10f55db36..f179ad1d58 100644
--- a/server/src/test/java/com/vaadin/server/VaadinServiceTest.java
+++ b/server/src/test/java/com/vaadin/server/VaadinServiceTest.java
@@ -8,8 +8,11 @@ import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSessionBindingEvent;
+import java.util.Collections;
+
import org.easymock.EasyMock;
import org.junit.Test;
+import org.mockito.Mockito;
import com.vaadin.shared.Registration;
import com.vaadin.util.CurrentInstance;
@@ -179,4 +182,45 @@ public class VaadinServiceTest {
assertEquals(1, listener.callCount);
assertEquals(1, listener2.callCount);
}
+
+ @Test
+ public void reinitializeSession_setVaadinSessionAttriuteWithLock() {
+ VaadinRequest request = Mockito.mock(VaadinRequest.class);
+
+ VaadinSession vaadinSession = Mockito.mock(VaadinSession.class);
+ VaadinSession newVaadinSession = Mockito.mock(VaadinSession.class);
+
+ WrappedSession session = mockSession(request, vaadinSession, "foo");
+
+ Mockito.doAnswer(invocation -> {
+ mockSession(request, newVaadinSession, "bar");
+ return null;
+ }).when(session).invalidate();
+
+ VaadinService.reinitializeSession(request);
+
+ Mockito.verify(vaadinSession, Mockito.times(2)).lock();
+ Mockito.verify(vaadinSession).setAttribute(
+ VaadinService.PRESERVE_UNBOUND_SESSION_ATTRIBUTE, Boolean.TRUE);
+ Mockito.verify(vaadinSession).setAttribute(
+ VaadinService.PRESERVE_UNBOUND_SESSION_ATTRIBUTE, null);
+ Mockito.verify(vaadinSession, Mockito.times(2)).unlock();
+ }
+
+ private WrappedSession mockSession(VaadinRequest request,
+ VaadinSession vaadinSession, String attributeName) {
+ WrappedSession session = Mockito.mock(WrappedSession.class);
+ Mockito.when(request.getWrappedSession()).thenReturn(session);
+
+ Mockito.when(session.getAttributeNames())
+ .thenReturn(Collections.singleton(attributeName));
+
+ Mockito.when(session.getAttribute(attributeName))
+ .thenReturn(vaadinSession);
+
+ VaadinService service = Mockito.mock(VaadinService.class);
+
+ Mockito.when(vaadinSession.getService()).thenReturn(service);
+ return session;
+ }
}
diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java
index 5320959967..f0284b7f28 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java
@@ -827,4 +827,23 @@ public class GridTest {
column.isSortableByUser());
}
+ @Test
+ public void extendGridCustomDataCommunicator() {
+ Grid<String> grid = new MyGrid<>();
+ }
+
+ public class MyDataCommunicator<T> extends DataCommunicator<T> {
+ @Override
+ protected int getMaximumAllowedRows() {
+ return 600;
+ }
+ }
+
+ public class MyGrid<T> extends Grid<T> {
+
+ public MyGrid() {
+ super(new MyDataCommunicator());
+ }
+
+ }
}