From e43b64a9ea8bf80ec62cd59ad4eed19b112f5093 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Wed, 13 Mar 2024 02:20:33 +0300 Subject: ActivityPub: handle Flag with multiple objects TODO: refactor Activity to handle multiple objects --- .../java/com/juick/www/api/activity/Profile.java | 46 +++++++--------------- .../com/juick/www/api/activity/model/Context.java | 10 +++++ .../www/api/activity/model/activities/Flag.java | 38 ++++++++++++++++-- .../juick/www/api/activity/model/objects/Note.java | 10 ----- .../java/com/juick/server/tests/ServerTests.java | 7 +++- src/test/resources/flag.json | 2 +- 6 files changed, 66 insertions(+), 47 deletions(-) diff --git a/src/main/java/com/juick/www/api/activity/Profile.java b/src/main/java/com/juick/www/api/activity/Profile.java index d815c9d6..101c59f9 100644 --- a/src/main/java/com/juick/www/api/activity/Profile.java +++ b/src/main/java/com/juick/www/api/activity/Profile.java @@ -19,39 +19,23 @@ package com.juick.www.api.activity; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.juick.ActivityPubManager; +import com.juick.CommandsManager; +import com.juick.model.CommandResult; import com.juick.model.Message; import com.juick.model.User; +import com.juick.service.MessagesService; +import com.juick.service.UserService; +import com.juick.service.activities.*; +import com.juick.util.HttpBadRequestException; import com.juick.util.HttpForbiddenException; +import com.juick.util.HttpNotFoundException; import com.juick.util.formatters.PlainTextFormatter; -import com.juick.model.CommandResult; -import com.juick.ActivityPubManager; -import com.juick.CommandsManager; import com.juick.www.api.activity.helpers.ProfileUriBuilder; import com.juick.www.api.activity.model.Activity; import com.juick.www.api.activity.model.Context; -import com.juick.www.api.activity.model.activities.Announce; -import com.juick.www.api.activity.model.activities.Block; -import com.juick.www.api.activity.model.activities.Create; -import com.juick.www.api.activity.model.activities.Delete; -import com.juick.www.api.activity.model.activities.Flag; -import com.juick.www.api.activity.model.activities.Follow; -import com.juick.www.api.activity.model.activities.Like; -import com.juick.www.api.activity.model.activities.Undo; -import com.juick.www.api.activity.model.activities.Update; -import com.juick.www.api.activity.model.objects.Actor; -import com.juick.www.api.activity.model.objects.Note; -import com.juick.www.api.activity.model.objects.OrderedCollection; -import com.juick.www.api.activity.model.objects.OrderedCollectionPage; -import com.juick.www.api.activity.model.objects.Person; -import com.juick.util.HttpBadRequestException; -import com.juick.util.HttpNotFoundException; -import com.juick.service.MessagesService; -import com.juick.service.UserService; -import com.juick.service.activities.AnnounceEvent; -import com.juick.service.activities.DirectMessageEvent; -import com.juick.service.activities.FollowEvent; -import com.juick.service.activities.UndoAnnounceEvent; -import com.juick.service.activities.UndoFollowEvent; +import com.juick.www.api.activity.model.activities.*; +import com.juick.www.api.activity.model.objects.*; import com.overzealous.remark.Remark; import io.swagger.v3.oas.annotations.Parameter; import org.apache.commons.io.IOUtils; @@ -59,7 +43,6 @@ import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; -import org.springframework.cache.annotation.CacheEvict; import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.convert.ConversionService; import org.springframework.http.HttpStatus; @@ -373,11 +356,6 @@ public class Profile { applicationEventPublisher.publishEvent(new AnnounceEvent(this, activity.getActor(), messageUri)); return new ResponseEntity<>(CommandResult.fromString("Like/announce request accepted"), HttpStatus.OK); } - if (activity instanceof Flag) { - URI actor = URI.create(activity.getActor()); - logger.info("{} flag some objects: {}", actor, activity.getObject()); - return new ResponseEntity<>(CommandResult.fromString("Report accepted"), HttpStatus.ACCEPTED); - } if (activity instanceof Update) { if (activity.getObject() instanceof Person && activity.getActor().equals(activity.getObject().getId())) { @@ -417,6 +395,10 @@ public class Profile { return new ResponseEntity<>(CommandResult.fromString("Delete request accepted"), HttpStatus.ACCEPTED); } } + } else if (context instanceof Flag flag) { + URI actor = URI.create(flag.getActor()); + logger.info("{} flagged some objects: {}, reason: {}", actor, String.join(", ", flag.getObject()), flag.getContent()); + return new ResponseEntity<>(CommandResult.fromString("Report accepted"), HttpStatus.ACCEPTED); } else { return new ResponseEntity<>(CommandResult.fromString("Can't parse"), HttpStatus.BAD_REQUEST); } diff --git a/src/main/java/com/juick/www/api/activity/model/Context.java b/src/main/java/com/juick/www/api/activity/model/Context.java index cfcc9379..80694b7a 100644 --- a/src/main/java/com/juick/www/api/activity/model/Context.java +++ b/src/main/java/com/juick/www/api/activity/model/Context.java @@ -68,6 +68,8 @@ public class Context implements Serializable { private Image icon; private Instant published; + private String content; + @JsonDeserialize(using = LinkValueDeserializer.class) private String url; @@ -172,4 +174,12 @@ public class Context implements Serializable { public void setCc(List cc) { this.cc = cc; } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } } diff --git a/src/main/java/com/juick/www/api/activity/model/activities/Flag.java b/src/main/java/com/juick/www/api/activity/model/activities/Flag.java index 2c61d344..1c37dec0 100644 --- a/src/main/java/com/juick/www/api/activity/model/activities/Flag.java +++ b/src/main/java/com/juick/www/api/activity/model/activities/Flag.java @@ -17,8 +17,40 @@ package com.juick.www.api.activity.model.activities; -import com.juick.www.api.activity.model.Activity; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.juick.www.api.activity.helpers.ActivityIdDeserializer; +import com.juick.www.api.activity.helpers.ContextDeserializer; +import com.juick.www.api.activity.model.Context; +import org.apache.commons.lang3.StringUtils; -public class Flag extends Activity { - +import java.util.List; +import java.util.UUID; + +public class Flag extends Context { + + @JsonDeserialize(using = ActivityIdDeserializer.class) + private String actor; + + public String getActor() { + return actor; + } + + public void setActor(String actor) { + this.actor = actor; + if (StringUtils.isEmpty(getId())) { + setId(String.format("%s#%s", this.actor, UUID.randomUUID())); + } + } + + @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY) + private List object; + + public List getObject() { + return object; + } + + public void setObject(List object) { + this.object = object; + } } diff --git a/src/main/java/com/juick/www/api/activity/model/objects/Note.java b/src/main/java/com/juick/www/api/activity/model/objects/Note.java index 465ad07c..6792c34e 100644 --- a/src/main/java/com/juick/www/api/activity/model/objects/Note.java +++ b/src/main/java/com/juick/www/api/activity/model/objects/Note.java @@ -24,7 +24,6 @@ import java.time.Instant; import java.util.List; public class Note extends Context { - private String content; private String attributedTo; private String inReplyTo; private List attachment; @@ -32,15 +31,6 @@ public class Note extends Context { private List cc; private boolean sensitive; private Instant updated; - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - public String getAttributedTo() { return attributedTo; } diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java index 0724eb4f..b97ae8a3 100644 --- a/src/test/java/com/juick/server/tests/ServerTests.java +++ b/src/test/java/com/juick/server/tests/ServerTests.java @@ -217,6 +217,8 @@ public class ServerTests { private Resource nojfif; @Value("classpath:hubzilla_activity.json") private Resource hubzillaActivity; + @Value("classpath:flag.json") + private Resource mastodonFlag; @Value("classpath:hubzilla_follow.json") private Resource hubzillaFollow; @Value("classpath:to_as_string.json") @@ -2275,7 +2277,7 @@ public class ServerTests { } @Test - public void hubzillaAndHonkActorAndFriendicaUpdate() throws Exception { + public void hubzillaAndHonkActorAndFriendicaUpdateAndMastodonFlag() throws Exception { String activity = IOUtils.toString(hubzillaActivity.getInputStream(), StandardCharsets.UTF_8); Create create = jsonMapper.readValue(activity, Create.class); String followData = IOUtils.toString(hubzillaFollow.getInputStream(), StandardCharsets.UTF_8); @@ -2286,6 +2288,9 @@ public class ServerTests { assertThat(hfollow.getTo().get(0), is("https://juick.com/u/vt")); String updateString = IOUtils.toString(friendicaUpdate.getInputStream(), StandardCharsets.UTF_8); Update update = jsonMapper.readValue(updateString, Update.class); + String flagString = IOUtils.toString(mastodonFlag.getInputStream(), StandardCharsets.UTF_8); + Flag flag = (Flag) jsonMapper.readValue(flagString, Context.class); + assertThat(flag.getObject().size(), is(3)); } @Test diff --git a/src/test/resources/flag.json b/src/test/resources/flag.json index c3363f01..9598d9d9 100644 --- a/src/test/resources/flag.json +++ b/src/test/resources/flag.json @@ -1 +1 @@ -{"@context":"https://www.w3.org/ns/activitystreams","id":"https://localhost/32ac2d3e-c75c-46c1-b0a7-d9fac0986b9a","type":"Flag","actor":"https://example.com/actor","content":"","object":["https://juick.com/u/rtfmpls","https://juick.com/n/2998271-0"]} \ No newline at end of file +{"@context":"https://www.w3.org/ns/activitystreams","id":"https://mastodon.social/bece4612-4dc7-4efd-871f-e388c393f239","type":"Flag","actor":"https://mastodon.social/actor","content":"","object":["https://juick.com/u/Monstreek","https://juick.com/n/3053193-14","https://juick.com/n/3053193-10"]} \ No newline at end of file -- cgit v1.2.3