diff --git a/src/main/java/de/caritas/cob/videoservice/api/facade/StartVideoCallFacade.java b/src/main/java/de/caritas/cob/videoservice/api/facade/StartVideoCallFacade.java index 9a99043..9324cda 100644 --- a/src/main/java/de/caritas/cob/videoservice/api/facade/StartVideoCallFacade.java +++ b/src/main/java/de/caritas/cob/videoservice/api/facade/StartVideoCallFacade.java @@ -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, diff --git a/src/main/java/de/caritas/cob/videoservice/api/service/RejectVideoCallService.java b/src/main/java/de/caritas/cob/videoservice/api/service/RejectVideoCallService.java index c2004e1..b225737 100644 --- a/src/main/java/de/caritas/cob/videoservice/api/service/RejectVideoCallService.java +++ b/src/main/java/de/caritas/cob/videoservice/api/service/RejectVideoCallService.java @@ -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. @@ -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())); } diff --git a/src/main/java/de/caritas/cob/videoservice/api/service/TenantHeaderSupplier.java b/src/main/java/de/caritas/cob/videoservice/api/service/TenantHeaderSupplier.java index 39f4ad8..7989075 100644 --- a/src/main/java/de/caritas/cob/videoservice/api/service/TenantHeaderSupplier.java +++ b/src/main/java/de/caritas/cob/videoservice/api/service/TenantHeaderSupplier.java @@ -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; @@ -33,12 +32,11 @@ public void addTenantHeader(HttpHeaders headers) { /** * Resolve tenantID from current request. * - * @return + * @return the id of the tenant */ public Optional 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) { @@ -46,4 +44,5 @@ public Optional getTenantFromHeader() { return Optional.empty(); } } + } diff --git a/src/main/java/de/caritas/cob/videoservice/api/service/video/VideoCallUrlGeneratorService.java b/src/main/java/de/caritas/cob/videoservice/api/service/video/VideoCallUrlGeneratorService.java index 5c81e62..b666b87 100644 --- a/src/main/java/de/caritas/cob/videoservice/api/service/video/VideoCallUrlGeneratorService.java +++ b/src/main/java/de/caritas/cob/videoservice/api/service/video/VideoCallUrlGeneratorService.java @@ -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())) diff --git a/src/main/java/de/caritas/cob/videoservice/api/service/video/jwt/TokenGeneratorService.java b/src/main/java/de/caritas/cob/videoservice/api/service/video/jwt/TokenGeneratorService.java index 280f1ca..7504160 100644 --- a/src/main/java/de/caritas/cob/videoservice/api/service/video/jwt/TokenGeneratorService.java +++ b/src/main/java/de/caritas/cob/videoservice/api/service/video/jwt/TokenGeneratorService.java @@ -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; @@ -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; @@ -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(); } @@ -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> createUserContext(String askerName) { - Map> context = new HashMap<>(); - Map 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. * @@ -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); } diff --git a/src/test/java/de/caritas/cob/videoservice/api/facade/StartVideoCallFacadeTest.java b/src/test/java/de/caritas/cob/videoservice/api/facade/StartVideoCallFacadeTest.java index 26fc01e..1069f0c 100644 --- a/src/test/java/de/caritas/cob/videoservice/api/facade/StartVideoCallFacadeTest.java +++ b/src/test/java/de/caritas/cob/videoservice/api/facade/StartVideoCallFacadeTest.java @@ -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"); @@ -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 argument = ArgumentCaptor.forClass(LiveEventMessage.class); @@ -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"); diff --git a/src/test/java/de/caritas/cob/videoservice/api/service/RejectVideoCallServiceTest.java b/src/test/java/de/caritas/cob/videoservice/api/service/RejectVideoCallServiceTest.java index 96891c0..fd79d9f 100644 --- a/src/test/java/de/caritas/cob/videoservice/api/service/RejectVideoCallServiceTest.java +++ b/src/test/java/de/caritas/cob/videoservice/api/service/RejectVideoCallServiceTest.java @@ -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; @@ -31,14 +30,18 @@ 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); @@ -46,9 +49,10 @@ public void rejectVideoCall_Should_useServicesCorrectly() { .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); } } diff --git a/src/test/java/de/caritas/cob/videoservice/api/service/TenantHeaderSupplierTest.java b/src/test/java/de/caritas/cob/videoservice/api/service/TenantHeaderSupplierTest.java new file mode 100644 index 0000000..bb85658 --- /dev/null +++ b/src/test/java/de/caritas/cob/videoservice/api/service/TenantHeaderSupplierTest.java @@ -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); + } + +} diff --git a/src/test/java/de/caritas/cob/videoservice/api/service/video/VideoCallUrlGeneratorServiceTest.java b/src/test/java/de/caritas/cob/videoservice/api/service/video/VideoCallUrlGeneratorServiceTest.java index c9a4af1..ef4b106 100644 --- a/src/test/java/de/caritas/cob/videoservice/api/service/video/VideoCallUrlGeneratorServiceTest.java +++ b/src/test/java/de/caritas/cob/videoservice/api/service/video/VideoCallUrlGeneratorServiceTest.java @@ -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; @@ -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())); @@ -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"); } } diff --git a/src/test/java/de/caritas/cob/videoservice/api/service/video/jwt/TokenGeneratorServiceTest.java b/src/test/java/de/caritas/cob/videoservice/api/service/video/jwt/TokenGeneratorServiceTest.java index a0ca77d..c65b1e0 100644 --- a/src/test/java/de/caritas/cob/videoservice/api/service/video/jwt/TokenGeneratorServiceTest.java +++ b/src/test/java/de/caritas/cob/videoservice/api/service/video/jwt/TokenGeneratorServiceTest.java @@ -59,7 +59,7 @@ private void verifyBasicTokenFields(String jwt, String expectedRoomId) { @Test public void generateNonModeratorToken_Should_returnExpectedTokens_When_roomIdIsGiven() { - VideoCallToken token = this.tokenGeneratorService.generateNonModeratorToken("validRoomId", ""); + VideoCallToken token = this.tokenGeneratorService.generateNonModeratorVideoCallToken("validRoomId"); String guestToken = token.getGuestToken(); String userToken = token.getUserRelatedToken(); @@ -70,7 +70,7 @@ public void generateNonModeratorToken_Should_returnExpectedTokens_When_roomIdIsG @Test public void generateNonModeratorToken_Should_returnExpectedTokens_When_roomIdAndAskerAreEmpty() { - VideoCallToken token = this.tokenGeneratorService.generateNonModeratorToken("", ""); + VideoCallToken token = this.tokenGeneratorService.generateNonModeratorVideoCallToken(""); String guestToken = token.getGuestToken(); String userToken = token.getUserRelatedToken(); @@ -78,18 +78,6 @@ public void generateNonModeratorToken_Should_returnExpectedTokens_When_roomIdAnd verifyBasicTokenFields(guestToken, ""); verifyBasicTokenFields(userToken, ""); assertThat(JWT.decode(guestToken).getClaim("context"), instanceOf(NullClaim.class)); - assertThat(JWT.decode(userToken).getClaim("context").asMap().get("user").toString(), - is("{name=}")); - } - - @Test - public void generateNonModeratorToken_Should_returnExpectedContextInUserToken_When_askerUsernameIsGiven() { - VideoCallToken token = this.tokenGeneratorService.generateNonModeratorToken("", "asker123"); - - String userToken = token.getUserRelatedToken(); - - assertThat(JWT.decode(userToken).getClaim("context").asMap().get("user").toString(), - is("{name=asker123}")); } @Test(expected = InternalServerErrorException.class) @@ -109,31 +97,24 @@ public void generateModeratorToken_Should_ThrowInternalServerErrorException_When @Test public void generateModeratorToken_Should_returnExpectedToken_When_ParamsAreGiven() { - when(authenticatedUser.getUsername()).thenReturn(USERNAME); - String moderatorToken = this.tokenGeneratorService .generateModeratorToken("validRoomId", GUEST_VIDEO_CALL_URL); verifyBasicTokenFields(moderatorToken, "validRoomId"); assertThat(JWT.decode(moderatorToken).getClaim("moderator").asBoolean(), is(true)); - assertThat(JWT.decode(moderatorToken).getClaim("context").asMap().get("user").toString(), - is("{name=" + USERNAME + "}")); assertThat(JWT.decode(moderatorToken).getClaim("guestVideoCallUrl").asString(), is(GUEST_VIDEO_CALL_URL)); } @Test public void generateToken_should_generate_moderator_token_if_user_is_consultant() { - when(authenticatedUser.getUsername()).thenReturn(USERNAME); when(authenticatedUser.isConsultant()).thenReturn(true); var moderatorToken = tokenGeneratorService.generateToken("privateRoom4711"); verifyBasicTokenFields(moderatorToken, "privateRoom4711"); assertThat(JWT.decode(moderatorToken).getClaim("moderator").asBoolean(), is(true)); - assertThat(JWT.decode(moderatorToken).getClaim("context").asMap().get("user").toString(), - is("{name=" + USERNAME + "}")); } @Test @@ -143,7 +124,6 @@ public void generateToken_should_generate_non_moderator_token_if_user_is_no_cons var moderatorToken = tokenGeneratorService.generateToken("privateRoom4711"); assertThat(JWT.decode(moderatorToken).getClaim("moderator").isNull(), is(true)); - assertThat(JWT.decode(moderatorToken).getClaim("context").isNull(), is(true)); verifyBasicTokenFields(moderatorToken, "privateRoom4711"); } }