SEBSERV-139 integration of token generation
This commit is contained in:
parent
548d4d132f
commit
7335547341
8 changed files with 209 additions and 57 deletions
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gbl.model.exam;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class SEBClientProctoringConnectionData {
|
||||
|
||||
public static final String ATTR_SERVER_URL = "serverURL";
|
||||
public static final String ATTR_ROOM_NAME = "roomName";
|
||||
public static final String ATTR_ACCESS_TOKEN = "accessToken";
|
||||
public static final String ATTR_CONNECTION_URL = "connectionURL";
|
||||
|
||||
@JsonProperty(ATTR_SERVER_URL)
|
||||
public final String serverURL;
|
||||
|
||||
@JsonProperty(ATTR_ROOM_NAME)
|
||||
public final String roomName;
|
||||
|
||||
@JsonProperty(ATTR_ACCESS_TOKEN)
|
||||
public final String accessToken;
|
||||
|
||||
@JsonProperty(ATTR_CONNECTION_URL)
|
||||
public final String connectionURL;
|
||||
|
||||
@JsonCreator
|
||||
public SEBClientProctoringConnectionData(
|
||||
@JsonProperty(ATTR_SERVER_URL) final String serverURL,
|
||||
@JsonProperty(ATTR_ROOM_NAME) final String roomName,
|
||||
@JsonProperty(ATTR_ACCESS_TOKEN) final String accessToken,
|
||||
@JsonProperty(ATTR_CONNECTION_URL) final String connectionURL) {
|
||||
|
||||
this.serverURL = serverURL;
|
||||
this.roomName = roomName;
|
||||
this.accessToken = accessToken;
|
||||
this.connectionURL = connectionURL;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return this.accessToken;
|
||||
}
|
||||
|
||||
public String getServerURL() {
|
||||
return this.serverURL;
|
||||
}
|
||||
|
||||
public String getConnectionURL() {
|
||||
return this.connectionURL;
|
||||
}
|
||||
|
||||
public String getRoomName() {
|
||||
return this.roomName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("SEBClientProctoringConnectionData [serverURL=");
|
||||
builder.append(this.serverURL);
|
||||
builder.append(", roomName=");
|
||||
builder.append(this.roomName);
|
||||
builder.append(", accessToken=");
|
||||
builder.append(this.accessToken);
|
||||
builder.append(", connectionURL=");
|
||||
builder.append(this.connectionURL);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -25,6 +25,7 @@ import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
|||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBClientProctoringConnectionData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent;
|
||||
|
@ -285,16 +286,17 @@ public class MonitoringClientConnection implements TemplateComposer {
|
|||
// urlLauncher.openURL(
|
||||
// "https://seb-jitsi.ethz.ch/TestRoomABC?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb250ZXh0Ijp7InVzZXIiOnsiYXZhdGFyIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9qb2huLWRvZSIsIm5hbWUiOiJEaXNwbGF5IE5hbWUiLCJlbWFpbCI6Im5hbWVAZXhhbXBsZS5jb20ifX0sImF1ZCI6InNlYi1qaXRzaSIsImlzcyI6InNlYi1qaXRzaSIsInN1YiI6Im1lZXQuaml0c2kiLCJyb29tIjoiKiJ9.SD9Zs78mMFqxS1tpalPTykYYaubIYsj_406WAOhcqxQ");
|
||||
|
||||
final String proctorURL = this.pageService.getRestService().getBuilder(GetProctorURLForClient.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, action.getEntityKey().modelId)
|
||||
.withURIVariable(API.EXAM_API_SEB_CONNECTION_TOKEN, connectionToken)
|
||||
.call()
|
||||
.getOrThrow();
|
||||
final SEBClientProctoringConnectionData proctoringConnectionData =
|
||||
this.pageService.getRestService().getBuilder(GetProctorURLForClient.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, action.getEntityKey().modelId)
|
||||
.withURIVariable(API.EXAM_API_SEB_CONNECTION_TOKEN, connectionToken)
|
||||
.call()
|
||||
.getOrThrow();
|
||||
|
||||
final JavaScriptExecutor javaScriptExecutor = RWT.getClient().getService(JavaScriptExecutor.class);
|
||||
javaScriptExecutor.execute(
|
||||
"window.open("
|
||||
+ "'https://seb-jitsi.ethz.ch/TestRoomABC?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb250ZXh0Ijp7InVzZXIiOnsiYXZhdGFyIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9qb2huLWRvZSIsIm5hbWUiOiJEaXNwbGF5IE5hbWUiLCJlbWFpbCI6Im5hbWVAZXhhbXBsZS5jb20ifX0sImF1ZCI6InNlYi1qaXRzaSIsImlzcyI6InNlYi1qaXRzaSIsInN1YiI6Im1lZXQuaml0c2kiLCJyb29tIjoiKiJ9.SD9Zs78mMFqxS1tpalPTykYYaubIYsj_406WAOhcqxQ',"
|
||||
+ "'" + proctoringConnectionData.connectionURL + "',"
|
||||
+ "'proctoring',"
|
||||
+ "'height=400,width=800,location=no,scrollbars=yes,status=no,menubar=yes,toolbar=yes,titlebar=yes');");
|
||||
|
||||
|
|
|
@ -17,22 +17,23 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
|||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBClientProctoringConnectionData;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GetProctorURLForClient extends RestCall<String> {
|
||||
public class GetProctorURLForClient extends RestCall<SEBClientProctoringConnectionData> {
|
||||
|
||||
public GetProctorURLForClient() {
|
||||
super(new TypeKey<>(
|
||||
CallType.GET_SINGLE,
|
||||
EntityType.EXAM_PROCTOR_DATA,
|
||||
new TypeReference<String>() {
|
||||
new TypeReference<SEBClientProctoringConnectionData>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_JSON_UTF8,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.EXAM_ADMINISTRATION_ENDPOINT
|
||||
+ API.MODEL_ID_VAR_PATH_SEGMENT
|
||||
+ API.EXAM_ADMINISTRATION_PROCTOR_PATH_SEGMENT
|
||||
|
|
|
@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.exam;
|
|||
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ServerType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBClientProctoringConnectionData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
|
||||
|
@ -19,12 +20,12 @@ public interface ExamProctoringService {
|
|||
|
||||
Result<Boolean> testExamProctoring(final ProctoringSettings examProctoring);
|
||||
|
||||
public Result<String> createProctoringURL(
|
||||
public Result<SEBClientProctoringConnectionData> createProctoringConnectionData(
|
||||
final ProctoringSettings examProctoring,
|
||||
final String connectionToken,
|
||||
final boolean server);
|
||||
|
||||
Result<String> createProctoringURL(
|
||||
Result<SEBClientProctoringConnectionData> createProctoringConnectionData(
|
||||
final ProctoringSettings examProctoring,
|
||||
ClientConnection clientConnection,
|
||||
boolean server);
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
package ch.ethz.seb.sebserver.webservice.servicelayer.exam.impl;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
import java.util.Base64.Encoder;
|
||||
|
||||
|
@ -23,8 +25,10 @@ import ch.ethz.seb.sebserver.gbl.Constants;
|
|||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ServerType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBClientProctoringConnectionData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamProctoringService;
|
||||
|
@ -42,9 +46,14 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
|||
"{\"context\":{\"user\":{\"name\":\"%s\"}},\"iss\":\"%s\",\"aud\":\"%s\",\"sub\":\"%s\",\"room\":\"%s\"%s}";
|
||||
|
||||
private final ExamSessionService examSessionService;
|
||||
private final Cryptor cryptor;
|
||||
|
||||
protected ExamJITSIProctoringService(
|
||||
final ExamSessionService examSessionService,
|
||||
final Cryptor cryptor) {
|
||||
|
||||
protected ExamJITSIProctoringService(final ExamSessionService examSessionService) {
|
||||
this.examSessionService = examSessionService;
|
||||
this.cryptor = cryptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -59,13 +68,14 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result<String> createProctoringURL(
|
||||
public Result<SEBClientProctoringConnectionData> createProctoringConnectionData(
|
||||
final ProctoringSettings examProctoring,
|
||||
final String connectionToken,
|
||||
final boolean server) {
|
||||
|
||||
return Result.tryCatch(() -> {
|
||||
return createProctoringURL(examProctoring,
|
||||
return createProctoringConnectionData(
|
||||
examProctoring,
|
||||
this.examSessionService
|
||||
.getConnectionData(connectionToken)
|
||||
.getOrThrow().clientConnection,
|
||||
|
@ -75,7 +85,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result<String> createProctoringURL(
|
||||
public Result<SEBClientProctoringConnectionData> createProctoringConnectionData(
|
||||
final ProctoringSettings examProctoring,
|
||||
final ClientConnection clientConnection,
|
||||
final boolean server) {
|
||||
|
@ -90,23 +100,29 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
|||
if (this.examSessionService.isExamRunning(examProctoring.examId)) {
|
||||
final Exam exam = this.examSessionService.getRunningExam(examProctoring.examId)
|
||||
.getOrThrow();
|
||||
expTime = exam.endTime.getMillis();
|
||||
if (exam.endTime != null) {
|
||||
expTime = exam.endTime.getMillis();
|
||||
}
|
||||
}
|
||||
|
||||
return createProctoringURL(
|
||||
final Encoder urlEncoder = Base64.getUrlEncoder().withoutPadding();
|
||||
final String roomName = urlEncoder.encodeToString(
|
||||
Utils.toByteArray(clientConnection.connectionToken));
|
||||
|
||||
return createProctoringConnectionData(
|
||||
examProctoring.serverURL,
|
||||
examProctoring.appKey,
|
||||
examProctoring.getAppSecret(),
|
||||
clientConnection.userSessionId,
|
||||
(server) ? "seb-server" : "seb-client",
|
||||
clientConnection.connectionToken,
|
||||
roomName,
|
||||
expTime)
|
||||
.getOrThrow();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public Result<String> createProctoringURL(
|
||||
public Result<SEBClientProctoringConnectionData> createProctoringConnectionData(
|
||||
final String url,
|
||||
final String appKey,
|
||||
final CharSequence appSecret,
|
||||
|
@ -117,46 +133,84 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
|||
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
final Encoder urlEncoder = Base64.getUrlEncoder().withoutPadding();
|
||||
|
||||
final String roomUrl = createServerConnectionURL(url, roomName);
|
||||
final String host = UriComponentsBuilder.fromHttpUrl(url)
|
||||
.build()
|
||||
.getHost();
|
||||
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append(url)
|
||||
.append("/")
|
||||
.append(roomName)
|
||||
.append("?jwt=");
|
||||
|
||||
final String jwtHeaderPart = urlEncoder
|
||||
.encodeToString(JITSI_ACCESS_TOKEN_HEADER.getBytes(StandardCharsets.UTF_8));
|
||||
final String jwtPayload = String.format(
|
||||
JITSI_ACCESS_TOKEN_PAYLOAD.replaceAll(" ", "").replaceAll("\n", ""),
|
||||
clientName,
|
||||
final CharSequence decryptedSecret = this.cryptor.decrypt(appSecret);
|
||||
final String token = createAccessToken(
|
||||
appKey,
|
||||
decryptedSecret,
|
||||
clientName,
|
||||
clientKey,
|
||||
host,
|
||||
roomName,
|
||||
(expTime != null)
|
||||
? String.format(",\"exp\":%s", String.valueOf(expTime))
|
||||
: "");
|
||||
final String jwtPayloadPart = urlEncoder
|
||||
.encodeToString(jwtPayload.getBytes(StandardCharsets.UTF_8));
|
||||
final String message = jwtHeaderPart + "." + jwtPayloadPart;
|
||||
expTime,
|
||||
host);
|
||||
|
||||
final Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
|
||||
final SecretKeySpec secret_key =
|
||||
new SecretKeySpec(Utils.toByteArray(appSecret), "HmacSHA256");
|
||||
sha256_HMAC.init(secret_key);
|
||||
final String hash = urlEncoder.encodeToString(sha256_HMAC.doFinal(Utils.toByteArray(message)));
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final String connectionURL = builder.append(roomUrl)
|
||||
.append("?jwt=")
|
||||
.append(token).toString();
|
||||
|
||||
builder.append(message)
|
||||
.append(".")
|
||||
.append(hash);
|
||||
|
||||
return builder.toString();
|
||||
return new SEBClientProctoringConnectionData(
|
||||
roomUrl,
|
||||
roomName,
|
||||
token,
|
||||
connectionURL);
|
||||
});
|
||||
}
|
||||
|
||||
private String createServerConnectionURL(
|
||||
final String url,
|
||||
final String roomName) {
|
||||
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
return builder.append(url)
|
||||
.append("/")
|
||||
.append(roomName)
|
||||
.toString();
|
||||
}
|
||||
|
||||
private String createAccessToken(
|
||||
final String appKey,
|
||||
final CharSequence appSecret,
|
||||
final String clientName,
|
||||
final String clientKey,
|
||||
final String roomName,
|
||||
final Long expTime,
|
||||
final String host) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final Encoder urlEncoder = Base64.getUrlEncoder().withoutPadding();
|
||||
|
||||
final String jwtHeaderPart = urlEncoder
|
||||
.encodeToString(JITSI_ACCESS_TOKEN_HEADER.getBytes(StandardCharsets.UTF_8));
|
||||
final String jwtPayload = String.format(
|
||||
JITSI_ACCESS_TOKEN_PAYLOAD.replaceAll(" ", "").replaceAll("\n", ""),
|
||||
clientName,
|
||||
appKey,
|
||||
clientKey,
|
||||
host,
|
||||
roomName,
|
||||
(expTime != null)
|
||||
? String.format(",\"exp\":%s", String.valueOf(expTime))
|
||||
: "");
|
||||
final String jwtPayloadPart = urlEncoder
|
||||
.encodeToString(jwtPayload.getBytes(StandardCharsets.UTF_8));
|
||||
final String message = jwtHeaderPart + "." + jwtPayloadPart;
|
||||
|
||||
final Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
|
||||
final SecretKeySpec secret_key =
|
||||
new SecretKeySpec(Utils.toByteArray(appSecret), "HmacSHA256");
|
||||
sha256_HMAC.init(secret_key);
|
||||
final String hash = urlEncoder.encodeToString(sha256_HMAC.doFinal(Utils.toByteArray(message)));
|
||||
|
||||
builder.append(message)
|
||||
.append(".")
|
||||
.append(hash);
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ import ch.ethz.seb.sebserver.gbl.model.exam.Chapters;
|
|||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBClientProctoringConnectionData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBRestriction;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.Features;
|
||||
|
@ -429,8 +430,8 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
|
|||
+ API.EXAM_ADMINISTRATION_PROCTOR_PATH_SEGMENT
|
||||
+ API.EXAM_MONITORING_SEB_CONNECTION_TOKEN_PATH_SEGMENT,
|
||||
method = RequestMethod.GET,
|
||||
produces = MediaType.TEXT_PLAIN_VALUE)
|
||||
public String getExamProctoringURL(
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public SEBClientProctoringConnectionData getExamProctoringURL(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
|
@ -444,8 +445,7 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
|
|||
.flatMap(this.examAdminService::getExamProctoring)
|
||||
.flatMap(proc -> this.examAdminService
|
||||
.getExamProctoringService(proc.serverType)
|
||||
.map(s -> s.createProctoringURL(proc, connectionToken, true))
|
||||
.getOrThrow())
|
||||
.flatMap(s -> s.createProctoringConnectionData(proc, connectionToken, true)))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,5 +5,5 @@ server.port=8080
|
|||
server.servlet.context-path=/
|
||||
server.tomcat.uri-encoding=UTF-8
|
||||
|
||||
logging.level.ch=DEBUG
|
||||
logging.level.ch=ERROR
|
||||
|
||||
|
|
|
@ -9,15 +9,22 @@
|
|||
package ch.ethz.seb.sebserver.webservice.servicelayer.exam.impl;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBClientProctoringConnectionData;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
|
||||
|
||||
public class ExamJITSIProctoringServiceTest {
|
||||
|
||||
@Test
|
||||
public void testCreateProctoringURL() {
|
||||
final ExamJITSIProctoringService examJITSIProctoringService = new ExamJITSIProctoringService(null);
|
||||
final String jwt = examJITSIProctoringService.createProctoringURL(
|
||||
Cryptor cryptorMock = Mockito.mock(Cryptor.class);
|
||||
Mockito.when(cryptorMock.decrypt(Mockito.any())).thenReturn("fbvgeghergrgrthrehreg123");
|
||||
final ExamJITSIProctoringService examJITSIProctoringService = new ExamJITSIProctoringService(null, cryptorMock);
|
||||
final SEBClientProctoringConnectionData data = examJITSIProctoringService.createProctoringConnectionData(
|
||||
"https://seb-jitsi.example.ch",
|
||||
"test-app",
|
||||
"fbvgeghergrgrthrehreg123",
|
||||
|
@ -27,9 +34,17 @@ public class ExamJITSIProctoringServiceTest {
|
|||
1609459200L)
|
||||
.getOrThrow();
|
||||
|
||||
assertNotNull(data);
|
||||
assertEquals(
|
||||
"https://seb-jitsi.example.ch/SomeRoom",
|
||||
data.serverURL);
|
||||
assertEquals(
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb250ZXh0Ijp7InVzZXIiOnsibmFtZSI6IlRlc3QgTmFtZSJ9fSwiaXNzIjoidGVzdC1hcHAiLCJhdWQiOiJ0ZXN0LWNsaWVudCIsInN1YiI6InNlYi1qaXRzaS5leGFtcGxlLmNoIiwicm9vbSI6IlNvbWVSb29tIiwiZXhwIjoxNjA5NDU5MjAwfQ.4ovqUkG6jrLvkDEZNdhbtFI_DFLDFsM2eBJHhcYq7a4",
|
||||
data.accessToken);
|
||||
assertEquals(
|
||||
"https://seb-jitsi.example.ch/SomeRoom?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb250ZXh0Ijp7InVzZXIiOnsibmFtZSI6IlRlc3QgTmFtZSJ9fSwiaXNzIjoidGVzdC1hcHAiLCJhdWQiOiJ0ZXN0LWNsaWVudCIsInN1YiI6InNlYi1qaXRzaS5leGFtcGxlLmNoIiwicm9vbSI6IlNvbWVSb29tIiwiZXhwIjoxNjA5NDU5MjAwfQ.4ovqUkG6jrLvkDEZNdhbtFI_DFLDFsM2eBJHhcYq7a4",
|
||||
jwt);
|
||||
data.connectionURL);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue