From 00ec56779ebb80f30813a43251414010da4ac675 Mon Sep 17 00:00:00 2001 From: EnesBaserr Date: Wed, 15 May 2024 11:58:21 +0300 Subject: [PATCH 1/2] Format responses for /follow & /unfollow endpoints. --- .../cuisines/controllers/UserController.java | 69 ++++++++++++------- .../group1/cuisines/services/UserService.java | 26 ++++++- 2 files changed, 66 insertions(+), 29 deletions(-) diff --git a/backend/src/main/java/com/group1/cuisines/controllers/UserController.java b/backend/src/main/java/com/group1/cuisines/controllers/UserController.java index a7b6a138..50e6a8da 100644 --- a/backend/src/main/java/com/group1/cuisines/controllers/UserController.java +++ b/backend/src/main/java/com/group1/cuisines/controllers/UserController.java @@ -56,10 +56,42 @@ public ResponseEntity getUserDetails(@AuthenticationPrincipal UserDetails use } return ResponseEntity.status(HttpStatus.FORBIDDEN).body("User not authenticated"); + } + @DeleteMapping("/{userId}/unfollow") + public ResponseEntity unfollowUser(@PathVariable Integer userId) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if(authentication.getPrincipal()=="anonymousUser"){ + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new ErrorResponse(401,"Authentication required") ); + } + + String username = authentication.getName(); + Integer followerId = userRepository.findUserIdByUsername(username); + - @PostMapping("/follow") - public ResponseEntity followUser(@RequestBody Map requestBody) { + + if (followerId == null || userId == null) { + return ResponseEntity.ok(new ErrorResponse(204,"Invalid user data")); + } + if (userId.equals(followerId)) { + return ResponseEntity.badRequest().body(new ErrorResponse(400, "Cannot unfollow yourself")); + } + + boolean result = userService.unfollowUser(userId, followerId); + if (!result) { + + return ResponseEntity.ok(new ErrorResponse(209,"Follow relationship does not exist")); + } + + UserProfileDto followedUserDto = userService.getUserProfileDtoById(userId); + if (followedUserDto == null) { + return ResponseEntity.ok(new ErrorResponse(404, "User not found")); + } + return ResponseEntity.ok(new SuccessResponse<>(200,followedUserDto,"Unfollowed successfully")); + } + + @PostMapping("/{userId}/follow") + public ResponseEntity followUser(@PathVariable Integer userId) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if(authentication.getPrincipal()=="anonymousUser"){ return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new ErrorResponse(401,"Authentication required") ); @@ -69,21 +101,28 @@ public ResponseEntity followUser(@RequestBody Map requestBod String username = authentication.getName(); Integer followerId = userRepository.findUserIdByUsername(username); - Integer userId = requestBody.get("userId"); + if (followerId == null || userId == null) { return ResponseEntity.ok(new ErrorResponse(204,"Invalid user data")); } + if (userId.equals(followerId)) { + return ResponseEntity.badRequest().body(new ErrorResponse(400, "Cannot follow yourself")); + } boolean result = userService.followUser(userId, followerId); if (!result) { return ResponseEntity.ok(new ErrorResponse(209,"Already following")); } + UserProfileDto followedUserDto = userService.getUserProfileDtoById(userId); + if (followedUserDto == null) { + return ResponseEntity.ok(new ErrorResponse(404, "User not found")); + } - return ResponseEntity.ok(new SuccessResponse<>(200,null,"Followed successfully")); + return ResponseEntity.ok(new SuccessResponse<>(200,followedUserDto,"Followed successfully")); } @GetMapping("/{userId}/following") public ResponseEntity getUserFollowing(@PathVariable Integer userId) { @@ -142,28 +181,6 @@ public ResponseEntity getUserFollowers(@PathVariable Integer userId) { return ResponseEntity.ok(new SuccessResponse<>(200,followingDto, "User followers fetched successfully")); } } - @PostMapping("/unfollow") - public ResponseEntity unfollowUser(@RequestBody Map requestBody) { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if(authentication.getPrincipal()=="anonymousUser"){ - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new ErrorResponse(401,"Authentication required") ); - } - - String username = authentication.getName(); - Integer followerId = userRepository.findUserIdByUsername(username); - Integer userId = requestBody.get("userId"); - if (followerId == null || userId == null) { - return ResponseEntity.ok(new ErrorResponse(204,"Invalid user data")); - } - - boolean result = userService.unfollowUser(userId, followerId); - if (!result) { - - return ResponseEntity.ok(new ErrorResponse(209,"Follow relationship does not exist")); - } - return ResponseEntity.ok(new SuccessResponse<>(200,null,"Unfollowed successfully")); - } - } diff --git a/backend/src/main/java/com/group1/cuisines/services/UserService.java b/backend/src/main/java/com/group1/cuisines/services/UserService.java index 7dacf859..a32c1c57 100644 --- a/backend/src/main/java/com/group1/cuisines/services/UserService.java +++ b/backend/src/main/java/com/group1/cuisines/services/UserService.java @@ -167,8 +167,8 @@ else if(recipe.getDish() != null && recipe.getDish().getCuisines().isEmpty()){ cuisineDto, new DishDto(recipe.getDish().getId(), recipe.getDish().getName(), recipe.getDish().getImage()), recipe.getAverageRating(), - new AuthorDto(recipe.getUser().getId(), recipe.getUser().getUsername(), recipe.getUser().getFirstName(), - recipe.getUser().getFollowingCount(), recipe.getUser().getFollowerCount(),recipe.getUser().getRecipeCount()) + new AuthorDto(recipe.getUser().getId(), recipe.getUser().getUsername(), recipe.getUser().getFirstName()+ " " + recipe.getUser().getLastName() , + recipe.getUser().getFollowerCount(), recipe.getUser().getFollowingCount(),recipe.getUser().getRecipeCount()) ); } @@ -200,7 +200,27 @@ else if(recipe.getDish() != null && recipe.getDish().getCuisines().isEmpty()){ new DishDto(recipe.getDish().getId(), recipe.getDish().getName(), recipe.getDish().getImage()), recipe.getAverageRating(), new AuthorDto(recipe.getUser().getId(), recipe.getUser().getUsername(), recipe.getUser().getFirstName(), - recipe.getUser().getFollowingCount(), recipe.getUser().getFollowerCount(),recipe.getUser().getRecipeCount()) + recipe.getUser().getFollowerCount(), recipe.getUser().getFollowingCount(),recipe.getUser().getRecipeCount()) ); } + + public UserProfileDto getUserProfileDtoById(Integer userId) { + User user = userRepository.findById(userId).orElse(null); + if (user == null) { + return null; + } + // Map the User entity to UserProfileDto, possibly using ModelMapper or manual mapping + UserProfileDto profile = new UserProfileDto(); + profile.setId(user.getId()); + profile.setUsername(user.getUsername()); + profile.setName(user.getFirstName() + " " + user.getLastName()); + profile.setBio(user.getBio()); + profile.setFollowersCount(user.getFollowers().size()); + profile.setFollowingCount(user.getFollowing().size()); + profile.setRecipeCount(user.getRecipes().size()); + profile.setRecipes(user.getRecipes().stream() + .map(this::convertToRecipeDetailsDto) + .collect(Collectors.toList())); + return profile; + } } From 072ea1c427a5e497214135dd4325f368884744ab Mon Sep 17 00:00:00 2001 From: EnesBaserr Date: Wed, 15 May 2024 12:57:12 +0300 Subject: [PATCH 2/2] Format responses for /follow & /unfollow endpoints. --- .../controllers/SearchController.java | 43 +++++++++++++++---- .../cuisines/controllers/UserController.java | 27 ++++++++++++ .../java/com/group1/cuisines/dto/UserDto.java | 1 + .../group1/cuisines/dto/UserProfileDto.java | 1 + .../group1/cuisines/services/UserService.java | 14 ++++++ 5 files changed, 77 insertions(+), 9 deletions(-) diff --git a/backend/src/main/java/com/group1/cuisines/controllers/SearchController.java b/backend/src/main/java/com/group1/cuisines/controllers/SearchController.java index 1d53a486..2b780fa3 100644 --- a/backend/src/main/java/com/group1/cuisines/controllers/SearchController.java +++ b/backend/src/main/java/com/group1/cuisines/controllers/SearchController.java @@ -17,6 +17,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; @RestController @@ -30,20 +32,43 @@ public class SearchController { @GetMapping("/users") public ResponseEntity searchUsers(@RequestParam(required = false) String q) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + Integer currentUserId = null; + if (authentication != null && authentication.isAuthenticated() && !authentication.getPrincipal().equals("anonymousUser")) { + currentUserId = ((User) authentication.getPrincipal()).getId(); + } + else{ + currentUserId = null; + } List users = userService.searchUsers(q); if (users.isEmpty()) { // Return a custom message with a "No Content" status when no users are found return ResponseEntity.ok(new ErrorResponse(204,"No users found")); } - return ResponseEntity.ok(new SuccessResponse<>(200, users.stream().map(user -> new UserDto( - user.getId(), - user.getUsername(), - user.getFirstName(), - user.getLastName(), - user.getFollowerCount(), - user.getFollowingCount(), - user.getRecipeCount() - )).collect(Collectors.toList()), "Users fetched successfully")); + Integer finalCurrentUserId = currentUserId; + List userDtos = users.stream().map(user -> { + Integer currentId = finalCurrentUserId; + boolean isSelf = user.getId().equals(currentId); // Check if the current user is the same as the user in the list + boolean isFollowing = false; + if (currentId != null && !isSelf) { + isFollowing = userService.isFollowing(currentId, user.getId()); // Checking following status + } + return new UserDto( + user.getId(), + user.getUsername(), + user.getFirstName(), + user.getLastName(), + isFollowing, + user.getFollowerCount(), + user.getFollowingCount(), + user.getRecipeCount() + + + ); + }).collect(Collectors.toList()); + + return ResponseEntity.ok(new SuccessResponse<>(200, userDtos, "Users fetched successfully")); + } diff --git a/backend/src/main/java/com/group1/cuisines/controllers/UserController.java b/backend/src/main/java/com/group1/cuisines/controllers/UserController.java index 50e6a8da..2b6dba8d 100644 --- a/backend/src/main/java/com/group1/cuisines/controllers/UserController.java +++ b/backend/src/main/java/com/group1/cuisines/controllers/UserController.java @@ -7,6 +7,7 @@ import com.group1.cuisines.entities.User; import com.group1.cuisines.repositories.UserRepository; import com.group1.cuisines.services.UserService; +import com.sun.security.auth.UserPrincipal; import jakarta.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; @@ -84,9 +85,11 @@ public ResponseEntity unfollowUser(@PathVariable Integer userId) { } UserProfileDto followedUserDto = userService.getUserProfileDtoById(userId); + if (followedUserDto == null) { return ResponseEntity.ok(new ErrorResponse(404, "User not found")); } + followedUserDto.setSelfFollowing(false); return ResponseEntity.ok(new SuccessResponse<>(200,followedUserDto,"Unfollowed successfully")); } @@ -121,6 +124,7 @@ public ResponseEntity followUser(@PathVariable Integer userId) { if (followedUserDto == null) { return ResponseEntity.ok(new ErrorResponse(404, "User not found")); } + followedUserDto.setSelfFollowing(true); return ResponseEntity.ok(new SuccessResponse<>(200,followedUserDto,"Followed successfully")); } @@ -134,17 +138,27 @@ public ResponseEntity getUserFollowing(@PathVariable Integer userId) { if(userRepository.findById(userId).isEmpty()){ return ResponseEntity.ok(new ErrorResponse(204,"User not found") ); } + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + Integer currentUserId = null; + if (authentication.getPrincipal()!="anonymousUser" && authentication != null && authentication.isAuthenticated()) { + currentUserId = ((User) authentication.getPrincipal()).getId(); + } + else{ + currentUserId=null; + } Set following = userService.getUserFollowing(userId); if (following.isEmpty()) { return ResponseEntity.ok(new ErrorResponse(204,"User is not following anyone")); } else { + Integer finalCurrentUserId = currentUserId; Set followingDto = following.stream() .map(user -> UserDto.builder() .id(user.getId()) .username(user.getUsername()) .firstName(user.getFirstName()) .lastName(user.getLastName()) + .selfFollowing(userService.isFollowing(finalCurrentUserId, user.getId())) .followerCount(user.getFollowerCount()) .followingCount(user.getFollowingCount()) .recipeCount(user.getRecipeCount()) @@ -163,16 +177,29 @@ public ResponseEntity getUserFollowers(@PathVariable Integer userId) { if(userRepository.findById(userId).isEmpty()){ return ResponseEntity.ok(new ErrorResponse(204,"User not found") ); } + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + Integer currentUserId = null; + if (authentication.getPrincipal()!="anonymousUser" && authentication != null && authentication.isAuthenticated()) { + currentUserId = ((User) authentication.getPrincipal()).getId(); + } + else{ + currentUserId=null; + } + + + Set followers = userService.getUserFollower(userId); if (followers.isEmpty()) { return ResponseEntity.ok(new ErrorResponse(204,"User is not followed by anyone")); } else { + Integer finalCurrentUserId = currentUserId; Set followingDto = followers.stream() .map(user -> UserDto.builder() .id(user.getId()) .username(user.getUsername()) .firstName(user.getFirstName()) .lastName(user.getLastName()) + .selfFollowing(userService.isFollowing(finalCurrentUserId, user.getId())) .followerCount(user.getFollowerCount()) .followingCount(user.getFollowingCount()) .recipeCount(user.getRecipeCount()) diff --git a/backend/src/main/java/com/group1/cuisines/dto/UserDto.java b/backend/src/main/java/com/group1/cuisines/dto/UserDto.java index 331ec8d9..97765d73 100644 --- a/backend/src/main/java/com/group1/cuisines/dto/UserDto.java +++ b/backend/src/main/java/com/group1/cuisines/dto/UserDto.java @@ -13,6 +13,7 @@ public class UserDto { private String username; private String firstName; private String lastName; + private boolean selfFollowing; private int followerCount; private int followingCount; private int recipeCount; diff --git a/backend/src/main/java/com/group1/cuisines/dto/UserProfileDto.java b/backend/src/main/java/com/group1/cuisines/dto/UserProfileDto.java index 447263f8..6bf6714d 100644 --- a/backend/src/main/java/com/group1/cuisines/dto/UserProfileDto.java +++ b/backend/src/main/java/com/group1/cuisines/dto/UserProfileDto.java @@ -13,6 +13,7 @@ public class UserProfileDto { private String username; private String name; private String bio; + private boolean selfFollowing; private Integer followersCount; private Integer followingCount; //private String gender; diff --git a/backend/src/main/java/com/group1/cuisines/services/UserService.java b/backend/src/main/java/com/group1/cuisines/services/UserService.java index a32c1c57..835b789c 100644 --- a/backend/src/main/java/com/group1/cuisines/services/UserService.java +++ b/backend/src/main/java/com/group1/cuisines/services/UserService.java @@ -74,6 +74,17 @@ public boolean followUser(Integer userId, Integer followerId) { } return false; } + public boolean isFollowing(Integer followerId, Integer followedId) { + if (followerId == null || followedId == null) { + return false; + } + User follower = userRepository.findById(followerId).orElse(null); + User followed = userRepository.findById(followedId).orElse(null); + if (follower != null && followed != null) { + return follower.getFollowing().contains(followed); + } + return false; + } public Set getUserFollowing(Integer userId) { User user = userRepository.findById(userId).orElse(null); if (user != null) { @@ -117,6 +128,7 @@ public Set getUserFollower(Integer userId) { public UserProfileDto getUserProfileById(Integer userId, String currentUsername) { User user = userRepository.findById(userId) .orElseThrow(() -> new EntityNotFoundException("User not found")); + Integer currentUserId = userRepository.findUserIdByUsername(currentUsername); boolean isSelf = user.getUsername().equals(currentUsername); @@ -125,6 +137,7 @@ public UserProfileDto getUserProfileById(Integer userId, String currentUsername) profile.setUsername(user.getUsername()); profile.setName(user.getFirstName() + " " + user.getLastName()); profile.setBio(user.getBio()); + profile.setSelfFollowing(isFollowing(currentUserId, userId)); profile.setFollowersCount(user.getFollowers().size()); profile.setFollowingCount(user.getFollowing().size()); profile.setRecipeCount(user.getRecipes().size()); @@ -215,6 +228,7 @@ public UserProfileDto getUserProfileDtoById(Integer userId) { profile.setUsername(user.getUsername()); profile.setName(user.getFirstName() + " " + user.getLastName()); profile.setBio(user.getBio()); + profile.setFollowersCount(user.getFollowers().size()); profile.setFollowingCount(user.getFollowing().size()); profile.setRecipeCount(user.getRecipes().size());