From 4ac8fac18dc0bbf7a0217c28cf10b97f159233ff Mon Sep 17 00:00:00 2001 From: Philipp Herz Date: Sat, 25 Nov 2023 15:17:33 +0100 Subject: [PATCH] Implemented mod actions for community --- .../CommunityModActionsController.java | 258 +++++++++++++++--- .../repositories/CommentRepository.java | 6 +- .../comment/services/CommentService.java | 13 + .../person/enums/LinkPersonCommunityType.java | 3 +- .../LinkPersonCommunityRepository.java | 7 + .../services/LinkPersonCommunityService.java | 46 ++-- .../repositories/PostReportRepository.java | 5 + .../post/repositories/PostRepository.java | 7 +- .../post/services/PostService.java | 18 +- 9 files changed, 290 insertions(+), 73 deletions(-) diff --git a/src/main/java/com/sublinks/sublinksapi/api/lemmy/v3/community/controllers/CommunityModActionsController.java b/src/main/java/com/sublinks/sublinksapi/api/lemmy/v3/community/controllers/CommunityModActionsController.java index 4ee9410f..57b3b37e 100644 --- a/src/main/java/com/sublinks/sublinksapi/api/lemmy/v3/community/controllers/CommunityModActionsController.java +++ b/src/main/java/com/sublinks/sublinksapi/api/lemmy/v3/community/controllers/CommunityModActionsController.java @@ -1,16 +1,30 @@ package com.sublinks.sublinksapi.api.lemmy.v3.community.controllers; +import com.sublinks.sublinksapi.api.lemmy.v3.authentication.JwtPerson; import com.sublinks.sublinksapi.api.lemmy.v3.common.controllers.AbstractLemmyApiController; import com.sublinks.sublinksapi.api.lemmy.v3.community.models.AddModToCommunity; import com.sublinks.sublinksapi.api.lemmy.v3.community.models.AddModToCommunityResponse; +import com.sublinks.sublinksapi.api.lemmy.v3.community.models.BanFromCommunity; import com.sublinks.sublinksapi.api.lemmy.v3.community.models.BanFromCommunityResponse; +import com.sublinks.sublinksapi.api.lemmy.v3.community.models.CommunityModeratorView; import com.sublinks.sublinksapi.api.lemmy.v3.community.models.CommunityResponse; import com.sublinks.sublinksapi.api.lemmy.v3.community.models.DeleteCommunity; import com.sublinks.sublinksapi.api.lemmy.v3.community.models.GetCommunityResponse; import com.sublinks.sublinksapi.api.lemmy.v3.community.models.HideCommunity; import com.sublinks.sublinksapi.api.lemmy.v3.community.models.RemoveCommunity; import com.sublinks.sublinksapi.api.lemmy.v3.community.models.TransferCommunity; -import com.sublinks.sublinksapi.api.lemmy.v3.user.models.BanPerson; +import com.sublinks.sublinksapi.api.lemmy.v3.community.services.LemmyCommunityService; +import com.sublinks.sublinksapi.api.lemmy.v3.user.services.LemmyPersonService; +import com.sublinks.sublinksapi.authorization.services.AuthorizationService; +import com.sublinks.sublinksapi.comment.services.CommentService; +import com.sublinks.sublinksapi.community.dto.Community; +import com.sublinks.sublinksapi.community.repositories.CommunityRepository; +import com.sublinks.sublinksapi.community.services.CommunityService; +import com.sublinks.sublinksapi.person.dto.Person; +import com.sublinks.sublinksapi.person.enums.LinkPersonCommunityType; +import com.sublinks.sublinksapi.person.repositories.PersonRepository; +import com.sublinks.sublinksapi.person.services.LinkPersonCommunityService; +import com.sublinks.sublinksapi.post.services.PostService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -18,88 +32,246 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import java.util.Collection; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.core.convert.ConversionService; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ResponseStatusException; + @RestController @RequestMapping(path = "/api/v3/community") @Tag(name = "Community") +@RequiredArgsConstructor public class CommunityModActionsController extends AbstractLemmyApiController { + private final CommunityService communityService; + private final CommunityRepository communityRepository; + private final AuthorizationService authorizationService; + private final LemmyCommunityService lemmyCommunityService; + private final LinkPersonCommunityService linkPersonCommunityService; + private final PersonRepository personRepository; + private final LemmyPersonService lemmyPersonService; + private final ConversionService conversionService; + private final CommentService commentService; + private final PostService postService; + @Operation(summary = "Hide a community from public / \"All\" view. Admins only.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", - content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = CommunityResponse.class))}) - }) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = CommunityResponse.class))})}) @PutMapping("hide") - CommunityResponse hide(@Valid final HideCommunity hideCommunityForm) { + CommunityResponse hide(@Valid @RequestBody final HideCommunity hideCommunityForm, + JwtPerson principal) { + + final Person person = getPersonOrThrowUnauthorized(principal); + + authorizationService.isAdminElseThrow(person, + () -> new ResponseStatusException(HttpStatus.FORBIDDEN)); + + final Community community = communityRepository.findById( + (long) hideCommunityForm.community_id()).orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "community_not_found")); - throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED); + community.setLocal(hideCommunityForm.hidden()); + communityRepository.save(community); + + return CommunityResponse.builder() + .community_view(lemmyCommunityService.communityViewFromCommunity(community)).build(); } @Operation(summary = "Delete a community.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", - content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = CommunityResponse.class))}) - }) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = CommunityResponse.class))})}) @PostMapping("delete") - CommunityResponse delete(@Valid final DeleteCommunity deleteCommunityForm) { + CommunityResponse delete(@Valid final DeleteCommunity deleteCommunityForm, JwtPerson principal) { + + final Person person = getPersonOrThrowUnauthorized(principal); + + authorizationService.isAdminElseThrow(person, + () -> new ResponseStatusException(HttpStatus.FORBIDDEN)); + + final Community community = communityRepository.findById( + (long) deleteCommunityForm.community_id()).orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "community_not_found")); + + community.setDeleted(deleteCommunityForm.deleted()); + communityRepository.save(community); - throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED); + return CommunityResponse.builder() + .community_view(lemmyCommunityService.communityViewFromCommunity(community)).build(); } @Operation(summary = "A moderator remove for a community.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", - content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = CommunityResponse.class))}) - }) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = CommunityResponse.class))})}) @PostMapping("remove") - CommunityResponse remove(@Valid final RemoveCommunity removeCommunityForm) { + CommunityResponse remove(@Valid @RequestBody final RemoveCommunity removeCommunityForm, + JwtPerson principal) { - throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED); + final Person person = getPersonOrThrowUnauthorized(principal); + + final Community community = communityRepository.findById( + (long) removeCommunityForm.community_id()).orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "community_not_found")); + + final boolean isAllowed = + linkPersonCommunityService.hasLink(person, community, LinkPersonCommunityType.moderator) + || linkPersonCommunityService.hasLink(person, community, LinkPersonCommunityType.owner); + + if (!isAllowed) { + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "not_allowed"); + } + + community.setRemoved(removeCommunityForm.removed()); + communityRepository.save(community); + + return CommunityResponse.builder() + .community_view(lemmyCommunityService.communityViewFromCommunity(community)).build(); } @Operation(summary = "Transfer your community to an existing moderator.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", - content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = GetCommunityResponse.class))}) - }) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = GetCommunityResponse.class))})}) @PostMapping("transfer") - GetCommunityResponse transfer(@Valid final TransferCommunity transferCommunityForm) { + GetCommunityResponse transfer(@Valid @RequestBody final TransferCommunity transferCommunityForm, + JwtPerson principal) { + + final Person person = getPersonOrThrowUnauthorized(principal); + + final Community community = communityRepository.findById( + (long) transferCommunityForm.community_id()).orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "community_not_found")); + + final boolean isAllowed = + authorizationService.isAdmin(person) || linkPersonCommunityService.hasLink(person, + community, LinkPersonCommunityType.owner); + + if (!isAllowed) { + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "not_allowed"); + } - throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED); + final Person newOwner = personRepository.findById((long) transferCommunityForm.person_id()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "person_not_found")); + + if (!linkPersonCommunityService.hasLink(newOwner, community, + LinkPersonCommunityType.moderator)) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "person_not_moderator"); + } + + final Person oldOwner = linkPersonCommunityService.getPersonsFromCommunityAndListTypes( + community, List.of(LinkPersonCommunityType.owner)).stream().findFirst() + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "owner_not_found")); + linkPersonCommunityService.addLink(oldOwner, community, LinkPersonCommunityType.moderator); + linkPersonCommunityService.removeLink(oldOwner, community, LinkPersonCommunityType.owner); + + linkPersonCommunityService.addLink(newOwner, community, LinkPersonCommunityType.owner); + linkPersonCommunityService.removeLink(newOwner, community, LinkPersonCommunityType.moderator); + + return GetCommunityResponse.builder() + .community_view(lemmyCommunityService.communityViewFromCommunity(community)).build(); } @Operation(summary = "Ban a user from a community.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", - content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = BanFromCommunityResponse.class))}) - }) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = BanFromCommunityResponse.class))})}) @PostMapping("ban_user") - BanFromCommunityResponse banUser(@Valid final BanPerson banPersonForm) { + BanFromCommunityResponse banUser(@Valid @RequestBody final BanFromCommunity banPersonForm, + JwtPerson principal) { + + final Person person = getPersonOrThrowUnauthorized(principal); + + final Community community = communityRepository.findById((long) banPersonForm.community_id()) + .orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "community_not_found")); + + final boolean isAllowed = + linkPersonCommunityService.hasLink(person, community, LinkPersonCommunityType.moderator) + || linkPersonCommunityService.hasLink(person, community, LinkPersonCommunityType.owner); + + if (!isAllowed) { + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "not_allowed"); + } + + final Person personToBan = personRepository.findById((long) banPersonForm.person_id()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "person_not_found")); + + if (banPersonForm.ban()) { + if (!linkPersonCommunityService.hasLink(personToBan, community, + LinkPersonCommunityType.banned)) { + linkPersonCommunityService.addLink(personToBan, community, LinkPersonCommunityType.banned); + } + } else { + if (linkPersonCommunityService.hasLink(personToBan, community, + LinkPersonCommunityType.banned)) { + linkPersonCommunityService.removeLink(personToBan, community, + LinkPersonCommunityType.banned); + } + } - throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED); + if (banPersonForm.remove_data()) { + commentService.removeAllCommentsFromUser(community, personToBan, true); + postService.removeAllPostsFromUser(community, personToBan, true); + } + + return BanFromCommunityResponse.builder().banned(banPersonForm.ban()) + .person_view(lemmyPersonService.getPersonView(personToBan)).build(); } @Operation(summary = "Add a moderator to your community.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK", - content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = AddModToCommunityResponse.class))}) - }) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = AddModToCommunityResponse.class))})}) @PostMapping("mod") - AddModToCommunityResponse addMod(@Valid final AddModToCommunity addModToCommunityForm) { + AddModToCommunityResponse addMod(@Valid @RequestBody AddModToCommunity addModToCommunityForm, + JwtPerson principal) { + + final Person person = getPersonOrThrowUnauthorized(principal); + + final Community community = communityRepository.findById( + (long) addModToCommunityForm.community_id()).orElseThrow( + () -> new ResponseStatusException(HttpStatus.NOT_FOUND, "community_not_found")); + + final boolean isAllowed = + linkPersonCommunityService.hasLink(person, community, LinkPersonCommunityType.moderator) + || linkPersonCommunityService.hasLink(person, community, LinkPersonCommunityType.owner); + + if (!isAllowed) { + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "not_allowed"); + } + + final Person personToAdd = personRepository.findById((long) addModToCommunityForm.person_id()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "person_not_found")); + + if (addModToCommunityForm.added()) { + if (!linkPersonCommunityService.hasLink(personToAdd, community, + LinkPersonCommunityType.moderator)) { + linkPersonCommunityService.addLink(personToAdd, community, + LinkPersonCommunityType.moderator); + } + } else { + if (linkPersonCommunityService.hasLink(personToAdd, community, + LinkPersonCommunityType.moderator)) { + linkPersonCommunityService.removeLink(personToAdd, community, + LinkPersonCommunityType.moderator); + } + } + + Collection moderators = linkPersonCommunityService.getPersonsFromCommunityAndListTypes( + community, List.of(LinkPersonCommunityType.moderator)); + + List moderatorsView = moderators.stream().map( + moderator -> CommunityModeratorView.builder().moderator(conversionService.convert(moderator, + com.sublinks.sublinksapi.api.lemmy.v3.user.models.Person.class)).community( + conversionService.convert(community, + com.sublinks.sublinksapi.api.lemmy.v3.community.models.Community.class)).build()) + .toList(); - throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED); + return AddModToCommunityResponse.builder().moderators(moderatorsView).build(); } } diff --git a/src/main/java/com/sublinks/sublinksapi/comment/repositories/CommentRepository.java b/src/main/java/com/sublinks/sublinksapi/comment/repositories/CommentRepository.java index a1275fab..5e926111 100644 --- a/src/main/java/com/sublinks/sublinksapi/comment/repositories/CommentRepository.java +++ b/src/main/java/com/sublinks/sublinksapi/comment/repositories/CommentRepository.java @@ -2,11 +2,11 @@ import com.sublinks.sublinksapi.comment.dto.Comment; import com.sublinks.sublinksapi.community.dto.Community; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; +import com.sublinks.sublinksapi.person.dto.Person; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; public interface CommentRepository extends JpaRepository, CommentRepositorySearch { + List allCommentsByCommunityAndPerson(Community community, Person person); } diff --git a/src/main/java/com/sublinks/sublinksapi/comment/services/CommentService.java b/src/main/java/com/sublinks/sublinksapi/comment/services/CommentService.java index a5c35767..67efb4ec 100644 --- a/src/main/java/com/sublinks/sublinksapi/comment/services/CommentService.java +++ b/src/main/java/com/sublinks/sublinksapi/comment/services/CommentService.java @@ -4,10 +4,13 @@ import com.sublinks.sublinksapi.comment.dto.CommentAggregate; import com.sublinks.sublinksapi.comment.events.CommentCreatedPublisher; import com.sublinks.sublinksapi.comment.events.CommentUpdatedPublisher; +import com.sublinks.sublinksapi.comment.models.CommentSearchCriteria; import com.sublinks.sublinksapi.comment.repositories.CommentAggregateRepository; import com.sublinks.sublinksapi.comment.repositories.CommentRepository; +import com.sublinks.sublinksapi.community.dto.Community; import com.sublinks.sublinksapi.instance.models.LocalInstanceContext; import java.util.Optional; +import com.sublinks.sublinksapi.person.dto.Person; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -82,4 +85,14 @@ public void updateComment(final Comment comment) { commentRepository.save(comment); commentUpdatedPublisher.publish(comment); } + + @Transactional + public void removeAllCommentsFromUser(final Community community, final Person person, + final boolean removed) { + + commentRepository.allCommentsByCommunityAndPerson(community, person).forEach(comment -> { + comment.setRemoved(removed); + commentRepository.save(comment); + }); + } } diff --git a/src/main/java/com/sublinks/sublinksapi/person/enums/LinkPersonCommunityType.java b/src/main/java/com/sublinks/sublinksapi/person/enums/LinkPersonCommunityType.java index 73752a76..70ec0651 100644 --- a/src/main/java/com/sublinks/sublinksapi/person/enums/LinkPersonCommunityType.java +++ b/src/main/java/com/sublinks/sublinksapi/person/enums/LinkPersonCommunityType.java @@ -5,5 +5,6 @@ public enum LinkPersonCommunityType { moderator, follower, pending_follow, - blocked + blocked, + banned } diff --git a/src/main/java/com/sublinks/sublinksapi/person/repositories/LinkPersonCommunityRepository.java b/src/main/java/com/sublinks/sublinksapi/person/repositories/LinkPersonCommunityRepository.java index 1bb10421..c0e8e097 100644 --- a/src/main/java/com/sublinks/sublinksapi/person/repositories/LinkPersonCommunityRepository.java +++ b/src/main/java/com/sublinks/sublinksapi/person/repositories/LinkPersonCommunityRepository.java @@ -5,6 +5,7 @@ import com.sublinks.sublinksapi.person.dto.Person; import com.sublinks.sublinksapi.person.enums.LinkPersonCommunityType; import java.util.Collection; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; @@ -13,9 +14,15 @@ public interface LinkPersonCommunityRepository extends JpaRepository getLinkPersonCommunityByCommunityAndPersonAndLinkType( Community community, Person person, LinkPersonCommunityType type); + List getLinkPersonCommunityByCommunityAndPersonAndLinkTypeIsIn( + Community community, Person person, List types); + Optional getLinkPersonCommunityByPersonAndLinkType(Person person, LinkPersonCommunityType type); Collection getLinkPersonCommunitiesByPersonAndLinkType(Person person, LinkPersonCommunityType type); + + Collection getLinkPersonCommunitiesByCommunityAndLinkTypeIsIn( + Community community, List types); } diff --git a/src/main/java/com/sublinks/sublinksapi/person/services/LinkPersonCommunityService.java b/src/main/java/com/sublinks/sublinksapi/person/services/LinkPersonCommunityService.java index 980969cf..cddc26e2 100644 --- a/src/main/java/com/sublinks/sublinksapi/person/services/LinkPersonCommunityService.java +++ b/src/main/java/com/sublinks/sublinksapi/person/services/LinkPersonCommunityService.java @@ -9,6 +9,7 @@ import com.sublinks.sublinksapi.person.repositories.LinkPersonCommunityRepository; import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.Objects; import java.util.Optional; import lombok.RequiredArgsConstructor; @@ -25,23 +26,24 @@ public class LinkPersonCommunityService { public boolean hasLink(Person person, Community community, LinkPersonCommunityType type) { - final Optional linkPersonCommunity = - linkPersonCommunityRepository.getLinkPersonCommunityByCommunityAndPersonAndLinkType( - community, - person, - type - ); + final Optional linkPersonCommunity = linkPersonCommunityRepository.getLinkPersonCommunityByCommunityAndPersonAndLinkType( + community, person, type); return linkPersonCommunity.isPresent(); } + public boolean hasAnyLink(Person person, Community community, + List types) { + + final List linkPersonCommunity = linkPersonCommunityRepository.getLinkPersonCommunityByCommunityAndPersonAndLinkTypeIsIn( + community, person, types); + return linkPersonCommunity.isEmpty(); + } + @Transactional public void addLink(Person person, Community community, LinkPersonCommunityType type) { - final LinkPersonCommunity newLink = LinkPersonCommunity.builder() - .community(community) - .person(person) - .linkType(type) - .build(); + final LinkPersonCommunity newLink = LinkPersonCommunity.builder().community(community) + .person(person).linkType(type).build(); person.getLinkPersonCommunity().add(newLink); community.getLinkPersonCommunity().add(newLink); linkPersonCommunityRepository.save(newLink); @@ -51,12 +53,8 @@ public void addLink(Person person, Community community, LinkPersonCommunityType @Transactional public void removeLink(Person person, Community community, LinkPersonCommunityType type) { - final Optional linkPersonCommunity = - linkPersonCommunityRepository.getLinkPersonCommunityByCommunityAndPersonAndLinkType( - community, - person, - type - ); + final Optional linkPersonCommunity = linkPersonCommunityRepository.getLinkPersonCommunityByCommunityAndPersonAndLinkType( + community, person, type); if (linkPersonCommunity.isEmpty()) { return; } @@ -70,8 +68,8 @@ public void removeLink(Person person, Community community, LinkPersonCommunityTy public Collection getPersonLinkByType(Person person, LinkPersonCommunityType type) { - Collection linkPersonCommunities = linkPersonCommunityRepository - .getLinkPersonCommunitiesByPersonAndLinkType(person, type); + Collection linkPersonCommunities = linkPersonCommunityRepository.getLinkPersonCommunitiesByPersonAndLinkType( + person, type); Collection communities = new ArrayList<>(); for (LinkPersonCommunity linkPersonCommunity : linkPersonCommunities) { @@ -79,4 +77,14 @@ public Collection getPersonLinkByType(Person person, LinkPersonCommun } return communities; } + + public Collection getPersonsFromCommunityAndListTypes(Community community, + List types) { + + Collection linkPersonCommunities = linkPersonCommunityRepository.getLinkPersonCommunitiesByCommunityAndLinkTypeIsIn( + community, types); + + return linkPersonCommunities.stream().map(LinkPersonCommunity::getPerson).toList(); + } + } diff --git a/src/main/java/com/sublinks/sublinksapi/post/repositories/PostReportRepository.java b/src/main/java/com/sublinks/sublinksapi/post/repositories/PostReportRepository.java index 7e59b66f..63f39c87 100644 --- a/src/main/java/com/sublinks/sublinksapi/post/repositories/PostReportRepository.java +++ b/src/main/java/com/sublinks/sublinksapi/post/repositories/PostReportRepository.java @@ -1,9 +1,14 @@ package com.sublinks.sublinksapi.post.repositories; +import com.sublinks.sublinksapi.comment.dto.Comment; +import com.sublinks.sublinksapi.community.dto.Community; +import com.sublinks.sublinksapi.person.dto.Person; import com.sublinks.sublinksapi.post.dto.PostReport; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; public interface PostReportRepository extends JpaRepository, PostReportRepositorySearch { + } diff --git a/src/main/java/com/sublinks/sublinksapi/post/repositories/PostRepository.java b/src/main/java/com/sublinks/sublinksapi/post/repositories/PostRepository.java index 0f8ef894..7624a1c8 100644 --- a/src/main/java/com/sublinks/sublinksapi/post/repositories/PostRepository.java +++ b/src/main/java/com/sublinks/sublinksapi/post/repositories/PostRepository.java @@ -1,12 +1,13 @@ package com.sublinks.sublinksapi.post.repositories; import com.sublinks.sublinksapi.community.dto.Community; +import com.sublinks.sublinksapi.person.dto.Person; import com.sublinks.sublinksapi.post.dto.Post; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; public interface PostRepository extends JpaRepository, PostRepositorySearch { + List allPostsByCommunityAndPerson(Community community, Person person); + } diff --git a/src/main/java/com/sublinks/sublinksapi/post/services/PostService.java b/src/main/java/com/sublinks/sublinksapi/post/services/PostService.java index 0b38fb85..4bb764ac 100644 --- a/src/main/java/com/sublinks/sublinksapi/post/services/PostService.java +++ b/src/main/java/com/sublinks/sublinksapi/post/services/PostService.java @@ -1,5 +1,6 @@ package com.sublinks.sublinksapi.post.services; +import com.sublinks.sublinksapi.community.dto.Community; import com.sublinks.sublinksapi.person.dto.LinkPersonPost; import com.sublinks.sublinksapi.person.dto.Person; import com.sublinks.sublinksapi.person.enums.LinkPersonPostType; @@ -34,6 +35,7 @@ public class PostService { private final UrlUtil urlUtil; public String getPostMd5Hash(final Post post) { + return getStringMd5Hash(post.getLinkUrl()); } @@ -81,10 +83,8 @@ public void createPost(final Post post, final Person creator) { post.setPrivateKey(keys.privateKey()); post.setLocal(true); - final PostAggregate postAggregate = PostAggregate.builder() - .post(post) - .community(post.getCommunity()) - .build(); + final PostAggregate postAggregate = PostAggregate.builder().post(post) + .community(post.getCommunity()).build(); post.setPostAggregate(postAggregate); post.setActivityPubId(""); postRepository.save(post); // @todo fix second save making post look edited right away @@ -102,4 +102,14 @@ public void softDeletePost(final Post post) { postRepository.save(post); postDeletedPublisher.publish(post); } + + @Transactional + public void removeAllPostsFromUser(final Community community, final Person person, + final boolean removed) { + + postRepository.allPostsByCommunityAndPerson(community, person).forEach(post -> { + post.setRemoved(removed); + postRepository.save(post); + }); + } }