mirror of https://github.com/OpenVidu/openvidu.git
Substantial openvidu-server refactoring to support metadata in users
parent
80216ffe30
commit
1ee067adc2
57
README.md
57
README.md
|
@ -262,7 +262,7 @@ For secret "MY_SECRET", the final header would be
|
||||||
| **Operation** | POST |
|
| **Operation** | POST |
|
||||||
| **URL** | https://[YOUR_OPENVIDUSERVER_IP]/newToken |
|
| **URL** | https://[YOUR_OPENVIDUSERVER_IP]/newToken |
|
||||||
| **Headers** | Authorization:Basic _EncodeBase64(OPENVIDUAPP:[YOUR_SECRET])_<br/>Content-Type:application/json |
|
| **Headers** | Authorization:Basic _EncodeBase64(OPENVIDUAPP:[YOUR_SECRET])_<br/>Content-Type:application/json |
|
||||||
| **Body** | {"0": "SESSIONID", "1": "ROLE"} |
|
| **Body** | {"0": "SESSIONID", "1": "ROLE", "2": "METADATA"} |
|
||||||
| **Returns** | {"0": "TOKEN"} |
|
| **Returns** | {"0": "TOKEN"} |
|
||||||
|
|
||||||
|
|
||||||
|
@ -279,6 +279,9 @@ For secret "MY_SECRET", the final header would be
|
||||||
|
|
||||||
API reference
|
API reference
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
> NOTE: all input parameters ("Parameters" columns) are listed in strict order, optional ones in _italics_
|
||||||
|
|
||||||
## openvidu-browser
|
## openvidu-browser
|
||||||
|
|
||||||
| Class | Description |
|
| Class | Description |
|
||||||
|
@ -290,7 +293,7 @@ API reference
|
||||||
| Stream | Represents each of the videos send and receive by a user in a session. Therefore each Publisher and Subscriber has an attribute of type Stream |
|
| Stream | Represents each of the videos send and receive by a user in a session. Therefore each Publisher and Subscriber has an attribute of type Stream |
|
||||||
|
|
||||||
#### **OpenVidu**
|
#### **OpenVidu**
|
||||||
| Method | Returns | Parameters (show in order, optional _italic_) | Description |
|
| Method | Returns | Parameters | Description |
|
||||||
| ---------------- | ------- | ------------------------------------------- | ----------- |
|
| ---------------- | ------- | ------------------------------------------- | ----------- |
|
||||||
| `initSession` | Session | _`apikey:string`_<br/>`sessionId:string` | Returns a session with id **sessionId** |
|
| `initSession` | Session | _`apikey:string`_<br/>`sessionId:string` | Returns a session with id **sessionId** |
|
||||||
| `initPublisher` | Publisher | `parentId:string`<br/>`cameraOptions:any`<br/>_`callback:function`_ | Starts local video stream, appending it to **parentId** HTML element, with the specific **cameraOptions** settings and executing **callback** function in the end |
|
| `initPublisher` | Publisher | `parentId:string`<br/>`cameraOptions:any`<br/>_`callback:function`_ | Starts local video stream, appending it to **parentId** HTML element, with the specific **cameraOptions** settings and executing **callback** function in the end |
|
||||||
|
@ -298,12 +301,12 @@ API reference
|
||||||
| `getDevices` | Promise | `callback(error, deviceInfo):function` | Collects information about the media input and output devices available on the system, returned in **deviceInfo** array |
|
| `getDevices` | Promise | `callback(error, deviceInfo):function` | Collects information about the media input and output devices available on the system, returned in **deviceInfo** array |
|
||||||
|
|
||||||
#### **Session**
|
#### **Session**
|
||||||
| Method | Returns | Parameters (show in order, optional _italic_) | Description |
|
| Method | Returns | Parameters | Description |
|
||||||
| ---------------- | ------- | ------------------------------------------- | ----------- |
|
| ---------------- | ------- | ------------------------------------------- | ----------- |
|
||||||
| `connect` | | `token:string`<br/>`callback(error):function` | Connects to the session using **token** and executes **callback** in the end (_error_ parameter null if success)|
|
| `connect` | | `token:string`<br/>_`metadata:string`_<br/>`callback(error):function` | Connects to the session using **token** and executes **callback** in the end (_error_ parameter null if success). **metadata** parameter allows you to pass a string as extra data to share with other users when they receive _participantJoined_ event. You can also add metadata through openvidu-backend-client when generating tokens (see [TokenOptions](#tokenoptions)). The structure of this string is up to you (maybe some standarized format as JSON or XML is a good idea), the only restriction is a maximum length of 1000 chars |
|
||||||
| `disconnect` | | | Leaves the session, destroying all streams and deleting the user as a participant |
|
| `disconnect` | | | Leaves the session, destroying all streams and deleting the user as a participant |
|
||||||
| `publish` | | `publisher:Publisher` | Publishes the specific user's local stream contained in Publisher object to the session |
|
| `publish` | | `publisher:Publisher` | Publishes the specific user's local stream contained in **publisher** object to the session |
|
||||||
| `unpublish` | | `publisher:Publisher` | Unpublishes the specific user's local stream contained in Publisher object |
|
| `unpublish` | | `publisher:Publisher` | Unpublishes the specific user's local stream contained in **publisher** object |
|
||||||
| `on` | | `eventName:string`<br/>`callback:function` | **callback** function will be triggered each time **eventName** event is recieved |
|
| `on` | | `eventName:string`<br/>`callback:function` | **callback** function will be triggered each time **eventName** event is recieved |
|
||||||
| `once` | | `eventName:string`<br/>`callback:function` | **callback** function will be triggered once when **eventName** event is recieved. The listener is removed immediately |
|
| `once` | | `eventName:string`<br/>`callback:function` | **callback** function will be triggered once when **eventName** event is recieved. The listener is removed immediately |
|
||||||
| `off` | | `eventName:string`<br/>`eventHandler:any` | Removes **eventHandler** handler for **eventName** event |
|
| `off` | | `eventName:string`<br/>`eventHandler:any` | Removes **eventHandler** handler for **eventName** event |
|
||||||
|
@ -316,7 +319,7 @@ API reference
|
||||||
|
|
||||||
|
|
||||||
#### **Publisher**
|
#### **Publisher**
|
||||||
| Method | Returns | Parameters (show in order, optional _italic_) | Description |
|
| Method | Returns | Parameters | Description |
|
||||||
| -------------- | ------- | ------------------------------------------- | ----------- |
|
| -------------- | ------- | ------------------------------------------- | ----------- |
|
||||||
| `publishAudio` | | `value:boolean`| Enable or disable the audio track depending on whether value is _true_ or _false_ |
|
| `publishAudio` | | `value:boolean`| Enable or disable the audio track depending on whether value is _true_ or _false_ |
|
||||||
| `publishVideo` | | `value:boolean`| Enable or disable the video track depending on whether value is _true_ or _false_ |
|
| `publishVideo` | | `value:boolean`| Enable or disable the video track depending on whether value is _true_ or _false_ |
|
||||||
|
@ -331,7 +334,7 @@ API reference
|
||||||
| `session` | Session | The session to which the publisher belongs |
|
| `session` | Session | The session to which the publisher belongs |
|
||||||
|
|
||||||
#### **Subscriber**
|
#### **Subscriber**
|
||||||
| Method | Returns | Parameters (show in order, optional _italic_) | Description |
|
| Method | Returns | Parameters | Description |
|
||||||
| -------------- | ------- | ------------------------------------------- | ----------- |
|
| -------------- | ------- | ------------------------------------------- | ----------- |
|
||||||
| | | | |
|
| | | | |
|
||||||
|
|
||||||
|
@ -344,23 +347,45 @@ API reference
|
||||||
|
|
||||||
## openvidu-backend-client
|
## openvidu-backend-client
|
||||||
|
|
||||||
| Class | Description |
|
| Class | Description |
|
||||||
| -------- | ------------------------------------------------------- |
|
| ------------ | ------------------------------------------------------- |
|
||||||
| OpenVidu | Use it to create all the sessions you need |
|
| OpenVidu | Use it to create all the sessions you need |
|
||||||
| Session | Allows for the creation of tokens with different roles |
|
| Session | Allows for the creation of tokens |
|
||||||
|
| OpenViduRole | Enum that defines the values accepted by _TokenOptions.Builder.role(OpenViduRole role)_ method |
|
||||||
|
| TokenOptions | Customize each token with this class when generating them |
|
||||||
|
|
||||||
#### **OpenVidu**
|
#### **OpenVidu**
|
||||||
| Method | Returns | Parameters (show in order, optional _italic_) | Description |
|
| Method | Returns | Parameters | Description |
|
||||||
| -------------- | ------- | --------------------------------------------- | ----------- |
|
| -------------- | ------- | --------------------------------------------- | ----------- |
|
||||||
| OpenVidu() | | `String urlOpenViduServer`<br>`String secret` | The constructor receives the URL of your OpenVidu Server and the secret shared with it |
|
| OpenVidu() | | `String:urlOpenViduServer`<br>`String:secret` | The constructor receives the URL of your OpenVidu Server and the secret shared with it |
|
||||||
| createSession() | Session | | Get a Session object by calling this method. You can then store it as you want |
|
| createSession() | Session | | Get a Session object by calling this method. You can then store it as you want |
|
||||||
|
|
||||||
#### **Session**
|
#### **Session**
|
||||||
| Method | Returns | Parameters (show in order, optional _italic_) | Description |
|
| Method | Returns | Parameters | Description |
|
||||||
| -------------- | ------- | --------------------------------------------- | ----------- |
|
| -------------- | ------- | --------------------------------------------- | ----------- |
|
||||||
| getSessionId() | String | | Returns the unique identifier of the session. You will need to return this parameter to the client side to pass it during the connection process to the session |
|
| getSessionId() | String | | Returns the unique identifier of the session. You will need to return this parameter to the client side to pass it during the connection process to the session |
|
||||||
| generateToken() | String | _OpenViduRole_ | You can choose which role each user has in a certain session. The value returned is required in the client side just as the sessionId in order to connect to a session. The input parameter can be _OpenViduRole.SUBSCRIBER_, _OpenViduRole.PUBLISHER_ or _OpenViduRole.MODERATOR_. The default value if it is void is _OpenViduRole.PUBLISHER_ |
|
| generateToken() | String | _`TokenOptions:tokenOptions`_ | The value returned is required in the client side just as the sessionId in order to connect to a session |
|
||||||
|
|
||||||
|
#### **OpenViduRole**
|
||||||
|
| Enum | Description |
|
||||||
|
| ---------- | ------- |
|
||||||
|
| SUBSCRIBER | They can subscribe to published streams of other users |
|
||||||
|
| PUBLISHER | They can subscribe to published streams of other users and publish their own streams|
|
||||||
|
| MODERATOR | They can subscribe to published streams of other users, publish their own streams and force _unpublish()_ and _disconnect()_ over a third-party stream or user |
|
||||||
|
|
||||||
|
#### **TokenOptions**
|
||||||
|
| Method | Returns | Parameters | Description |
|
||||||
|
| -------------- | ------- | -------------------------------------------| -- |
|
||||||
|
| getData() | String | | Returns the metadata associated to the token |
|
||||||
|
| getRole() | OpenViduRole | | Returns the role associated to the token |
|
||||||
|
|
||||||
|
##### **TokenOptions.Builder** _(inner static class)_
|
||||||
|
| Method | Returns | Parameters | Description |
|
||||||
|
| -------------- | ------- | --------------------------------------------- | ----------- |
|
||||||
|
| TokenOptions.Builder() | | | Constructor |
|
||||||
|
| build() | TokenOptions | | Returns a new **TokenOptions** object with the stablished properties. Default values if methods _data()_ and _role()_ are not called are an empty string and OpenViduRole.PUBLISHER, respectively |
|
||||||
|
| data() | TokenOptions.Builder | `String:data` | Some extra metadata to be associated to the user through its token. The structure of this string is up to you (maybe some standarized format as JSON or XML is a good idea), the only restriction is a maximum length of 1000 chars |
|
||||||
|
| role() | TokenOptions.Builder | `OpenViduRole:role` | The role associated to this token |
|
||||||
|
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
|
@ -65,100 +65,4 @@ public class OpenVidu {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class Session {
|
|
||||||
|
|
||||||
private HttpClient httpClient;
|
|
||||||
private String urlOpenViduServer;
|
|
||||||
private String sessionId;
|
|
||||||
|
|
||||||
private Session(HttpClient httpClient, String urlOpenViduServer) throws OpenViduException {
|
|
||||||
this.httpClient = httpClient;
|
|
||||||
this.urlOpenViduServer = urlOpenViduServer;
|
|
||||||
this.sessionId = this.getSessionId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSessionId() throws OpenViduException {
|
|
||||||
|
|
||||||
if (this.hasSessionId()) {
|
|
||||||
return this.sessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
HttpResponse response = httpClient.execute(new HttpGet(this.urlOpenViduServer + "getSessionId"));
|
|
||||||
int statusCode = response.getStatusLine().getStatusCode();
|
|
||||||
if ((statusCode == org.apache.http.HttpStatus.SC_OK)){
|
|
||||||
System.out.println("Returning a SESSIONID");
|
|
||||||
String id = "";
|
|
||||||
id = this.httpResponseToString(response);
|
|
||||||
this.sessionId = id;
|
|
||||||
return id;
|
|
||||||
} else {
|
|
||||||
throw new OpenViduException(Code.SESSIONID_CANNOT_BE_CREATED_ERROR_CODE, Integer.toString(statusCode));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new OpenViduException(Code.SESSIONID_CANNOT_BE_CREATED_ERROR_CODE, "Unable to generate a sessionID: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String generateToken() throws OpenViduException {
|
|
||||||
return this.generateToken(OpenViduRole.PUBLISHER);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String generateToken(OpenViduRole role) throws OpenViduException {
|
|
||||||
|
|
||||||
if (!this.hasSessionId()){
|
|
||||||
this.getSessionId();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
JSONObject json = new JSONObject();
|
|
||||||
json.put(0, this.sessionId);
|
|
||||||
json.put(1, role.name());
|
|
||||||
|
|
||||||
HttpPost request = new HttpPost(this.urlOpenViduServer + "newToken");
|
|
||||||
StringEntity params = new StringEntity(json.toString());
|
|
||||||
request.addHeader("content-type", "application/json");
|
|
||||||
request.setEntity(params);
|
|
||||||
|
|
||||||
HttpResponse response = httpClient.execute(request);
|
|
||||||
|
|
||||||
int statusCode = response.getStatusLine().getStatusCode();
|
|
||||||
if ((statusCode == org.apache.http.HttpStatus.SC_OK)){
|
|
||||||
System.out.println("Returning a TOKEN");
|
|
||||||
return this.httpResponseToString(response);
|
|
||||||
} else {
|
|
||||||
throw new OpenViduException(Code.TOKEN_CANNOT_BE_CREATED_ERROR_CODE, Integer.toString(statusCode));
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new OpenViduException(Code.TOKEN_CANNOT_BE_CREATED_ERROR_CODE, "Unable to generate a token: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.sessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String httpResponseToString(HttpResponse response) throws IOException, ParseException{
|
|
||||||
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
|
|
||||||
StringBuffer buf = new StringBuffer();
|
|
||||||
String line = "";
|
|
||||||
while ((line = rd.readLine()) != null) {
|
|
||||||
buf.append(line);
|
|
||||||
}
|
|
||||||
JSONParser parser = new JSONParser();
|
|
||||||
return ((String) ((JSONObject) parser.parse(buf.toString())).get("0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasSessionId() {
|
|
||||||
return (this.sessionId != null && !this.sessionId.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,9 @@ public class OpenViduException extends RuntimeException {
|
||||||
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_ERROR_CODE(401), ROLE_NOT_FOUND_ERROR_CODE(402),
|
USER_UNAUTHORIZED_ERROR_CODE(401), ROLE_NOT_FOUND_ERROR_CODE(402),
|
||||||
SESSIONID_CANNOT_BE_CREATED_ERROR_CODE(403), TOKEN_CANNOT_BE_CREATED_ERROR_CODE(404);
|
SESSIONID_CANNOT_BE_CREATED_ERROR_CODE(403), TOKEN_CANNOT_BE_CREATED_ERROR_CODE(404),
|
||||||
|
|
||||||
|
USER_METADATA_FORMAT_INVALID_ERROR_CODE(500);
|
||||||
|
|
||||||
private int value;
|
private int value;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
package org.openvidu.client;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
import org.json.simple.parser.JSONParser;
|
||||||
|
import org.json.simple.parser.ParseException;
|
||||||
|
import org.openvidu.client.OpenViduException.Code;
|
||||||
|
|
||||||
|
public class Session {
|
||||||
|
|
||||||
|
private HttpClient httpClient;
|
||||||
|
private String urlOpenViduServer;
|
||||||
|
private String sessionId;
|
||||||
|
|
||||||
|
protected Session(HttpClient httpClient, String urlOpenViduServer) throws OpenViduException {
|
||||||
|
this.httpClient = httpClient;
|
||||||
|
this.urlOpenViduServer = urlOpenViduServer;
|
||||||
|
this.sessionId = this.getSessionId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionId() throws OpenViduException {
|
||||||
|
|
||||||
|
if (this.hasSessionId()) {
|
||||||
|
return this.sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
HttpResponse response = httpClient.execute(new HttpGet(this.urlOpenViduServer + "getSessionId"));
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
if ((statusCode == org.apache.http.HttpStatus.SC_OK)){
|
||||||
|
System.out.println("Returning a SESSIONID");
|
||||||
|
String id = "";
|
||||||
|
id = this.httpResponseToString(response);
|
||||||
|
this.sessionId = id;
|
||||||
|
return id;
|
||||||
|
} else {
|
||||||
|
throw new OpenViduException(Code.SESSIONID_CANNOT_BE_CREATED_ERROR_CODE, Integer.toString(statusCode));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new OpenViduException(Code.SESSIONID_CANNOT_BE_CREATED_ERROR_CODE, "Unable to generate a sessionID: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generateToken() throws OpenViduException {
|
||||||
|
return this.generateToken(new TokenOptions.Builder().role(OpenViduRole.PUBLISHER).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generateToken(TokenOptions tokenOptions) throws OpenViduException {
|
||||||
|
|
||||||
|
if (!this.hasSessionId()){
|
||||||
|
this.getSessionId();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put(0, this.sessionId);
|
||||||
|
json.put(1, tokenOptions.getRole().name());
|
||||||
|
json.put(2, tokenOptions.getData());
|
||||||
|
|
||||||
|
HttpPost request = new HttpPost(this.urlOpenViduServer + "newToken");
|
||||||
|
StringEntity params = new StringEntity(json.toString());
|
||||||
|
request.addHeader("content-type", "application/json");
|
||||||
|
request.setEntity(params);
|
||||||
|
|
||||||
|
HttpResponse response = httpClient.execute(request);
|
||||||
|
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
if ((statusCode == org.apache.http.HttpStatus.SC_OK)){
|
||||||
|
System.out.println("Returning a TOKEN");
|
||||||
|
return this.httpResponseToString(response);
|
||||||
|
} else {
|
||||||
|
throw new OpenViduException(Code.TOKEN_CANNOT_BE_CREATED_ERROR_CODE, Integer.toString(statusCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new OpenViduException(Code.TOKEN_CANNOT_BE_CREATED_ERROR_CODE, "Unable to generate a token: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String httpResponseToString(HttpResponse response) throws IOException, ParseException{
|
||||||
|
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
String line = "";
|
||||||
|
while ((line = rd.readLine()) != null) {
|
||||||
|
buf.append(line);
|
||||||
|
}
|
||||||
|
JSONParser parser = new JSONParser();
|
||||||
|
return ((String) ((JSONObject) parser.parse(buf.toString())).get("0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasSessionId() {
|
||||||
|
return (this.sessionId != null && !this.sessionId.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package org.openvidu.client;
|
||||||
|
|
||||||
|
public class TokenOptions {
|
||||||
|
|
||||||
|
private String data;
|
||||||
|
private OpenViduRole role;
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
private String data = "";
|
||||||
|
private OpenViduRole role = OpenViduRole.PUBLISHER;
|
||||||
|
|
||||||
|
public TokenOptions build() {
|
||||||
|
return new TokenOptions(this.data, this.role);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder data(String data){
|
||||||
|
this.data = data;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder role(OpenViduRole role){
|
||||||
|
this.role = role;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TokenOptions(String data, OpenViduRole role){
|
||||||
|
this.data = data;
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData() {
|
||||||
|
return this.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenViduRole getRole() {
|
||||||
|
return this.role;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -18,14 +18,28 @@ export class Session {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(token, callback) {
|
connect(token: string, callback: any);
|
||||||
|
connect(token:string, metadata: string, callback: any);
|
||||||
|
|
||||||
|
connect(param1, param2, param3?) {
|
||||||
// Early configuration to deactivate automatic subscription to streams
|
// Early configuration to deactivate automatic subscription to streams
|
||||||
this.session.configure({
|
if (typeof param2 == "string") {
|
||||||
sessionId: this.session.getSessionId(),
|
this.session.configure({
|
||||||
participantId: token,
|
sessionId: this.session.getSessionId(),
|
||||||
subscribeToStreams: false
|
participantId: param1,
|
||||||
});
|
metadata: param2,
|
||||||
this.session.connect(token, callback);
|
subscribeToStreams: false
|
||||||
|
});
|
||||||
|
this.session.connect(param1, param3);
|
||||||
|
} else {
|
||||||
|
this.session.configure({
|
||||||
|
sessionId: this.session.getSessionId(),
|
||||||
|
participantId: param1,
|
||||||
|
metadata: '',
|
||||||
|
subscribeToStreams: false
|
||||||
|
});
|
||||||
|
this.session.connect(param1, param2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnect() {
|
disconnect() {
|
||||||
|
|
|
@ -46,8 +46,9 @@ export class SessionInternal {
|
||||||
});
|
});
|
||||||
|
|
||||||
let joinParams = {
|
let joinParams = {
|
||||||
user: token,
|
token: token,
|
||||||
room: this.sessionId,
|
session: this.sessionId,
|
||||||
|
metadata: '',
|
||||||
dataChannels: false
|
dataChannels: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,60 +112,6 @@ export class SessionInternal {
|
||||||
publish() {
|
publish() {
|
||||||
this.openVidu.getCamera().publish();
|
this.openVidu.getCamera().publish();
|
||||||
}
|
}
|
||||||
|
|
||||||
onStreamAddedOV(callback) {
|
|
||||||
this.addEventListener("stream-added", streamEvent => {
|
|
||||||
callback(streamEvent.stream);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onStreamRemovedOV(callback) {
|
|
||||||
this.addEventListener("stream-removed", streamEvent => {
|
|
||||||
callback(streamEvent.stream);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onParticipantJoinedOV(callback) {
|
|
||||||
this.addEventListener("participant-joined", participantEvent => {
|
|
||||||
callback(participantEvent.participant);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onParticipantLeftOV(callback) {
|
|
||||||
this.addEventListener("participant-left", participantEvent => {
|
|
||||||
callback(participantEvent.participant);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onParticipantPublishedOV(callback) {
|
|
||||||
this.addEventListener("participant-published", participantEvent => {
|
|
||||||
callback(participantEvent.participant);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onParticipantEvictedOV(callback) {
|
|
||||||
this.addEventListener("participant-evicted", participantEvent => {
|
|
||||||
callback(participantEvent.participant);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onRoomClosedOV(callback) {
|
|
||||||
this.addEventListener("room-closed", roomEvent => {
|
|
||||||
callback(roomEvent.room);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onLostConnectionOV(callback) {
|
|
||||||
this.addEventListener("lost-connection", roomEvent => {
|
|
||||||
callback(roomEvent.room);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onMediaErrorOV(callback) {
|
|
||||||
this.addEventListener("error-media", errorEvent => {
|
|
||||||
callback(errorEvent.error)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/* NEW METHODS */
|
/* NEW METHODS */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,9 @@ public class OpenViduException extends RuntimeException {
|
||||||
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_ERROR_CODE(401), ROLE_NOT_FOUND_ERROR_CODE(402),
|
USER_UNAUTHORIZED_ERROR_CODE(401), ROLE_NOT_FOUND_ERROR_CODE(402),
|
||||||
SESSIONID_CANNOT_BE_CREATED_ERROR_CODE(403), TOKEN_CANNOT_BE_CREATED_ERROR_CODE(404);
|
SESSIONID_CANNOT_BE_CREATED_ERROR_CODE(403), TOKEN_CANNOT_BE_CREATED_ERROR_CODE(404),
|
||||||
|
|
||||||
|
USER_METADATA_FORMAT_INVALID_ERROR_CODE(500);
|
||||||
|
|
||||||
private int value;
|
private int value;
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,9 @@ public class ProtocolElements {
|
||||||
public static final String LEAVEROOM_METHOD = "leaveRoom";
|
public static final String LEAVEROOM_METHOD = "leaveRoom";
|
||||||
|
|
||||||
public static final String JOINROOM_METHOD = "joinRoom";
|
public static final String JOINROOM_METHOD = "joinRoom";
|
||||||
public static final String JOINROOM_USER_PARAM = "user";
|
public static final String JOINROOM_USER_PARAM = "token";
|
||||||
public static final String JOINROOM_ROOM_PARAM = "room";
|
public static final String JOINROOM_ROOM_PARAM = "session";
|
||||||
|
public static final String JOINROOM_METADATA_PARAM = "metadata";
|
||||||
public static final String JOINROOM_DATACHANNELS_PARAM = "dataChannels";
|
public static final String JOINROOM_DATACHANNELS_PARAM = "dataChannels";
|
||||||
public static final String JOINROOM_PEERID_PARAM = "id";
|
public static final String JOINROOM_PEERID_PARAM = "id";
|
||||||
public static final String JOINROOM_PEERSTREAMS_PARAM = "streams";
|
public static final String JOINROOM_PEERSTREAMS_PARAM = "streams";
|
||||||
|
@ -67,6 +68,7 @@ public class ProtocolElements {
|
||||||
|
|
||||||
public static final String PARTICIPANTJOINED_METHOD = "participantJoined";
|
public static final String PARTICIPANTJOINED_METHOD = "participantJoined";
|
||||||
public static final String PARTICIPANTJOINED_USER_PARAM = "id";
|
public static final String PARTICIPANTJOINED_USER_PARAM = "id";
|
||||||
|
public static final String PARTICIPANTJOINED_METADATA_PARAM = "metadata";
|
||||||
|
|
||||||
public static final String PARTICIPANTLEFT_METHOD = "participantLeft";
|
public static final String PARTICIPANTLEFT_METHOD = "participantLeft";
|
||||||
public static final String PARTICIPANTLEFT_NAME_PARAM = "name";
|
public static final String PARTICIPANTLEFT_NAME_PARAM = "name";
|
||||||
|
|
|
@ -7,7 +7,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
import org.openvidu.client.OpenVidu;
|
import org.openvidu.client.OpenVidu;
|
||||||
import org.openvidu.client.OpenVidu.Session;
|
import org.openvidu.client.Session;
|
||||||
|
import org.openvidu.client.TokenOptions;
|
||||||
import org.openvidu.client.OpenViduRole;
|
import org.openvidu.client.OpenViduRole;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
@ -80,9 +81,10 @@ public class SessionController {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
|
// IMPORTANT STUFF
|
||||||
Session session = this.openVidu.createSession();
|
Session session = this.openVidu.createSession();
|
||||||
String sessionId = session.getSessionId();
|
String sessionId = session.getSessionId();
|
||||||
|
// END IMPORTANT STUFF
|
||||||
|
|
||||||
this.lessonIdSession.put(id_lesson, session);
|
this.lessonIdSession.put(id_lesson, session);
|
||||||
this.sessionIdUserIdToken.put(sessionId, new HashMap<>());
|
this.sessionIdUserIdToken.put(sessionId, new HashMap<>());
|
||||||
|
@ -130,7 +132,14 @@ public class SessionController {
|
||||||
JSONObject responseJson = new JSONObject();
|
JSONObject responseJson = new JSONObject();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String token = (String) this.lessonIdSession.get(id_lesson).generateToken(role);
|
// IMPORTANT STUFF
|
||||||
|
TokenOptions tokenOpts = new TokenOptions.Builder()
|
||||||
|
.role(role)
|
||||||
|
.data("mydata=mydata")
|
||||||
|
.build();
|
||||||
|
String token = (String) this.lessonIdSession.get(id_lesson).generateToken(tokenOpts);
|
||||||
|
// END IMPORTANT STUFF
|
||||||
|
|
||||||
this.sessionIdUserIdToken.get(session.getSessionId()).put(this.user.getLoggedUser().getId(), token);
|
this.sessionIdUserIdToken.get(session.getSessionId()).put(this.user.getLoggedUser().getId(), token);
|
||||||
|
|
||||||
responseJson.put(0, session.getSessionId());
|
responseJson.put(0, session.getSessionId());
|
||||||
|
|
|
@ -76,22 +76,22 @@ public class NotificationRoomManager {
|
||||||
* when responding back to the client)
|
* when responding back to the client)
|
||||||
* @see RoomManager#joinRoom(String, String, boolean, boolean, KurentoClientSessionInfo, String)
|
* @see RoomManager#joinRoom(String, String, boolean, boolean, KurentoClientSessionInfo, String)
|
||||||
*/
|
*/
|
||||||
public void joinRoom(String userName, String roomName, boolean dataChannels,
|
public void joinRoom(String user, String session, boolean dataChannels,
|
||||||
boolean webParticipant, ParticipantRequest request) {
|
boolean webParticipant, ParticipantRequest request) {
|
||||||
Set<UserParticipant> existingParticipants = null;
|
Set<UserParticipant> existingParticipants = null;
|
||||||
try {
|
try {
|
||||||
KurentoClientSessionInfo kcSessionInfo =
|
KurentoClientSessionInfo kcSessionInfo =
|
||||||
new DefaultKurentoClientSessionInfo(request.getParticipantId(), roomName);
|
new DefaultKurentoClientSessionInfo(request.getParticipantId(), session);
|
||||||
existingParticipants = internalManager
|
existingParticipants = internalManager
|
||||||
.joinRoom(userName, roomName, dataChannels, webParticipant, kcSessionInfo,
|
.joinRoom(user, session, dataChannels, webParticipant, kcSessionInfo,
|
||||||
request.getParticipantId());
|
request.getParticipantId());
|
||||||
} catch (OpenViduException e) {
|
} catch (OpenViduException e) {
|
||||||
log.warn("PARTICIPANT {}: Error joining/creating room {}", userName, roomName, e);
|
log.warn("PARTICIPANT {}: Error joining/creating room {}", user, session, e);
|
||||||
notificationRoomHandler.onParticipantJoined(request, roomName, userName, null, e);
|
notificationRoomHandler.onParticipantJoined(request, session, user, null, e);
|
||||||
}
|
}
|
||||||
if (existingParticipants != null) {
|
if (existingParticipants != null) {
|
||||||
notificationRoomHandler
|
notificationRoomHandler
|
||||||
.onParticipantJoined(request, roomName, userName, existingParticipants, null);
|
.onParticipantJoined(request, session, user, existingParticipants, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,7 +431,7 @@ public class NotificationRoomManager {
|
||||||
return this.internalManager.newSessionId();
|
return this.internalManager.newSessionId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String newToken(String sessionId, ParticipantRole role){
|
public String newToken(String sessionId, ParticipantRole role, String metaData){
|
||||||
return this.internalManager.newToken(sessionId, role);
|
return this.internalManager.newToken(sessionId, role, metaData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ 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.ParticipantRole;
|
import org.openvidu.server.security.ParticipantRole;
|
||||||
|
import org.openvidu.server.security.Token;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -71,7 +72,7 @@ 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, ParticipantRole>> sessionIdTokenRole = new ConcurrentHashMap<>();
|
private final ConcurrentMap<String, ConcurrentHashMap<String, Token>> sessionIdToken = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Value("${openvidu.security}")
|
@Value("${openvidu.security}")
|
||||||
private boolean SECURITY_ENABLED;
|
private boolean SECURITY_ENABLED;
|
||||||
|
@ -107,30 +108,30 @@ public class RoomManager {
|
||||||
* @return set of existing peers of type {@link UserParticipant}, can be empty if first
|
* @return set of existing peers of type {@link UserParticipant}, can be empty if first
|
||||||
* @throws OpenViduException on error while joining (like the room is not found or is closing)
|
* @throws OpenViduException on error while joining (like the room is not found or is closing)
|
||||||
*/
|
*/
|
||||||
public Set<UserParticipant> joinRoom(String userName, String roomName, boolean dataChannels,
|
public Set<UserParticipant> joinRoom(String user, String session, boolean dataChannels,
|
||||||
boolean webParticipant, KurentoClientSessionInfo kcSessionInfo, String participantId)
|
boolean webParticipant, KurentoClientSessionInfo kcSessionInfo, String participantId)
|
||||||
throws OpenViduException {
|
throws OpenViduException {
|
||||||
log.debug("Request [JOIN_ROOM] user={}, room={}, web={} " + "kcSessionInfo.room={} ({})",
|
log.debug("Request [JOIN_ROOM] user={}, room={}, web={} " + "kcSessionInfo.room={} ({})",
|
||||||
userName, roomName, webParticipant,
|
user, session, webParticipant,
|
||||||
kcSessionInfo != null ? kcSessionInfo.getRoomName() : null, participantId);
|
kcSessionInfo != null ? kcSessionInfo.getRoomName() : null, participantId);
|
||||||
Room room = rooms.get(roomName);
|
Room room = rooms.get(session);
|
||||||
if (room == null && kcSessionInfo != null) {
|
if (room == null && kcSessionInfo != null) {
|
||||||
createRoom(kcSessionInfo);
|
createRoom(kcSessionInfo);
|
||||||
}
|
}
|
||||||
room = rooms.get(roomName);
|
room = rooms.get(session);
|
||||||
if (room == null) {
|
if (room == null) {
|
||||||
log.warn("Room '{}' not found");
|
log.warn("Room '{}' not found");
|
||||||
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE,
|
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE,
|
||||||
"Room '" + roomName + "' was not found, must be created before '" + userName
|
"Room '" + session + "' was not found, must be created before '" + session
|
||||||
+ "' can join");
|
+ "' can join");
|
||||||
}
|
}
|
||||||
if (room.isClosed()) {
|
if (room.isClosed()) {
|
||||||
log.warn("'{}' is trying to join room '{}' but it is closing", userName, roomName);
|
log.warn("'{}' is trying to join room '{}' but it is closing", user, session);
|
||||||
throw new OpenViduException(Code.ROOM_CLOSED_ERROR_CODE,
|
throw new OpenViduException(Code.ROOM_CLOSED_ERROR_CODE,
|
||||||
"'" + userName + "' is trying to join room '" + roomName + "' but it is closing");
|
"'" + user + "' is trying to join room '" + session + "' but it is closing");
|
||||||
}
|
}
|
||||||
Set<UserParticipant> existingParticipants = getParticipants(roomName);
|
Set<UserParticipant> existingParticipants = getParticipants(session);
|
||||||
room.join(participantId, userName, dataChannels, webParticipant);
|
room.join(participantId, user, dataChannels, webParticipant);
|
||||||
return existingParticipants;
|
return existingParticipants;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,8 +160,8 @@ public class RoomManager {
|
||||||
}
|
}
|
||||||
room.leave(participantId);
|
room.leave(participantId);
|
||||||
|
|
||||||
if (this.sessionIdTokenRole.get(roomName) != null){
|
if (this.sessionIdToken.get(roomName) != null){
|
||||||
this.sessionIdTokenRole.get(roomName).remove(participant.getName());
|
this.sessionIdToken.get(roomName).remove(participant.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
showMap();
|
showMap();
|
||||||
|
@ -177,7 +178,7 @@ public class RoomManager {
|
||||||
room.close();
|
room.close();
|
||||||
rooms.remove(roomName);
|
rooms.remove(roomName);
|
||||||
|
|
||||||
sessionIdTokenRole.remove(roomName);
|
sessionIdToken.remove(roomName);
|
||||||
|
|
||||||
showMap();
|
showMap();
|
||||||
|
|
||||||
|
@ -848,7 +849,7 @@ public class RoomManager {
|
||||||
room.close();
|
room.close();
|
||||||
rooms.remove(roomName);
|
rooms.remove(roomName);
|
||||||
|
|
||||||
sessionIdTokenRole.remove(roomName);
|
sessionIdToken.remove(roomName);
|
||||||
|
|
||||||
log.warn("Room '{}' removed and closed", roomName);
|
log.warn("Room '{}' removed and closed", roomName);
|
||||||
return participants;
|
return participants;
|
||||||
|
@ -932,7 +933,7 @@ public class RoomManager {
|
||||||
|
|
||||||
private void showMap(){
|
private void showMap(){
|
||||||
System.out.println("------------------------------");
|
System.out.println("------------------------------");
|
||||||
System.out.println(this.sessionIdTokenRole.toString());
|
System.out.println(this.sessionIdToken.toString());
|
||||||
System.out.println("------------------------------");
|
System.out.println("------------------------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,10 +941,10 @@ public class RoomManager {
|
||||||
return getParticipant(pid).getRoom().getName();
|
return getParticipant(pid).getRoom().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isParticipantInRoom(String participantName, String roomName) {
|
public boolean isParticipantInRoom(String token, String session) {
|
||||||
if (SECURITY_ENABLED) {
|
if (SECURITY_ENABLED) {
|
||||||
if (this.sessionIdTokenRole.get(roomName) != null) {
|
if (this.sessionIdToken.get(session) != null) {
|
||||||
return this.sessionIdTokenRole.get(roomName).containsKey(participantName);
|
return this.sessionIdToken.get(session).containsKey(token);
|
||||||
} else{
|
} else{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -952,11 +953,11 @@ public class RoomManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPublisherInRoom(String participantName, String roomName) {
|
public boolean isPublisherInRoom(String token, String session) {
|
||||||
if (SECURITY_ENABLED) {
|
if (SECURITY_ENABLED) {
|
||||||
if (this.sessionIdTokenRole.get(roomName) != null){
|
if (this.sessionIdToken.get(session) != null){
|
||||||
if (this.sessionIdTokenRole.get(roomName).get(participantName) != null){
|
if (this.sessionIdToken.get(session).get(token) != null){
|
||||||
return (this.sessionIdTokenRole.get(roomName).get(participantName).equals(ParticipantRole.PUBLISHER));
|
return (this.sessionIdToken.get(session).get(token).getRole().equals(ParticipantRole.PUBLISHER));
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -968,29 +969,41 @@ public class RoomManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTokenClientMetadata(String token, String session, String metadata){
|
||||||
|
if (this.sessionIdToken.get(session) != null){
|
||||||
|
if (this.sessionIdToken.get(session).get(token) != null){
|
||||||
|
this.sessionIdToken.get(session).get(token).setClientMetadata(metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String newSessionId(){
|
public String newSessionId(){
|
||||||
String sessionId = new BigInteger(130, new SecureRandom()).toString(32);
|
String sessionId = new BigInteger(130, new SecureRandom()).toString(32);
|
||||||
|
this.sessionIdToken.put(sessionId, new ConcurrentHashMap<>());
|
||||||
this.sessionIdTokenRole.put(sessionId, new ConcurrentHashMap<>());
|
|
||||||
|
|
||||||
showMap();
|
showMap();
|
||||||
|
|
||||||
return sessionId;
|
return sessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String newToken(String sessionId, ParticipantRole role){
|
public String newToken(String session, ParticipantRole role, String metadata){
|
||||||
if (this.sessionIdTokenRole.get(sessionId) != null) {
|
if (this.sessionIdToken.get(session) != null) {
|
||||||
String token = new BigInteger(130, new SecureRandom()).toString(32);
|
if(metadataFormatCorrect(metadata)){
|
||||||
|
String token = new BigInteger(130, new SecureRandom()).toString(32);
|
||||||
this.sessionIdTokenRole.get(sessionId).put(token, role);
|
this.sessionIdToken.get(session).put(token, new Token(token, role, metadata));
|
||||||
|
showMap();
|
||||||
showMap();
|
return token;
|
||||||
|
}
|
||||||
return token;
|
else {
|
||||||
|
throw new OpenViduException(Code.GENERIC_ERROR_CODE, "Data invalid format. Max length allowed is 1000 chars");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Error: the sessionId [" + sessionId + "] is not valid");
|
System.out.println("Error: the sessionId [" + session + "] is not valid");
|
||||||
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE,
|
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE,
|
||||||
"[" + sessionId +"] is not a valid sessionId");
|
"[" + session +"] is not a valid sessionId");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean metadataFormatCorrect(String metadata){
|
||||||
|
// Max 1000 chars
|
||||||
|
return (metadata.length() <= 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,10 @@ public class DefaultNotificationRoomHandler implements NotificationRoomHandler {
|
||||||
|
|
||||||
JsonObject notifParams = new JsonObject();
|
JsonObject notifParams = new JsonObject();
|
||||||
notifParams.addProperty(ProtocolElements.PARTICIPANTJOINED_USER_PARAM, newUserName);
|
notifParams.addProperty(ProtocolElements.PARTICIPANTJOINED_USER_PARAM, newUserName);
|
||||||
|
|
||||||
|
// TO-DO: Return metadata associated to each participant
|
||||||
|
//notifParams.addProperty(ProtocolElements.PARTICIPANTJOINED_METADATA_PARAM, participant.getUserName());
|
||||||
|
|
||||||
notifService.sendNotification(participant.getParticipantId(),
|
notifService.sendNotification(participant.getParticipantId(),
|
||||||
ProtocolElements.PARTICIPANTJOINED_METHOD, notifParams);
|
ProtocolElements.PARTICIPANTJOINED_METHOD, notifParams);
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,25 +91,25 @@ public class Room {
|
||||||
return this.pipeline;
|
return this.pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void join(String participantId, String userName, boolean dataChannels,
|
public synchronized void join(String participantId, String user, boolean dataChannels,
|
||||||
boolean webParticipant) throws OpenViduException {
|
boolean webParticipant) throws OpenViduException {
|
||||||
|
|
||||||
checkClosed();
|
checkClosed();
|
||||||
|
|
||||||
if (userName == null || userName.isEmpty()) {
|
if (user == null || user.isEmpty()) {
|
||||||
throw new OpenViduException(Code.GENERIC_ERROR_CODE, "Empty user name is not allowed");
|
throw new OpenViduException(Code.GENERIC_ERROR_CODE, "Empty user name is not allowed");
|
||||||
}
|
}
|
||||||
for (Participant p : participants.values()) {
|
for (Participant p : participants.values()) {
|
||||||
if (p.getName().equals(userName)) {
|
if (p.getName().equals(user)) {
|
||||||
throw new OpenViduException(Code.EXISTING_USER_IN_ROOM_ERROR_CODE,
|
throw new OpenViduException(Code.EXISTING_USER_IN_ROOM_ERROR_CODE,
|
||||||
"User '" + userName + "' already exists in room '" + name + "'");
|
"User '" + user + "' already exists in room '" + name + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createPipeline();
|
createPipeline();
|
||||||
|
|
||||||
Participant participant =
|
Participant participant =
|
||||||
new Participant(participantId, userName, this, getPipeline(), dataChannels, webParticipant);
|
new Participant(participantId, user, this, getPipeline(), dataChannels, webParticipant);
|
||||||
participants.put(participantId, participant);
|
participants.put(participantId, participant);
|
||||||
|
|
||||||
filterStates.forEach((filterId, state) -> {
|
filterStates.forEach((filterId, state) -> {
|
||||||
|
@ -117,7 +117,7 @@ public class Room {
|
||||||
roomHandler.updateFilter(name, participant, filterId, state);
|
roomHandler.updateFilter(name, participant, filterId, state);
|
||||||
});
|
});
|
||||||
|
|
||||||
log.info("ROOM {}: Added participant {}", name, userName);
|
log.info("ROOM {}: Added participant {}", name, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void newPublisher(Participant participant) {
|
public void newPublisher(Participant participant) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import static org.kurento.commons.PropertiesManager.getProperty;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
|
import org.openvidu.client.OpenViduException;
|
||||||
import org.openvidu.server.core.NotificationRoomManager;
|
import org.openvidu.server.core.NotificationRoomManager;
|
||||||
import org.openvidu.server.security.ParticipantRole;
|
import org.openvidu.server.security.ParticipantRole;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -68,21 +69,30 @@ public class RoomController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/newToken", method = RequestMethod.POST)
|
@RequestMapping(value = "/newToken", method = RequestMethod.POST)
|
||||||
public ResponseEntity<JSONObject> getToken(@RequestBody Map sessionIdAndRole) {
|
public ResponseEntity<JSONObject> getToken(@RequestBody Map sessionIdRoleMetadata) { // {0: sessionID, 1: role, 2: metadata}
|
||||||
JSONObject responseJson = new JSONObject();
|
String errorMessage = "";
|
||||||
try {
|
try {
|
||||||
ParticipantRole role = ParticipantRole.valueOf((String) sessionIdAndRole.get("1"));
|
ParticipantRole role = ParticipantRole.valueOf((String) sessionIdRoleMetadata.get("1"));
|
||||||
String token = roomManager.newToken((String) sessionIdAndRole.get("0"), role);
|
String metadata = (String) sessionIdRoleMetadata.get("2");
|
||||||
|
String token = roomManager.newToken((String) sessionIdRoleMetadata.get("0"), role, metadata);
|
||||||
|
JSONObject responseJson = new JSONObject();
|
||||||
responseJson.put(0, token);
|
responseJson.put(0, token);
|
||||||
return new ResponseEntity<JSONObject>(responseJson, HttpStatus.OK);
|
return new ResponseEntity<JSONObject>(responseJson, HttpStatus.OK);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e){
|
catch (IllegalArgumentException e){
|
||||||
responseJson.put("timestamp", System.currentTimeMillis());
|
return this.generateErrorResponse("Role " + sessionIdRoleMetadata.get("1") + " is not defined");
|
||||||
responseJson.put("status", HttpStatus.BAD_REQUEST.value());
|
} catch (OpenViduException e) {
|
||||||
responseJson.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
|
return this.generateErrorResponse("Metadata [" + sessionIdRoleMetadata.get("2") + "] unexpected format. Max length allowed is 1000 chars");
|
||||||
responseJson.put("message", "Role " + sessionIdAndRole.get("1") + " is not defined");
|
|
||||||
responseJson.put("path", "/newToken");
|
|
||||||
return new ResponseEntity<JSONObject>(responseJson, HttpStatus.BAD_REQUEST);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ResponseEntity<JSONObject> generateErrorResponse(String errorMessage){
|
||||||
|
JSONObject responseJson = new JSONObject();
|
||||||
|
responseJson.put("timestamp", System.currentTimeMillis());
|
||||||
|
responseJson.put("status", HttpStatus.BAD_REQUEST.value());
|
||||||
|
responseJson.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
|
||||||
|
responseJson.put("message", errorMessage);
|
||||||
|
responseJson.put("path", "/newToken");
|
||||||
|
return new ResponseEntity<JSONObject>(responseJson, HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,26 +51,35 @@ public class JsonRpcUserControl {
|
||||||
public void joinRoom(Transaction transaction, Request<JsonObject> request,
|
public void joinRoom(Transaction transaction, Request<JsonObject> request,
|
||||||
ParticipantRequest participantRequest) throws IOException, InterruptedException,
|
ParticipantRequest participantRequest) throws IOException, InterruptedException,
|
||||||
ExecutionException {
|
ExecutionException {
|
||||||
String roomName = getStringParam(request, ProtocolElements.JOINROOM_ROOM_PARAM);
|
|
||||||
String userName = getStringParam(request, ProtocolElements.JOINROOM_USER_PARAM);
|
String session = getStringParam(request, ProtocolElements.JOINROOM_ROOM_PARAM);
|
||||||
|
String user = getStringParam(request, ProtocolElements.JOINROOM_USER_PARAM);
|
||||||
|
String userData = getStringParam(request, ProtocolElements.JOINROOM_METADATA_PARAM);
|
||||||
|
|
||||||
if(roomManager.getRoomManager().isParticipantInRoom(userName, roomName)){
|
if(roomManager.getRoomManager().isParticipantInRoom(user, session)){
|
||||||
|
|
||||||
boolean dataChannels = false;
|
if(roomManager.getRoomManager().metadataFormatCorrect(userData)){
|
||||||
if (request.getParams().has(ProtocolElements.JOINROOM_DATACHANNELS_PARAM)) {
|
|
||||||
dataChannels = request.getParams().get(ProtocolElements.JOINROOM_DATACHANNELS_PARAM)
|
this.roomManager.getRoomManager().setTokenClientMetadata(user, session, userData);
|
||||||
.getAsBoolean();
|
|
||||||
}
|
boolean dataChannels = false;
|
||||||
|
if (request.getParams().has(ProtocolElements.JOINROOM_DATACHANNELS_PARAM)) {
|
||||||
ParticipantSession participantSession = getParticipantSession(transaction);
|
dataChannels = request.getParams().get(ProtocolElements.JOINROOM_DATACHANNELS_PARAM)
|
||||||
participantSession.setParticipantName(userName);
|
.getAsBoolean();
|
||||||
participantSession.setRoomName(roomName);
|
}
|
||||||
participantSession.setDataChannels(dataChannels);
|
|
||||||
|
ParticipantSession participantSession = getParticipantSession(transaction);
|
||||||
roomManager.joinRoom(userName, roomName, dataChannels, true, participantRequest);
|
participantSession.setParticipantName(user);
|
||||||
|
participantSession.setRoomName(session);
|
||||||
}
|
participantSession.setDataChannels(dataChannels);
|
||||||
else {
|
|
||||||
|
roomManager.joinRoom(user, session, dataChannels, true, participantRequest);
|
||||||
|
} else {
|
||||||
|
System.out.println("Error: metadata format is incorrect");
|
||||||
|
throw new OpenViduException(Code.USER_METADATA_FORMAT_INVALID_ERROR_CODE,
|
||||||
|
"Unable to join room. The metadata received has an invalid format");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
System.out.println("Error: sessionId or token not valid");
|
System.out.println("Error: sessionId or token not valid");
|
||||||
throw new OpenViduException(Code.USER_UNAUTHORIZED_ERROR_CODE,
|
throw new OpenViduException(Code.USER_UNAUTHORIZED_ERROR_CODE,
|
||||||
"Unable to join room. The user does not have a valid token");
|
"Unable to join room. The user does not have a valid token");
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.openvidu.server.security;
|
||||||
|
|
||||||
|
public class Token {
|
||||||
|
|
||||||
|
String token;
|
||||||
|
ParticipantRole role;
|
||||||
|
String serverMetadata;
|
||||||
|
String clientMetadata ;
|
||||||
|
|
||||||
|
public Token(String token, ParticipantRole role, String metadata) {
|
||||||
|
this.token = token;
|
||||||
|
this.role = role;
|
||||||
|
this.serverMetadata = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParticipantRole getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientMetadata(String metadata){
|
||||||
|
this.clientMetadata = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
return this.role.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,4 +6,4 @@ server.ssl.keyStoreType: JKS
|
||||||
server.ssl.keyAlias: kurento-selfsigned
|
server.ssl.keyAlias: kurento-selfsigned
|
||||||
|
|
||||||
openvidu.secret: MY_SECRET
|
openvidu.secret: MY_SECRET
|
||||||
openvidu.security: false
|
openvidu.security: true
|
Loading…
Reference in New Issue