diff --git a/server/src/main/java/dev/findfirst/users/controller/UserController.java b/server/src/main/java/dev/findfirst/users/controller/UserController.java index 82ccc2c5..75ff6835 100644 --- a/server/src/main/java/dev/findfirst/users/controller/UserController.java +++ b/server/src/main/java/dev/findfirst/users/controller/UserController.java @@ -249,4 +249,15 @@ public ResponseEntity getUserProfilePicture(@RequestParam("userId") in return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } } + + @DeleteMapping + public ResponseEntity deleteUserAccount() { + try { + userService.deleteUserAccount(); + } catch (NoUserFoundException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User is already deleted"); + } + return ResponseEntity.status(HttpStatus.OK).build(); + } + } diff --git a/server/src/main/java/dev/findfirst/users/service/UserManagementService.java b/server/src/main/java/dev/findfirst/users/service/UserManagementService.java index 0346d4ff..e271c5ec 100644 --- a/server/src/main/java/dev/findfirst/users/service/UserManagementService.java +++ b/server/src/main/java/dev/findfirst/users/service/UserManagementService.java @@ -10,6 +10,8 @@ import java.util.Optional; import java.util.UUID; +import dev.findfirst.core.service.BookmarkService; +import dev.findfirst.core.service.TagService; import dev.findfirst.security.jwt.service.RefreshTokenService; import dev.findfirst.security.jwt.service.TokenService; import dev.findfirst.security.userauth.context.UserContext; @@ -32,6 +34,7 @@ import org.springframework.data.jdbc.core.mapping.AggregateReference; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @Service @@ -46,6 +49,8 @@ public class UserManagementService { private final PasswordEncoder passwdEncoder; private final TokenService ts; private final UserContext ut; + private final BookmarkService bookmarkService; + private final TagService tagService; @Value("${findfirst.upload.location}") private String uploadLocation; @@ -219,4 +224,18 @@ public SigninTokens signinUser(String authorization) throws NoUserFoundException } throw new NoUserFoundException(); } + + @Transactional + public void deleteUserAccount() throws NoUserFoundException { + Integer id = ut.getUserId(); + User user = getUserById(id) + .orElseThrow(NoUserFoundException::new); + log.info("Deleting user account"+id); + + bookmarkService.deleteAllBookmarks(); + tagService.deleteAllTags(); + userRepo.delete(user); + + log.info("Successfully deleted user "+id); + } } diff --git a/server/src/test/java/dev/findfirst/users/controller/UserControllerTest.java b/server/src/test/java/dev/findfirst/users/controller/UserControllerTest.java index aa25f25e..3cefc557 100644 --- a/server/src/test/java/dev/findfirst/users/controller/UserControllerTest.java +++ b/server/src/test/java/dev/findfirst/users/controller/UserControllerTest.java @@ -1,9 +1,7 @@ package dev.findfirst.users.controller; import static dev.findfirst.utilities.HttpUtility.getHttpEntity; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import java.nio.file.Files; import java.nio.file.Path; @@ -12,14 +10,19 @@ import dev.findfirst.core.annotations.IntegrationTest; import dev.findfirst.core.annotations.MockTypesense; +import dev.findfirst.core.repository.jdbc.BookmarkJDBCRepository; +import dev.findfirst.core.repository.jdbc.TagJDBCRepository; import dev.findfirst.core.service.TypesenseService; import dev.findfirst.security.userauth.models.TokenRefreshResponse; import dev.findfirst.security.userauth.models.payload.request.SignupRequest; +import dev.findfirst.users.exceptions.NoUserFoundException; import dev.findfirst.users.model.MailHogMessage; import dev.findfirst.users.model.oauth2.Oauth2Source; import dev.findfirst.users.model.user.TokenPassword; import com.fasterxml.jackson.databind.ObjectMapper; +import dev.findfirst.users.model.user.User; +import dev.findfirst.users.repository.UserRepo; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -250,4 +253,48 @@ void getAllProivders() { assertTrue(sources.length == 1); assertEquals("GitHub", sources[0].provider(), "Github should be the provider."); } + + @Autowired + private UserRepo userRepo; + + @Autowired + private BookmarkJDBCRepository bookmarkJDBCRepository; + + @Autowired + private TagJDBCRepository tagJDBCRepository; + + @Test + void testDeleteUser() throws Exception { + + SignupRequest request = new SignupRequest( + "testUser", + "testUser@gmail.com", + "testPassword" + ); + + restTemplate.postForEntity("/user/signup",request,String.class); + + var token = getTokenFromEmail(0, 1); + + var regResponse = restTemplate.getForEntity("/user/regitrationConfirm?token={token}", + String.class, token); + assertEquals(HttpStatus.SEE_OTHER, regResponse.getStatusCode()); + + User user = userRepo.findByUsername("testUser") + .orElseThrow(NoUserFoundException::new); + +// first delete + HttpHeaders headers = new HttpHeaders(); + headers.setBasicAuth("testUser","testPassword"); + HttpEntity entity = new HttpEntity<>(headers); + var response = restTemplate.exchange("/user",HttpMethod.DELETE,entity,Void.class); + assertEquals(HttpStatus.OK,response.getStatusCode()); + +// Checking + + assertFalse(userRepo.existsByUsername("testUser")); + assertTrue(bookmarkJDBCRepository.findAllBookmarksByUser(user.getUserId()).isEmpty()); + assertTrue(tagJDBCRepository.findAllByUserId(user.getUserId()).isEmpty()); + + } }