Skip to content

Commit

Permalink
Merge pull request #1 from Onlineberatung/develop
Browse files Browse the repository at this point in the history
[pull] develop from Onlineberatung:develop
  • Loading branch information
mebo4b authored Jul 4, 2022
2 parents cfd1803 + 9785730 commit 384296e
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public CreateVideoCallResponseDTO startVideoCall(Long sessionId, String initiato

var videoCallUuid = uuidRegistry.generateUniqueUuid();
var videoCallUrls = this.videoCallUrlGeneratorService
.generateVideoCallUrls(consultantSessionDto.getAskerUserName(), videoCallUuid);
.generateVideoCallUrls(videoCallUuid);

this.liveEventNotificationService
.sendVideoCallRequestLiveEvent(buildLiveEventMessage(consultantSessionDto,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class RejectVideoCallService {

private final @NonNull MessageControllerApi messageControllerApi;
private final @NonNull SecurityHeaderSupplier securityHeaderSupplier;
private final @NonNull TenantHeaderSupplier tenantHeaderSupplier;

/**
* Sends a system message with rejection type to the message service.
Expand All @@ -34,6 +35,7 @@ public void rejectVideoCall(RejectVideoCallDTO rejectVideoCallDto) {

private void addDefaultHeaders(ApiClient apiClient) {
var headers = this.securityHeaderSupplier.getKeycloakAndCsrfHttpHeaders();
tenantHeaderSupplier.addTenantHeader(headers);
headers.forEach((key, value) -> apiClient.addDefaultHeader(key, value.iterator().next()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import de.caritas.cob.videoservice.api.tenant.TenantContext;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand Down Expand Up @@ -33,17 +32,17 @@ public void addTenantHeader(HttpHeaders headers) {
/**
* Resolve tenantID from current request.
*
* @return
* @return the id of the tenant
*/
public Optional<Long> getTenantFromHeader() {
HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
var request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
try {
return Optional.of(Long.parseLong(request.getHeader("tenantId")));
} catch (NumberFormatException exception) {
log.debug("No tenantId provided via headers.");
return Optional.empty();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,12 @@ public class VideoCallUrlGeneratorService {
/**
* Generates the {@link VideoCallUrls} for guest, asker and consultant.
*
* @param askerName the username of the asker
* @param uuid the uuid of the video call
* @return the generated {@link VideoCallUrls}
*/
public VideoCallUrls generateVideoCallUrls(String askerName, String uuid) {
public VideoCallUrls generateVideoCallUrls(String uuid) {

var token = this.tokenGeneratorService.generateNonModeratorToken(uuid, askerName);
var token = this.tokenGeneratorService.generateNonModeratorVideoCallToken(uuid);

return VideoCallUrls.builder()
.userVideoUrl(buildUrl(uuid, token.getUserRelatedToken()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@
import com.auth0.jwt.algorithms.Algorithm;
import de.caritas.cob.videoservice.api.authorization.VideoUser;
import de.caritas.cob.videoservice.api.exception.httpresponse.InternalServerErrorException;
import de.caritas.cob.videoservice.api.service.decoder.UsernameDecoder;
import de.caritas.cob.videoservice.api.service.video.jwt.model.VideoCallToken;
import java.sql.Date;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import lombok.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
Expand All @@ -37,12 +34,9 @@ public TokenGeneratorService(

private final @NonNull VideoUser videoUser;

private static final String CONTEXT_CLAIM = "context";
private static final String ROOM_CLAIM = "room";
private static final String MODERATOR_CLAIM = "moderator";
private static final String GUEST_URL_CLAIM = "guestVideoCallUrl";
private static final String CONTEXT_USER = "user";
private static final String USER_NAME = "name";

@Value("${video.call.security.jwt.audience}")
private String audience;
Expand Down Expand Up @@ -79,16 +73,15 @@ public String generateToken(String roomId) {
}

/**
* Generates the {@link VideoCallToken} for anonymous user and asker (containing user name).
* Generates the {@link VideoCallToken} for anonymous user and asker.
*
* @param roomId the generated unique roomId
* @param askerName the username of the asker
* @return the generated {@link VideoCallToken}
*/
public VideoCallToken generateNonModeratorToken(String roomId, String askerName) {
public VideoCallToken generateNonModeratorVideoCallToken(String roomId) {
return VideoCallToken.builder()
.guestToken(generateNonModeratorToken(roomId))
.userRelatedToken(buildUserRelatedJwt(roomId, askerName))
.userRelatedToken(buildUserRelatedJwt(roomId))
.build();
}

Expand All @@ -114,21 +107,11 @@ private Date buildThreeHoursValidityDate() {
return new Date(epochMilli);
}

private String buildUserRelatedJwt(String roomId, String askerName) {
private String buildUserRelatedJwt(String roomId) {
return buildBasicJwt(roomId)
.withClaim(CONTEXT_CLAIM, createUserContext(askerName))
.sign(algorithm);
}

private Map<String, Map<String, String>> createUserContext(String askerName) {
Map<String, Map<String, String>> context = new HashMap<>();
Map<String, String> user = new HashMap<>();
user.put(USER_NAME, new UsernameDecoder().decodeUsername(askerName));
context.put(CONTEXT_USER, user);

return context;
}

/**
* Generates the {@link VideoCallToken} for the currently logged in moderator.
*
Expand All @@ -153,18 +136,14 @@ public String generateModeratorToken(String roomId, String guestVideoCallUrl) {
* @return token
*/
public String generateModeratorToken(String roomId) {
var userContext = createUserContext(videoUser.getUsername());

return buildBasicJwt(roomId)
.withClaim(MODERATOR_CLAIM, true)
.withClaim(CONTEXT_CLAIM, userContext)
.sign(algorithm);
}

private String buildModeratorJwt(String roomId, String guestVideoCallUrl) {
return buildBasicJwt(roomId)
.withClaim(MODERATOR_CLAIM, true)
.withClaim(CONTEXT_CLAIM, createUserContext(videoUser.getUsername()))
.withClaim(GUEST_URL_CLAIM, guestVideoCallUrl)
.sign(algorithm);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public void startVideoCall_Should_ReturnCorrectVideoCallUrl_When_UrlWasGenerated

when(sessionService.findSessionOfCurrentConsultant(SESSION_ID))
.thenReturn(consultantSessionDto);
when(videoCallUrlGeneratorService.generateVideoCallUrls(any(), any())).thenReturn(videoCallUrls);
when(videoCallUrlGeneratorService.generateVideoCallUrls(any())).thenReturn(videoCallUrls);

CreateVideoCallResponseDTO result = startVideoCallFacade.startVideoCall(SESSION_ID, "rcUserId");

Expand All @@ -88,7 +88,7 @@ public void startVideoCall_Should_CallLiveServiceAndBuildCorrectLiveEventMessage

when(sessionService.findSessionOfCurrentConsultant(SESSION_ID))
.thenReturn(consultantSessionDto);
when(videoCallUrlGeneratorService.generateVideoCallUrls(any(), any()))
when(videoCallUrlGeneratorService.generateVideoCallUrls(any()))
.thenReturn(videoCallUrls);
when(authenticatedUser.getUsername()).thenReturn(USERNAME);
ArgumentCaptor<LiveEventMessage> argument = ArgumentCaptor.forClass(LiveEventMessage.class);
Expand Down Expand Up @@ -131,7 +131,7 @@ public void startVideoCall_Should_FireAssignSessionStatisticsEvent() {

when(sessionService.findSessionOfCurrentConsultant(SESSION_ID))
.thenReturn(consultantSessionDto);
when(videoCallUrlGeneratorService.generateVideoCallUrls(any(), any())).thenReturn(videoCallUrls);
when(videoCallUrlGeneratorService.generateVideoCallUrls(any())).thenReturn(videoCallUrls);

CreateVideoCallResponseDTO result = startVideoCallFacade.startVideoCall(SESSION_ID, "rcUserId");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package de.caritas.cob.videoservice.api.service;

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -31,24 +30,29 @@ public class RejectVideoCallServiceTest {
@Mock
private SecurityHeaderSupplier securityHeaderSupplier;

@Mock
private TenantHeaderSupplier tenantHeaderSupplier;

@Mock
private ApiClient apiClient;

@Test
public void rejectVideoCall_Should_useServicesCorrectly() {
var securityHeaders = new HttpHeaders();
when(this.messageControllerApi.getApiClient()).thenReturn(this.apiClient);
when(this.securityHeaderSupplier.getKeycloakAndCsrfHttpHeaders()).thenReturn(new HttpHeaders());
RejectVideoCallDTO rejectVideoCallDto = new EasyRandom().nextObject(RejectVideoCallDTO.class);
when(this.securityHeaderSupplier.getKeycloakAndCsrfHttpHeaders()).thenReturn(securityHeaders);
var rejectVideoCallDto = new EasyRandom().nextObject(RejectVideoCallDTO.class);

this.rejectVideoCallService.rejectVideoCall(rejectVideoCallDto);

VideoCallMessageDTO expectedMessage = new VideoCallMessageDTO()
.eventType(EventTypeEnum.IGNORED_CALL)
.initiatorUserName(rejectVideoCallDto.getInitiatorUsername())
.initiatorRcUserId(rejectVideoCallDto.getInitiatorRcUserId());
verify(this.securityHeaderSupplier, times(1)).getKeycloakAndCsrfHttpHeaders();
verify(this.messageControllerApi, times(1))
.createVideoHintMessage(eq(rejectVideoCallDto.getRcGroupId()), eq(expectedMessage));
verify(this.securityHeaderSupplier).getKeycloakAndCsrfHttpHeaders();
verify(this.tenantHeaderSupplier).addTenantHeader(securityHeaders);
verify(this.messageControllerApi)
.createVideoHintMessage(rejectVideoCallDto.getRcGroupId(), expectedMessage);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package de.caritas.cob.videoservice.api.service;


import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.test.util.ReflectionTestUtils.setField;

import de.caritas.cob.videoservice.api.tenant.TenantContext;
import javax.servlet.http.HttpServletRequest;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

class TenantHeaderSupplierTest {

private final TenantHeaderSupplier tenantHeaderSupplier = new TenantHeaderSupplier();

@Test
void addTenantHeader_Should_addTenantIdToHeaders_When_multiTenancyIsEnabled() {
setField(tenantHeaderSupplier, "multitenancy", true);
var httpHeaders = new HttpHeaders();
TenantContext.setCurrentTenant(1L);

tenantHeaderSupplier.addTenantHeader(httpHeaders);

assertThat(httpHeaders.get("tenantId").get(0), is("1"));
}

@Test
void addTenantHeader_Should_notAddTenantIdToHeaders_When_multiTenancyIsDisabled() {
setField(tenantHeaderSupplier, "multitenancy", false);
var httpHeaders = new HttpHeaders();

tenantHeaderSupplier.addTenantHeader(httpHeaders);

assertThat(httpHeaders.get("tenantId"), nullValue());
}

@Test
void getTenantFromHeader_Should_returnTenantId_When_tenantIdExistsInHeader() {
givenMockedServletRequestWithTenandIdHeaderValue("1");

var result = tenantHeaderSupplier.getTenantFromHeader();

assertThat(result.isPresent(), is(true));
assertThat(result.get(), is(1L));
}

@Test
void getTenantFromHeader_Should_returnOptionalEmpty_When_tenantIdIsNoNumber() {
givenMockedServletRequestWithTenandIdHeaderValue("no number");

var result = tenantHeaderSupplier.getTenantFromHeader();

assertThat(result.isPresent(), is(false));
}

private void givenMockedServletRequestWithTenandIdHeaderValue(String tenantIdValue) {
var mockedServletRequest = mock(HttpServletRequest.class);
when(mockedServletRequest.getHeader("tenantId")).thenReturn(tenantIdValue);
var requestAttributes = new ServletRequestAttributes(mockedServletRequest);
RequestContextHolder.setRequestAttributes(requestAttributes);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import static org.springframework.test.util.ReflectionTestUtils.setField;

import de.caritas.cob.videoservice.api.exception.httpresponse.InternalServerErrorException;
import de.caritas.cob.videoservice.api.service.UuidRegistry;
import de.caritas.cob.videoservice.api.service.video.jwt.TokenGeneratorService;
import de.caritas.cob.videoservice.api.service.video.jwt.model.VideoCallToken;
import de.caritas.cob.videoservice.api.service.video.jwt.model.VideoCallUrls;
Expand Down Expand Up @@ -35,13 +34,13 @@ public void generateVideoCallUrls_Should_generateExpectedVideoCallUrls_When_aske
setField(this.videoCallUrlGeneratorService, FIELD_NAME_VIDEO_CALL_URL, VIDEO_CALL_URL);
VideoCallToken videoCallToken = new EasyRandom().nextObject(VideoCallToken.class);
String moderatorToken = "moderatorToken";
when(this.tokenGeneratorService.generateNonModeratorToken(any(), any()))
when(this.tokenGeneratorService.generateNonModeratorVideoCallToken(any()))
.thenReturn(videoCallToken);
when(this.tokenGeneratorService.generateModeratorToken(any(), any()))
.thenReturn(moderatorToken);

VideoCallUrls videoCallUrls = this.videoCallUrlGeneratorService
.generateVideoCallUrls("asker123", "uniqueId");
.generateVideoCallUrls("uniqueId");

assertThat(videoCallUrls.getUserVideoUrl(),
is(VIDEO_CALL_URL + "/uniqueId?jwt=" + videoCallToken.getUserRelatedToken()));
Expand All @@ -52,10 +51,10 @@ public void generateVideoCallUrls_Should_generateExpectedVideoCallUrls_When_aske
@Test(expected = InternalServerErrorException.class)
public void generateVideoCallUrls_Should_throwInternalServerErrorException_When_videoUrlIsInvalid() {
VideoCallToken videoCallToken = new EasyRandom().nextObject(VideoCallToken.class);
when(this.tokenGeneratorService.generateNonModeratorToken(any(), any()))
when(this.tokenGeneratorService.generateNonModeratorVideoCallToken(any()))
.thenReturn(videoCallToken);

this.videoCallUrlGeneratorService.generateVideoCallUrls("asker123", "uniqueId");
this.videoCallUrlGeneratorService.generateVideoCallUrls("uniqueId");
}

}
Loading

0 comments on commit 384296e

Please sign in to comment.