You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2026/09/17 01:30:30 UTC

(openmeetings) branch master updated: [OPENMEETINGS-2841] more checks for WB createObj/modifyObj are added

This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openmeetings.git


The following commit(s) were added to refs/heads/master by this push:
     new c4c926e7a [OPENMEETINGS-2841] more checks for WB createObj/modifyObj are added
c4c926e7a is described below

commit c4c926e7afa9aa73a55ca53c8c6e5679213d3ac1
Author: Maxim Solodovnik <so...@apache.org>
AuthorDate: Thu Sep 17 08:30:20 2026 +0700

    [OPENMEETINGS-2841] more checks for WB createObj/modifyObj are added
---
 .../openmeetings/db/dto/room/Whiteboard.java       |  1 +
 .../openmeetings/db/entity/basic/Client.java       |  6 ++-
 ...skSipUserTest.java => TestAsteriskSipUser.java} |  2 +-
 .../file/{FileItemTest.java => TestFileItem.java}  |  2 +-
 openmeetings-web/src/main/front/src/css/_room.scss |  5 +-
 .../src/main/front/src/wb/wb-tool-clipart.js       |  4 +-
 openmeetings-web/src/main/front/src/wb/wb.js       | 10 ++--
 .../apache/openmeetings/web/room/wb/WbPanel.java   | 55 ++++++++++++++++++++--
 8 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
