27.1. Modify userId to be UUID instead of String (#27 refactor http calls to use userId instead of username or email)
This commit is contained in:
@ -23,6 +23,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.springframework.http.HttpStatus.OK;
|
||||
|
||||
@ -93,7 +94,7 @@ public class UserResource {
|
||||
|
||||
@DeleteMapping("{userId}")
|
||||
@PreAuthorize("hasAuthority('user:delete')")
|
||||
public HttpResponse deleteUser(@PathVariable String userId) {
|
||||
public HttpResponse deleteUser(@PathVariable UUID userId) {
|
||||
userService.deleteUser(userId);
|
||||
return HttpResponse.builder()
|
||||
.httpStatusCode(OK.value())
|
||||
@ -114,12 +115,12 @@ public class UserResource {
|
||||
}
|
||||
|
||||
@GetMapping(path = "image/profile/{userId}/{filename}", produces = MediaType.IMAGE_JPEG_VALUE)
|
||||
public byte[] getProfileImageByUserId(@PathVariable String userId, @PathVariable String filename) throws IOException {
|
||||
public byte[] getProfileImageByUserId(@PathVariable UUID userId, @PathVariable String filename) throws IOException {
|
||||
return userService.getImageByUserId(userId, filename);
|
||||
}
|
||||
|
||||
@GetMapping(path = "image/profile/{userId}", produces = MediaType.IMAGE_JPEG_VALUE)
|
||||
public byte[] getDefaultProfileImage(@PathVariable String userId) {
|
||||
public byte[] getDefaultProfileImage(@PathVariable UUID userId) {
|
||||
return userService.getDefaultProfileImage(userId);
|
||||
}
|
||||
|
||||
|
||||
@ -2,13 +2,12 @@ package net.shyshkin.study.fullstack.supportportal.backend.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.Type;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
@Entity
|
||||
@ -27,7 +26,9 @@ public class User implements Serializable {
|
||||
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
|
||||
private Long id;
|
||||
|
||||
private String userId;
|
||||
@Type(type="org.hibernate.type.UUIDCharType")
|
||||
@Column(length = 36, columnDefinition = "varchar(255)", updatable = false, nullable = false )
|
||||
private UUID userId;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String username;
|
||||
|
||||
@ -4,6 +4,7 @@ import net.shyshkin.study.fullstack.supportportal.backend.domain.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
@ -15,6 +16,6 @@ public interface UserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
Boolean existsByEmail(String email);
|
||||
|
||||
Optional<User> findByUserId(String userId);
|
||||
Optional<User> findByUserId(UUID userId);
|
||||
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface UserService extends UserDetailsService {
|
||||
|
||||
@ -23,7 +24,7 @@ public interface UserService extends UserDetailsService {
|
||||
|
||||
User updateUser(String username, UserDto userDto);
|
||||
|
||||
void deleteUser(String userId);
|
||||
void deleteUser(UUID userId);
|
||||
|
||||
void resetPassword(String email);
|
||||
|
||||
@ -31,7 +32,7 @@ public interface UserService extends UserDetailsService {
|
||||
|
||||
byte[] getProfileImage(String username) throws IOException;
|
||||
|
||||
byte[] getImageByUserId(String userId, String filename) throws IOException;
|
||||
byte[] getImageByUserId(UUID userId, String filename) throws IOException;
|
||||
|
||||
byte[] getDefaultProfileImage(String userId);
|
||||
byte[] getDefaultProfileImage(UUID userId);
|
||||
}
|
||||
|
||||
@ -102,17 +102,17 @@ public class UserServiceImpl implements UserService {
|
||||
return addNewUser(newUserDto);
|
||||
}
|
||||
|
||||
private String generateDefaultProfileImageUrl(String userId) {
|
||||
private String generateDefaultProfileImageUrl(UUID userId) {
|
||||
return ServletUriComponentsBuilder.fromCurrentContextPath()
|
||||
.path(DEFAULT_USER_IMAGE_PATH)
|
||||
.pathSegment(userId)
|
||||
.pathSegment(userId.toString())
|
||||
.toUriString();
|
||||
}
|
||||
|
||||
private String generateProfileImageUrl(String userId) {
|
||||
private String generateProfileImageUrl(UUID userId) {
|
||||
return ServletUriComponentsBuilder.fromCurrentContextPath()
|
||||
.path(DEFAULT_USER_IMAGE_PATH)
|
||||
.pathSegment(userId)
|
||||
.pathSegment(userId.toString())
|
||||
.pathSegment(USER_IMAGE_FILENAME)
|
||||
.toUriString();
|
||||
}
|
||||
@ -121,8 +121,8 @@ public class UserServiceImpl implements UserService {
|
||||
return RandomStringUtils.randomAscii(10);
|
||||
}
|
||||
|
||||
private String generateUserId() {
|
||||
return UUID.randomUUID().toString();
|
||||
private UUID generateUserId() {
|
||||
return UUID.randomUUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -182,7 +182,7 @@ public class UserServiceImpl implements UserService {
|
||||
throw new NotAnImageFileException(profileImage.getOriginalFilename() + " is not an image file. Please upload an image");
|
||||
}
|
||||
|
||||
Path userFolder = Paths.get(USER_FOLDER, user.getUserId());
|
||||
Path userFolder = Paths.get(USER_FOLDER, user.getUserId().toString());
|
||||
try {
|
||||
if (Files.notExists(userFolder)) {
|
||||
Files.createDirectories(userFolder);
|
||||
@ -200,7 +200,7 @@ public class UserServiceImpl implements UserService {
|
||||
|
||||
private void deleteProfileImageFolder(User user) {
|
||||
|
||||
Path userFolder = Paths.get(USER_FOLDER, user.getUserId());
|
||||
Path userFolder = Paths.get(USER_FOLDER, user.getUserId().toString());
|
||||
try {
|
||||
FileSystemUtils.deleteRecursively(userFolder);
|
||||
} catch (IOException exception) {
|
||||
@ -232,7 +232,7 @@ public class UserServiceImpl implements UserService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteUser(String userId) {
|
||||
public void deleteUser(UUID userId) {
|
||||
User userToBeDeleted = userRepository
|
||||
.findByUserId(userId)
|
||||
.orElseThrow(() -> new UserNotFoundException("User was not found"));
|
||||
@ -270,14 +270,14 @@ public class UserServiceImpl implements UserService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getImageByUserId(String userId, String filename) throws IOException {
|
||||
public byte[] getImageByUserId(UUID userId, String filename) throws IOException {
|
||||
Path userProfileImagePath = Paths
|
||||
.get(USER_FOLDER, userId, filename);
|
||||
.get(USER_FOLDER, userId.toString(), filename);
|
||||
return Files.readAllBytes(userProfileImagePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getDefaultProfileImage(String userId) {
|
||||
public byte[] getDefaultProfileImage(UUID userId) {
|
||||
// "https://robohash.org/11951691-d373-4126-bef2-84d157a6546b"
|
||||
RequestEntity<Void> requestEntity = RequestEntity
|
||||
.get("/{userId}", userId)
|
||||
|
||||
@ -27,7 +27,7 @@ public abstract class BaseUserTest {
|
||||
protected static User user;
|
||||
|
||||
protected User createRandomUser() {
|
||||
String userId = UUID.randomUUID().toString();
|
||||
UUID userId = UUID.randomUUID();
|
||||
return User.builder()
|
||||
.email(FAKER.bothify("????##@example.com"))
|
||||
.firstName(FAKER.name().firstName())
|
||||
@ -58,11 +58,11 @@ public abstract class BaseUserTest {
|
||||
.build();
|
||||
}
|
||||
|
||||
private String generateProfileImageUrl(String userId) {
|
||||
private String generateProfileImageUrl(UUID userId) {
|
||||
return UriComponentsBuilder
|
||||
.fromUriString("http://localhost:8080")
|
||||
.path(DEFAULT_USER_IMAGE_PATH)
|
||||
.pathSegment(userId)
|
||||
.pathSegment(userId.toString())
|
||||
// .pathSegment(USER_IMAGE_FILENAME)
|
||||
.toUriString();
|
||||
}
|
||||
|
||||
@ -576,7 +576,7 @@ class UserResourceTest extends BaseUserTest {
|
||||
.satisfies(u -> assertThat(u.getProfileImageUrl()).endsWith(String.format("/user/image/profile/%s/avatar.jpg", u.getUserId())));
|
||||
|
||||
User createdUser = responseEntity.getBody();
|
||||
Path path = Path.of(FileConstant.USER_FOLDER, createdUser.getUserId(), FileConstant.USER_IMAGE_FILENAME);
|
||||
Path path = Path.of(FileConstant.USER_FOLDER, createdUser.getUserId().toString(), FileConstant.USER_IMAGE_FILENAME);
|
||||
log.debug("Path of created file: {}", path);
|
||||
assertThat(Files.exists(path)).isTrue();
|
||||
assertThat(Files.getLastModifiedTime(path).toInstant()).isCloseTo(Instant.now(), within(1, ChronoUnit.SECONDS));
|
||||
@ -634,7 +634,7 @@ class UserResourceTest extends BaseUserTest {
|
||||
.satisfies(u -> assertThat(u.getProfileImageUrl()).endsWith(String.format("/user/image/profile/%s/avatar.jpg", u.getUserId())));
|
||||
|
||||
User createdUser = responseEntity.getBody();
|
||||
Path path = Path.of(FileConstant.USER_FOLDER, createdUser.getUserId(), FileConstant.USER_IMAGE_FILENAME);
|
||||
Path path = Path.of(FileConstant.USER_FOLDER, createdUser.getUserId().toString(), FileConstant.USER_IMAGE_FILENAME);
|
||||
log.debug("Path of created file: {}", path);
|
||||
assertThat(Files.exists(path)).isTrue();
|
||||
assertThat(Files.getLastModifiedTime(path).toInstant()).isCloseTo(Instant.now(), within(1, ChronoUnit.SECONDS));
|
||||
@ -657,7 +657,7 @@ class UserResourceTest extends BaseUserTest {
|
||||
superAdmin.setAuthorities(Role.ROLE_SUPER_ADMIN.getAuthorities());
|
||||
String token = jwtTokenProvider.generateJwtToken(new UserPrincipal(superAdmin));
|
||||
|
||||
String userId = user.getUserId();
|
||||
UUID userId = user.getUserId();
|
||||
|
||||
//when
|
||||
var requestEntity = RequestEntity.delete("/user/{userId}", userId)
|
||||
@ -682,7 +682,7 @@ class UserResourceTest extends BaseUserTest {
|
||||
User roleUser = createRandomUser();
|
||||
String token = jwtTokenProvider.generateJwtToken(new UserPrincipal(roleUser));
|
||||
|
||||
String userId = user.getUserId();
|
||||
UUID userId = user.getUserId();
|
||||
|
||||
//when
|
||||
var requestEntity = RequestEntity.delete("/user/{userId}", userId)
|
||||
|
||||
@ -8,6 +8,7 @@ import net.shyshkin.study.fullstack.supportportal.backend.domain.HttpResponse;
|
||||
import net.shyshkin.study.fullstack.supportportal.backend.domain.Role;
|
||||
import net.shyshkin.study.fullstack.supportportal.backend.domain.User;
|
||||
import net.shyshkin.study.fullstack.supportportal.backend.domain.dto.UserDto;
|
||||
import net.shyshkin.study.fullstack.supportportal.backend.repository.UserRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -48,6 +49,9 @@ class UserResourceUnSecureTest extends BaseUserTest {
|
||||
@Autowired
|
||||
TestRestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
UserRepository userRepository;
|
||||
|
||||
@Nested
|
||||
class AddNewUserTests {
|
||||
|
||||
@ -490,6 +494,9 @@ class UserResourceUnSecureTest extends BaseUserTest {
|
||||
@Test
|
||||
void getAllUsers() {
|
||||
|
||||
//given
|
||||
long usersCount = userRepository.count();
|
||||
|
||||
//when
|
||||
var responseEntity = restTemplate.exchange("/user", HttpMethod.GET, null, UserPage.class);
|
||||
|
||||
@ -499,7 +506,7 @@ class UserResourceUnSecureTest extends BaseUserTest {
|
||||
assertThat(responseEntity.getBody())
|
||||
.isNotNull();
|
||||
assertThat(responseEntity.getBody().getContent())
|
||||
.hasSizeGreaterThan(2);
|
||||
.hasSize(Math.toIntExact(usersCount));
|
||||
}
|
||||
}
|
||||
|
||||
@ -594,7 +601,7 @@ class UserResourceUnSecureTest extends BaseUserTest {
|
||||
.hasFieldOrPropertyWithValue("role", user.getRole())
|
||||
.satisfies(u -> assertThat(u.getProfileImageUrl()).endsWith(String.format("/user/image/profile/%s/avatar.jpg", user.getUserId())));
|
||||
|
||||
Path path = Path.of(FileConstant.USER_FOLDER, user.getUserId(), FileConstant.USER_IMAGE_FILENAME);
|
||||
Path path = Path.of(FileConstant.USER_FOLDER, user.getUserId().toString(), FileConstant.USER_IMAGE_FILENAME);
|
||||
log.debug("Path of created file: {}", path);
|
||||
assertThat(Files.exists(path)).isTrue();
|
||||
assertThat(Files.getLastModifiedTime(path).toInstant()).isCloseTo(Instant.now(), within(100, ChronoUnit.MILLIS));
|
||||
@ -739,7 +746,7 @@ class UserResourceUnSecureTest extends BaseUserTest {
|
||||
void getDefaultProfileImage_correct() throws IOException {
|
||||
|
||||
//given
|
||||
String userId = user.getUserId();
|
||||
UUID userId = user.getUserId();
|
||||
|
||||
//when
|
||||
RequestEntity<Void> requestEntity = RequestEntity.get("/user/image/profile/{userId}", userId)
|
||||
@ -785,7 +792,7 @@ class UserResourceUnSecureTest extends BaseUserTest {
|
||||
.hasFieldOrPropertyWithValue("role", user.getRole())
|
||||
.satisfies(u -> assertThat(u.getProfileImageUrl()).endsWith(String.format("/user/image/profile/%s/avatar.jpg", user.getUserId())));
|
||||
|
||||
Path path = Path.of(FileConstant.USER_FOLDER, user.getUserId(), FileConstant.USER_IMAGE_FILENAME);
|
||||
Path path = Path.of(FileConstant.USER_FOLDER, user.getUserId().toString(), FileConstant.USER_IMAGE_FILENAME);
|
||||
log.debug("Path of created file: {}", path);
|
||||
assertThat(Files.exists(path)).isTrue();
|
||||
assertThat(Files.getLastModifiedTime(path).toInstant()).isCloseTo(Instant.now(), within(200, ChronoUnit.MILLIS));
|
||||
|
||||
@ -125,7 +125,7 @@ class UserServiceTest extends BaseUserTest {
|
||||
userService.updateProfileImage(username, multipartFile);
|
||||
|
||||
//then
|
||||
Path path = Path.of(FileConstant.USER_FOLDER, user.getUserId(), FileConstant.USER_IMAGE_FILENAME);
|
||||
Path path = Path.of(FileConstant.USER_FOLDER, user.getUserId().toString(), FileConstant.USER_IMAGE_FILENAME);
|
||||
log.debug("Path of created file: {}", path);
|
||||
assertThat(Files.exists(path)).isTrue();
|
||||
assertThat(Files.getLastModifiedTime(path).toInstant()).isCloseTo(Instant.now(), within(100, ChronoUnit.MILLIS));
|
||||
|
||||
Reference in New Issue
Block a user