diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/user/UserFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/user/UserFacade.java index e54454f2027..b7628155784 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/user/UserFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/user/UserFacade.java @@ -46,7 +46,7 @@ public interface UserFacade { UserDto saveUser(@Valid UserDto dto, boolean isUserSettingsUpdate); - UserDto setUserRoles(UserReferenceDto userReference, Set userRoles); + UserDto saveUserRolesAndRestrictions(UserDto user, Set userRoles); boolean isLoginUnique(String uuid, String userName); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserFacadeEjb.java index ba99c3562d6..e3eaf4780b9 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserFacadeEjb.java @@ -16,6 +16,7 @@ import static java.util.Objects.isNull; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -53,6 +54,7 @@ import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -629,17 +631,33 @@ public UserDto saveUser(@Valid UserDto dto, boolean isUserSettingsUpdate) { throw new AccessDeniedException(I18nProperties.getString(Strings.errorForbidden)); } - User user = userService.getByUuid(dto.getUuid()); + User existingUser = userService.getByUuid(dto.getUuid()); // current user should be able to edit itself if (!DataHelper.isSame(userService.getCurrentUser(), dto)) { - FacadeHelper.checkCreateAndEditRights(user, userService, UserRight.USER_CREATE, UserRight.USER_EDIT); + FacadeHelper.checkCreateAndEditRights(existingUser, userService, UserRight.USER_CREATE, UserRight.USER_EDIT); } - return saveUserRoles(dto, isUserSettingsUpdate, user); + if (!isLoginUnique(existingUser == null ? null : existingUser.getUuid(), dto.getUserName())) { + throw new ValidationException(I18nProperties.getValidationError(Validations.userNameNotUnique)); + } + + validateUserRoles(dto.getUserRoles(), isUserSettingsUpdate, existingUser, dto.getCreationDate() != null); + + User user = fillOrBuildEntity(dto, existingUser, true); + userService.ensurePersisted(user); + + if (existingUser == null) { + userCreateEvent.fire(new UserCreateEvent(user)); + } else { + userUpdateEvent.fire(new UserUpdateEvent(existingUser, user)); + } + + return toDto(user); } - private UserDto saveUserRoles(UserDto dto, boolean isUserSettingsUpdate, User user) { - Collection newRoles = userRoleFacade.getByReferences(dto.getUserRoles()); + @Nullable + private User validateUserRoles(Set roles, boolean isUserSettingsUpdate, User user, boolean isUserUpdate) { + Collection newRoles = userRoleFacade.getByReferences(roles); try { userRoleFacade.validateUserRoleCombination(newRoles); @@ -647,13 +665,9 @@ private UserDto saveUserRoles(UserDto dto, boolean isUserSettingsUpdate, User us throw new ValidationException(e); } - if (!isLoginUnique(user == null ? null : user.getUuid(), dto.getUserName())) { - throw new ValidationException(I18nProperties.getValidationError(Validations.userNameNotUnique)); - } - User oldUser = null; Set oldUserRights = Collections.emptySet(); - if (dto.getCreationDate() != null) { + if (isUserUpdate) { try { oldUser = (User) BeanUtils.cloneBean(user); oldUserRights = UserRole.getUserRights(oldUser.getUserRoles()); @@ -671,28 +685,39 @@ private UserDto saveUserRoles(UserDto dto, boolean isUserSettingsUpdate, User us throw new ValidationException(I18nProperties.getValidationError(Validations.removeUserEditRightFromOwnUser)); } } + return oldUser; + } - user = fillOrBuildEntity(dto, user, true); - userService.ensurePersisted(user); + @Override + @RightsAllowed(UserRight._USER_EDIT) + public UserDto saveUserRolesAndRestrictions(UserDto userDto, Set userRoles) { + User user = userService.getByReferenceDto(userDto.toReference()); - if (oldUser == null) { - userCreateEvent.fire(new UserCreateEvent(user)); - } else { - userUpdateEvent.fire(new UserUpdateEvent(oldUser, user)); + User oldUser; + try { + oldUser = (User) BeanUtils.cloneBean(user); + } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { + throw new RuntimeException(e); } - return toDto(user); - } + validateUserRoles(userDto.getUserRoles(), false, user, true); - @Override - @RightsAllowed(UserRight._USER_EDIT) - public UserDto setUserRoles(UserReferenceDto userReference, Set userRoles) { - User user = userService.getByReferenceDto(userReference); + fillEntityUserRoles(user, userDto); - UserDto userToBeSaved = toDto(user); - userToBeSaved.setUserRoles(userRoles); + user.setRegion(regionService.getByReferenceDto(userDto.getRegion())); + user.setDistrict(districtService.getByReferenceDto(userDto.getDistrict())); + user.setCommunity(communityService.getByReferenceDto(userDto.getCommunity())); + user.setHealthFacility(facilityService.getByReferenceDto(userDto.getHealthFacility())); + user.setAssociatedOfficer(userService.getByReferenceDto(userDto.getAssociatedOfficer())); + user.setLaboratory(facilityService.getByReferenceDto(userDto.getLaboratory())); + user.setPointOfEntry(pointOfEntryService.getByReferenceDto(userDto.getPointOfEntry())); + user.setLimitedDiseases(userDto.getLimitedDiseases()); - return saveUserRoles(userToBeSaved, false, user); + userService.ensurePersisted(user); + + userUpdateEvent.fire(new UserUpdateEvent(oldUser, user)); + + return toDto(user); } @Override @@ -830,6 +855,14 @@ private User fillOrBuildEntity(UserDto source, User target, boolean checkChangeD target.setLanguage(source.getLanguage()); target.setHasConsentedToGdpr(source.isHasConsentedToGdpr()); + fillEntityUserRoles(target, source); + + target.updateJurisdictionLevel(); + + return target; + } + + private void fillEntityUserRoles(User target, UserDto source) { //Make sure userroles of target are attached Set userRoles = Optional.of(target).map(User::getUserRoles).orElseGet(HashSet::new); target.setUserRoles(userRoles); @@ -845,10 +878,6 @@ private User fillOrBuildEntity(UserDto source, User target, boolean checkChangeD target.getUserRoles().addAll(newUserRoles); //Remove userroles that were removed target.getUserRoles().removeIf(userRole -> !sourceUserRoleUuids.contains(userRole.getUuid())); - - target.updateJurisdictionLevel(); - - return target; } @Override diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserController.java index 40aeb1ddcae..a057578e97c 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserController.java @@ -179,7 +179,7 @@ private void openRemoveUserAsOfficerPrompt(Consumer callback) { private void saveUser(UserDto user) { if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.AUTH_PROVIDER_TO_SORMAS_USER_SYNC)) { - FacadeProvider.getUserFacade().setUserRoles(user.toReference(), user.getUserRoles()); + FacadeProvider.getUserFacade().saveUserRolesAndRestrictions(user, user.getUserRoles()); } else { FacadeProvider.getUserFacade().saveUser(user, false); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserEditForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserEditForm.java index c081c80ee8c..7888092fd23 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserEditForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserEditForm.java @@ -24,6 +24,7 @@ import static de.symeda.sormas.ui.utils.LayoutUtil.loc; import static java.util.function.Predicate.not; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -80,6 +81,16 @@ public class UserEditForm extends AbstractEditForm { private static final String LIMITED_DISEASES_HEADING_LOC = "limitedDiseasesHeadingLoc"; public static final String RESTRICT_DISEASES_CHECKBOX_LOC = "restrictDiseasesCheckboxLoc"; private static final String RESTRICT_DISEASES_DESCRIPTION_LOC = "restrictDiseasesDescriptionLoc"; + public static List excludedFields = Arrays.asList( + UserDto.USER_ROLES, + UserDto.REGION, + UserDto.DISTRICT, + UserDto.COMMUNITY, + UserDto.HEALTH_FACILITY, + UserDto.POINT_OF_ENTRY, + UserDto.ASSOCIATED_OFFICER, + UserDto.LABORATORY, + UserDto.LIMITED_DISEASES); //@formatter:off private static final String HTML_LAYOUT = @@ -244,11 +255,10 @@ protected void addFields() { if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.AUTH_PROVIDER_TO_SORMAS_USER_SYNC)) { this.getFieldGroup().getFields().forEach(userField ->{ - if (!userField.getId().equals(UserDto.USER_ROLES)) { + if (!excludedFields.contains(userField.getId())) { userField.setEnabled(false); } }); - this.getField(UserEditForm.RESTRICT_DISEASES_CHECKBOX_LOC).setEnabled(false); } }