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 2018/09/20 16:46:39 UTC

[openmeetings] branch master updated: [OPENMEETINGS-1649] basic securing is implemented

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 718fa9e  [OPENMEETINGS-1649] basic securing is implemented
718fa9e is described below

commit 718fa9e82e21eb9e87e7545e956c9622192ea895
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Thu Sep 20 23:46:24 2018 +0700

    [OPENMEETINGS-1649] basic securing is implemented
---
 .../org/apache/openmeetings/core/remote/KRoom.java |  4 +
 .../openmeetings/core/remote/KurentoHandler.java   | 91 +++++++++++++++++++---
 .../org/apache/openmeetings/web/room/raw-video.js  |  2 +-
 .../webapp/WEB-INF/classes/applicationContext.xml  |  2 +-
 openmeetings-web/src/main/webapp/css/raw-room.css  |  2 +-
 5 files changed, 88 insertions(+), 13 deletions(-)

diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java
index c3a43cd..f06e141 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java
@@ -56,6 +56,10 @@ public class KRoom implements Closeable {
 		return roomId;
 	}
 
+	public String getPipelineId() {
+		return pipeline.getId();
+	}
+
 	public KRoom(Long roomId, MediaPipeline pipeline) {
 		this.roomId = roomId;
 		this.pipeline = pipeline;
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java
index a19a27d..627977a 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java
@@ -19,8 +19,13 @@
  */
 package org.apache.openmeetings.core.remote;
 
+import java.util.HashMap;
 import java.util.Map;
+import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.entity.basic.Client;
@@ -34,7 +39,10 @@ import org.apache.openmeetings.db.util.ws.TextRoomMessage;
 import org.kurento.client.EventListener;
 import org.kurento.client.IceCandidate;
 import org.kurento.client.KurentoClient;
+import org.kurento.client.MediaPipeline;
 import org.kurento.client.ObjectCreatedEvent;
+import org.kurento.client.Tag;
+import org.kurento.client.WebRtcEndpoint;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -43,9 +51,15 @@ import com.github.openjson.JSONObject;
 
 public class KurentoHandler {
 	private final static Logger log = LoggerFactory.getLogger(KurentoHandler.class);
+	private final static String MODE_TEST = "test";
+	private final static String TAG_KUID = "kuid";
+	private final static String TAG_MODE = "mode";
+	private final static String TAG_ROOM = "roomId";
 	public final static String KURENTO_TYPE = "kurento";
 	private String kurentoWsUrl;
 	private KurentoClient client;
+	private String kuid;
+	private ScheduledExecutorService scheduler;
 	private final Map<Long, KRoom> rooms = new ConcurrentHashMap<>();
 	final Map<String, KStream> usersByUid = new ConcurrentHashMap<>();
 	final Map<String, KTestStream> testsByUid = new ConcurrentHashMap<>();
@@ -64,9 +78,48 @@ public class KurentoHandler {
 			client.getServerManager().addObjectCreatedListener(new EventListener<ObjectCreatedEvent>() {
 				@Override
 				public void onEvent(ObjectCreatedEvent evt) {
-					log.warn("Kurento::ObjectCreated -> {}", evt);
+					log.debug("Kurento::ObjectCreated -> {}", evt.getObject());
+					if (evt.getObject() instanceof MediaPipeline) {
+						// room created
+						final String roid = evt.getObject().getId();
+						scheduler.schedule(() -> {
+							if (client != null) { // still alive
+								MediaPipeline pipe = client.getById(roid, MediaPipeline.class);
+								try {
+									Map<String, String> tags = tagsAsMap(pipe);
+									if (kuid.equals(tags.get(TAG_KUID))) {
+										if (MODE_TEST.equals(tags.get(TAG_MODE)) && MODE_TEST.equals(tags.get(TAG_MODE))) {
+											return;
+										}
+										KRoom r = rooms.get(Long.valueOf(tags.get(TAG_ROOM)));
+										if (r.getPipelineId().equals(pipe.getId())) {
+											return;
+										} else if (r != null) {
+											rooms.remove(r.getRoomId());
+											r.close();
+										}
+									}
+								} catch(Exception e) {
+									//no-op, connect will be dropped
+								}
+								log.warn("Invalid MediaPipeline {} detected, will be dropped", pipe.getId());
+								pipe.release();
+							}
+						}, 2, TimeUnit.SECONDS);
+					} else if (evt.getObject() instanceof WebRtcEndpoint) { //FIXME TODO RecordingEndpoint
+						// endpoint created
+						final String eoid = evt.getObject().getId();
+						scheduler.schedule(() -> {
+							if (client != null) { // still alive
+								WebRtcEndpoint point = client.getById(eoid, WebRtcEndpoint.class);
+								//point.release();
+							}
+						}, 2, TimeUnit.SECONDS);
+					}
 				}
 			});
+			kuid = UUID.randomUUID().toString(); //FIXME TODO regenerate on re-connect
+			scheduler = Executors.newScheduledThreadPool(10);
 		} catch (Exception e) {
 			log.error("Fail to create Kurento client", e);
 		}
@@ -78,19 +131,35 @@ public class KurentoHandler {
 		}
 	}
 
+	private static Map<String, String> tagsAsMap(MediaPipeline pipe) {
+		Map<String, String> map = new HashMap<>();
+		for (Tag t : pipe.getTags()) {
+			map.put(t.getKey(), t.getValue());
+		}
+		return map;
+	}
+
+	private MediaPipeline createTestPipeline() {
+		MediaPipeline pipe = client.createMediaPipeline();
+		pipe.addTag(TAG_KUID, kuid);
+		pipe.addTag(TAG_MODE, MODE_TEST);
+		pipe.addTag(TAG_ROOM, MODE_TEST);
+		return pipe;
+	}
+
 	public void onMessage(IWsClient _c, JSONObject msg) {
 		if (client == null) {
 			sendError(_c, "Multimedia server is inaccessible");
 			return;
 		}
 		final String cmdId = msg.getString("id");
-		if ("test".equals(msg.optString("mode"))) {
+		if (MODE_TEST.equals(msg.optString(TAG_MODE))) {
 			KTestStream user = getTestByUid(_c.getUid());
 			switch (cmdId) {
 				case "start":
 				{
 					//TODO FIXME assert null user ???
-					user = new KTestStream(_c, msg, client.createMediaPipeline());
+					user = new KTestStream(_c, msg, createTestPipeline());
 					testsByUid.put(_c.getUid(), user);
 				}
 					break;
@@ -106,17 +175,16 @@ public class KurentoHandler {
 				}
 					break;
 				case "play":
-					user.play(_c, msg, client.createMediaPipeline());
+					user.play(_c, msg, createTestPipeline());
 					break;
 			}
 		} else {
 			final Client c = (Client)_c;
 
-			if (c != null) {
-				log.debug("Incoming message from user with ID '{}': {}", c.getUserId(), msg);
-			} else {
-				log.debug("Incoming message from new user: {}", msg);
+			if (c == null) {
+				log.warn("Incoming message from invalid user");
 			}
+			log.debug("Incoming message from user with ID '{}': {}", c.getUserId(), msg);
 			KStream user = getByUid(_c.getUid());
 			switch (cmdId) {
 				case "toggleActivity":
@@ -241,7 +309,10 @@ public class KurentoHandler {
 
 		if (room == null) {
 			log.debug("Room {} does not exist. Will create now!", roomId);
-			room = new KRoom(roomId, client.createMediaPipeline());
+			MediaPipeline pipe = client.createMediaPipeline();
+			pipe.addTag(TAG_KUID, kuid);
+			pipe.addTag(TAG_ROOM, String.valueOf(roomId));
+			room = new KRoom(roomId, pipe);
 			rooms.put(roomId, room);
 		}
 		log.debug("Room {} found!", roomId);
@@ -273,7 +344,7 @@ public class KurentoHandler {
 	}
 
 	static JSONObject newTestKurentoMsg() {
-		return newKurentoMsg().put("mode", "test");
+		return newKurentoMsg().put(TAG_MODE, MODE_TEST);
 	}
 
 	public static boolean activityAllowed(Client c, Client.Activity a, Room room) {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video.js
index 53f8282..6f590d4 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-video.js
@@ -100,7 +100,7 @@ var Video = (function() {
 			contSel = '.room.box';
 		}
 		$(contSel).append(OmUtil.tmpl('#user-video', _id).attr('title', name)
-				.attr('data-client-uid', c.type + c.cuid).data(self));
+				.attr('data-client-uid', c.type + c.cuid).data(self)); //FIXME TODO c.type === 'undefined'
 		return contSel;
 	}
 	function _initDialog(v, opts) {
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
index 90cee61..2248d18 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
@@ -140,6 +140,6 @@
 
 	<!-- Kurento -->
 	<bean id="kurentoHandler" class="org.apache.openmeetings.core.remote.KurentoHandler" init-method="init" destroy-method="destroy">
-		<property name="kurentoWsUrl" value="ws://192.168.15.177:8888/kurento"/>
+		<property name="kurentoWsUrl" value="wss://192.168.15.177:8883/kurento"/>
 	</bean>
 </beans>
diff --git a/openmeetings-web/src/main/webapp/css/raw-room.css b/openmeetings-web/src/main/webapp/css/raw-room.css
index 469a7ec..bf72e99 100644
--- a/openmeetings-web/src/main/webapp/css/raw-room.css
+++ b/openmeetings-web/src/main/webapp/css/raw-room.css
@@ -294,7 +294,7 @@ ul.settings-menu {
 }
 .ui-dialog.video .sett-container {
 	position: relative;
-	min-height: 200px;
+	min-height: 250px;
 }
 .ui-dialog.video .sett-row {
 	padding-top: 10px;