index 769a237bf..6b16931b9 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
@@ -50,6 +50,7 @@ public class Whiteboard implements Serializable {
 	public static final String ATTR_OMTYPE = "omType";
 	public static final String ATTR_FILE_ID = "fileId";
 	public static final String ATTR_FILE_TYPE = "fileType";
+	public static final String ATTR_COUNT = "count";
 	public static final String ATTR_SLIDE = "slide";
 	public static final String ATTR_WIDTH = "width";
 	public static final String ATTR_HEIGHT = "height";
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
index 58cd9af06..65e0c6202 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
@@ -47,7 +47,6 @@ import com.github.openjson.JSONObject;
 public class Client implements IDataProviderEntity, IWsClient {
 	private static final long serialVersionUID = 1L;
 
-
 	public enum Activity {
 		AUDIO //sends Audio to the room
 		, VIDEO //sends Video to the room
@@ -55,10 +54,12 @@ public class Client implements IDataProviderEntity, IWsClient {
 		, SCREEN //screen is shared
 		, RECORD //record in non-interview room
 	}
+
 	public enum StreamType {
 		WEBCAM //sends Audio/Video to the room
 		, SCREEN //send screen sharing
 	}
+
 	private final String sessionId;
 	private final int pageId;
 	private User user;
@@ -111,7 +112,8 @@ public class Client implements IDataProviderEntity, IWsClient {
 	}
 
 	public boolean sameUserId(Long userId) {
-		return getUserId() != null && getUserId().equals(userId);
+		Long id = getUserId();
+		return id != null && id.equals(userId);
 	}
 
 	public String getPictureUri() {
diff --git a/openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/AsteriskSipUserTest.java b/openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/TestAsteriskSipUser.java
similarity index 98%
rename from openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/AsteriskSipUserTest.java
rename to openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/TestAsteriskSipUser.java
index 506836a40..cf03bfac3 100644
--- a/openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/AsteriskSipUserTest.java
+++ b/openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/TestAsteriskSipUser.java
@@ -24,7 +24,7 @@ import static org.apache.openmeetings.util.ImportHelper.getPrivateValue;
 import org.apache.openmeetings.db.entity.user.AsteriskSipUser;
 import org.junit.jupiter.api.Test;
 
-class AsteriskSipUserTest {
+class TestAsteriskSipUser {
 	@Test
 	void testGetFileShouldReturnFirstSlideWithPDF() throws Exception {
 		AsteriskSipUser u = new AsteriskSipUser();
diff --git a/openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/FileItemTest.java b/openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/TestFileItem.java
similarity index 99%
rename from openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/FileItemTest.java
rename to openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/TestFileItem.java
index cdfb6b99e..5fdd1a94d 100644
--- a/openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/FileItemTest.java
+++ b/openmeetings-db/src/test/java/org/apache/openmeetings/db/entity/file/TestFileItem.java
@@ -32,7 +32,7 @@ import org.mockito.MockedStatic;
 import org.mockito.junit.jupiter.MockitoExtension;
 
 @ExtendWith(MockitoExtension.class)
-class FileItemTest {
+class TestFileItem {
 	private FileItem fileItem;
 
 	@BeforeEach
diff --git a/openmeetings-web/src/main/front/src/css/_room.scss b/openmeetings-web/src/main/front/src/css/_room.scss
index eee6fc56b..333546dfd 100644
--- a/openmeetings-web/src/main/front/src/css/_room.scss
+++ b/openmeetings-web/src/main/front/src/css/_room.scss
@@ -220,6 +220,7 @@
 	}
 }
 .user-list {
+	--user-pic-size: 80px;
 	overflow-y: auto;
 	overflow-x: hidden;
 	height: calc(100% - var(--room-sidebar-header-height) - var(--buffer-size));
@@ -228,7 +229,7 @@
 		line-height: 18px;
 		height: 18px;
 		padding: 0;
-		padding-inline-start: 64px;
+		padding-inline-start: var(--user-pic-size);
 		margin-inline-end: 20px;
 		overflow: hidden;
 	}
@@ -236,7 +237,7 @@
 		min-height: 90px;
 		padding-inline-start: 5px;
 		padding-top: 5px;
-		background-size: 80px;
+		background-size: var(--user-pic-size);
 		background-repeat: no-repeat;
 		background-position: var(--background-start) 2px;
 		position: relative;
diff --git a/openmeetings-web/src/main/front/src/wb/wb-tool-clipart.js b/openmeetings-web/src/main/front/src/wb/wb-tool-clipart.js
index fb906544c..ed88f4d45 100644
--- a/openmeetings-web/src/main/front/src/wb/wb-tool-clipart.js
+++ b/openmeetings-web/src/main/front/src/wb/wb-tool-clipart.js
@@ -14,8 +14,8 @@ export class Clipart extends WbShape {
 				, opts = {
 					left: self.orig.x
 					, top: self.orig.y
-					, scaleX: 0.
-					, scaleY: 0.
+					, scaleX: 1.
+					, scaleY: 1.
 					, omType: 'Clipart'
 					, _src: imgSrc
 					, opacity: self.opacity
diff --git a/openmeetings-web/src/main/front/src/wb/wb.js b/openmeetings-web/src/main/front/src/wb/wb.js
index b6d23ef79..948f46c0e 100644
--- a/openmeetings-web/src/main/front/src/wb/wb.js
+++ b/openmeetings-web/src/main/front/src/wb/wb.js
@@ -164,16 +164,16 @@ export class Wb {
 				}});
 			}
 			o.includeDefaultValues = false;
-			if ('activeSelection' === o.type) {
-				o.clone(function(_o) {
+			if ('activeselection' === o.type) {
+				o.clone(extraProps).then((cloned) => {
 					// ungrouping
-					_o.includeDefaultValues = false;
-					const _items = _o.destroy().getObjects();
+					cloned.includeDefaultValues = false;
+					const _items = cloned.removeAll();
 					for (let i = 0; i < _items.length; ++i) {
 						items.push(self._toOmJson(_items[i]));
 					}
 					modifiedAction(items);
-				}, extraProps);
+				});
 			} else {
 				items.push(self._toOmJson(o));
 				modifiedAction(items);
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
index 0aaf145e7..f6e1cc144 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
@@ -19,6 +19,7 @@
 package org.apache.openmeetings.web.room.wb;
 
 import static java.util.UUID.randomUUID;
+import static org.apache.openmeetings.db.dto.room.Whiteboard.ATTR_COUNT;
 import static org.apache.openmeetings.db.dto.room.Whiteboard.ATTR_FILE_ID;
 import static org.apache.openmeetings.db.dto.room.Whiteboard.ATTR_FILE_TYPE;
 import static org.apache.openmeetings.db.dto.room.Whiteboard.ATTR_HEIGHT;
@@ -31,12 +32,15 @@ import static org.apache.openmeetings.db.dto.room.Whiteboard.ITEMS_KEY;
 import static org.apache.openmeetings.web.room.wb.WbWebSocketHelper.getObjWbJson;
 import static org.apache.openmeetings.web.room.wb.WbWebSocketHelper.getWbJson;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.ATTR_CLASS;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.PARAM_SRC;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.PARAM_SRC_UND;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.PARAM_STATUS;
 import static org.apache.wicket.AttributeModifier.append;
 
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
+import java.net.URI;
 import java.nio.file.Files;
 import java.util.Deque;
 import java.util.HashMap;
@@ -311,12 +315,39 @@ public class WbPanel extends AbstractWbPanel {
 		}
 	}
 
+	private static boolean validClipartSrc(String src) {
+		if (src == null) {
+			return false;
+		}
+		URI uri = URI.create(src).normalize();
+		return uri.getScheme() == null && uri.getPath().startsWith("public/cliparts/");
+	}
+
+	private static boolean validCreateObj(JSONObject o) {
+		if (o.has(ATTR_FILE_ID) || o.has(ATTR_FILE_TYPE)) {
+			return false;
+		}
+		if ("image".equalsIgnoreCase(o.getString(ATTR_TYPE))) {
+			String src = o.optString(PARAM_SRC);
+			String _src = o.optString(PARAM_SRC_UND);
+			if (!validClipartSrc(src) || !validClipartSrc(_src)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
 	private void doActionWhiteboard(Client c, WbAction a, JSONObject obj, boolean redo, IPartialPageRequestHandler handler) throws IOException {
 		switch (a) {
 			case CREATE_OBJ:
 			{
 				Whiteboard wb = wbm.get(roomId).get(obj.getLong("wbId"));
 				JSONObject o = obj.getJSONObject("obj");
+				if (!validCreateObj(o)) {
+					// unexpected, warn and no-op
+					log.warn("Got CREATE_OBJ message with file, ignoring");
+					return;
+				}
 				wb.put(o.getString("uid"), o);
 				wbm.update(roomId, wb);
 				addUndo(wb.getId(), new UndoObject(a, obj, UndoObject.Type.ADD, o));
@@ -333,14 +364,28 @@ public class WbPanel extends AbstractWbPanel {
 				Whiteboard wb = wbm.get(roomId).get(obj.getLong("wbId"));
 				JSONArray arr = obj.getJSONArray("obj");
 				JSONArray undo = new JSONArray();
-				for (int i = 0; i < arr.length(); ++i) {
+				// reverse order to be able to remove
+				for (int i = arr.length() - 1; i > -1; --i) {
 					JSONObject oi = arr.getJSONObject(i);
 					String uid = oi.getString("uid");
 					JSONObject po = wb.get(uid);
-					if (po != null) {
-						undo.put(po);
-						wb.put(uid, oi);
+					if (po == null || BaseFileItem.Type.PRESENTATION.name().equals(po.optString(ATTR_FILE_TYPE))) {
+						// update of non-existing or inapropriate object
+						arr.remove(i);
+						continue;
+					}
+					// restore immutable props
+					oi.put(ATTR_TYPE, po.getString(ATTR_TYPE));
+					if (po.has(ATTR_FILE_ID) || po.has(ATTR_FILE_TYPE)) {
+						oi.put(ATTR_FILE_ID, po.getLong(ATTR_FILE_ID));
+						oi.put(ATTR_FILE_TYPE, po.getString(ATTR_FILE_TYPE));
+						oi.put(ATTR_COUNT, po.getInt(ATTR_COUNT));
+					}
+					if (po.has(ATTR_OMTYPE)) {
+						oi.put(ATTR_OMTYPE, po.getString(ATTR_OMTYPE));
 					}
+					undo.put(po);
+					wb.put(uid, oi);
 				}
 				if (arr.length() != 0) {
 					wbm.update(roomId, wb);
@@ -562,7 +607,7 @@ public class WbPanel extends AbstractWbPanel {
 				JSONObject file = new JSONObject()
 						.put(ATTR_FILE_ID, fi.getId())
 						.put(ATTR_FILE_TYPE, fi.getType().name())
-						.put("count", fi.getCount())
+						.put(ATTR_COUNT, fi.getCount())
 						.put(ATTR_TYPE, "image")
 						.put("left", UPLOAD_WB_LEFT + width / 2)
 						.put("top", UPLOAD_WB_TOP + height / 2)