Skip to content

Commit

Permalink
refact: [admin/users] modifie la section utilisateur de l’espace admi…
Browse files Browse the repository at this point in the history
…nistration (#306)

* restructuration du module adminstration en fragments / widgets
  • Loading branch information
matthieuaudemard committed Apr 30, 2023
1 parent 0dacb41 commit 7dbb525
Show file tree
Hide file tree
Showing 78 changed files with 843 additions and 756 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public void signup(@Valid final RegisterRequest registerRequest) throws Implicac
final String activationKey = generateActivationKey();
final UserModel user = registerUser(registerRequest, activationKey);


if (user.isEnabled()) {
publisher.publishEvent(new UserEnabledEvent(this, user.getUsername()));
} else {
Expand All @@ -83,7 +83,7 @@ public void signup(@Valid final RegisterRequest registerRequest) throws Implicac
/**
* Vérifie la validité de la requête de sign-up
*
* @throws AuthenticationException si le nom d’utilisateur ou l’email est déjà utilisé
* @throws AuthenticationException si le nom d’utilisateur ou l’adresse mail est déjà utilisé
*/
private void validateRegisterRequest(@Valid final RegisterRequest registerRequest) throws ImplicactionException {
if (userRepository.existsByUsername(registerRequest.getUsername())) {
Expand All @@ -96,10 +96,10 @@ private void validateRegisterRequest(@Valid final RegisterRequest registerReques
}

/**
* Définit l’adresse email de l’utilisateur correspondant à la clé d’activation comme vérifié si elle ne l’est pas déjà
* Définit l’adresse mail de l’utilisateur correspondant à la clé d’activation comme vérifié si elle ne l’est pas déjà
*
* @throws EntityNotFoundException si aucun utilisateur n’est associé à cette clé d’activation
* @throws AuthenticationException si l’email de l’utilisateur est déjà vérifié
* @throws AuthenticationException si l’adresse mail de l’utilisateur est déjà vérifié
*/
@Transactional
public void verifyAccount(final String activationKey) throws ImplicactionException {
Expand All @@ -114,7 +114,7 @@ public void verifyAccount(final String activationKey) throws ImplicactionExcepti
userRepository.save(user);
}

// TODO: revoir potentiellement la logique des jetons (ex: suppression des refresh tokens associés précédemment)
// TODO : revoir potentiellement la logique des jetons (ex: suppression des refresh tokens associés précédemment)
@Transactional
public LoginResponse login(@Valid final LoginRequest loginRequest) throws ImplicactionException {
final String username = loginRequest.getUsername();
Expand Down Expand Up @@ -179,8 +179,7 @@ private UserModel registerUser(final RegisterRequest registerRequest, final Stri
.registeredAt(now())
.build();

// On est obligé de flush ici pour que l'objet soit modifié instantanément dans le cas
// où il faille créer le profil dans la foulée
// On est obligé de flush ici pour que l’objet soit modifié instantanément dans le cas où il faille créer le profil dans la foulée.
userRepository.saveAndFlush(user);

return user;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package com.dynonuggets.refonteimplicaction.core.controller;

import com.dynonuggets.refonteimplicaction.core.domain.model.properties.enums.RoleEnum;
import com.dynonuggets.refonteimplicaction.core.dto.UserDto;
import com.dynonuggets.refonteimplicaction.core.service.UserService;
import lombok.AllArgsConstructor;
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.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Set;

import static com.dynonuggets.refonteimplicaction.core.utils.UserUris.*;


Expand All @@ -23,9 +27,11 @@ public class UserController {
@GetMapping
public ResponseEntity<Page<UserDto>> getAll(
@RequestParam(defaultValue = "0") final int page,
@RequestParam(defaultValue = "10") final int rows
@RequestParam(defaultValue = "10") final int rows,
@RequestParam(value = "sortBy", defaultValue = "id") final String[] sortBy,
@RequestParam(value = "sortOrder", defaultValue = "ASC") final String sortOrder
) {
final Pageable pageable = PageRequest.of(page, rows);
final Pageable pageable = PageRequest.of(page, rows, Sort.by(Sort.Direction.valueOf(sortOrder), sortBy));
final Page<UserDto> users = userService.getAll(pageable);
return ResponseEntity.ok(users);
}
Expand All @@ -43,8 +49,13 @@ public ResponseEntity<Page<UserDto>> getAllPendingUsers(

@PostMapping(ENABLE_USER)
@PreAuthorize("hasRole('ROLE_ADMIN')")
public ResponseEntity<Void> enableUser(@PathVariable final String username) {
userService.enableUser(username);
return ResponseEntity.ok().build();
public ResponseEntity<UserDto> enableUser(@PathVariable final String username) {
return ResponseEntity.ok(userService.enableUser(username));
}

@PostMapping(UPDATE_USER_ROLES)
@PreAuthorize("hasRole('ROLE_ADMIN')")
public ResponseEntity<UserDto> updateUserRoles(@PathVariable final String username, @RequestBody final Set<RoleEnum> roles) {
return ResponseEntity.ok(userService.updateUserRoles(username, roles));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.dynonuggets.refonteimplicaction.core.domain.model.RoleModel;
import com.dynonuggets.refonteimplicaction.core.domain.model.UserModel;
import com.dynonuggets.refonteimplicaction.core.domain.model.properties.enums.RoleEnum;
import com.dynonuggets.refonteimplicaction.core.domain.repository.UserRepository;
import com.dynonuggets.refonteimplicaction.core.dto.UserDto;
import com.dynonuggets.refonteimplicaction.core.error.EntityNotFoundException;
Expand All @@ -14,6 +15,9 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Set;
import java.util.stream.Collectors;

import static com.dynonuggets.refonteimplicaction.core.domain.model.properties.enums.RoleEnum.ROLE_USER;
import static com.dynonuggets.refonteimplicaction.core.error.UserErrorResult.USERNAME_NOT_FOUND;
import static com.dynonuggets.refonteimplicaction.core.error.UserErrorResult.USER_ID_NOT_FOUND;
Expand Down Expand Up @@ -71,7 +75,7 @@ public UserModel getUserByIdIfExists(final Long userId) {
}

@Transactional
public void enableUser(final String username) {
public UserDto enableUser(final String username) {
final UserModel user = getUserByUsernameIfExists(username);
final RoleModel roleUser = roleService.getRoleByName(ROLE_USER);

Expand All @@ -80,5 +84,19 @@ public void enableUser(final String username) {

userRepository.save(user);
publisher.publishEvent(new UserEnabledEvent(this, user.getUsername()));

return userMapper.toDto(user);
}

@Transactional
public UserDto updateUserRoles(final String username, final Set<RoleEnum> roles) {
final UserModel user = getUserByUsernameIfExists(username);
final Set<RoleModel> rolesModels = roles.stream()
.map(roleService::getRoleByName)
.collect(Collectors.toSet());

user.setRoles(rolesModels);

return userMapper.toDto(userRepository.save(user));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ public class UserUris {
public static final String USER_BASE_URI = "/api/users";
public static final String GET_PENDING_USER_URI = "/pending";
public static final String ENABLE_USER = "/{username}/enable";
public static final String UPDATE_USER_ROLES = "/{username}/roles";
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
import com.dynonuggets.refonteimplicaction.core.domain.repository.UserRepository;
import com.dynonuggets.refonteimplicaction.core.error.EntityNotFoundException;
import com.dynonuggets.refonteimplicaction.core.error.ImplicactionException;
import com.dynonuggets.refonteimplicaction.core.event.UserCreatedEvent;
import com.dynonuggets.refonteimplicaction.core.event.UserEnabledEvent;
import com.dynonuggets.refonteimplicaction.core.service.RoleService;
import com.dynonuggets.refonteimplicaction.core.service.UserService;
import com.dynonuggets.refonteimplicaction.notification.service.NotificationService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
Expand All @@ -37,7 +38,7 @@

import static com.dynonuggets.refonteimplicaction.auth.error.AuthErrorResult.*;
import static com.dynonuggets.refonteimplicaction.core.error.UserErrorResult.USERNAME_NOT_FOUND;
import static com.dynonuggets.refonteimplicaction.core.utils.UserTestUtils.generateRandomUser;
import static com.dynonuggets.refonteimplicaction.core.utils.UserTestUtils.generateRandomUserModel;
import static com.dynonuggets.refonteimplicaction.utils.AssertionUtils.assertImplicactionException;
import static java.lang.String.format;
import static java.time.Instant.now;
Expand Down Expand Up @@ -70,8 +71,6 @@ class AuthServiceTest {
JwtProvider jwtProvider;
@Mock
RefreshTokenService refreshTokenService;
@Mock
NotificationService notificationService;
@InjectMocks
AuthService authService;
@Captor
Expand Down Expand Up @@ -137,6 +136,7 @@ void should_register_user_when_request_is_valid_and_no_user_in_DB() {
verify(userRepository, times(1)).existsByEmail(any());
verify(passwordEncoder, times(1)).encode(any());
verify(roleService, times(3)).getRoleByName(any(RoleEnum.class));
verify(publisher, times(1)).publishEvent(any(UserEnabledEvent.class));
}

@Test
Expand Down Expand Up @@ -170,6 +170,7 @@ void should_register_user_when_request_is_valid_and_user_not_already_exists() {
verify(userRepository, times(1)).existsByUsername(any());
verify(userRepository, times(1)).existsByEmail(any());
verify(passwordEncoder, times(1)).encode(any());
verify(publisher, times(1)).publishEvent(any(UserCreatedEvent.class));
}

@Test
Expand Down Expand Up @@ -210,7 +211,7 @@ class VerifyAccountTest {
@DisplayName("doit activer l'utilisateur correspondant à la clé d'activation transmise s'il n'est pas déjà activé")
void should_activate_corresponding_user() {
// given
final UserModel user = generateRandomUser(Set.of(RoleEnum.ROLE_USER), false);
final UserModel user = generateRandomUserModel(Set.of(RoleEnum.ROLE_USER), false);
given(userRepository.findByActivationKey(any())).willReturn(of(user));

// when
Expand Down Expand Up @@ -267,7 +268,7 @@ class LoginTest {
@DisplayName("doit identifier l'utilisateur quand il existe")
void should_log_user_when_exists() {
// given
final UserModel user = generateRandomUser();
final UserModel user = generateRandomUserModel();
final String username = user.getUsername();
final LoginRequest loginRequest = LoginRequest.builder().username(username).password("password").build();
final String jwtToken = "jwt-token";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import static com.dynonuggets.refonteimplicaction.community.group.error.GroupErrorResult.USER_ALREADY_SUBSCRIBED_TO_GROUP;
import static com.dynonuggets.refonteimplicaction.community.group.utils.GroupTestUtils.generateRandomGroup;
import static com.dynonuggets.refonteimplicaction.core.domain.model.properties.enums.RoleEnum.ROLE_PREMIUM;
import static com.dynonuggets.refonteimplicaction.core.utils.UserTestUtils.generateRandomUser;
import static com.dynonuggets.refonteimplicaction.core.utils.UserTestUtils.generateRandomUserModel;
import static com.dynonuggets.refonteimplicaction.utils.AssertionUtils.assertImplicactionException;
import static java.time.Instant.now;
import static java.util.List.of;
Expand Down Expand Up @@ -78,7 +78,7 @@ void should_create_group_when_image_is_submitted() {
// given
final MockMultipartFile mockedImage = new MockMultipartFile("user-file", "test.jpg", "image/jpeg", "test data".getBytes());
final GroupCreationRequest groupCreationRequest = GroupCreationRequest.builder().name("coucou subreddit").description("Elle est super bien ma description").build();
final UserModel currentUser = generateRandomUser(Set.of(ROLE_PREMIUM), true);
final UserModel currentUser = generateRandomUserModel(Set.of(ROLE_PREMIUM), true);
final String imageUrl = "http://localhost/imapge.png";
final String username = currentUser.getUsername();
final ProfileModel profile = ProfileModel.builder().user(currentUser).build();
Expand Down Expand Up @@ -107,7 +107,7 @@ void should_create_group_when_image_is_submitted() {
void should_create_group_when_no_image_is_submitted() {
// given
final GroupCreationRequest groupCreationRequest = GroupCreationRequest.builder().name("coucou subreddit").description("Elle est super bien ma description").build();
final UserModel currentUser = generateRandomUser(Set.of(ROLE_PREMIUM), true);
final UserModel currentUser = generateRandomUserModel(Set.of(ROLE_PREMIUM), true);
final String username = currentUser.getUsername();
final ProfileModel profile = ProfileModel.builder().user(currentUser).build();
final GroupModel expectedGroup = GroupModel.builder().id(12L).name(groupCreationRequest.getName()).description(groupCreationRequest.getDescription()).creator(profile).createdAt(now()).enabled(false).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import static com.dynonuggets.refonteimplicaction.community.profile.utils.ProfileTestUtils.*;
import static com.dynonuggets.refonteimplicaction.core.error.CoreErrorResult.OPERATION_NOT_PERMITTED;
import static com.dynonuggets.refonteimplicaction.core.error.UserErrorResult.USERNAME_NOT_FOUND;
import static com.dynonuggets.refonteimplicaction.core.utils.UserTestUtils.generateRandomUser;
import static com.dynonuggets.refonteimplicaction.core.utils.UserTestUtils.generateRandomUserModel;
import static com.dynonuggets.refonteimplicaction.utils.AssertionUtils.assertImplicactionException;
import static java.lang.String.format;
import static java.util.List.of;
Expand Down Expand Up @@ -75,7 +75,7 @@ class CreateProfileTests {
@DisplayName("doit créer un profil utilisateur si l'utilisateur existe et que son profil n'existe pas encore")
void should_create_profile_if_user_exists_and_profile_is_not_already_created() {
// given
final UserModel userModel = generateRandomUser();
final UserModel userModel = generateRandomUserModel();
final String username = userModel.getUsername();
given(userService.getUserByUsernameIfExists(username)).willReturn(userModel);
given(profileRepository.findByUser_Username(username)).willReturn(Optional.empty());
Expand Down Expand Up @@ -109,7 +109,7 @@ void should_throw_exception_if_user_not_exists() {
@DisplayName("doit lancer une exception si le profil existe déjà")
void should_throw_exception_if_profile_already_exists() {
// given
final UserModel userModel = generateRandomUser();
final UserModel userModel = generateRandomUserModel();
final String username = userModel.getUsername();
given(userService.getUserByUsernameIfExists(username)).willReturn(userModel);
given(profileRepository.findByUser_Username(username)).willReturn(Optional.of(ProfileModel.builder().build()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import java.util.List;

import static com.dynonuggets.refonteimplicaction.core.utils.AppUtils.callIfNotNull;
import static com.dynonuggets.refonteimplicaction.core.utils.UserTestUtils.generateRandomUser;
import static com.dynonuggets.refonteimplicaction.core.utils.UserTestUtils.generateRandomUserModel;
import static com.dynonuggets.refonteimplicaction.utils.TestUtils.generateRandomLocalDate;
import static com.dynonuggets.refonteimplicaction.utils.TestUtils.generateRandomNumber;
import static java.lang.String.format;
Expand All @@ -31,7 +31,7 @@ public class ProfileTestUtils {
public static ProfileModel generateRandomProfile() {
return ProfileModel.builder()
.id((long) generateRandomNumber())
.user(generateRandomUser())
.user(generateRandomUserModel())
.hobbies(randomAlphabetic(100))
.purpose(randomAlphabetic(100))
.presentation(randomAlphabetic(100))
Expand Down
Loading

0 comments on commit 7dbb525

Please sign in to comment.