Skip to content

Commit

Permalink
Merge branch 'release-uat' into feature/SELC-4483
Browse files Browse the repository at this point in the history
# Conflicts:
#	core/src/main/java/it/pagopa/selfcare/dashboard/core/UserV2ServiceImpl.java
  • Loading branch information
flaminiaScarciofolo committed Mar 22, 2024
2 parents 9234a75 + de6570a commit 6992c57
Show file tree
Hide file tree
Showing 19 changed files with 2,269 additions and 120 deletions.
640 changes: 639 additions & 1 deletion app/src/main/resources/swagger/api-docs.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ class SwaggerConfigTest {
@MockBean
private UserMapperV2 userMapperImpl;

@MockBean
private UserGroupV2Service userGroupServiceV2Mock;

@MockBean
private InstitutionResourceMapper institutionResourceMapper;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public interface UserApiConnector {

List<InstitutionBase> getUserInstitutions(String userId);

User getUserById(String userId);
User getUserById(String userId, List<String> fields);

User searchByFiscalCode(String fiscalCode);

Expand Down
7 changes: 7 additions & 0 deletions connector/rest/docs/openapi/selfcare-user-docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,13 @@
"schema": {
"type": "string"
}
},
{
"name": "field",
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ public Boolean hasPermission(String institutionId, String permission, String pro
}

@Override
public User getUserById(String userId) {
public User getUserById(String userId, List<String> fields) {
log.trace("getUserById start");
log.debug("getUserById id = {}", userId);
User user = userMapper.toUser(userApiRestClient._usersIdDetailsGet(userId).getBody());
String fieldsString = !CollectionUtils.isEmpty(fields) ? String.join(",", fields) : null;
User user = userMapper.toUser(userApiRestClient._usersIdDetailsGet(userId, fieldsString).getBody());
log.debug(LogUtils.CONFIDENTIAL_MARKER, "getUserById = {}", user);
log.trace("getUserById end");
return user;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,12 @@ void getUserById() {
//given
String userId = "userId";
UserDetailResponse userDetailResponse = mockInstance(new UserDetailResponse());
when(userApiRestClient._usersIdDetailsGet(anyString())).thenReturn(new ResponseEntity<>(userDetailResponse, HttpStatus.OK));
when(userApiRestClient._usersIdDetailsGet(userId, null)).thenReturn(new ResponseEntity<>(userDetailResponse, HttpStatus.OK));
//when
User user = userConnector.getUserById(userId);
User user = userConnector.getUserById(userId, null);
//then
assertNotNull(user);
verify(userApiRestClient, times(1))._usersIdDetailsGet(userId);
verify(userApiRestClient, times(1))._usersIdDetailsGet(userId, null);
}
@Test
void verifyUserExist_UserExists() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package it.pagopa.selfcare.dashboard.core;

import it.pagopa.selfcare.dashboard.connector.model.groups.CreateUserGroup;
import it.pagopa.selfcare.dashboard.connector.model.groups.UpdateUserGroup;
import it.pagopa.selfcare.dashboard.connector.model.groups.UserGroupInfo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.Optional;
import java.util.UUID;

public interface UserGroupV2Service {
void deleteMembersByUserId(String userId, String institutionId, String productId);

String createUserGroup(CreateUserGroup group);

void delete(String groupId);

void activate(String groupId);

void suspend(String groupId);

void updateUserGroup(String groupId, UpdateUserGroup group);

void addMemberToUserGroup(String groupId, UUID userId);

void deleteMemberFromUserGroup(String groupId, UUID userId);

UserGroupInfo getUserGroupById(String groupId, String institutionId);

Page<UserGroupInfo> getUserGroups(String institutionId, String productId, UUID userId, Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
package it.pagopa.selfcare.dashboard.core;

import it.pagopa.selfcare.commons.base.logging.LogUtils;
import it.pagopa.selfcare.commons.base.security.SelfCareUser;
import it.pagopa.selfcare.dashboard.connector.api.UserApiConnector;
import it.pagopa.selfcare.dashboard.connector.api.UserGroupConnector;
import it.pagopa.selfcare.dashboard.connector.model.groups.CreateUserGroup;
import it.pagopa.selfcare.dashboard.connector.model.groups.UpdateUserGroup;
import it.pagopa.selfcare.dashboard.connector.model.groups.UserGroupFilter;
import it.pagopa.selfcare.dashboard.connector.model.groups.UserGroupInfo;
import it.pagopa.selfcare.dashboard.connector.model.user.User;
import it.pagopa.selfcare.dashboard.connector.model.user.UserInfo;
import it.pagopa.selfcare.dashboard.connector.model.user.UserInstitution;
import it.pagopa.selfcare.dashboard.core.exception.InvalidMemberListException;
import it.pagopa.selfcare.dashboard.core.exception.InvalidUserGroupException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.*;

import static it.pagopa.selfcare.dashboard.connector.model.institution.RelationshipState.ACTIVE;
import static it.pagopa.selfcare.dashboard.connector.model.institution.RelationshipState.SUSPENDED;
import static it.pagopa.selfcare.dashboard.connector.model.user.User.Fields.*;

@Component
@Slf4j
@RequiredArgsConstructor
public class UserGroupV2ServiceImpl implements UserGroupV2Service{


private static final EnumSet<User.Fields> MEMBER_FIELD_LIST = EnumSet.of(name, familyName, workContacts);
private static final EnumSet<User.Fields> FIELD_LIST = EnumSet.of(name, familyName);

private final UserGroupConnector groupConnector;
private final UserApiConnector userApiConnector;

static final String REQUIRED_GROUP_ID_MESSAGE = "A user group id is required";

@Override
public String createUserGroup(CreateUserGroup group) {
log.trace("createUserGroup start");
log.debug("createUserGroup group = {}", group);
UserInfo.UserInfoFilter userInfoFilter = new UserInfo.UserInfoFilter();
userInfoFilter.setProductId(group.getProductId());
userInfoFilter.setAllowedStates(List.of(ACTIVE, SUSPENDED));

List<String> retrievedId = retrievedIds(group.getInstitutionId(), userInfoFilter);

if (group.getMembers().stream()
.filter(uuid -> Collections.binarySearch(retrievedId, uuid) >= 0)
.count() != group.getMembers().size()) {
throw new InvalidMemberListException("Some members in the list aren't allowed for this institution");
}
String groupId = groupConnector.createUserGroup(group);
log.debug("createUserGroup result = {}", groupId);
log.trace("createUserGroup end");
return groupId;
}

@Override
public void delete(String groupId) {
log.trace("delete start");
log.debug("delete groupId = {}", groupId);
Assert.hasText(groupId, REQUIRED_GROUP_ID_MESSAGE);
groupConnector.delete(groupId);
log.trace("delete end");
}

@Override
public void activate(String groupId) {
log.trace("activate start");
log.debug("activate groupId = {}", groupId);
Assert.hasText(groupId, REQUIRED_GROUP_ID_MESSAGE);
groupConnector.activate(groupId);
log.trace("activate end");
}

private List<String> retrievedIds(String institutionId, UserInfo.UserInfoFilter userInfoFilter) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String loggedUserId = ((SelfCareUser) authentication.getPrincipal()).getId();
Collection<UserInfo> retrievedUsers = userApiConnector.getUsers(
institutionId,
userInfoFilter, loggedUserId);
return retrievedUsers.stream()
.map(UserInfo::getId)
.sorted()
.toList();
}

@Override
public void suspend(String groupId) {
log.trace("suspend start");
log.debug("suspend groupId = {}", groupId);
Assert.hasText(groupId, REQUIRED_GROUP_ID_MESSAGE);
groupConnector.suspend(groupId);
log.trace("suspend end");
}

@Override
public void updateUserGroup(String groupId, UpdateUserGroup group) {
log.trace("updateUserGroup start");
log.debug("updateUserGroup groupId = {}, group = {}", groupId, group);
UserGroupInfo userGroupInfo = groupConnector.getUserGroupById(groupId);

UserInfo.UserInfoFilter userInfoFilter = new UserInfo.UserInfoFilter();
userInfoFilter.setProductId(userGroupInfo.getProductId());
userInfoFilter.setAllowedStates(List.of(ACTIVE, SUSPENDED));

List<String> retrievedId = retrievedIds(userGroupInfo.getInstitutionId(), userInfoFilter);

if (group.getMembers().stream()
.filter(uuid -> Collections.binarySearch(retrievedId, uuid) >= 0)
.count() != group.getMembers().size()) {
throw new InvalidMemberListException("Some members in the list aren't allowed for this institution");
}
groupConnector.updateUserGroup(groupId, group);
log.trace("updateUserGroup end");
}

@Override
public void addMemberToUserGroup(String groupId, UUID userId) {
log.trace("addMemberToUserGroup start");
log.debug("addMemberToUserGroup groupId = {}, userId = {}", groupId, userId);
Assert.hasText(groupId, REQUIRED_GROUP_ID_MESSAGE);
Assert.notNull(userId, "A userId is required");
UserGroupInfo retrievedGroup = groupConnector.getUserGroupById(groupId);
UserInfo.UserInfoFilter userInfoFilter = new UserInfo.UserInfoFilter();
userInfoFilter.setProductId(retrievedGroup.getProductId());
userInfoFilter.setAllowedStates(List.of(ACTIVE, SUSPENDED));
List<String> retrievedIds = retrievedIds(retrievedGroup.getInstitutionId(), userInfoFilter);
if (!retrievedIds.contains(userId.toString())) {
throw new InvalidMemberListException("This user is not allowed for this group");
}
groupConnector.addMemberToUserGroup(groupId, userId);
log.trace("addMemberToUserGroup end");
}

@Override
public void deleteMemberFromUserGroup(String groupId, UUID userId) {
log.trace("deleteMemberFromUserGroup start");
log.debug("deleteMemberFromUserGroup groupId = {}, userId = {}", groupId, userId);
Assert.hasText(groupId, REQUIRED_GROUP_ID_MESSAGE);
Assert.notNull(userId, "A userId is required");
groupConnector.deleteMemberFromUserGroup(groupId, userId);
log.trace("deleteMemberFromUserGroup end");
}

@Override
public UserGroupInfo getUserGroupById(String groupId, String institutionId) {
log.trace("getUserGroupById start");
log.debug("getUserGroupById groupId = {}", groupId);
Assert.hasText(groupId, REQUIRED_GROUP_ID_MESSAGE);
UserGroupInfo userGroupInfo = groupConnector.getUserGroupById(groupId);
Optional.ofNullable(institutionId).ifPresent(value -> {
if (!value.equalsIgnoreCase(userGroupInfo.getInstitutionId())) {
throw new InvalidUserGroupException("Could not find a UserGroup for given institutionId");
}
});
Comparator<UserInfo> userInfoComparator = Comparator.comparing(UserInfo::getId);
UserInfo.UserInfoFilter userInfoFilter = new UserInfo.UserInfoFilter();
userInfoFilter.setProductId(userGroupInfo.getProductId());
userInfoFilter.setAllowedStates(List.of(ACTIVE, SUSPENDED));
List<UserInfo> userInfos = retrievedIds(userGroupInfo.getInstitutionId(), userInfoFilter).stream()
.map(id -> {
UserInfo userInfo = new UserInfo();
userInfo.setId(id);
return userInfo;
}).toList();
userGroupInfo.setMembers(userGroupInfo.getMembers().stream()
.map(userInfo -> {
int index = Collections.binarySearch(userInfos, userInfo, userInfoComparator);
if (index < 0) {
log.error(String.format("Member with uuid %s has no relationship with institution id '%s' and product id '%s'",
userInfo.getId(),
userGroupInfo.getInstitutionId(),
userGroupInfo.getProductId()));
return null;
}
userInfos.get(index).setUser(userApiConnector.getUserById(userInfo.getId(), MEMBER_FIELD_LIST.stream().map(Enum::name).toList()));
return userInfos.get(index);
}).filter(Objects::nonNull)
.toList());
User createdBy = userApiConnector.getUserById(userGroupInfo.getCreatedBy().getId(), FIELD_LIST.stream().map(Enum::name).toList());
userGroupInfo.setCreatedBy(createdBy);
if (userGroupInfo.getModifiedBy() != null) {
User modifiedBy = userApiConnector.getUserById(userGroupInfo.getModifiedBy().getId(), FIELD_LIST.stream().map(Enum::name).toList());
userGroupInfo.setModifiedBy(modifiedBy);
}
log.debug(LogUtils.CONFIDENTIAL_MARKER, "getUserGroupById userGroupInfo = {}", userGroupInfo);
log.trace("getUserGroupById end");
return userGroupInfo;
}

@Override
public Page<UserGroupInfo> getUserGroups(String institutionId, String productId, UUID userId, Pageable pageable) {
log.trace("getUserGroups start");
log.debug("getUserGroups institutionId = {}, productId = {}, userId = {}, pageable = {}", institutionId, productId, userId, pageable);
UserGroupFilter userGroupFilter = new UserGroupFilter();
userGroupFilter.setInstitutionId(Optional.ofNullable(institutionId));
userGroupFilter.setUserId(Optional.ofNullable(userId));
userGroupFilter.setProductId(Optional.ofNullable(productId));
Page<UserGroupInfo> groupInfos = groupConnector.getUserGroups(userGroupFilter, pageable);
log.debug("getUserGroups result = {}", groupInfos);
log.trace("getUserGroups end");

return groupInfos;
}

@Override
public void deleteMembersByUserId(String userId, String institutionId, String productId) {
log.trace("deleteMembersByUserId start");
log.debug("deleteMembersByUserId userId = {}", userId);
List<UserInstitution> userInstitutionList = userApiConnector.retrieveFilteredUser(userId, institutionId, productId);
if (CollectionUtils.isEmpty(userInstitutionList)) {
log.debug("User not found, deleting members for userId = {}", userId);
groupConnector.deleteMembers(userId, institutionId, productId);
} else {
log.debug("User found, not deleting members for userId = {}", userId);
}
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
public class UserV2ServiceImpl implements UserV2Service {

private final MsCoreConnector msCoreConnector;
private final UserGroupV2Service userGroupService;
private final UserApiConnector userApiConnector;
private final UserV2GroupService userGroupService;
private final ProductsConnector productsConnector;
private static final EnumSet<PartyRole> PARTY_ROLE_WHITE_LIST = EnumSet.of(PartyRole.SUB_DELEGATE, PartyRole.OPERATOR);

Expand Down Expand Up @@ -72,7 +72,7 @@ public void suspendUserProduct(String userId, String institutionId, String produ
public User getUserById(String userId) {
log.trace("getUserById start");
log.debug("getUserById id = {}", userId);
User user = userApiConnector.getUserById(userId);
User user = userApiConnector.getUserById(userId, null);
log.debug(LogUtils.CONFIDENTIAL_MARKER, "getUserById = {}", user);
log.trace("getUserById end");
return user;
Expand Down
Loading

0 comments on commit 6992c57

Please sign in to comment.