diff --git a/server/src/main/java/io/flexwork/modules/usermanagement/domain/User.java b/server/src/main/java/io/flexwork/modules/usermanagement/domain/User.java index abf4a6be..3bff1fed 100644 --- a/server/src/main/java/io/flexwork/modules/usermanagement/domain/User.java +++ b/server/src/main/java/io/flexwork/modules/usermanagement/domain/User.java @@ -10,10 +10,8 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; -import java.util.HashSet; import java.util.Set; import lombok.*; -import org.hibernate.annotations.BatchSize; /** A user. */ @Entity @@ -115,16 +113,12 @@ public class User extends AbstractAuditingEntity implements Serializable { @Column(name = "last_login_time") private LocalDateTime lastLoginTime; - @JsonIgnore @ManyToMany @JoinTable( name = "fw_user_authority", - joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")}, - inverseJoinColumns = { - @JoinColumn(name = "authority_name", referencedColumnName = "name") - }) - @BatchSize(size = 20) - private Set authorities = new HashSet<>(); + joinColumns = @JoinColumn(name = "user_id"), + inverseJoinColumns = @JoinColumn(name = "authority_name")) + private Set authorities; public LocalDateTime getLastLoginTime() { if (lastLoginTime == null) return null; diff --git a/server/src/main/java/io/flexwork/modules/usermanagement/repository/UserRepository.java b/server/src/main/java/io/flexwork/modules/usermanagement/repository/UserRepository.java index f2c1bf8f..76e7f0d9 100644 --- a/server/src/main/java/io/flexwork/modules/usermanagement/repository/UserRepository.java +++ b/server/src/main/java/io/flexwork/modules/usermanagement/repository/UserRepository.java @@ -47,4 +47,14 @@ List findAllByActivatedIsFalseAndActivationKeyIsNotNullAndCreatedDateBefor @Query("SELECT u FROM User u JOIN u.authorities a WHERE a.name = :authorityName") List findAllUsersByAuthority(@Param("authorityName") String authorityName); + + @Query( + "SELECT u FROM User u " + + "WHERE (LOWER(u.email) LIKE LOWER(CONCAT('%', :searchTerm, '%')) " + + "OR LOWER(CONCAT(u.firstName, ' ', u.lastName)) LIKE LOWER(CONCAT('%', :searchTerm, '%'))) " + + "AND :authorityName NOT IN (SELECT a.name FROM u.authorities a)") + List findUsersNotInAuthority( + @Param("searchTerm") String searchTerm, + @Param("authorityName") String authorityName, + Pageable pageable); } diff --git a/server/src/main/java/io/flexwork/modules/usermanagement/service/UserService.java b/server/src/main/java/io/flexwork/modules/usermanagement/service/UserService.java index 5419f6f8..22118209 100644 --- a/server/src/main/java/io/flexwork/modules/usermanagement/service/UserService.java +++ b/server/src/main/java/io/flexwork/modules/usermanagement/service/UserService.java @@ -354,9 +354,38 @@ public List getAuthorities() { return authorityRepository.findAll().stream().map(Authority::getName).toList(); } + @Transactional(readOnly = true) public List findAllUsersByAuthority(String authorityName) { return userRepository.findAllUsersByAuthority(authorityName).stream() .map(userMapper::toDto) .collect(Collectors.toList()); } + + @Transactional(readOnly = true) + public List findUsersNotInAuthority( + String searchTerm, String authorityName, Pageable pageable) { + return userMapper.toDtos( + userRepository.findUsersNotInAuthority(searchTerm, authorityName, pageable)); + } + + @Transactional + public void addUsersToAuthority(List userIds, String authorityName) { + // Fetch the authority entity + Authority authority = + authorityRepository + .findById(authorityName) + .orElseThrow( + () -> + new IllegalArgumentException( + "Authority not found: " + authorityName)); + + // Fetch the users and associate them with the authority + List users = userRepository.findAllById(userIds); + for (User user : users) { + user.getAuthorities().add(authority); + } + + // Save all updated users + userRepository.saveAll(users); + } } diff --git a/server/src/main/java/io/flexwork/modules/usermanagement/service/mapper/UserMapper.java b/server/src/main/java/io/flexwork/modules/usermanagement/service/mapper/UserMapper.java index dc125b4f..d82f32ba 100644 --- a/server/src/main/java/io/flexwork/modules/usermanagement/service/mapper/UserMapper.java +++ b/server/src/main/java/io/flexwork/modules/usermanagement/service/mapper/UserMapper.java @@ -2,6 +2,7 @@ import io.flexwork.modules.usermanagement.domain.User; import io.flexwork.modules.usermanagement.service.dto.UserDTO; +import java.util.List; import org.mapstruct.Mapper; @Mapper(componentModel = "spring") @@ -10,4 +11,6 @@ public interface UserMapper { UserDTO toDto(User user); User toEntity(UserDTO userDTO); + + List toDtos(List users); } diff --git a/server/src/main/java/io/flexwork/modules/usermanagement/web/rest/AuthorityController.java b/server/src/main/java/io/flexwork/modules/usermanagement/web/rest/AuthorityController.java index b95057ed..f095a96f 100644 --- a/server/src/main/java/io/flexwork/modules/usermanagement/web/rest/AuthorityController.java +++ b/server/src/main/java/io/flexwork/modules/usermanagement/web/rest/AuthorityController.java @@ -2,9 +2,11 @@ import io.flexwork.modules.usermanagement.domain.Authority; import io.flexwork.modules.usermanagement.repository.AuthorityRepository; +import io.flexwork.modules.usermanagement.service.UserService; import jakarta.validation.Valid; import java.net.URI; import java.net.URISyntaxException; +import java.util.List; import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,8 +34,11 @@ public class AuthorityController { private final AuthorityRepository authorityRepository; - public AuthorityController(AuthorityRepository authorityRepository) { + private final UserService userService; + + public AuthorityController(AuthorityRepository authorityRepository, UserService userService) { this.authorityRepository = authorityRepository; + this.userService = userService; } /** @@ -74,7 +79,7 @@ public Page getAllAuthorities(Pageable pageable) { /** * {@code GET /authorities/:id} : get the "id" authority. * - * @param id the id of the authority to retrieve. + * @param name the id of the authority to retrieve. * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the authority, * or with status {@code 404 (Not Found)}. */ @@ -101,4 +106,11 @@ public ResponseEntity deleteAuthority(@PathVariable("id") String id) { applicationName, true, ENTITY_NAME, id)) .build(); } + + @PostMapping("/{authorityName}/add-users") + public ResponseEntity addUsersToAuthority( + @PathVariable String authorityName, @RequestBody List userIds) { + userService.addUsersToAuthority(userIds, authorityName); + return ResponseEntity.ok().build(); + } } diff --git a/server/src/main/java/io/flexwork/modules/usermanagement/web/rest/PublicUserController.java b/server/src/main/java/io/flexwork/modules/usermanagement/web/rest/PublicUserController.java index 2e4337a7..a4063bcf 100644 --- a/server/src/main/java/io/flexwork/modules/usermanagement/web/rest/PublicUserController.java +++ b/server/src/main/java/io/flexwork/modules/usermanagement/web/rest/PublicUserController.java @@ -9,6 +9,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.http.HttpHeaders; @@ -19,6 +20,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import tech.jhipster.web.util.PaginationUtil; @@ -77,6 +79,16 @@ public ResponseEntity> getUsersByAuthority(@PathVariable String au return ResponseEntity.ok(users); } + @GetMapping("/authorities/searchUsersNotInAuthority") + public ResponseEntity> findUsersNotInAuthority( + @RequestParam("userTerm") String searchTerm, + @RequestParam("authorityName") String authorityName) { + PageRequest pageRequest = PageRequest.of(0, 20); // Limit to 20 results + List users = + userService.findUsersNotInAuthority(searchTerm, authorityName, pageRequest); + return ResponseEntity.ok(users); + } + private boolean onlyContainsAllowedProperties(Pageable pageable) { return pageable.getSort().stream() .map(Sort.Order::getProperty) diff --git a/tools/liquibase/src/main/resources/config/liquibase/tenant/changelog/00000000000000_initial_schema.xml b/tools/liquibase/src/main/resources/config/liquibase/tenant/changelog/00000000000000_initial_schema.xml index fc979fe1..93d7c03d 100644 --- a/tools/liquibase/src/main/resources/config/liquibase/tenant/changelog/00000000000000_initial_schema.xml +++ b/tools/liquibase/src/main/resources/config/liquibase/tenant/changelog/00000000000000_initial_schema.xml @@ -208,14 +208,15 @@ - + - @@ -247,8 +248,9 @@ id="00000000000000:05-insert-default-user-authority-data" context="!test"> + file="config/liquibase/tenant/data/fw_user_authority.csv" + separator=";" tableName="fw_user_authority" + usePreparedStatements="true"> - @@ -297,7 +299,7 @@ id="00000000000000:09-insert-default-fw-authority-resource-permission" context="!test"> diff --git a/tools/liquibase/src/main/resources/config/liquibase/tenant/data/authority.csv b/tools/liquibase/src/main/resources/config/liquibase/tenant/data/fw_authority.csv similarity index 100% rename from tools/liquibase/src/main/resources/config/liquibase/tenant/data/authority.csv rename to tools/liquibase/src/main/resources/config/liquibase/tenant/data/fw_authority.csv diff --git a/tools/liquibase/src/main/resources/config/liquibase/tenant/data/authority_resource_permission.csv b/tools/liquibase/src/main/resources/config/liquibase/tenant/data/fw_authority_resource_permission.csv similarity index 100% rename from tools/liquibase/src/main/resources/config/liquibase/tenant/data/authority_resource_permission.csv rename to tools/liquibase/src/main/resources/config/liquibase/tenant/data/fw_authority_resource_permission.csv diff --git a/tools/liquibase/src/main/resources/config/liquibase/tenant/data/resource.csv b/tools/liquibase/src/main/resources/config/liquibase/tenant/data/fw_resource.csv similarity index 100% rename from tools/liquibase/src/main/resources/config/liquibase/tenant/data/resource.csv rename to tools/liquibase/src/main/resources/config/liquibase/tenant/data/fw_resource.csv diff --git a/tools/liquibase/src/main/resources/config/liquibase/tenant/data/user.csv b/tools/liquibase/src/main/resources/config/liquibase/tenant/data/fw_user.csv similarity index 100% rename from tools/liquibase/src/main/resources/config/liquibase/tenant/data/user.csv rename to tools/liquibase/src/main/resources/config/liquibase/tenant/data/fw_user.csv diff --git a/tools/liquibase/src/main/resources/config/liquibase/tenant/data/user_authority.csv b/tools/liquibase/src/main/resources/config/liquibase/tenant/data/fw_user_authority.csv similarity index 100% rename from tools/liquibase/src/main/resources/config/liquibase/tenant/data/user_authority.csv rename to tools/liquibase/src/main/resources/config/liquibase/tenant/data/fw_user_authority.csv