From ff05bb190656db480ba1358df56bdac99eddc474 Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Mon, 9 Jul 2018 15:49:27 +0200 Subject: [PATCH] openvidu-server: RPC Session.forceUnpublish and Session.forceDisconnect --- .../server/config/OpenviduConfig.java | 3 + .../server/core/SessionEventsHandler.java | 59 ++++-- .../openvidu/server/core/SessionManager.java | 36 ++-- .../kurento/core/KurentoSessionManager.java | 49 ++--- .../server/rest/SessionRestController.java | 9 +- .../io/openvidu/server/rpc/RpcHandler.java | 184 +++++++++++++----- 6 files changed, 227 insertions(+), 113 deletions(-) diff --git a/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java b/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java index b52e361a..80abae51 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java +++ b/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java @@ -175,6 +175,9 @@ public class OpenviduConfig { case "none": roles = new ParticipantRole[0]; break; + case "moderator": + roles = new ParticipantRole[] { ParticipantRole.MODERATOR }; + break; case "publisher_moderator": roles = new ParticipantRole[] { ParticipantRole.PUBLISHER, ParticipantRole.MODERATOR }; break; diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java b/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java index 656f422d..a15d10ff 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java @@ -214,16 +214,18 @@ public class SessionEventsHandler { } } - public void onUnpublishMedia(Participant participant, Set participants, Integer transactionId, - OpenViduException error, String reason) { - boolean force = reason.contains("force") || transactionId == null; - if (!force) { + public void onUnpublishMedia(Participant participant, Set participants, Participant moderator, + Integer transactionId, OpenViduException error, String reason) { + boolean isRpcFromModerator = transactionId != null && moderator != null; + boolean isRpcFromOwner = transactionId != null && moderator == null; + + if (isRpcFromModerator) { if (error != null) { - rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, + rpcNotificationService.sendErrorResponse(moderator.getParticipantPrivateId(), transactionId, null, error); return; } - rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, new JsonObject()); + rpcNotificationService.sendResponse(moderator.getParticipantPrivateId(), transactionId, new JsonObject()); } JsonObject params = new JsonObject(); @@ -232,21 +234,28 @@ public class SessionEventsHandler { for (Participant p : participants) { if (p.getParticipantPrivateId().equals(participant.getParticipantPrivateId())) { - if (force) { + if (!isRpcFromOwner) { rpcNotificationService.sendNotification(p.getParticipantPrivateId(), ProtocolElements.PARTICIPANTUNPUBLISHED_METHOD, params); } else { - continue; + if (error != null) { + rpcNotificationService.sendErrorResponse(p.getParticipantPrivateId(), transactionId, null, + error); + return; + } + rpcNotificationService.sendResponse(p.getParticipantPrivateId(), transactionId, new JsonObject()); } } else { - rpcNotificationService.sendNotification(p.getParticipantPrivateId(), - ProtocolElements.PARTICIPANTUNPUBLISHED_METHOD, params); + if (error == null) { + rpcNotificationService.sendNotification(p.getParticipantPrivateId(), + ProtocolElements.PARTICIPANTUNPUBLISHED_METHOD, params); + } } } } - public void onSubscribe(Participant participant, Session session, String senderName, String sdpAnswer, - Integer transactionId, OpenViduException error) { + public void onSubscribe(Participant participant, Session session, String sdpAnswer, Integer transactionId, + OpenViduException error) { if (error != null) { rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error); return; @@ -269,8 +278,7 @@ public class SessionEventsHandler { } } - public void onUnsubscribe(Participant participant, String senderName, Integer transactionId, - OpenViduException error) { + public void onUnsubscribe(Participant participant, Integer transactionId, OpenViduException error) { if (error != null) { rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error); return; @@ -358,13 +366,30 @@ public class SessionEventsHandler { rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, new JsonObject()); } - public void onParticipantEvicted(Participant participant, String reason) { + public void onForceDisconnect(Participant moderator, Participant evictedParticipant, Set participants, + Integer transactionId, OpenViduException error, String reason) { + + boolean isRpcCall = transactionId != null; + if (isRpcCall) { + if (error != null) { + rpcNotificationService.sendErrorResponse(moderator.getParticipantPrivateId(), transactionId, null, + error); + return; + } + rpcNotificationService.sendResponse(moderator.getParticipantPrivateId(), transactionId, new JsonObject()); + } + JsonObject params = new JsonObject(); params.addProperty(ProtocolElements.PARTICIPANTEVICTED_CONNECTIONID_PARAM, - participant.getParticipantPublicId()); + evictedParticipant.getParticipantPublicId()); params.addProperty(ProtocolElements.PARTICIPANTEVICTED_REASON_PARAM, reason); - rpcNotificationService.sendNotification(participant.getParticipantPrivateId(), + + rpcNotificationService.sendNotification(evictedParticipant.getParticipantPrivateId(), ProtocolElements.PARTICIPANTEVICTED_METHOD, params); + for (Participant p : participants) { + rpcNotificationService.sendNotification(p.getParticipantPrivateId(), + ProtocolElements.PARTICIPANTEVICTED_METHOD, params); + } } public void sendRecordingStartedNotification(Session session, Recording recording) { diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java b/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java index fa90596b..224837f7 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java @@ -22,7 +22,6 @@ import java.util.HashSet; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.stream.Collectors; import javax.annotation.PreDestroy; @@ -80,7 +79,7 @@ public abstract class SessionManager { public abstract void publishVideo(Participant participant, MediaOptions mediaOptions, Integer transactionId); - public abstract void unpublishVideo(Participant participant, Integer transactionId, String reason); + public abstract void unpublishVideo(Participant participant, Participant moderator, Integer transactionId, String reason); public abstract void subscribe(Participant participant, String senderName, String sdpOffer, Integer transactionId); @@ -94,17 +93,10 @@ public abstract class SessionManager { public abstract void onIceCandidate(Participant participant, String endpointName, String candidate, int sdpMLineIndex, String sdpMid, Integer transactionId); - public abstract boolean unpublishStream(Session session, String streamId, String reason); + public abstract boolean unpublishStream(Session session, String streamId, Participant moderator, Integer transactionId, String reason); - /** - * Application-originated request to remove a participant from a session.
- * Side effects: The session event handler should notify the - * participant that she has been evicted. Should also send notifications to all - * other participants about the one that's just been evicted. - * - */ - public void evictParticipant(String participantPrivateId, String reason) throws OpenViduException { - } + public abstract void evictParticipant(Participant evictedParticipant, Participant moderator, Integer transactionId, + String reason); /** * Returns a Session given its id @@ -287,6 +279,18 @@ public abstract class SessionManager { } } + public boolean isModeratorInSession(String sessionId, Participant participant) { + if (!this.isInsecureParticipant(participant.getParticipantPrivateId())) { + if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) { + return ParticipantRole.MODERATOR.equals(participant.getToken().getRole()); + } else { + return false; + } + } else { + return true; + } + } + public boolean isInsecureParticipant(String participantPrivateId) { if (this.insecureUsers.containsKey(participantPrivateId)) { log.info("The user with private id {} is an INSECURE user", participantPrivateId); @@ -409,13 +413,11 @@ public abstract class SessionManager { throw new OpenViduException(Code.ROOM_CLOSED_ERROR_CODE, "Session '" + sessionId + "' already closed"); } Set participants = getParticipants(sessionId); - // copy the ids as they will be removed from the map - Set pids = participants.stream().map(Participant::getParticipantPrivateId).collect(Collectors.toSet()); - for (String pid : pids) { + for (Participant p : participants) { try { - this.evictParticipant(pid, reason); + this.evictParticipant(p, null, null, reason); } catch (OpenViduException e) { - log.warn("Error evicting participant with id '{}' from session '{}'", pid, sessionId, e); + log.warn("Error evicting participant '{}' from session '{}'", p.getParticipantPublicId(), sessionId, e); } } diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java index 6d4235f1..1a38d8d0 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java @@ -172,8 +172,8 @@ public class KurentoSessionManager extends SessionManager { log.info("Last participant left. Stopping recording for session {}", sessionId); recordingService.stopRecording(session); - evictParticipant(session.getParticipantByPublicId(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID) - .getParticipantPrivateId(), "EVICT_RECORDER"); + evictParticipant(session.getParticipantByPublicId(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID), null, + null, "EVICT_RECORDER"); } // Finally close websocket session if required @@ -268,7 +268,7 @@ public class KurentoSessionManager extends SessionManager { } @Override - public void unpublishVideo(Participant participant, Integer transactionId, String reason) { + public void unpublishVideo(Participant participant, Participant moderator, Integer transactionId, String reason) { try { KurentoParticipant kParticipant = (KurentoParticipant) participant; KurentoSession session = kParticipant.getSession(); @@ -283,11 +283,11 @@ public class KurentoSessionManager extends SessionManager { Set participants = session.getParticipants(); - sessionEventsHandler.onUnpublishMedia(participant, participants, transactionId, null, reason); + sessionEventsHandler.onUnpublishMedia(participant, participants, moderator, transactionId, null, reason); } catch (OpenViduException e) { log.warn("PARTICIPANT {}: Error unpublishing media", participant.getParticipantPublicId(), e); - sessionEventsHandler.onUnpublishMedia(participant, null, transactionId, e, ""); + sessionEventsHandler.onUnpublishMedia(participant, null, moderator, transactionId, e, ""); } } @@ -328,10 +328,10 @@ public class KurentoSessionManager extends SessionManager { } } catch (OpenViduException e) { log.error("PARTICIPANT {}: Error subscribing to {}", participant.getParticipantPublicId(), senderName, e); - sessionEventsHandler.onSubscribe(participant, session, senderName, null, transactionId, e); + sessionEventsHandler.onSubscribe(participant, session, null, transactionId, e); } if (sdpAnswer != null) { - sessionEventsHandler.onSubscribe(participant, session, senderName, sdpAnswer, transactionId, null); + sessionEventsHandler.onSubscribe(participant, session, sdpAnswer, transactionId, null); } } @@ -354,7 +354,7 @@ public class KurentoSessionManager extends SessionManager { kParticipant.cancelReceivingMedia(senderName, "unsubscribe"); - sessionEventsHandler.onUnsubscribe(participant, senderName, transactionId, null); + sessionEventsHandler.onUnsubscribe(participant, transactionId, null); } @Override @@ -457,19 +457,24 @@ public class KurentoSessionManager extends SessionManager { sessionEventsHandler.onSessionCreated(sessionId); } - /** - * Application-originated request to remove a participant from a session.
- * Side effects: The session event handler should notify the - * participant that she has been evicted. Should also send notifications to all - * other participants about the one that's just been evicted. - * - */ @Override - public void evictParticipant(String participantPrivateId, String reason) throws OpenViduException { - Participant participant = this.getParticipant(participantPrivateId); - this.leaveRoom(participant, null, reason, false); - sessionEventsHandler.onParticipantEvicted(participant, reason); - sessionEventsHandler.closeRpcSession(participantPrivateId); + public void evictParticipant(Participant evictedParticipant, Participant moderator, Integer transactionId, + String reason) throws OpenViduException { + if (evictedParticipant != null) { + KurentoParticipant kParticipant = (KurentoParticipant) evictedParticipant; + Set participants = kParticipant.getSession().getParticipants(); + this.leaveRoom(kParticipant, null, reason, false); + this.sessionEventsHandler.onForceDisconnect(moderator, evictedParticipant, participants, transactionId, + null, reason); + sessionEventsHandler.closeRpcSession(evictedParticipant.getParticipantPrivateId()); + } else { + if (moderator != null && transactionId != null) { + this.sessionEventsHandler.onForceDisconnect(moderator, evictedParticipant, null, transactionId, + new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE, + "Connection not found when calling 'forceDisconnect'"), + ""); + } + } } @Override @@ -511,12 +516,12 @@ public class KurentoSessionManager extends SessionManager { } @Override - public boolean unpublishStream(Session session, String streamId, String reason) { + public boolean unpublishStream(Session session, String streamId, Participant moderator, Integer transactionId, String reason) { String participantPrivateId = ((KurentoSession) session).getParticipantPrivateIdFromStreamId(streamId); if (participantPrivateId != null) { Participant participant = this.getParticipant(participantPrivateId); if (participant != null) { - this.unpublishVideo(participant, null, reason); + this.unpublishVideo(participant, moderator, transactionId, reason); return true; } else { return false; diff --git a/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java b/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java index c126dd2a..49b5af8c 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java +++ b/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java @@ -185,7 +185,7 @@ public class SessionRestController { if (session != null) { Participant participant = session.getParticipantByPublicId(participantPublicId); if (participant != null) { - this.sessionManager.evictParticipant(participant.getParticipantPrivateId(), "forceDisconnectByServer"); + this.sessionManager.evictParticipant(participant, null, null, "forceDisconnectByServer"); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } else { return new ResponseEntity<>(HttpStatus.NOT_FOUND); @@ -200,7 +200,7 @@ public class SessionRestController { @PathVariable("streamId") String streamId) { Session session = this.sessionManager.getSession(sessionId); if (session != null) { - if (this.sessionManager.unpublishStream(session, streamId, "forceUnpublishByServer")) { + if (this.sessionManager.unpublishStream(session, streamId, null, null, "forceUnpublishByServer")) { return new ResponseEntity<>(HttpStatus.NO_CONTENT); } else { return new ResponseEntity<>(HttpStatus.NOT_FOUND); @@ -331,8 +331,9 @@ public class SessionRestController { Recording stoppedRecording = this.recordingService.stopRecording(session); - sessionManager.evictParticipant(session.getParticipantByPublicId(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID) - .getParticipantPrivateId(), "EVICT_RECORDER"); + sessionManager.evictParticipant( + session.getParticipantByPublicId(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID), null, null, + "EVICT_RECORDER"); return new ResponseEntity<>(stoppedRecording.toJson(), HttpStatus.OK); } diff --git a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java index 854c5ede..0382dd60 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java +++ b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java @@ -125,6 +125,12 @@ public class RpcHandler extends DefaultJsonRpcHandler { case ProtocolElements.STREAMPROPERTYCHANGED_METHOD: streamPropertyChanged(rpcConnection, request); break; + case ProtocolElements.FORCEDISCONNECT_METHOD: + forceDisconnect(rpcConnection, request); + break; + case ProtocolElements.FORCEUNPUBLISH_METHOD: + forceUnpublish(rpcConnection, request); + break; default: log.error("Unrecognized request {}", request); break; @@ -189,36 +195,27 @@ public class RpcHandler extends DefaultJsonRpcHandler { } private void leaveRoom(RpcConnection rpcConnection, Request request) { - - String participantPrivateId = rpcConnection.getParticipantPrivateId(); - String sessionId = rpcConnection.getSessionId(); - - if (sessionId == null) { // null when afterConnectionClosed - log.warn("No session information found for participant with privateId {}. " - + "Using the admin method to evict the user.", participantPrivateId); - leaveRoomAfterConnClosed(participantPrivateId, ""); - } else { - // Sanity check: don't call leaveRoom unless the id checks out - Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId); - if (participant != null) { - log.info("Participant {} is leaving session {}", participant.getParticipantPublicId(), sessionId); - sessionManager.leaveRoom(participant, request.getId(), "disconnect", true); - log.info("Participant {} has left session {}", participant.getParticipantPublicId(), sessionId); - } else { - log.warn("Participant with private id {} not found in session {}. " - + "Using the admin method to evict the user.", participantPrivateId, sessionId); - leaveRoomAfterConnClosed(participantPrivateId, ""); - } + Participant participant; + try { + participant = sanityCheckOfSession(rpcConnection, "disconnect"); + } catch (OpenViduException e) { + return; } + + sessionManager.leaveRoom(participant, request.getId(), "disconnect", true); + log.info("Participant {} has left session {}", participant.getParticipantPublicId(), + rpcConnection.getSessionId()); } private void publishVideo(RpcConnection rpcConnection, Request request) { + Participant participant; + try { + participant = sanityCheckOfSession(rpcConnection, "publish"); + } catch (OpenViduException e) { + return; + } - String participantPrivateId = rpcConnection.getParticipantPrivateId(); - String sessionId = rpcConnection.getSessionId(); - Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId); - - if (sessionManager.isPublisherInSession(sessionId, participant)) { + if (sessionManager.isPublisherInSession(rpcConnection.getSessionId(), participant)) { MediaOptions options = sessionManager.generateMediaOptions(request); sessionManager.publishVideo(participant, options, request.getId()); } else { @@ -229,10 +226,12 @@ public class RpcHandler extends DefaultJsonRpcHandler { } private void receiveVideoFrom(RpcConnection rpcConnection, Request request) { - - String participantPrivateId = rpcConnection.getParticipantPrivateId(); - String sessionId = rpcConnection.getSessionId(); - Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId); + Participant participant; + try { + participant = sanityCheckOfSession(rpcConnection, "subscribe"); + } catch (OpenViduException e) { + return; + } String senderName = getStringParam(request, ProtocolElements.RECEIVEVIDEO_SENDER_PARAM); senderName = senderName.substring(0, senderName.indexOf("_")); @@ -242,21 +241,24 @@ public class RpcHandler extends DefaultJsonRpcHandler { } private void unsubscribeFromVideo(RpcConnection rpcConnection, Request request) { - - String participantPrivateId = rpcConnection.getParticipantPrivateId(); - String sessionId = rpcConnection.getSessionId(); - Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId); + Participant participant; + try { + participant = sanityCheckOfSession(rpcConnection, "unsubscribe"); + } catch (OpenViduException e) { + return; + } String senderName = getStringParam(request, ProtocolElements.UNSUBSCRIBEFROMVIDEO_SENDER_PARAM); - sessionManager.unsubscribe(participant, senderName, request.getId()); } private void onIceCandidate(RpcConnection rpcConnection, Request request) { - - String participantPrivateId = rpcConnection.getParticipantPrivateId(); - String sessionId = rpcConnection.getSessionId(); - Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId); + Participant participant; + try { + participant = sanityCheckOfSession(rpcConnection, "onIceCandidate"); + } catch (OpenViduException e) { + return; + } String endpointName = getStringParam(request, ProtocolElements.ONICECANDIDATE_EPNAME_PARAM); String candidate = getStringParam(request, ProtocolElements.ONICECANDIDATE_CANDIDATE_PARAM); @@ -267,29 +269,75 @@ public class RpcHandler extends DefaultJsonRpcHandler { } private void sendMessage(RpcConnection rpcConnection, Request request) { - - String participantPrivateId = rpcConnection.getParticipantPrivateId(); - String sessionId = rpcConnection.getSessionId(); - Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId); + Participant participant; + try { + participant = sanityCheckOfSession(rpcConnection, "signal"); + } catch (OpenViduException e) { + return; + } String message = getStringParam(request, ProtocolElements.SENDMESSAGE_MESSAGE_PARAM); - sessionManager.sendMessage(participant, message, request.getId()); } private void unpublishVideo(RpcConnection rpcConnection, Request request) { + Participant participant; + try { + participant = sanityCheckOfSession(rpcConnection, "unpublish"); + } catch (OpenViduException e) { + return; + } - String participantPrivateId = rpcConnection.getParticipantPrivateId(); - String sessionId = rpcConnection.getSessionId(); - Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId); - - sessionManager.unpublishVideo(participant, request.getId(), "unpublish"); + sessionManager.unpublishVideo(participant, null, request.getId(), "unpublish"); } - public void streamPropertyChanged(RpcConnection rpcConnection, Request request) { - String participantPrivateId = rpcConnection.getParticipantPrivateId(); - String sessionId = rpcConnection.getSessionId(); - Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId); + private void forceDisconnect(RpcConnection rpcConnection, Request request) { + Participant participant; + try { + participant = sanityCheckOfSession(rpcConnection, "forceDisconnect"); + } catch (OpenViduException e) { + return; + } + + if (sessionManager.isModeratorInSession(rpcConnection.getSessionId(), participant)) { + String connectionId = getStringParam(request, ProtocolElements.FORCEDISCONNECT_CONNECTIONID_PARAM); + sessionManager.evictParticipant( + sessionManager.getSession(rpcConnection.getSessionId()).getParticipantByPublicId(connectionId), + participant, request.getId(), "forceDisconnectByUser"); + } else { + log.error("Error: participant {} is not a moderator", participant.getParticipantPublicId()); + throw new OpenViduException(Code.USER_UNAUTHORIZED_ERROR_CODE, + "Unable to force disconnect. The user does not have a valid token"); + } + } + + private void forceUnpublish(RpcConnection rpcConnection, Request request) { + Participant participant; + try { + participant = sanityCheckOfSession(rpcConnection, "forceUnpublish"); + } catch (OpenViduException e) { + return; + } + + if (sessionManager.isModeratorInSession(rpcConnection.getSessionId(), participant)) { + String streamId = getStringParam(request, ProtocolElements.FORCEUNPUBLISH_STREAMID_PARAM); + sessionManager.unpublishStream(sessionManager.getSession(rpcConnection.getSessionId()), streamId, + participant, request.getId(), "forceUnpublishByUser"); + } else { + log.error("Error: participant {} is not a moderator", participant.getParticipantPublicId()); + throw new OpenViduException(Code.USER_UNAUTHORIZED_ERROR_CODE, + "Unable to force unpublish. The user does not have a valid token"); + } + + } + + private void streamPropertyChanged(RpcConnection rpcConnection, Request request) { + Participant participant; + try { + participant = sanityCheckOfSession(rpcConnection, "onStreamPropertyChanged"); + } catch (OpenViduException e) { + return; + } String streamId = getStringParam(request, ProtocolElements.STREAMPROPERTYCHANGED_STREAMID_PARAM); String property = getStringParam(request, ProtocolElements.STREAMPROPERTYCHANGED_PROPERTY_PARAM); @@ -301,7 +349,8 @@ public class RpcHandler extends DefaultJsonRpcHandler { public void leaveRoomAfterConnClosed(String participantPrivateId, String reason) { try { - sessionManager.evictParticipant(participantPrivateId, reason); + sessionManager.evictParticipant(this.sessionManager.getParticipant(participantPrivateId), null, null, + reason); log.info("Evicted participant with privateId {}", participantPrivateId); } catch (OpenViduException e) { log.warn("Unable to evict: {}", e.getMessage()); @@ -409,4 +458,33 @@ public class RpcHandler extends DefaultJsonRpcHandler { return request.getParams().get(key); } + private Participant sanityCheckOfSession(RpcConnection rpcConnection, String methodName) throws OpenViduException { + String participantPrivateId = rpcConnection.getParticipantPrivateId(); + String sessionId = rpcConnection.getSessionId(); + String errorMsg; + + if (sessionId == null) { // null when afterConnectionClosed + errorMsg = "No session information found for participant with privateId " + participantPrivateId + + ". Using the admin method to evict the user."; + log.warn(errorMsg); + leaveRoomAfterConnClosed(participantPrivateId, ""); + throw new OpenViduException(Code.GENERIC_ERROR_CODE, errorMsg); + } else { + // Sanity check: don't call RPC method unless the id checks out + Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId); + if (participant != null) { + errorMsg = "Participant " + participant.getParticipantPublicId() + " is calling method '" + methodName + + "' in session " + sessionId; + log.info(errorMsg); + return participant; + } else { + errorMsg = "Participant with private id " + participantPrivateId + " not found in session " + sessionId + + ". Using the admin method to evict the user."; + log.warn(errorMsg); + leaveRoomAfterConnClosed(participantPrivateId, ""); + throw new OpenViduException(Code.GENERIC_ERROR_CODE, errorMsg); + } + } + } + }