diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/domain/UserRef.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/domain/UserRef.java index da0098fbfe5bb36ae4ad03b4a1f08d8f9c5ac3cd..e312c32f34a0291fedc34a49c7b55453879e7a1d 100644 --- a/src/main/java/cz/muni/ics/kypo/training/adaptive/domain/UserRef.java +++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/domain/UserRef.java @@ -46,6 +46,14 @@ public class UserRef extends AbstractEntity<Long> { public UserRef() { } + /** + * Instantiates a new user reference + * @param userRefId id of the user stored in user management service + */ + public UserRef(Long userRefId) { + this.userRefId = userRefId; + } + /** * Gets unique identification number of user reference * diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingDefinitionFacade.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingDefinitionFacade.java index 1bd8d45c15181e2135b69e2d5292f002276681ff..8daa63b23b070523b683121b0c6973500f9f9d00 100644 --- a/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingDefinitionFacade.java +++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingDefinitionFacade.java @@ -110,7 +110,7 @@ public class TrainingDefinitionFacade { if (securityService.hasRole(RoleTypeSecurity.ROLE_ADAPTIVE_TRAINING_ADMINISTRATOR)) { return mapToDtoAndAddArchivingInfo(trainingDefinitionService.findAll(predicate, pageable)); } else { - Long loggedInUserId = securityService.getUserRefIdFromUserAndGroup(); + Long loggedInUserId = userService.getLoggedInUserRefId(); return mapToDtoAndAddArchivingInfo(trainingDefinitionService.findAll(predicate, pageable, loggedInUserId)); } } @@ -133,7 +133,7 @@ public class TrainingDefinitionFacade { @IsOrganizerOrAdmin @TransactionalRO public PageResultResource<TrainingDefinitionInfoDTO> findAllForOrganizers(TDState state, Pageable pageable) { - Long loggedInUserId = securityService.getUserRefIdFromUserAndGroup(); + Long loggedInUserId = userService.getLoggedInUserRefId(); if (state == TDState.RELEASED) { return trainingDefinitionMapper.mapToPageResultResourceInfoDTO( trainingDefinitionService.findAllForOrganizers(TDState.RELEASED, pageable)); @@ -297,7 +297,7 @@ public class TrainingDefinitionFacade { @TransactionalWO public void editAuthors(Long trainingDefinitionId, Set<Long> authorsAddition, Set<Long> authorsRemoval) { TrainingDefinition trainingDefinition = trainingDefinitionService.findById(trainingDefinitionId); - Long loggedInUserRefId = securityService.getUserRefIdFromUserAndGroup(); + Long loggedInUserRefId = userService.getLoggedInUserRefId(); if (authorsRemoval != null && !authorsRemoval.isEmpty()) { authorsRemoval.remove(loggedInUserRefId); trainingDefinition.removeAuthorsByUserRefIds(authorsRemoval); diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingInstanceFacade.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingInstanceFacade.java index 84bca1e5a4cf03b1c136ba1314ce321aeb11c9c1..cb12dfb0f0da9376c32cd966039924c1dcbdb768 100644 --- a/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingInstanceFacade.java +++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingInstanceFacade.java @@ -23,6 +23,7 @@ import cz.muni.ics.kypo.training.adaptive.service.SecurityService; import cz.muni.ics.kypo.training.adaptive.service.UserService; import cz.muni.ics.kypo.training.adaptive.service.api.ElasticsearchServiceApi; import cz.muni.ics.kypo.training.adaptive.service.api.SandboxServiceApi; +import cz.muni.ics.kypo.training.adaptive.service.api.UserManagementServiceApi; import cz.muni.ics.kypo.training.adaptive.service.training.TrainingDefinitionService; import cz.muni.ics.kypo.training.adaptive.service.training.TrainingInstanceService; import cz.muni.ics.kypo.training.adaptive.service.training.TrainingRunService; @@ -115,7 +116,7 @@ public class TrainingInstanceFacade { if (securityService.hasRole(RoleTypeSecurity.ROLE_ADAPTIVE_TRAINING_ADMINISTRATOR)) { return trainingInstanceMapper.mapToPageResultResourceBasicView(trainingInstanceService.findAll(predicate, pageable)); } - return trainingInstanceMapper.mapToPageResultResourceBasicView(trainingInstanceService.findAll(predicate, pageable, securityService.getUserRefIdFromUserAndGroup())); + return trainingInstanceMapper.mapToPageResultResourceBasicView(trainingInstanceService.findAll(predicate, pageable, userService.getLoggedInUserRefId())); } /** @@ -363,7 +364,7 @@ public class TrainingInstanceFacade { @TransactionalWO public void editOrganizers(Long trainingInstanceId, Set<Long> organizersAddition, Set<Long> organizersRemoval) { TrainingInstance trainingInstance = trainingInstanceService.findById(trainingInstanceId); - Long loggedInUserRefId = securityService.getUserRefIdFromUserAndGroup(); + Long loggedInUserRefId = userService.getLoggedInUserRefId(); if (organizersRemoval != null && !organizersRemoval.isEmpty()) { organizersRemoval.remove(loggedInUserRefId); trainingInstance.removeOrganizersByUserRefIds(organizersRemoval); diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingRunFacade.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingRunFacade.java index 853a34d2d88e3b6b13c1a080568fc8d351490587..b2999644caeffdc918268cc12cbae2eae5260971 100644 --- a/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingRunFacade.java +++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingRunFacade.java @@ -30,6 +30,7 @@ import cz.muni.ics.kypo.training.adaptive.mapping.mapstruct.PhaseMapper; import cz.muni.ics.kypo.training.adaptive.mapping.mapstruct.TrainingRunMapper; import cz.muni.ics.kypo.training.adaptive.service.SecurityService; import cz.muni.ics.kypo.training.adaptive.service.UserService; +import cz.muni.ics.kypo.training.adaptive.service.api.UserManagementServiceApi; import cz.muni.ics.kypo.training.adaptive.service.training.TrainingRunService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,7 +57,6 @@ public class TrainingRunFacade { private static final Logger LOG = LoggerFactory.getLogger(TrainingRunFacade.class); private TrainingRunService trainingRunService; - private SecurityService securityService; private UserService userService; private TrainingRunMapper trainingRunMapper; private PhaseMapper phaseMapper; @@ -66,19 +66,16 @@ public class TrainingRunFacade { * Instantiates a new Training run facade. * * @param trainingRunService the training run service - * @param securityService the security service * @param userService the user service * @param trainingRunMapper the training run mapper * @param phaseMapper the phase mapper */ @Autowired public TrainingRunFacade(TrainingRunService trainingRunService, - SecurityService securityService, UserService userService, TrainingRunMapper trainingRunMapper, PhaseMapper phaseMapper) { this.trainingRunService = trainingRunService; - this.securityService = securityService; this.userService = userService; this.trainingRunMapper = trainingRunMapper; this.phaseMapper = phaseMapper; @@ -180,7 +177,7 @@ public class TrainingRunFacade { public AccessTrainingRunDTO accessTrainingRun(String accessToken) { TrainingInstance trainingInstance = trainingRunService.getTrainingInstanceForParticularAccessToken(accessToken); // checking if the user is not accessing to his existing training run (resume action) - Long participantRefId = securityService.getUserRefIdFromUserAndGroup(); + Long participantRefId = userService.getLoggedInUserRefId(); Optional<TrainingRun> accessedTrainingRun = trainingRunService.findRunningTrainingRunOfUser(accessToken, participantRefId); if (accessedTrainingRun.isPresent()) { return convertToAccessTrainingRunDTO(trainingRunService.resumeTrainingRun(accessedTrainingRun.get().getId())); diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/SecurityService.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/SecurityService.java index a9faf9a3bcba92a11be0ada98344f5c568978ec6..f9ef5b3b073a1cc4f99e4c7c41016966723a67f4 100644 --- a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/SecurityService.java +++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/SecurityService.java @@ -11,14 +11,13 @@ import cz.muni.ics.kypo.training.adaptive.exceptions.*; import cz.muni.ics.kypo.training.adaptive.repository.training.TrainingDefinitionRepository; import cz.muni.ics.kypo.training.adaptive.repository.training.TrainingInstanceRepository; import cz.muni.ics.kypo.training.adaptive.repository.training.TrainingRunRepository; +import cz.muni.ics.kypo.training.adaptive.service.api.UserManagementServiceApi; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; -import org.springframework.web.reactive.function.client.WebClient; /** @@ -28,10 +27,10 @@ import org.springframework.web.reactive.function.client.WebClient; @TransactionalRO(propagation = Propagation.REQUIRES_NEW) public class SecurityService { + private UserManagementServiceApi userManagementServiceApi; private TrainingRunRepository trainingRunRepository; private TrainingDefinitionRepository trainingDefinitionRepository; private TrainingInstanceRepository trainingInstanceRepository; - private WebClient userManagementWebClient; /** * Instantiates a new Security service. @@ -39,17 +38,16 @@ public class SecurityService { * @param trainingInstanceRepository the training instance repository * @param trainingDefinitionRepository the training definition repository * @param trainingRunRepository the training run repository - * @param userManagementWebClient the java rest template */ @Autowired - public SecurityService(TrainingInstanceRepository trainingInstanceRepository, + public SecurityService(UserManagementServiceApi userManagementServiceApi, + TrainingInstanceRepository trainingInstanceRepository, TrainingDefinitionRepository trainingDefinitionRepository, - TrainingRunRepository trainingRunRepository, - @Qualifier("userManagementServiceWebClient") WebClient userManagementWebClient) { + TrainingRunRepository trainingRunRepository) { + this.userManagementServiceApi = userManagementServiceApi; this.trainingDefinitionRepository = trainingDefinitionRepository; this.trainingInstanceRepository = trainingInstanceRepository; this.trainingRunRepository = trainingRunRepository; - this.userManagementWebClient = userManagementWebClient; } /** @@ -62,7 +60,7 @@ public class SecurityService { TrainingRun trainingRun = trainingRunRepository.findById(trainingRunId) .orElseThrow(() -> new EntityNotFoundException(new EntityErrorDetail(TrainingRun.class, "id", trainingRunId.getClass(), trainingRunId, "The necessary permissions are required for a resource."))); - return trainingRun.getParticipantRef().getUserRefId().equals(getUserRefIdFromUserAndGroup()); + return trainingRun.getParticipantRef().getUserRefId().equals(userManagementServiceApi.getUserRefIdFromUserAndGroup()); } /** @@ -76,7 +74,7 @@ public class SecurityService { .orElseThrow(() -> new EntityNotFoundException(new EntityErrorDetail(TrainingInstance.class, "id", instanceId.getClass(), instanceId, "The necessary permissions are required for a resource."))); return trainingInstance.getOrganizers().stream() - .anyMatch(o -> o.getUserRefId().equals(getUserRefIdFromUserAndGroup())); + .anyMatch(o -> o.getUserRefId().equals(userManagementServiceApi.getUserRefIdFromUserAndGroup())); } /** @@ -90,7 +88,7 @@ public class SecurityService { .orElseThrow(() -> new EntityNotFoundException(new EntityErrorDetail(TrainingRun.class, "id", trainingRunId.getClass(), trainingRunId, "The necessary permissions are required for a resource."))); return trainingRun.getTrainingInstance().getOrganizers().stream() - .anyMatch(o -> o.getUserRefId().equals(getUserRefIdFromUserAndGroup())); + .anyMatch(o -> o.getUserRefId().equals(userManagementServiceApi.getUserRefIdFromUserAndGroup())); } /** @@ -103,7 +101,7 @@ public class SecurityService { TrainingDefinition trainingDefinition = trainingDefinitionRepository.findById(definitionId) .orElseThrow(() -> new ForbiddenException("The necessary permissions are required for a resource.")); return trainingDefinition.getAuthors().stream() - .anyMatch(a -> a.getUserRefId().equals(getUserRefIdFromUserAndGroup())); + .anyMatch(a -> a.getUserRefId().equals(userManagementServiceApi.getUserRefIdFromUserAndGroup())); } /** @@ -116,7 +114,7 @@ public class SecurityService { TrainingDefinition trainingDefinition = trainingDefinitionRepository.findByPhaseId(phaseId) .orElseThrow(() -> new ForbiddenException("The necessary permissions are required for a resource.")); return trainingDefinition.getAuthors().stream() - .anyMatch(a -> a.getUserRefId().equals(getUserRefIdFromUserAndGroup())); + .anyMatch(a -> a.getUserRefId().equals(userManagementServiceApi.getUserRefIdFromUserAndGroup())); } /** @@ -129,7 +127,7 @@ public class SecurityService { TrainingDefinition trainingDefinition = trainingDefinitionRepository.findByTaskId(taskId) .orElseThrow(() -> new ForbiddenException("The necessary permissions are required for a resource.")); return trainingDefinition.getAuthors().stream() - .anyMatch(a -> a.getUserRefId().equals(getUserRefIdFromUserAndGroup())); + .anyMatch(a -> a.getUserRefId().equals(userManagementServiceApi.getUserRefIdFromUserAndGroup())); } /** @@ -148,48 +146,6 @@ public class SecurityService { return false; } - /** - * Gets user ref id from user and group. - * - * @return the user ref id from user and group - */ - public Long getUserRefIdFromUserAndGroup() { - try { - UserRefDTO userRefDTO = userManagementWebClient - .get() - .uri("/users/info") - .retrieve() - .bodyToMono(UserRefDTO.class) - .block(); - checkNonNull(userRefDTO, "Returned null response when calling user management service API to get info about logged in user."); - return userRefDTO.getUserRefId(); - } catch (CustomWebClientException ex) { - throw new MicroserviceApiException("Error when calling user management service API to get info about logged in user.", ex.getApiSubError()); - } - } - - /** - * Create user ref entity by info from user and group user ref. - * - * @return the user ref - */ - public UserRef createUserRefEntityByInfoFromUserAndGroup() { - try { - UserRefDTO userRefDTO = userManagementWebClient - .get() - .uri("/users/info") - .retrieve() - .bodyToMono(UserRefDTO.class) - .block(); - checkNonNull(userRefDTO, "Returned null response when calling user management service API to get info about logged in user."); - UserRef userRef = new UserRef(); - userRef.setUserRefId(userRefDTO.getUserRefId()); - return userRef; - } catch (CustomWebClientException ex) { - throw new MicroserviceApiException("Error when calling user management service API to get info about logged in user.", ex.getApiSubError()); - } - } - /** * Check if response from external API is not null. * diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/UserService.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/UserService.java index fc20b10cde3fa2ff110d4e216955eaae26c3bd76..c3fab5355cbfb9002cd8d3b29f296a6dd8381bf0 100644 --- a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/UserService.java +++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/UserService.java @@ -10,6 +10,7 @@ import cz.muni.ics.kypo.training.adaptive.exceptions.EntityErrorDetail; import cz.muni.ics.kypo.training.adaptive.exceptions.EntityNotFoundException; import cz.muni.ics.kypo.training.adaptive.exceptions.MicroserviceApiException; import cz.muni.ics.kypo.training.adaptive.repository.UserRefRepository; +import cz.muni.ics.kypo.training.adaptive.service.api.UserManagementServiceApi; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; @@ -31,19 +32,18 @@ public class UserService { private static final Logger LOG = LoggerFactory.getLogger(UserService.class); - private WebClient userManagementServiceWebClient; - private UserRefRepository userRefRepository; + private final UserRefRepository userRefRepository; + private final UserManagementServiceApi userManagementServiceApi; /** * Instantiates a new User service. * - * @param userManagementServiceWebClient the rest template * @param userRefRepository the user ref repository */ - public UserService(@Qualifier("userManagementServiceWebClient") WebClient userManagementServiceWebClient, - UserRefRepository userRefRepository) { - this.userManagementServiceWebClient = userManagementServiceWebClient; + public UserService(UserRefRepository userRefRepository, + UserManagementServiceApi userManagementServiceApi) { this.userRefRepository = userRefRepository; + this.userManagementServiceApi = userManagementServiceApi; } /** @@ -58,121 +58,6 @@ public class UserService { .orElseThrow(() -> new EntityNotFoundException(new EntityErrorDetail(UserRef.class, "id", userRefId.getClass(), userRefId))); } - /** - * Finds specific User reference by login - * - * @param id of wanted User reference - * @return {@link UserRef} with corresponding login - * @throws EntityNotFoundException UserRef was not found - */ - public UserRefDTO getUserRefDTOByUserRefId(Long id) { - try { - return userManagementServiceWebClient - .get() - .uri("/users/{id}", id) - .retrieve() - .bodyToMono(UserRefDTO.class) - .block(); - } catch (CustomWebClientException ex) { - throw new MicroserviceApiException("Error when calling user management service API to obtain info about user(ID: " + id + ").", ex.getApiSubError()); - } - } - - /** - * Gets users with given user ref ids. - * - * @param userRefIds the user ref ids - * @param pageable pageable parameter with information about pagination. - * @param givenName optional parameter used for filtration - * @param familyName optional parameter used for filtration - * @return the users with given user ref ids - */ - public PageResultResource<UserRefDTO> getUsersRefDTOByGivenUserIds(Set<Long> userRefIds, Pageable pageable, String givenName, String familyName) { - if (userRefIds.isEmpty()) { - return new PageResultResource<>(Collections.emptyList(), new PageResultResource.Pagination(0, 0, pageable.getPageSize(), 0, 0)); - } - try { - return userManagementServiceWebClient - .get() - .uri(uriBuilder -> { - uriBuilder - .path("/users/ids") - .queryParam("ids", StringUtils.collectionToDelimitedString(userRefIds, ",")); - this.setCommonParams(givenName, familyName, pageable, uriBuilder); - return uriBuilder.build(); - } - ) - .retrieve() - .bodyToMono(new ParameterizedTypeReference<PageResultResource<UserRefDTO>>() { - }) - .block(); - } catch (CustomWebClientException ex) { - throw new MicroserviceApiException("Error when calling user management service API to obtain users by IDs: " + userRefIds + ".", ex.getApiSubError()); - } - } - - /** - * Finds all logins of users that have role of designer - * - * @param roleType the role type - * @param pageable pageable parameter with information about pagination. - * @param givenName optional parameter used for filtration - * @param familyName optional parameter used for filtration - * @return list of users with given role - */ - public PageResultResource<UserRefDTO> getUsersByGivenRole(RoleType roleType, Pageable pageable, String givenName, String familyName) { - try { - return userManagementServiceWebClient - .get() - .uri(uriBuilder -> { - uriBuilder - .path("/roles/users") - .queryParam("roleType", roleType.name()); - this.setCommonParams(givenName, familyName, pageable, uriBuilder); - return uriBuilder.build(); - } - ) - .retrieve() - .bodyToMono(new ParameterizedTypeReference<PageResultResource<UserRefDTO>>() { - }) - .block(); - } catch (CustomWebClientException ex) { - throw new MicroserviceApiException("Error when calling user management service API to obtain users with role " + roleType.name() + ".", ex.getApiSubError()); - } - } - - /** - * Finds all logins of users that have role of designer - * - * @param roleType the role type - * @param userRefIds ids of the users who should be excluded from the result set. - * @param pageable the pageable - * @param givenName optional parameter used for filtration - * @param familyName optional parameter used for filtration - * @return list of users with given role - */ - public PageResultResource<UserRefDTO> getUsersByGivenRoleAndNotWithGivenIds(RoleType roleType, Set<Long> userRefIds, Pageable pageable, String givenName, String familyName) { - try { - return userManagementServiceWebClient - .get() - .uri(uriBuilder -> { - uriBuilder - .path("/roles/users-not-with-ids") - .queryParam("roleType", roleType.name()) - .queryParam("ids", StringUtils.collectionToDelimitedString(userRefIds, ",")); - this.setCommonParams(givenName, familyName, pageable, uriBuilder); - return uriBuilder.build(); - } - ) - .retrieve() - .bodyToMono(new ParameterizedTypeReference<PageResultResource<UserRefDTO>>() { - }) - .block(); - } catch (CustomWebClientException ex) { - throw new MicroserviceApiException("Error when calling user management service API to obtain users with role " + roleType.name() + " and IDs: " + userRefIds + ".", ex.getApiSubError()); - } - } - /** * Create new user reference * @@ -186,27 +71,23 @@ public class UserService { return userRef; } - private void setCommonParams(String givenName, String familyName, Pageable pageable, UriBuilder builder) { - if (givenName != null) { - builder.queryParam("givenName", givenName); - } - if (familyName != null) { - builder.queryParam("familyName", familyName); - } - builder.queryParam("page", pageable.getPageNumber()); - builder.queryParam("size", pageable.getPageSize()); + public UserRefDTO getUserRefDTOByUserRefId(Long id) { + return userManagementServiceApi.getUserRefDTOByUserRefId(id); } - /** - * Check if response from external API is not null. - * - * @param object object to check - * @param message exception message if response is null - * @throws MicroserviceApiException if response is null - */ - private void checkNonNull(Object object, String message) { - if (object == null) { - throw new MicroserviceApiException(message); - } + public Long getLoggedInUserRefId() { + return userManagementServiceApi.getUserRefIdFromUserAndGroup(); + } + + public PageResultResource<UserRefDTO> getUsersRefDTOByGivenUserIds(Set<Long> userRefIds, Pageable pageable, String givenName, String familyName) { + return userManagementServiceApi.getUsersRefDTOByGivenUserIds(userRefIds, pageable, givenName, familyName); + } + + public PageResultResource<UserRefDTO> getUsersByGivenRoleAndNotWithGivenIds(RoleType roleType, Set<Long> userRefIds, Pageable pageable, String givenName, String familyName) { + return userManagementServiceApi.getUsersByGivenRoleAndNotWithGivenIds(roleType, userRefIds, pageable, givenName, familyName); + } + + public PageResultResource<UserRefDTO> getUsersByGivenRole(RoleType roleType, Pageable pageable, String givenName, String familyName) { + return userManagementServiceApi.getUsersByGivenRole(roleType, pageable, givenName, familyName); } } diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/api/UserManagementServiceApi.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/api/UserManagementServiceApi.java new file mode 100644 index 0000000000000000000000000000000000000000..d7574cf04894d249bdb68573ed97e4d22aedf2f7 --- /dev/null +++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/api/UserManagementServiceApi.java @@ -0,0 +1,220 @@ +package cz.muni.ics.kypo.training.adaptive.service.api; + +import cz.muni.ics.kypo.training.adaptive.domain.UserRef; +import cz.muni.ics.kypo.training.adaptive.dto.UserRefDTO; +import cz.muni.ics.kypo.training.adaptive.dto.responses.PageResultResource; +import cz.muni.ics.kypo.training.adaptive.enums.RoleType; +import cz.muni.ics.kypo.training.adaptive.exceptions.CustomWebClientException; +import cz.muni.ics.kypo.training.adaptive.exceptions.EntityNotFoundException; +import cz.muni.ics.kypo.training.adaptive.exceptions.MicroserviceApiException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.UriBuilder; + +import java.util.Collections; +import java.util.Set; + +/** + * The type User Management Api. + */ +@Service +public class UserManagementServiceApi { + + private static final Logger LOG = LoggerFactory.getLogger(UserManagementServiceApi.class); + + private WebClient userManagementServiceWebClient; + + /** + * Instantiates a new User Management Api. + * + * @param userManagementServiceWebClient the rest template + */ + public UserManagementServiceApi(@Qualifier("userManagementServiceWebClient") WebClient userManagementServiceWebClient) { + this.userManagementServiceWebClient = userManagementServiceWebClient; + } + + /** + * Finds specific User reference by login + * + * @param id of wanted User reference + * @return {@link UserRef} with corresponding login + * @throws EntityNotFoundException UserRef was not found + */ + public UserRefDTO getUserRefDTOByUserRefId(Long id) { + try { + return userManagementServiceWebClient + .get() + .uri("/users/{id}", id) + .retrieve() + .bodyToMono(UserRefDTO.class) + .block(); + } catch (CustomWebClientException ex) { + throw new MicroserviceApiException("Error when calling user management service API to obtain info about user(ID: " + id + ").", ex.getApiSubError()); + } + } + + /** + * Gets users with given user ref ids. + * + * @param userRefIds the user ref ids + * @param pageable pageable parameter with information about pagination. + * @param givenName optional parameter used for filtration + * @param familyName optional parameter used for filtration + * @return the users with given user ref ids + */ + public PageResultResource<UserRefDTO> getUsersRefDTOByGivenUserIds(Set<Long> userRefIds, Pageable pageable, String givenName, String familyName) { + if (userRefIds.isEmpty()) { + return new PageResultResource<>(Collections.emptyList(), new PageResultResource.Pagination(0, 0, pageable.getPageSize(), 0, 0)); + } + try { + return userManagementServiceWebClient + .get() + .uri(uriBuilder -> { + uriBuilder + .path("/users/ids") + .queryParam("ids", StringUtils.collectionToDelimitedString(userRefIds, ",")); + this.setCommonParams(givenName, familyName, pageable, uriBuilder); + return uriBuilder.build(); + } + ) + .retrieve() + .bodyToMono(new ParameterizedTypeReference<PageResultResource<UserRefDTO>>() { + }) + .block(); + } catch (CustomWebClientException ex) { + throw new MicroserviceApiException("Error when calling user management service API to obtain users by IDs: " + userRefIds + ".", ex.getApiSubError()); + } + } + + /** + * Finds all logins of users that have role of designer + * + * @param roleType the role type + * @param pageable pageable parameter with information about pagination. + * @param givenName optional parameter used for filtration + * @param familyName optional parameter used for filtration + * @return list of users with given role + */ + public PageResultResource<UserRefDTO> getUsersByGivenRole(RoleType roleType, Pageable pageable, String givenName, String familyName) { + try { + return userManagementServiceWebClient + .get() + .uri(uriBuilder -> { + uriBuilder + .path("/roles/users") + .queryParam("roleType", roleType.name()); + this.setCommonParams(givenName, familyName, pageable, uriBuilder); + return uriBuilder.build(); + } + ) + .retrieve() + .bodyToMono(new ParameterizedTypeReference<PageResultResource<UserRefDTO>>() { + }) + .block(); + } catch (CustomWebClientException ex) { + throw new MicroserviceApiException("Error when calling user management service API to obtain users with role " + roleType.name() + ".", ex.getApiSubError()); + } + } + + /** + * Finds all logins of users that have role of designer + * + * @param roleType the role type + * @param userRefIds ids of the users who should be excluded from the result set. + * @param pageable the pageable + * @param givenName optional parameter used for filtration + * @param familyName optional parameter used for filtration + * @return list of users with given role + */ + public PageResultResource<UserRefDTO> getUsersByGivenRoleAndNotWithGivenIds(RoleType roleType, Set<Long> userRefIds, Pageable pageable, String givenName, String familyName) { + try { + return userManagementServiceWebClient + .get() + .uri(uriBuilder -> { + uriBuilder + .path("/roles/users-not-with-ids") + .queryParam("roleType", roleType.name()) + .queryParam("ids", StringUtils.collectionToDelimitedString(userRefIds, ",")); + this.setCommonParams(givenName, familyName, pageable, uriBuilder); + return uriBuilder.build(); + } + ) + .retrieve() + .bodyToMono(new ParameterizedTypeReference<PageResultResource<UserRefDTO>>() { + }) + .block(); + } catch (CustomWebClientException ex) { + throw new MicroserviceApiException("Error when calling user management service API to obtain users with role " + roleType.name() + " and IDs: " + userRefIds + ".", ex.getApiSubError()); + } + } + + /** + * Gets user ref id from user and group. + * + * @return the user ref id from user and group + */ + public Long getUserRefIdFromUserAndGroup() { + try { + UserRefDTO userRefDTO = userManagementServiceWebClient + .get() + .uri("/users/info") + .retrieve() + .bodyToMono(UserRefDTO.class) + .block(); + checkNonNull(userRefDTO, "Returned null response when calling user management service API to get info about logged in user."); + return userRefDTO.getUserRefId(); + } catch (CustomWebClientException ex) { + throw new MicroserviceApiException("Error when calling user management service API to get info about logged in user.", ex.getApiSubError()); + } + } + + /** + * Gets user ref id from user and group. + * + * @return the user ref id from user and group + */ + public UserRefDTO getUserRefFromUserAndGroup() { + try { + UserRefDTO userRefDTO = userManagementServiceWebClient + .get() + .uri("/users/info") + .retrieve() + .bodyToMono(UserRefDTO.class) + .block(); + checkNonNull(userRefDTO, "Returned null response when calling user management service API to get info about logged in user."); + return userRefDTO; + } catch (CustomWebClientException ex) { + throw new MicroserviceApiException("Error when calling user management service API to get info about logged in user.", ex.getApiSubError()); + } + } + + private void setCommonParams(String givenName, String familyName, Pageable pageable, UriBuilder builder) { + if (givenName != null) { + builder.queryParam("givenName", givenName); + } + if (familyName != null) { + builder.queryParam("familyName", familyName); + } + builder.queryParam("page", pageable.getPageNumber()); + builder.queryParam("size", pageable.getPageSize()); + } + + /** + * Check if response from external API is not null. + * + * @param object object to check + * @param message exception message if response is null + * @throws MicroserviceApiException if response is null + */ + private void checkNonNull(Object object, String message) { + if (object == null) { + throw new MicroserviceApiException(message); + } + } +} diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingDefinitionService.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingDefinitionService.java index 7bcfc74def62adbdcdcee9f64cde0590708146e3..db69286fdbdb72cd3b6db3da4b5ed1a193f203cf 100644 --- a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingDefinitionService.java +++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingDefinitionService.java @@ -17,7 +17,7 @@ import cz.muni.ics.kypo.training.adaptive.repository.UserRefRepository; import cz.muni.ics.kypo.training.adaptive.repository.phases.*; import cz.muni.ics.kypo.training.adaptive.repository.training.TrainingDefinitionRepository; import cz.muni.ics.kypo.training.adaptive.repository.training.TrainingInstanceRepository; -import cz.muni.ics.kypo.training.adaptive.service.SecurityService; +import cz.muni.ics.kypo.training.adaptive.service.api.UserManagementServiceApi; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -46,7 +46,7 @@ public class TrainingDefinitionService { private InfoPhaseRepository infoPhaseRepository; private QuestionnairePhaseRepository questionnairePhaseRepository; private UserRefRepository userRefRepository; - private SecurityService securityService; + private UserManagementServiceApi userManagementServiceApi; private CloneMapper cloneMapper; /** @@ -59,7 +59,7 @@ public class TrainingDefinitionService { * @param questionnairePhaseRepository the questionnaire phase repository * @param trainingInstanceRepository the training instance repository * @param userRefRepository the user ref repository - * @param securityService the security service + * @param userManagementServiceApi the security service */ @Autowired public TrainingDefinitionService(TrainingDefinitionRepository trainingDefinitionRepository, @@ -69,7 +69,7 @@ public class TrainingDefinitionService { QuestionnairePhaseRepository questionnairePhaseRepository, TrainingInstanceRepository trainingInstanceRepository, UserRefRepository userRefRepository, - SecurityService securityService, + UserManagementServiceApi userManagementServiceApi, CloneMapper cloneMapper) { this.trainingDefinitionRepository = trainingDefinitionRepository; this.abstractPhaseRepository = abstractPhaseRepository; @@ -78,7 +78,7 @@ public class TrainingDefinitionService { this.questionnairePhaseRepository = questionnairePhaseRepository; this.trainingInstanceRepository = trainingInstanceRepository; this.userRefRepository = userRefRepository; - this.securityService = securityService; + this.userManagementServiceApi = userManagementServiceApi; this.cloneMapper = cloneMapper; } @@ -421,11 +421,11 @@ public class TrainingDefinitionService { } private void addLoggedInUserToTrainingDefinitionAsAuthor(TrainingDefinition trainingDefinition) { - Optional<UserRef> user = userRefRepository.findUserByUserRefId(securityService.getUserRefIdFromUserAndGroup()); + Optional<UserRef> user = userRefRepository.findUserByUserRefId(userManagementServiceApi.getUserRefIdFromUserAndGroup()); if (user.isPresent()) { trainingDefinition.addAuthor(user.get()); } else { - UserRef newUser = securityService.createUserRefEntityByInfoFromUserAndGroup(); + UserRef newUser = new UserRef(userManagementServiceApi.getUserRefIdFromUserAndGroup()); trainingDefinition.addAuthor(newUser); } trainingDefinition.setLastEdited(getCurrentTimeInUTC()); diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingInstanceService.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingInstanceService.java index ef615f1e02da5c1606bf28616e5bf4f1542d7634..5c6f7e7a3debb269f4dc831515836da4fd4aa698 100644 --- a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingInstanceService.java +++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingInstanceService.java @@ -13,6 +13,7 @@ import cz.muni.ics.kypo.training.adaptive.repository.UserRefRepository; import cz.muni.ics.kypo.training.adaptive.repository.training.TrainingInstanceRepository; import cz.muni.ics.kypo.training.adaptive.repository.training.TrainingRunRepository; import cz.muni.ics.kypo.training.adaptive.service.SecurityService; +import cz.muni.ics.kypo.training.adaptive.service.api.UserManagementServiceApi; import org.apache.commons.lang3.RandomStringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,7 +41,7 @@ public class TrainingInstanceService { private TrainingRunRepository trainingRunRepository; private AccessTokenRepository accessTokenRepository; private UserRefRepository organizerRefRepository; - private SecurityService securityService; + private UserManagementServiceApi userManagementServiceApi; /** * Instantiates a new Training instance service. @@ -49,7 +50,7 @@ public class TrainingInstanceService { * @param accessTokenRepository the access token repository * @param trainingRunRepository the training run repository * @param organizerRefRepository the organizer ref repository - * @param securityService the security service + * @param userManagementServiceApi the user management service */ @Autowired @@ -57,12 +58,12 @@ public class TrainingInstanceService { AccessTokenRepository accessTokenRepository, TrainingRunRepository trainingRunRepository, UserRefRepository organizerRefRepository, - SecurityService securityService) { + UserManagementServiceApi userManagementServiceApi) { this.trainingInstanceRepository = trainingInstanceRepository; this.trainingRunRepository = trainingRunRepository; this.accessTokenRepository = accessTokenRepository; this.organizerRefRepository = organizerRefRepository; - this.securityService = securityService; + this.userManagementServiceApi = userManagementServiceApi; } /** @@ -203,11 +204,11 @@ public class TrainingInstanceService { } private void addLoggedInUserAsOrganizerToTrainingInstance(TrainingInstance trainingInstance) { - Optional<UserRef> authorOfTrainingInstance = organizerRefRepository.findUserByUserRefId(securityService.getUserRefIdFromUserAndGroup()); + Optional<UserRef> authorOfTrainingInstance = organizerRefRepository.findUserByUserRefId(userManagementServiceApi.getUserRefIdFromUserAndGroup()); if (authorOfTrainingInstance.isPresent()) { trainingInstance.addOrganizer(authorOfTrainingInstance.get()); } else { - UserRef userRef = securityService.createUserRefEntityByInfoFromUserAndGroup(); + UserRef userRef = new UserRef(userManagementServiceApi.getUserRefIdFromUserAndGroup()); trainingInstance.addOrganizer(organizerRefRepository.save(userRef)); } } diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingRunService.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingRunService.java index 352a75b7023bc866e23105955ab60524aefcc409..28270418dd273d0f0ac7e659efae26cfc1bfa459 100644 --- a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingRunService.java +++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingRunService.java @@ -18,6 +18,7 @@ import cz.muni.ics.kypo.training.adaptive.repository.training.TrainingRunReposit import cz.muni.ics.kypo.training.adaptive.service.SecurityService; import cz.muni.ics.kypo.training.adaptive.service.api.ElasticsearchServiceApi; import cz.muni.ics.kypo.training.adaptive.service.api.SandboxServiceApi; +import cz.muni.ics.kypo.training.adaptive.service.api.UserManagementServiceApi; import cz.muni.ics.kypo.training.adaptive.service.audit.AuditEventsService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,7 +50,7 @@ public class TrainingRunService { private UserRefRepository participantRefRepository; private AuditEventsService auditEventsService; private ElasticsearchServiceApi elasticsearchServiceApi; - private SecurityService securityService; + private UserManagementServiceApi userManagementServiceApi; private TRAcquisitionLockRepository trAcquisitionLockRepository; /** @@ -71,7 +72,7 @@ public class TrainingRunService { UserRefRepository participantRefRepository, AuditEventsService auditEventsService, ElasticsearchServiceApi elasticsearchServiceApi, - SecurityService securityService, + UserManagementServiceApi userManagementServiceApi, TRAcquisitionLockRepository trAcquisitionLockRepository) { this.sandboxServiceApi = sandboxServiceApi; this.trainingRunRepository = trainingRunRepository; @@ -80,7 +81,7 @@ public class TrainingRunService { this.participantRefRepository = participantRefRepository; this.auditEventsService = auditEventsService; this.elasticsearchServiceApi = elasticsearchServiceApi; - this.securityService = securityService; + this.userManagementServiceApi = userManagementServiceApi; this.trAcquisitionLockRepository = trAcquisitionLockRepository; } @@ -155,7 +156,7 @@ public class TrainingRunService { * @return {@link TrainingRun}s of logged in user. */ public Page<TrainingRun> findAllByParticipantRefUserRefId(Pageable pageable) { - return trainingRunRepository.findAllByParticipantRefId(securityService.getUserRefIdFromUserAndGroup(), pageable); + return trainingRunRepository.findAllByParticipantRefId(userManagementServiceApi.getUserRefIdFromUserAndGroup(), pageable); } /** @@ -213,7 +214,7 @@ public class TrainingRunService { * @return {@link TrainingRun}s of specific Training Definition of logged in user */ public Page<TrainingRun> findAllByTrainingDefinitionAndParticipant(Long definitionId, Pageable pageable) { - return trainingRunRepository.findAllByTrainingDefinitionIdAndParticipantUserRefId(definitionId, securityService.getUserRefIdFromUserAndGroup(), pageable); + return trainingRunRepository.findAllByTrainingDefinitionIdAndParticipantUserRefId(definitionId, userManagementServiceApi.getUserRefIdFromUserAndGroup(), pageable); } /** @@ -320,7 +321,7 @@ public class TrainingRunService { if (userRefOpt.isPresent()) { newTrainingRun.setParticipantRef(userRefOpt.get()); } else { - newTrainingRun.setParticipantRef(participantRefRepository.save(securityService.createUserRefEntityByInfoFromUserAndGroup())); + newTrainingRun.setParticipantRef(participantRefRepository.save(new UserRef(userManagementServiceApi.getUserRefIdFromUserAndGroup()))); } newTrainingRun.setQuestionnaireResponses("[]"); newTrainingRun.setState(TRState.RUNNING);