Skip to content

Commit

Permalink
feat: implement web token creation
Browse files Browse the repository at this point in the history
  • Loading branch information
webatspeed committed Apr 1, 2022
1 parent e53d4e4 commit 359048b
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package de.caritas.cob.videoservice.api.authorization;

import static java.util.Objects.nonNull;

import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -23,4 +27,11 @@ public class AuthenticatedUser {

@NonNull
private String accessToken;

private Set<String> roles;

@JsonIgnore
public boolean isConsultant() {
return nonNull(roles) && roles.contains(Authority.CONSULTANT.name());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import de.caritas.cob.videoservice.api.model.RejectVideoCallDTO;
import de.caritas.cob.videoservice.api.model.VideoCallInfoDTO;
import de.caritas.cob.videoservice.api.service.RejectVideoCallService;
import de.caritas.cob.videoservice.api.service.video.VideoCallUrlGeneratorService;
import de.caritas.cob.videoservice.generated.api.controller.VideocallsApi;
import io.swagger.annotations.Api;
import java.util.Optional;
import javax.validation.Valid;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
Expand All @@ -27,6 +27,7 @@ public class VideoController implements VideocallsApi {

private final @NonNull StartVideoCallFacade startVideoCallFacade;
private final @NonNull RejectVideoCallService rejectVideoCallService;
private final @NonNull VideoCallUrlGeneratorService videoCallUrlGeneratorService;

/**
* Starts a new video call.
Expand Down Expand Up @@ -55,7 +56,9 @@ public ResponseEntity<Void> rejectVideoCall(@Valid RejectVideoCallDTO rejectVide
}

@Override
public ResponseEntity<VideoCallInfoDTO> getWebToken(String rcUserId, String groupId) {
return ResponseEntity.of(Optional.empty());
public ResponseEntity<VideoCallInfoDTO> getWebToken(String rcUserId, String roomId) {
var videoCallInfo = videoCallUrlGeneratorService.generateJwt(roomId);

return ResponseEntity.ok(videoCallInfo);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.caritas.cob.videoservice.api.service.video;

import de.caritas.cob.videoservice.api.exception.httpresponse.InternalServerErrorException;
import de.caritas.cob.videoservice.api.model.VideoCallInfoDTO;
import de.caritas.cob.videoservice.api.service.video.jwt.TokenGeneratorService;
import de.caritas.cob.videoservice.api.service.video.jwt.model.VideoCallUrls;
import java.net.MalformedURLException;
Expand Down Expand Up @@ -57,4 +58,17 @@ private String buildUrl(String uuid, String token) {
}
}

/**
* Generate JWT.
*
* @param roomId room id
* @return VideoCallInfoDTO
*/
public VideoCallInfoDTO generateJwt(String roomId) {
var videoCallInfo = new VideoCallInfoDTO();
videoCallInfo.setJwt(tokenGeneratorService.generateToken(roomId));
videoCallInfo.setDomain(videoCallServerUrl);

return videoCallInfo;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ public void initAlgorithm() {
this.algorithm = Algorithm.HMAC256(this.secret);
}

/**
* Generate token.
*
* @param roomId room id
* @return token
*/
public String generateToken(String roomId) {
return authenticatedUser.isConsultant()
? generateModeratorToken(roomId)
: generateNonModeratorToken(roomId);
}

/**
* Generates the {@link VideoCallToken} for anonymous user and asker (containing user name).
*
Expand All @@ -69,12 +81,12 @@ public void initAlgorithm() {
*/
public VideoCallToken generateNonModeratorToken(String roomId, String askerName) {
return VideoCallToken.builder()
.guestToken(buildGuestJwt(roomId))
.guestToken(generateNonModeratorToken(roomId))
.userRelatedToken(buildUserRelatedJwt(roomId, askerName))
.build();
}

private String buildGuestJwt(String roomId) {
public String generateNonModeratorToken(String roomId) {
return buildBasicJwt(roomId)
.sign(algorithm);
}
Expand Down Expand Up @@ -128,6 +140,21 @@ public String generateModeratorToken(String roomId, String guestVideoCallUrl) {
return buildModeratorJwt(roomId, guestVideoCallUrl);
}

/**
* Generate moderator token.
*
* @param roomId room id
* @return token
*/
public String generateModeratorToken(String roomId) {
var userContext = createUserContext(authenticatedUser.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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public AuthenticatedUser getAuthenticatedUser() {
authenticatedUser.setUserId(getUserAttribute(claimMap, CLAIM_NAME_USER_ID));
authenticatedUser.setUsername(getUserAttribute(claimMap, CLAIM_NAME_USERNAME));

var roles = keycloakSecContext.getToken().getRealmAccess().getRoles();
authenticatedUser.setRoles(roles);

return authenticatedUser;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ protected void configure(HttpSecurity http) throws Exception {
.hasAuthority(CONSULTANT.getAuthority())
.antMatchers("/videocalls/reject")
.hasAnyAuthority(USER.getAuthority())
.antMatchers("/videocalls/*/jwt")
.hasAnyAuthority(CONSULTANT.getAuthority()) //TODO: add anonymous
.anyRequest().denyAll()
.and()
.exceptionHandling()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import de.caritas.cob.videoservice.api.facade.StartVideoCallFacade;
import de.caritas.cob.videoservice.api.model.RejectVideoCallDTO;
import de.caritas.cob.videoservice.api.service.RejectVideoCallService;
import de.caritas.cob.videoservice.api.service.video.VideoCallUrlGeneratorService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -48,6 +49,9 @@ public class VideoControllerIT {
@MockBean
private RoleAuthorizationAuthorityMapper roleAuthorizationAuthorityMapper;

@MockBean
private VideoCallUrlGeneratorService videoCallUrlGeneratorService;

@Test
public void createVideoCall_Should_ReturnCreated_When_EverythingSucceeded() throws Exception {

Expand Down

0 comments on commit 359048b

Please sign in to comment.