Skip to content

Commit

Permalink
Merge pull request #11 from Onlineberatung/develop
Browse files Browse the repository at this point in the history
Merge OS
  • Loading branch information
Leandro13Silva13 authored Apr 9, 2024
2 parents a56f735 + 2e5c4aa commit 0405c60
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package de.caritas.cob.userservice.api.adapters.rocketchat;

import static de.caritas.cob.userservice.api.helper.CustomLocalDateTime.nowInUtc;
import static java.util.Arrays.asList;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static org.apache.commons.lang3.ArrayUtils.isNotEmpty;

import com.google.common.collect.Lists;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import com.mongodb.client.MongoClient;
Expand Down Expand Up @@ -59,7 +61,6 @@
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -132,6 +133,7 @@ public class RocketChatService implements MessageClient {
private static final String USERS_LIST_ERROR_MESSAGE =
"Could not get users list from Rocket.Chat";
private static final String USER_LIST_GET_FIELD_SELECTION = "{\"_id\":1}";
private static final Integer PAGE_SIZE = 100;
private final LocalDateTime localDateTime1900 = LocalDateTime.of(1900, 1, 1, 0, 0);

private final LocalDateTime localDateTimeFuture = nowInUtc().plusYears(1L);
Expand Down Expand Up @@ -809,7 +811,7 @@ public List<GroupMemberDTO> getMembersOfGroup(String rcGroupId)
}

