diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/GroupController.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/GroupController.java index d14375f55319f38065b48773fbc6ebb284fb508d..a33ab537ddf929fb423fc6ab82aed0e7af3babf0 100644 --- a/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/GroupController.java +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/GroupController.java @@ -1,6 +1,7 @@ package ntnu.idatt2016.v233.SmartMat.controller.group; import lombok.AllArgsConstructor; +import ntnu.idatt2016.v233.SmartMat.dto.request.group.ChangeAuthorityRequest; import ntnu.idatt2016.v233.SmartMat.dto.request.group.GroupConnectionRequest; import ntnu.idatt2016.v233.SmartMat.dto.request.group.GroupRequest; import ntnu.idatt2016.v233.SmartMat.dto.response.group.GroupDetailsResponse; @@ -12,7 +13,9 @@ import ntnu.idatt2016.v233.SmartMat.entity.group.UserGroupId; import ntnu.idatt2016.v233.SmartMat.entity.user.User; import ntnu.idatt2016.v233.SmartMat.service.group.GroupService; import ntnu.idatt2016.v233.SmartMat.service.user.UserService; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; import java.util.*; @@ -32,18 +35,6 @@ public class GroupController { private final UserService userService; - /** - * Gets a group by its name - * @param groupName the name of the group - * @return a ResponseEntity containing the group if it exists, or a 404 if it doesn't - */ - /*@GetMapping("/{groupName}") - public ResponseEntity<Group> getGroupByName(@PathVariable("groupName") String groupName){ - return groupService.getGroupByName(groupName) - .map(ResponseEntity::ok) - .orElseGet(() -> ResponseEntity.notFound().build()); - }*/ - /** * Gets a group by its id * @param groupId the id of the group @@ -80,7 +71,7 @@ public class GroupController { * or a 400 if the group name is invalid or already exists, or if the username is invalid */ @PostMapping("/group") - public ResponseEntity<?> createGroup(@RequestBody GroupRequest groupRequest) { + public ResponseEntity<?> createGroup(@RequestBody GroupRequest groupRequest, Authentication auth) { if (groupRequest.groupName() == null || groupRequest.groupName().trim().length() < 3) { return ResponseEntity.badRequest().body("Group name must be at least 3 characters long."); } @@ -89,7 +80,7 @@ public class GroupController { return ResponseEntity.badRequest().body("Group name already exists."); } - Optional<User> optionalUser = userService.getUserFromUsername(groupRequest.username()); + Optional<User> optionalUser = userService.getUserFromUsername(auth.getName()); if (optionalUser.isEmpty()) { return ResponseEntity.badRequest().body("Invalid username."); } @@ -201,15 +192,13 @@ public class GroupController { /** * Handles the HTTP PUT request to change the primary group of a user. * - * @param username the username of the user whose primary group is to be changed * @param newPrimaryGroupId the ID of the new primary group * @return a ResponseEntity object containing an HTTP status code and the updated UserGroupAsso object, * or a ResponseEntity object with an HTTP status code indicating that the request was not successful */ - @PutMapping("/markNewPrimary/{username}/{newPrimaryGroupId}") - public ResponseEntity<?> markNewPrimaryGroup(@PathVariable("username") String username, - @PathVariable("newPrimaryGroupId") long newPrimaryGroupId) { - Optional<User> optionalUser = userService.getUserFromUsername(username); + @PutMapping("/markNewPrimary/{newPrimaryGroupId}") + public ResponseEntity<?> markNewPrimaryGroup(@PathVariable("newPrimaryGroupId") long newPrimaryGroupId, Authentication auth) { + Optional<User> optionalUser = userService.getUserFromUsername(auth.getName()); if (optionalUser.isEmpty()) { return ResponseEntity.badRequest().body("Invalid username."); @@ -217,7 +206,7 @@ public class GroupController { User user = optionalUser.get(); - Optional<UserGroupAsso> oldPrimaryOpt = groupService.findPrimaryUserGroupAssoForUser(username); + Optional<UserGroupAsso> oldPrimaryOpt = groupService.findPrimaryUserGroupAssoForUser(user.getUsername()); if (oldPrimaryOpt.isEmpty()) { return ResponseEntity.badRequest().body("No primary group found for the user."); } @@ -226,7 +215,7 @@ public class GroupController { oldPrimary.setPrimaryGroup(false); groupService.updateUserGroupAsso(oldPrimary); - Optional<UserGroupAsso> newPrimaryOpt = groupService.getUserGroupAsso(username, newPrimaryGroupId); + Optional<UserGroupAsso> newPrimaryOpt = groupService.getUserGroupAsso(user.getUsername(), newPrimaryGroupId); if (newPrimaryOpt.isEmpty()) { return ResponseEntity.badRequest().body("Invalid new primary group ID."); } @@ -238,7 +227,7 @@ public class GroupController { userService.updateUser(user); Map<String, Object> responseBody = new HashMap<>(); - responseBody.put("username", username); + responseBody.put("username", user.getUsername()); responseBody.put("oldPrimaryGroupId", oldPrimary.getGroup().getGroupId()); responseBody.put("newPrimaryGroupId", newPrimary.getGroup().getGroupId()); return ResponseEntity.ok(responseBody); @@ -252,14 +241,14 @@ public class GroupController { * or a ResponseEntity object with an HTTP status code indicating that the request was not successful */ @PostMapping("/connection") - public ResponseEntity<?> addConnection(@RequestBody GroupConnectionRequest groupConnectionRequest) { + public ResponseEntity<?> addConnection(@RequestBody GroupConnectionRequest groupConnectionRequest, Authentication auth) { Optional<Group> optionalGroup = groupService.getGroupByLinkCode(groupConnectionRequest.linkCode()); if (optionalGroup.isEmpty()) { return ResponseEntity.badRequest().body("Invalid link code."); } - Optional<User> optionalUser = userService.getUserFromUsername(groupConnectionRequest.username()); + Optional<User> optionalUser = userService.getUserFromUsername(auth.getName()); if (optionalUser.isEmpty()) { return ResponseEntity.badRequest().body("Invalid username."); @@ -297,31 +286,42 @@ public class GroupController { /** * Changes the authority level of a user in a group. * - * @param groupId the ID of the group - * @param username the username of the user whose authority level is to be changed - * @param authority the new authority level of the user + * @param authorityRequest the request object containing the username and group ID of the user to change the authority of * @return a ResponseEntity object containing the updated UserGroupAsso object and an HTTP status code of 200, + * or a ResponseEntity object with an HTTP status code of 403 if the user is not authorized to change the authority, * or a ResponseEntity object with an HTTP status code of 404 if the group or user does not exist */ - @PutMapping("/changeAuthority/{groupId}/{username}/{authority}") - public ResponseEntity<?> changeAuthority(@PathVariable("groupId") long groupId, - @PathVariable("username") String username, - @PathVariable("authority") String authority){ - return groupService.getGroupById(groupId).flatMap(group -> userService.getUserFromUsername(username) - .flatMap(user -> { - UserGroupAsso userGroupAsso = user.getGroup().stream() - .filter(asso -> asso.getGroup().getGroupId() == groupId) - .findFirst() - .orElse(null); - if(userGroupAsso != null){ - userGroupAsso.setGroupAuthority(authority); - userService.updateUser(user); - return Optional.of(userGroupAsso); - } - return Optional.empty(); - })) - .map(ResponseEntity::ok) - .orElseGet(() -> ResponseEntity.notFound().build()); + @PutMapping("/groupAuthority") + public ResponseEntity<?> changeAuthority(@RequestBody ChangeAuthorityRequest authorityRequest, + Authentication auth) { + Optional<User> groupAdminOpt = userService.getUserFromUsername(auth.getName()); + if (groupAdminOpt.isPresent()) { + User groupAdmin = groupAdminOpt.get(); + if (!(groupService.isUserAssociatedWithGroup(groupAdmin.getUsername(), authorityRequest.groupId()) + && (groupService.getUserGroupAssoAuthority(groupAdmin.getUsername(), authorityRequest.groupId()).equals("ADMIN")))) + return ResponseEntity.status(HttpStatus.FORBIDDEN).body("You are not authorized to change the authority of this user."); + } + + Optional<Group> groupOpt = groupService.getGroupById(authorityRequest.groupId()); + Optional<User> userOpt = userService.getUserFromUsername(authorityRequest.username()); + + if (groupOpt.isEmpty() || userOpt.isEmpty()) { + return ResponseEntity.notFound().build(); + } + + User user = userOpt.get(); + UserGroupAsso userGroupAsso = user.getGroup().stream() + .filter(asso -> asso.getGroup().getGroupId() == authorityRequest.groupId()) + .findFirst() + .orElse(null); + + if (userGroupAsso != null) { + userGroupAsso.setGroupAuthority(authorityRequest.authority()); + userService.updateUser(user); + return ResponseEntity.ok("Authority changed successfully."); + } else { + return ResponseEntity.notFound().build(); + } } } diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/dto/request/group/ChangeAuthorityRequest.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/dto/request/group/ChangeAuthorityRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..ae7282ae1bb3e9f436dbca53a6e817aa14176d3b --- /dev/null +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/dto/request/group/ChangeAuthorityRequest.java @@ -0,0 +1,4 @@ +package ntnu.idatt2016.v233.SmartMat.dto.request.group; + +public record ChangeAuthorityRequest(String username, long groupId, String authority) {} + diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/dto/request/group/GroupConnectionRequest.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/dto/request/group/GroupConnectionRequest.java index 90b8f27af3e83f851333e87e556fc073054d6ccf..e15cd9de783edc43892cf09fe32dd650a6c280e4 100644 --- a/src/main/java/ntnu/idatt2016/v233/SmartMat/dto/request/group/GroupConnectionRequest.java +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/dto/request/group/GroupConnectionRequest.java @@ -2,8 +2,7 @@ package ntnu.idatt2016.v233.SmartMat.dto.request.group; /** * GroupConnectionRequest is a record class representing a request to connect to a group. - * @param username the username of the user connecting to the group * @param linkCode the link code of the group */ -public record GroupConnectionRequest(String username, String linkCode) { +public record GroupConnectionRequest(String linkCode) { } diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/dto/request/group/GroupRequest.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/dto/request/group/GroupRequest.java index 4078bab3eab8af22269719c9529be17a48973906..0028c07d89af042b479d532a20af32dd2ead5b89 100644 --- a/src/main/java/ntnu/idatt2016/v233/SmartMat/dto/request/group/GroupRequest.java +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/dto/request/group/GroupRequest.java @@ -3,7 +3,6 @@ package ntnu.idatt2016.v233.SmartMat.dto.request.group; /** * GroupRequest is a record class representing a request to create a group. * @param groupName the name of the group - * @param username the username of the user creating the group */ -public record GroupRequest(String groupName, String username) { +public record GroupRequest(String groupName) { } diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/repository/group/UserGroupAssoRepository.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/repository/group/UserGroupAssoRepository.java index 8e3c12e3d9a31db60e7262729b8fe06eebfb83ab..77f294fc3cb98207701c5c2bf9eb9c155f2c43eb 100644 --- a/src/main/java/ntnu/idatt2016/v233/SmartMat/repository/group/UserGroupAssoRepository.java +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/repository/group/UserGroupAssoRepository.java @@ -65,4 +65,12 @@ public interface UserGroupAssoRepository extends JpaRepository<UserGroupAsso, Us * @return an optional containing the UserGroupAsso if it exists */ Optional<UserGroupAsso> findByUser_UsernameAndPrimaryGroupTrue(String username); + + /** + * Finds the authority level of a user in a group + * @param username the username of the user + * @param groupId the id of the group + * @return + */ + String findAuthorityByUser_UsernameAndGroup_GroupId(String username, long groupId); } diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/GroupService.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/GroupService.java index 1d9b8637e16ab959553848b76594bc366e8934ca..484f3ff93f71a911ef9b0bf1424443c5e7389ccc 100644 --- a/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/GroupService.java +++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/GroupService.java @@ -191,10 +191,21 @@ public class GroupService { return userGroupAssoRepository.save(userGroupAsso); } + /** + * Finds the primary group for a user + * @param username the username of the user + * @return an optional containing the primary group if it exists + */ public Optional<UserGroupAsso> findPrimaryUserGroupAssoForUser(String username) { return userGroupAssoRepository.findByUser_UsernameAndPrimaryGroupTrue(username); } + /** + * Gets a user group association + * @param username the username of the user + * @param groupId the id of the group + * @return + */ public Optional<UserGroupAsso> getUserGroupAsso(String username, Long groupId) { UserGroupId userGroupId = UserGroupId.builder() .username(username) @@ -203,4 +214,9 @@ public class GroupService { return userGroupAssoRepository.findById(userGroupId); } + + public String getUserGroupAssoAuthority(String username, long groupId) { + Optional<UserGroupAsso> userGroupAsso = getUserGroupAsso(username, groupId); + return userGroupAsso.map(UserGroupAsso::getGroupAuthority).orElseThrow(() -> new IllegalArgumentException("User is not associated with group")); + } }