From b848f6f34fd97da99673e225213fcee87589eeb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Theodor=20Angerg=C3=A5rd?= Date: Mon, 10 Jun 2024 19:52:57 +0200 Subject: [PATCH] Be able to update unofficial post name yourself (not requiring admin) --- .../adapter/primary/web/GroupsController.java | 59 +++++++++++++++++-- .../gamma/app/authentication/AccessGuard.java | 11 ++++ .../chalmers/gamma/app/group/GroupFacade.java | 36 +++++++++++ .../templates/pages/group-details.html | 18 ++++++ 4 files changed, 118 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/it/chalmers/gamma/adapter/primary/web/GroupsController.java b/app/src/main/java/it/chalmers/gamma/adapter/primary/web/GroupsController.java index b7568699c..774e57a01 100644 --- a/app/src/main/java/it/chalmers/gamma/adapter/primary/web/GroupsController.java +++ b/app/src/main/java/it/chalmers/gamma/adapter/primary/web/GroupsController.java @@ -54,6 +54,23 @@ public ModelAndView getGroups( public record Member(String name, String post, UUID userId) {} + public static class MyMembershipsForm { + + private MyMembershipsForm() { + this.postNames = new HashMap<>(); + } + + private Map postNames; + + public Map getPostNames() { + return postNames; + } + + public void setPostNames(Map postNames) { + this.postNames = postNames; + } + } + @GetMapping("/groups/{id}") public ModelAndView getGroup( @RequestHeader(value = "HX-Request", required = false) boolean htmxRequest, @@ -96,14 +113,27 @@ public ModelAndView getGroup( boolean canEditImages = false; if (SecurityContextHolder.getContext().getAuthentication() instanceof UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) { + UUID myUserId = UUID.fromString(usernamePasswordAuthenticationToken.getName()); + canEditImages = group.get().groupMembers().stream() - .anyMatch( - groupMember -> - groupMember - .user() - .id() - .equals(UUID.fromString(usernamePasswordAuthenticationToken.getName()))); + .anyMatch(groupMember -> groupMember.user().id().equals(myUserId)); + + List myGroupMembers = + group.get().groupMembers().stream() + .filter(groupMember -> groupMember.user().id().equals(myUserId)) + .toList(); + mv.addObject("myMembers", myGroupMembers); + + MyMembershipsForm form = new MyMembershipsForm(); + + myGroupMembers.forEach( + groupMember -> { + form.postNames.put( + groupMember.post().id().toString(), groupMember.unofficialPostName()); + }); + + mv.addObject("myMembershipsForm", form); } mv.addObject("canEditImages", canEditImages); @@ -392,4 +422,21 @@ public ModelAndView deleteGroup( return new ModelAndView("redirect:/groups"); } + + @PutMapping("/groups/{groupId}/my-posts") + public ModelAndView updateUnofficialPostNames( + @PathVariable("groupId") UUID groupId, MyMembershipsForm myMembershipsForm) { + if (SecurityContextHolder.getContext().getAuthentication() + instanceof UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) { + UUID myUserId = UUID.fromString(usernamePasswordAuthenticationToken.getName()); + + myMembershipsForm.postNames.forEach( + (postId, newUnofficialPostName) -> { + groupFacade.changeUnofficialPostName( + groupId, UUID.fromString(postId), myUserId, newUnofficialPostName); + }); + } + + return new ModelAndView("redirect:/groups/" + groupId); + } } diff --git a/app/src/main/java/it/chalmers/gamma/app/authentication/AccessGuard.java b/app/src/main/java/it/chalmers/gamma/app/authentication/AccessGuard.java index 521d80025..78c11581a 100644 --- a/app/src/main/java/it/chalmers/gamma/app/authentication/AccessGuard.java +++ b/app/src/main/java/it/chalmers/gamma/app/authentication/AccessGuard.java @@ -41,6 +41,17 @@ public static AccessChecker isAdmin() { }; } + public static AccessChecker isMe(UserId userId) { + return (clientRepository, userRepository) -> { + if (AuthenticationExtractor.getAuthentication() + instanceof UserAuthentication userAuthenticated) { + return userAuthenticated.gammaUser().id().equals(userId); + } + + return false; + }; + } + public static AccessChecker passwordCheck(String password) { return (clientRepository, userRepository) -> { if (AuthenticationExtractor.getAuthentication() diff --git a/app/src/main/java/it/chalmers/gamma/app/group/GroupFacade.java b/app/src/main/java/it/chalmers/gamma/app/group/GroupFacade.java index 951b2b3fd..c756c3e8a 100644 --- a/app/src/main/java/it/chalmers/gamma/app/group/GroupFacade.java +++ b/app/src/main/java/it/chalmers/gamma/app/group/GroupFacade.java @@ -133,6 +133,42 @@ public void setMembers(UUID groupId, List newMembers) } } + @Transactional + public void changeUnofficialPostName( + UUID groupId, UUID postId, UUID userId, String newUnofficialPostName) { + accessGuard.requireEither(isAdmin(), isMe(new UserId(userId))); + + Group group = + this.groupRepository + .get(new GroupId(groupId)) + .orElseThrow(GroupNotFoundRuntimeException::new); + + List groupMembers = new ArrayList<>(group.groupMembers()); + boolean found = false; + for (int i = 0; i < groupMembers.size() && !found; i++) { + GroupMember groupMember = groupMembers.get(i); + if (groupMember.user().id().value().equals(userId) + && groupMember.post().id().value().equals(postId)) { + GroupMember newGroupMember = + groupMember.withUnofficialPostName(new UnofficialPostName(newUnofficialPostName)); + groupMembers.set(i, newGroupMember); + found = true; + } + } + + if (!found) { + throw new PostNotFoundRuntimeException(); + } + + group = group.withGroupMembers(groupMembers); + try { + this.groupRepository.save(group); + } catch (GroupRepository.GroupNameAlreadyExistsException e) { + LOGGER.error("GroupAlreadyExistsException when just trying to update withGroupMembers", e); + throw new UnexpectedRuntimeException(); + } + } + @Transactional public void delete(UUID id) throws GroupNotFoundRuntimeException { accessGuard.require(isAdmin()); diff --git a/app/src/main/resources/templates/pages/group-details.html b/app/src/main/resources/templates/pages/group-details.html index 405c29d6f..dde30a95b 100644 --- a/app/src/main/resources/templates/pages/group-details.html +++ b/app/src/main/resources/templates/pages/group-details.html @@ -43,6 +43,24 @@ +
+
+ Change unofficial post name for your posts +
+ +
+ +
+
+
+ +
+ +
+
+