if (response.getStatusCode() == HttpStatus.OK && nonNull(response.getBody())) {
return Arrays.asList(response.getBody().getMembers());
return asList(response.getBody().getMembers());
} else {
var error = "Could not get Rocket.Chat group members for room id %s";
throw new RocketChatGetGroupMembersException(String.format(error, rcGroupId));
Expand Down Expand Up @@ -908,7 +910,7 @@ public List<SubscriptionsUpdateDTO> getSubscriptionsOfUser(
}

if (response.getStatusCode() == HttpStatus.OK && nonNull(response.getBody())) {
return Arrays.asList(response.getBody().getUpdate());
return asList(response.getBody().getUpdate());
} else {
var error = "Could not get Rocket.Chat subscriptions for user id %s";
throw new InternalServerErrorException(error, LogService::logRocketChatError);
Expand Down Expand Up @@ -967,7 +969,7 @@ public List<RoomsUpdateDTO> getRoomsOfUser(RocketChatCredentials rocketChatCrede
}

if (response.getStatusCode() == HttpStatus.OK && nonNull(response.getBody())) {
return Arrays.asList(response.getBody().getUpdate());
return asList(response.getBody().getUpdate());
} else {
var error =
String.format(CHAT_ROOM_ERROR_MESSAGE, rocketChatCredentials.getRocketChatUserId());
Expand Down Expand Up @@ -1188,28 +1190,72 @@ public List<GroupDTO> fetchAllInactivePrivateGroupsSinceGivenDate(
private List<GroupDTO> getGroupsListAll(DBObject mongoDbQuery)
throws RocketChatGetGroupsListAllException {

ResponseEntity<GroupsListAllResponseDTO> response;
try {
var technicalUser = rcCredentialHelper.getTechnicalUser();
var header = getStandardHttpHeaders(technicalUser);
HttpEntity<GroupAddUserBodyDTO> request = new HttpEntity<>(header);
var url = rocketChatConfig.getApiUrl(ENDPOINT_GROUP_LIST) + "?query={query}";
response =
restTemplate.exchange(
url,
HttpMethod.GET,
request,
GroupsListAllResponseDTO.class,
mongoDbQuery.toString());

return getGroupListAllCombiningPages(mongoDbQuery, request);
} catch (Exception ex) {
log.error("Rocket.Chat Error: Could not get Rocket.Chat groups list all. Reason: ", ex);
throw new RocketChatGetGroupsListAllException(GROUPS_LIST_ALL_ERROR_MESSAGE, ex);
}
}

if (response.getStatusCode() == HttpStatus.OK && nonNull(response.getBody())) {
return Arrays.asList(response.getBody().getGroups());
} else {
private List<GroupDTO> getGroupListAllCombiningPages(
DBObject mongoDbQuery, HttpEntity<GroupAddUserBodyDTO> request)
throws RocketChatGetGroupsListAllException {
List<GroupDTO> result = Lists.newArrayList();
int currentOffset = 0;
var pageResponse =
getGroupsListAllResponseDTOResponseEntityForCurrentOffset(
mongoDbQuery, request, currentOffset);

var totalResultSize = 0;
if (isResponseSuccessful(pageResponse)) {
totalResultSize = pageResponse.getBody().getTotal();
}

while (isResponseSuccessful(pageResponse) && currentOffset < totalResultSize) {
result.addAll(asList(pageResponse.getBody().getGroups()));
currentOffset += PAGE_SIZE;
pageResponse =
getGroupsListAllResponseDTOResponseEntityForCurrentOffset(
mongoDbQuery, request, currentOffset);
}
if (pageResponse.getStatusCode() != HttpStatus.OK || isNull(pageResponse.getBody())) {
log.error(
"Could not get Rocket.Chat groups list all. Reason {} {}. Url {}",
pageResponse.getStatusCode(),
pageResponse.getBody(),
getGroupAllPaginatedUrl(currentOffset));
throw new RocketChatGetGroupsListAllException(GROUPS_LIST_ALL_ERROR_MESSAGE);
}

return result;
}

private boolean isResponseSuccessful(ResponseEntity<GroupsListAllResponseDTO> pageResponse) {
return pageResponse.getStatusCode() == HttpStatus.OK && nonNull(pageResponse.getBody());
}

private ResponseEntity<GroupsListAllResponseDTO>
getGroupsListAllResponseDTOResponseEntityForCurrentOffset(
DBObject mongoDbQuery, HttpEntity<GroupAddUserBodyDTO> request, int currentOffset) {
ResponseEntity<GroupsListAllResponseDTO> response;
var url = getGroupAllPaginatedUrl(currentOffset);
response =
restTemplate.exchange(
url, HttpMethod.GET, request, GroupsListAllResponseDTO.class, mongoDbQuery.toString());
return response;
}

private String getGroupAllPaginatedUrl(int currentOffset) {
return rocketChatConfig.getApiUrl(ENDPOINT_GROUP_LIST)
+ "?query={query}&offset="
+ currentOffset
+ "&count="
+ PAGE_SIZE;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ public class GroupsListAllResponseDTO {

@JsonProperty("groups")
private GroupDTO[] groups;

private Integer offset;
private Integer count;
private Integer total;
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,15 @@
import javax.ws.rs.BadRequestException;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

/** Service for sessions */
@Service
@RequiredArgsConstructor
@Slf4j
public class SessionService {

private final @NonNull SessionRepository sessionRepository;
Expand Down Expand Up @@ -437,12 +439,18 @@ private List<AgencyDTO> fetchAgencies(List<Session> sessions) {
* @param roles the roles of the given consultant
* @return {@link ConsultantSessionResponseDTO}
*/
public List<ConsultantSessionResponseDTO> getSessionsByConsultantAndGroupOrFeedbackGroupIds(
Consultant consultant, Set<String> rcGroupIds, Set<String> roles) {
public List<ConsultantSessionResponseDTO>
getAllowedSessionsByConsultantAndGroupOrFeedbackGroupIds(
Consultant consultant, Set<String> rcGroupIds, Set<String> roles) {
checkForUserOrConsultantRole(roles);
var sessions = sessionRepository.findByGroupOrFeedbackGroupIds(rcGroupIds);
sessions.forEach(session -> checkConsultantAssignment(consultant, session));
return mapSessionsToConsultantSessionDto(sessions);

List<Session> allowedSessions =
sessions.stream()
.filter(session -> isConsultantPermittedToSession(consultant, session))
.collect(Collectors.toList());

return mapSessionsToConsultantSessionDto(allowedSessions);
}

/**
Expand Down Expand Up @@ -536,6 +544,16 @@ private void checkIfConsultantAndNotAssignedToSessionOrAgency(
}
}

private boolean isConsultantPermittedToSession(Consultant consultant, Session session) {
try {
checkConsultantAssignment(consultant, session);
} catch (ForbiddenException e) {
log.info(e.getMessage());
return false;
}
return true;
}

private void checkConsultantAssignment(Consultant consultant, Session session) {
if (session.isAdvisedBy(consultant)
|| isAllowedToAdvise(consultant, session)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public List<ConsultantSessionResponseDTO> retrieveSessionsForConsultantAndGroupI
Consultant consultant, List<String> rcGroupIds, Set<String> roles) {
var groupIds = new HashSet<>(rcGroupIds);
var sessions =
sessionService.getSessionsByConsultantAndGroupOrFeedbackGroupIds(
sessionService.getAllowedSessionsByConsultantAndGroupOrFeedbackGroupIds(
consultant, groupIds, roles);
var chats = chatService.getChatSessionsForConsultantByGroupIds(groupIds);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.RoleMappingResource;
Expand Down Expand Up @@ -710,36 +712,19 @@ void getSessionsForGroupOrFeedbackGroupIdsShouldBeForbiddenIfUserDoesNotParticip
.andExpect(status().isForbidden());
}

@Test
@ParameterizedTest
@WithMockUser(authorities = {AuthorityValue.CONSULTANT_DEFAULT})
@ValueSource(strings = {"QBv2xym9qQ2DoAxkR", "doesNotExist", "mzAdWzQEobJ2PkoxP"})
void
getSessionsForGroupOrFeedbackGroupIdsShouldBeForbiddenIfConsultantDoesNotParticipateInSession()
throws Exception {
givenAConsultantWithSessions();
givenNoRocketChatSubscriptionUpdates();
givenNoRocketChatRoomUpdates();

mockMvc
.perform(
get("/users/sessions/room?rcGroupIds=QBv2xym9qQ2DoAxkR")
.cookie(CSRF_COOKIE)
.header(CSRF_HEADER, CSRF_VALUE)
.header(RC_TOKEN_HEADER_PARAMETER_NAME, RC_TOKEN)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isForbidden());
}

@Test
@WithMockUser(authorities = {AuthorityValue.CONSULTANT_DEFAULT})
void getSessionsForGroupOrFeedbackGroupIdsShouldBeNoContentIfNoSessionsFoundForIds()
throws Exception {
getSessionsForGroupOrFeedbackGroupIdsShouldBeNoContentIfConsultantDoesNotParticipateInSessionOrNoSessionsFoundForIdsOrNewEnquiriesForConsultantsNotInAgency(
String rcGroupId) throws Exception {
givenAConsultantWithSessions();
givenNoRocketChatSubscriptionUpdates();
givenNoRocketChatRoomUpdates();

mockMvc
.perform(
get("/users/sessions/room?rcGroupIds=doesNotExist")
get("/users/sessions/room?rcGroupIds=" + rcGroupId)
.cookie(CSRF_COOKIE)
.header(CSRF_HEADER, CSRF_VALUE)
.header(RC_TOKEN_HEADER_PARAMETER_NAME, RC_TOKEN)
Expand Down Expand Up @@ -768,25 +753,6 @@ void getSessionsForGroupOrFeedbackGroupIdsShouldBeNoContentIfNoSessionsFoundForI
.andExpect(jsonPath("sessions", hasSize(1)));
}

@Test
@WithMockUser(authorities = {AuthorityValue.CONSULTANT_DEFAULT})
void
getSessionsForGroupOrFeedbackGroupIdsShouldReturnForbiddenForNewEnquiriesForConsultantsNotInAgency()
throws Exception {
givenAConsultantWithSessions();
givenNoRocketChatSubscriptionUpdates();
givenNoRocketChatRoomUpdates();

mockMvc
.perform(
get("/users/sessions/room?rcGroupIds=mzAdWzQEobJ2PkoxP")
.cookie(CSRF_COOKIE)
.header(CSRF_HEADER, CSRF_VALUE)
.header(RC_TOKEN_HEADER_PARAMETER_NAME, RC_TOKEN)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isForbidden());
}

@Test
@WithMockUser(authorities = {AuthorityValue.USER_DEFAULT})
void getSessionForIdShouldFindSessionsBySessionId() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,16 @@ public class RocketChatServiceTest {
new UsersListReponseDTO(
new RocketChatUserDTO[] {ROCKET_CHAT_USER_DTO, ROCKET_CHAT_USER_DTO_2});
private final GroupsListAllResponseDTO GROUPS_LIST_ALL_RESPONSE_DTO_EMPTY =
new GroupsListAllResponseDTO(new GroupDTO[0]);
new GroupsListAllResponseDTO(new GroupDTO[0], 1, 0, 0);
private final GroupsListAllResponseDTO GROUPS_LIST_ALL_RESPONSE_DTO =
new GroupsListAllResponseDTO(new GroupDTO[] {GROUP_DTO, GROUP_DTO_2});
new GroupsListAllResponseDTO(new GroupDTO[] {GROUP_DTO, GROUP_DTO_2}, 0, 2, 10);

private final GroupsListAllResponseDTO GROUPS_LIST_ALL_RESPONSE_DTO_PAGINATED =
new GroupsListAllResponseDTO(new GroupDTO[] {GROUP_DTO, GROUP_DTO_2}, 0, 100, 1000);

private final GroupsListAllResponseDTO
GROUPS_LIST_ALL_RESPONSE_DTO_PAGINATED_WITH_TOTAL_ZERO_ELEMENTS =
new GroupsListAllResponseDTO(new GroupDTO[] {GROUP_DTO, GROUP_DTO_2}, 0, 0, 0);
private final LocalDateTime DATETIME_OLDEST = nowInUtc();
private final LocalDateTime DATETIME_LATEST = nowInUtc();
private final String PASSWORD = "password";
Expand Down Expand Up @@ -738,7 +745,7 @@ public void removeAllMessages_Should_NotThrowException_WhenRemoveMessagesSucceed
List<GroupMemberDTO> result = rocketChatService.getStandardMembersOfGroup(GROUP_ID);

assertEquals(1, result.size());
assertEquals(result.get(0).get_id(), "a");
assertEquals("a", result.get(0).get_id());
}

/** Method: getUserInfo */
Expand Down Expand Up @@ -1096,6 +1103,68 @@ public void fetchAllInactivePrivateGroupsSinceGivenDate_Should_UseCorrectMongoQu

this.rocketChatService.fetchAllInactivePrivateGroupsSinceGivenDate(dateToCheck);

String correctMongoQuery =
"{\"lm\": {\"$lt\": {\"$date\": \"2021-01-01T00:00:00.000Z\"}},"
+ " \"$and\": [{\"t\": \"p\"}]}";
verify(restTemplate, times(2))
.exchange(
anyString(),
eq(HttpMethod.GET),
any(),
eq(GroupsListAllResponseDTO.class),
eq(correctMongoQuery));
}

@Test
public void
fetchAllInactivePrivateGroupsSinceGivenDate_Should_CallRocketChatApiMultipleTimes_When_ResultIsPaginated()
throws RocketChatUserNotInitializedException, RocketChatGetGroupsListAllException {

LocalDateTime dateToCheck = LocalDateTime.of(2021, 1, 1, 0, 0, 0);

when(rcCredentialsHelper.getTechnicalUser()).thenReturn(RC_CREDENTIALS_TECHNICAL_A);
when(restTemplate.exchange(
anyString(),
eq(HttpMethod.GET),
any(),
eq(GroupsListAllResponseDTO.class),
anyString()))
.thenReturn(new ResponseEntity<>(GROUPS_LIST_ALL_RESPONSE_DTO_PAGINATED, HttpStatus.OK));

this.rocketChatService.fetchAllInactivePrivateGroupsSinceGivenDate(dateToCheck);

String correctMongoQuery =
"{\"lm\": {\"$lt\": {\"$date\": \"2021-01-01T00:00:00.000Z\"}},"
+ " \"$and\": [{\"t\": \"p\"}]}";
verify(restTemplate, times(11))
.exchange(
anyString(),
eq(HttpMethod.GET),
any(),
eq(GroupsListAllResponseDTO.class),
eq(correctMongoQuery));
}

@Test
public void
fetchAllInactivePrivateGroupsSinceGivenDate_Should_CallRocketChatApiOnlyOnce_When_ResponseContainsTotalOfZeroElements()
throws RocketChatUserNotInitializedException, RocketChatGetGroupsListAllException {

LocalDateTime dateToCheck = LocalDateTime.of(2021, 1, 1, 0, 0, 0);

when(rcCredentialsHelper.getTechnicalUser()).thenReturn(RC_CREDENTIALS_TECHNICAL_A);
when(restTemplate.exchange(
anyString(),
eq(HttpMethod.GET),
any(),
eq(GroupsListAllResponseDTO.class),
anyString()))
.thenReturn(
new ResponseEntity<>(
GROUPS_LIST_ALL_RESPONSE_DTO_PAGINATED_WITH_TOTAL_ZERO_ELEMENTS, HttpStatus.OK));

this.rocketChatService.fetchAllInactivePrivateGroupsSinceGivenDate(dateToCheck);

String correctMongoQuery =
"{\"lm\": {\"$lt\": {\"$date\": \"2021-01-01T00:00:00.000Z\"}},"
+ " \"$and\": [{\"t\": \"p\"}]}";
Expand Down
Loading

0 comments on commit 0405c60

Please sign in to comment.