mirror of https://github.com/OpenVidu/openvidu.git
OpenVidu security - First version
parent
0e94c71a04
commit
eefef0f89e
|
@ -47,22 +47,28 @@ export class OpenVidu {
|
||||||
return this.session;
|
return this.session;
|
||||||
}
|
}
|
||||||
|
|
||||||
initPublisherTagged(parentId: string, cameraOptions: any) {
|
initPublisherTagged(parentId: string, cameraOptions: any, callback) {
|
||||||
console.log("Publisher tagged initialized!");
|
console.log("Publisher tagged initialized!");
|
||||||
|
|
||||||
let camera = this.getCamera(cameraOptions);
|
this.getCamera(cameraOptions);
|
||||||
camera.requestCameraAccess((error, camera) => {
|
this.camera.requestCameraAccess((error, camera) => {
|
||||||
if (error) return console.log(error);
|
if (error){
|
||||||
camera!.playOnlyVideo(parentId, null);
|
callback(error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.camera.playOnlyVideo(parentId, null);
|
||||||
|
callback(undefined);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initPublisher(cameraOptions: any) {
|
initPublisher(cameraOptions: any, callback) {
|
||||||
console.log("Publisher initialized!");
|
console.log("Publisher initialized!");
|
||||||
|
|
||||||
let camera = this.getCamera(cameraOptions);
|
this.getCamera(cameraOptions);
|
||||||
camera.requestCameraAccess((error, camera) => {
|
this.camera.requestCameraAccess((error, camera) => {
|
||||||
if (error) return console.log(error);
|
if (error) callback(error);
|
||||||
|
else callback(undefined);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +138,7 @@ export class OpenVidu {
|
||||||
if ( error ) {
|
if ( error ) {
|
||||||
this.callback( error );
|
this.callback( error );
|
||||||
} else {
|
} else {
|
||||||
this.callback( null, this );
|
this.callback( null );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +282,7 @@ export class OpenVidu {
|
||||||
|
|
||||||
this.session.configure(options);
|
this.session.configure(options);
|
||||||
|
|
||||||
this.session.connect();
|
this.session.connect2();
|
||||||
|
|
||||||
this.session.addEventListener('room-connected', roomEvent => callback(undefined,this.session));
|
this.session.addEventListener('room-connected', roomEvent => callback(undefined,this.session));
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,7 @@ public class OpenViduException extends RuntimeException {
|
||||||
|
|
||||||
USER_NOT_STREAMING_ERROR_CODE(105), EXISTING_USER_IN_ROOM_ERROR_CODE(
|
USER_NOT_STREAMING_ERROR_CODE(105), EXISTING_USER_IN_ROOM_ERROR_CODE(
|
||||||
104), USER_CLOSED_ERROR_CODE(
|
104), USER_CLOSED_ERROR_CODE(
|
||||||
103), USER_NOT_FOUND_ERROR_CODE(102), USER_GENERIC_ERROR_CODE(101),
|
103), USER_NOT_FOUND_ERROR_CODE(102), USER_GENERIC_ERROR_CODE(101);
|
||||||
|
|
||||||
USER_UNAUTHORIZED(401);
|
|
||||||
|
|
||||||
private int value;
|
private int value;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
package org.openvidu.server.core;
|
package org.openvidu.server.core;
|
||||||
|
|
||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.SecureRandom;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.kurento.client.MediaElement;
|
import org.kurento.client.MediaElement;
|
||||||
|
@ -33,6 +36,7 @@ import org.openvidu.server.core.api.pojo.ParticipantRequest;
|
||||||
import org.openvidu.server.core.api.pojo.UserParticipant;
|
import org.openvidu.server.core.api.pojo.UserParticipant;
|
||||||
import org.openvidu.server.core.internal.DefaultKurentoClientSessionInfo;
|
import org.openvidu.server.core.internal.DefaultKurentoClientSessionInfo;
|
||||||
import org.openvidu.server.core.internal.DefaultNotificationRoomHandler;
|
import org.openvidu.server.core.internal.DefaultNotificationRoomHandler;
|
||||||
|
import org.openvidu.server.security.ParticipantRoles;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -443,4 +447,14 @@ public class NotificationRoomManager {
|
||||||
public void updateFilter(String roomId, String filterId) {
|
public void updateFilter(String roomId, String filterId) {
|
||||||
internalManager.updateFilter(roomId, filterId);
|
internalManager.updateFilter(roomId, filterId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public String newSessionId(){
|
||||||
|
return this.internalManager.newSessionId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String newToken(String sessionId, ParticipantRoles role){
|
||||||
|
return this.internalManager.newToken(sessionId, role);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,16 @@
|
||||||
package org.openvidu.server.core;
|
package org.openvidu.server.core;
|
||||||
|
|
||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.SecureRandom;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
import java.util.concurrent.ConcurrentSkipListSet;
|
||||||
|
|
||||||
import org.kurento.client.IceCandidate;
|
import org.kurento.client.IceCandidate;
|
||||||
import org.kurento.client.KurentoClient;
|
import org.kurento.client.KurentoClient;
|
||||||
|
@ -41,6 +45,7 @@ import org.openvidu.server.core.api.pojo.UserParticipant;
|
||||||
import org.openvidu.server.core.endpoint.SdpType;
|
import org.openvidu.server.core.endpoint.SdpType;
|
||||||
import org.openvidu.server.core.internal.Participant;
|
import org.openvidu.server.core.internal.Participant;
|
||||||
import org.openvidu.server.core.internal.Room;
|
import org.openvidu.server.core.internal.Room;
|
||||||
|
import org.openvidu.server.security.ParticipantRoles;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -62,6 +67,9 @@ public class RoomManager {
|
||||||
|
|
||||||
private final ConcurrentMap<String, Room> rooms = new ConcurrentHashMap<String, Room>();
|
private final ConcurrentMap<String, Room> rooms = new ConcurrentHashMap<String, Room>();
|
||||||
|
|
||||||
|
private final ConcurrentMap<String, ConcurrentHashMap<String, ParticipantRoles>> sessionIdTokenRole = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
private volatile boolean closed = false;
|
private volatile boolean closed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -153,6 +161,9 @@ public class RoomManager {
|
||||||
+ "' but it is closing");
|
+ "' but it is closing");
|
||||||
}
|
}
|
||||||
room.leave(participantId);
|
room.leave(participantId);
|
||||||
|
|
||||||
|
this.sessionIdTokenRole.get(roomName).remove(participantId);
|
||||||
|
|
||||||
Set<UserParticipant> remainingParticipants = null;
|
Set<UserParticipant> remainingParticipants = null;
|
||||||
try {
|
try {
|
||||||
remainingParticipants = getParticipants(roomName);
|
remainingParticipants = getParticipants(roomName);
|
||||||
|
@ -164,6 +175,9 @@ public class RoomManager {
|
||||||
log.debug("No more participants in room '{}', removing it and closing it", roomName);
|
log.debug("No more participants in room '{}', removing it and closing it", roomName);
|
||||||
room.close();
|
room.close();
|
||||||
rooms.remove(roomName);
|
rooms.remove(roomName);
|
||||||
|
|
||||||
|
sessionIdTokenRole.remove(roomName);
|
||||||
|
|
||||||
log.warn("Room '{}' removed and closed", roomName);
|
log.warn("Room '{}' removed and closed", roomName);
|
||||||
}
|
}
|
||||||
return remainingParticipants;
|
return remainingParticipants;
|
||||||
|
@ -830,6 +844,9 @@ public class RoomManager {
|
||||||
}
|
}
|
||||||
room.close();
|
room.close();
|
||||||
rooms.remove(roomName);
|
rooms.remove(roomName);
|
||||||
|
|
||||||
|
sessionIdTokenRole.remove(roomName);
|
||||||
|
|
||||||
log.warn("Room '{}' removed and closed", roomName);
|
log.warn("Room '{}' removed and closed", roomName);
|
||||||
return participants;
|
return participants;
|
||||||
}
|
}
|
||||||
|
@ -906,4 +923,47 @@ public class RoomManager {
|
||||||
|
|
||||||
room.updateFilter(filterId);
|
room.updateFilter(filterId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public String getRoomNameFromParticipantId(String pid){
|
||||||
|
return getParticipant(pid).getRoom().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isParticipantInRoom(String participantName, String roomName) {
|
||||||
|
return this.sessionIdTokenRole.get(roomName).containsKey(participantName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPublisherInRoom(String participantName, String roomName) {
|
||||||
|
return this.sessionIdTokenRole.get(roomName).get(participantName).equals(ParticipantRoles.PUBLISHER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String newSessionId(){
|
||||||
|
String sessionId = new BigInteger(130, new SecureRandom()).toString(32);
|
||||||
|
|
||||||
|
this.sessionIdTokenRole.put(sessionId, new ConcurrentHashMap<>());
|
||||||
|
|
||||||
|
System.out.println(this.sessionIdTokenRole.toString());
|
||||||
|
|
||||||
|
return sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String newToken(String sessionId, ParticipantRoles role){
|
||||||
|
if (this.sessionIdTokenRole.get(sessionId) != null) {
|
||||||
|
String token = new BigInteger(130, new SecureRandom()).toString(32);
|
||||||
|
|
||||||
|
this.sessionIdTokenRole.get(sessionId).put(token, role);
|
||||||
|
|
||||||
|
System.out.println(this.sessionIdTokenRole.toString());
|
||||||
|
|
||||||
|
return token;
|
||||||
|
} else {
|
||||||
|
System.out.println("Error: the sessionId [" + sessionId + "] is not valid");
|
||||||
|
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE,
|
||||||
|
"[" + sessionId +"] is not a valid sessionId");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,15 @@ package org.openvidu.server.rest;
|
||||||
|
|
||||||
import static org.kurento.commons.PropertiesManager.getProperty;
|
import static org.kurento.commons.PropertiesManager.getProperty;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.openvidu.server.core.NotificationRoomManager;
|
import org.openvidu.server.core.NotificationRoomManager;
|
||||||
|
import org.openvidu.server.security.ParticipantRoles;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@ -57,11 +60,14 @@ public class RoomController {
|
||||||
|
|
||||||
@RequestMapping("/getSessionId")
|
@RequestMapping("/getSessionId")
|
||||||
public ResponseEntity<String> getSessionId() {
|
public ResponseEntity<String> getSessionId() {
|
||||||
return new ResponseEntity<String>("SUPER_SESSIONID", HttpStatus.OK);
|
String sessionId = roomManager.newSessionId();
|
||||||
|
return new ResponseEntity<String>(sessionId, HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/getToken")
|
@RequestMapping("/getToken")
|
||||||
public ResponseEntity<String> getToken() {
|
public ResponseEntity<String> getToken(@RequestBody Map sessionIdAndRole) {
|
||||||
return new ResponseEntity<String>("SUPER_TOKEN", HttpStatus.OK);
|
System.out.println("SESSIONID: " + sessionIdAndRole.get("0") + " - ROLE: " + sessionIdAndRole.get("1"));
|
||||||
|
String token = roomManager.newToken((String) sessionIdAndRole.get("0"), ParticipantRoles.valueOf((String) sessionIdAndRole.get("1")));
|
||||||
|
return new ResponseEntity<String>(token, HttpStatus.OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.kurento.jsonrpc.Session;
|
||||||
import org.kurento.jsonrpc.Transaction;
|
import org.kurento.jsonrpc.Transaction;
|
||||||
import org.kurento.jsonrpc.message.Request;
|
import org.kurento.jsonrpc.message.Request;
|
||||||
import org.openvidu.client.OpenViduException;
|
import org.openvidu.client.OpenViduException;
|
||||||
|
import org.openvidu.client.OpenViduException.Code;
|
||||||
import org.openvidu.client.internal.ProtocolElements;
|
import org.openvidu.client.internal.ProtocolElements;
|
||||||
import org.openvidu.server.core.NotificationRoomManager;
|
import org.openvidu.server.core.NotificationRoomManager;
|
||||||
import org.openvidu.server.core.api.pojo.ParticipantRequest;
|
import org.openvidu.server.core.api.pojo.ParticipantRequest;
|
||||||
|
@ -55,6 +56,8 @@ public class JsonRpcUserControl {
|
||||||
String roomName = getStringParam(request, ProtocolElements.JOINROOM_ROOM_PARAM);
|
String roomName = getStringParam(request, ProtocolElements.JOINROOM_ROOM_PARAM);
|
||||||
String userName = getStringParam(request, ProtocolElements.JOINROOM_USER_PARAM);
|
String userName = getStringParam(request, ProtocolElements.JOINROOM_USER_PARAM);
|
||||||
|
|
||||||
|
if(roomManager.getRoomManager().isParticipantInRoom(userName, roomName)){
|
||||||
|
|
||||||
boolean dataChannels = false;
|
boolean dataChannels = false;
|
||||||
if (request.getParams().has(ProtocolElements.JOINROOM_DATACHANNELS_PARAM)) {
|
if (request.getParams().has(ProtocolElements.JOINROOM_DATACHANNELS_PARAM)) {
|
||||||
dataChannels = request.getParams().get(ProtocolElements.JOINROOM_DATACHANNELS_PARAM)
|
dataChannels = request.getParams().get(ProtocolElements.JOINROOM_DATACHANNELS_PARAM)
|
||||||
|
@ -67,15 +70,35 @@ public class JsonRpcUserControl {
|
||||||
participantSession.setDataChannels(dataChannels);
|
participantSession.setDataChannels(dataChannels);
|
||||||
|
|
||||||
roomManager.joinRoom(userName, roomName, dataChannels, true, participantRequest);
|
roomManager.joinRoom(userName, roomName, dataChannels, true, participantRequest);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.out.println("Error: sessionId or token not valid");
|
||||||
|
throw new OpenViduException(Code.GENERIC_ERROR_CODE,
|
||||||
|
"Unable to join room. The user does not have a valid token");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void publishVideo(Transaction transaction, Request<JsonObject> request,
|
public void publishVideo(Transaction transaction, Request<JsonObject> request,
|
||||||
ParticipantRequest participantRequest) {
|
ParticipantRequest participantRequest) {
|
||||||
|
|
||||||
|
String pid = participantRequest.getParticipantId();
|
||||||
|
String participantName = roomManager.getRoomManager().getParticipantName(pid);
|
||||||
|
String roomName = roomManager.getRoomManager().getRoomNameFromParticipantId(pid);
|
||||||
|
|
||||||
|
if (roomManager.getRoomManager().isPublisherInRoom(participantName, roomName)) {
|
||||||
|
|
||||||
String sdpOffer = getStringParam(request, ProtocolElements.PUBLISHVIDEO_SDPOFFER_PARAM);
|
String sdpOffer = getStringParam(request, ProtocolElements.PUBLISHVIDEO_SDPOFFER_PARAM);
|
||||||
boolean doLoopback = getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_DOLOOPBACK_PARAM);
|
boolean doLoopback = getBooleanParam(request, ProtocolElements.PUBLISHVIDEO_DOLOOPBACK_PARAM);
|
||||||
|
|
||||||
roomManager.publishMedia(participantRequest, sdpOffer, doLoopback);
|
roomManager.publishMedia(participantRequest, sdpOffer, doLoopback);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
System.out.println("Error: user is not a publisher");
|
||||||
|
throw new OpenViduException(Code.GENERIC_ERROR_CODE,
|
||||||
|
"Unable to join room. The user does not have a valid token");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void unpublishVideo(Transaction transaction, Request<JsonObject> request,
|
public void unpublishVideo(Transaction transaction, Request<JsonObject> request,
|
||||||
ParticipantRequest participantRequest) {
|
ParticipantRequest participantRequest) {
|
||||||
|
@ -186,6 +209,7 @@ public class JsonRpcUserControl {
|
||||||
if (request.getParams() == null || request.getParams().get(key) == null) {
|
if (request.getParams() == null || request.getParams().get(key) == null) {
|
||||||
throw new RuntimeException("Request element '" + key + "' is missing");
|
throw new RuntimeException("Request element '" + key + "' is missing");
|
||||||
}
|
}
|
||||||
|
System.out.println(request.getParams().get(key));
|
||||||
return request.getParams().get(key).getAsString();
|
return request.getParams().get(key).getAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class ParticipantSecurity extends Participant{
|
||||||
if (this.isPublisher()){
|
if (this.isPublisher()){
|
||||||
super.createPublishingEndpoint();
|
super.createPublishingEndpoint();
|
||||||
} else {
|
} else {
|
||||||
throw new OpenViduException(Code.USER_UNAUTHORIZED,
|
throw new OpenViduException(Code.GENERIC_ERROR_CODE,
|
||||||
"Unable to create publisher endpoint");
|
"Unable to create publisher endpoint");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue