diff options
Diffstat (limited to 'src/main/java/com/juick/www/api/activity')
6 files changed, 133 insertions, 75 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 72cc849e..751d0cff 100644 --- a/src/main/java/com/juick/www/api/activity/Profile.java +++ b/src/main/java/com/juick/www/api/activity/Profile.java @@ -40,6 +40,7 @@ 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.www.api.activity.model.objects.Tombstone; import com.juick.util.HttpNotFoundException; import com.juick.www.WebApp; import com.juick.service.MessagesService; @@ -310,32 +311,52 @@ public class Profile { } } if (activity instanceof Create) { - if (activity.getObject() instanceof Map) { - Map<String, Object> note = (Map<String, Object>) activity.getObject(); - if (note.get("type").equals("Note")) { - URI noteId = URI.create((String) note.get("id")); - if (messagesService.replyExists(noteId)) { - return new ResponseEntity<>(CommandResult.fromString("Reply already exists"), - HttpStatus.OK); - } else { - String inReplyTo = (String) note.get("inReplyTo"); - if (StringUtils.isNotBlank(inReplyTo)) { - if (inReplyTo.startsWith(baseUri)) { - String postId = activityPubManager.postId(inReplyTo); + if (activity.getObject() instanceof Note) { + Note note = (Note) activity.getObject(); + URI noteId = URI.create((String) note.getId()); + if (messagesService.replyExists(noteId)) { + return new ResponseEntity<>(CommandResult.fromString("Reply already exists"), HttpStatus.OK); + } else { + String inReplyTo = (String) note.getInReplyTo(); + if (StringUtils.isNotBlank(inReplyTo)) { + if (inReplyTo.startsWith(baseUri)) { + String postId = activityPubManager.postId(inReplyTo); + User user = new User(); + user.setUri(URI.create(activity.getActor())); + String markdown = remarkConverter.convertFragment((String) note.getContent()); + String commandBody = note.getAttachment() == null ? markdown + : note.getAttachment().stream().map(attachment -> { + String attachmentUrl = attachment.getUrl(); + String attachmentName = attachment.getName(); + return PlainTextFormatter.markdownUrl(attachmentUrl, attachmentName); + }).reduce(markdown, + (currentUrl, nextUrl) -> String.format("%s\n%s", currentUrl, nextUrl)); + + CommandResult result = commandsManager.processCommand(user, + String.format("#%s %s", postId, commandBody), URI.create(StringUtils.EMPTY)); + logger.info(jsonMapper.writeValueAsString(result)); + if (result.getNewMessage().isPresent()) { + messagesService.updateReplyUri(result.getNewMessage().get(), noteId); + return new ResponseEntity<>(result, HttpStatus.OK); + } else { + return new ResponseEntity<>(result, HttpStatus.BAD_REQUEST); + } + } else { + Message reply = messagesService.getReplyByUri(inReplyTo); + if (reply != null) { User user = new User(); user.setUri(URI.create(activity.getActor())); - String markdown = remarkConverter.convertFragment((String) note.get("content")); - String commandBody = note.get("attachment") == null ? markdown - : ((List<Object>) note.get("attachment")).stream().map(attachmentObj -> { - Map<String, String> attachment = (Map<String, String>) attachmentObj; - String attachmentUrl = attachment.get("url"); - String attachmentName = attachment.get("name"); + String markdown = remarkConverter.convertFragment((String) note.getContent()); + // combine note text with attachment urls + String commandBody = note.getAttachment() == null ? markdown + : note.getAttachment().stream().map(attachment -> { + String attachmentUrl = attachment.getUrl(); + String attachmentName = attachment.getName(); return PlainTextFormatter.markdownUrl(attachmentUrl, attachmentName); }).reduce(markdown, (currentUrl, nextUrl) -> String.format("%s\n%s", currentUrl, nextUrl)); - CommandResult result = commandsManager.processCommand(user, - String.format("#%s %s", postId, commandBody), + String.format("#%d/%d %s", reply.getMid(), reply.getRid(), commandBody), URI.create(StringUtils.EMPTY)); logger.info(jsonMapper.writeValueAsString(result)); if (result.getNewMessage().isPresent()) { @@ -344,34 +365,6 @@ public class Profile { } else { return new ResponseEntity<>(result, HttpStatus.BAD_REQUEST); } - } else { - Message reply = messagesService.getReplyByUri(inReplyTo); - if (reply != null) { - User user = new User(); - user.setUri(URI.create(activity.getActor())); - String markdown = remarkConverter.convertFragment((String) note.get("content")); - // combine note text with attachment urls - String commandBody = note.get("attachment") == null ? markdown - : ((List<Object>) note.get("attachment")).stream() - .map(attachmentObj -> { - Map<String, String> attachment = (Map<String, String>) attachmentObj; - String attachmentUrl = attachment.get("url"); - String attachmentName = attachment.get("name"); - return PlainTextFormatter.markdownUrl(attachmentUrl, - attachmentName); - }).reduce(markdown, (currentUrl, nextUrl) -> String - .format("%s\n%s", currentUrl, nextUrl)); - CommandResult result = commandsManager.processCommand(user, - String.format("#%d/%d %s", reply.getMid(), reply.getRid(), commandBody), - URI.create(StringUtils.EMPTY)); - logger.info(jsonMapper.writeValueAsString(result)); - if (result.getNewMessage().isPresent()) { - messagesService.updateReplyUri(result.getNewMessage().get(), noteId); - return new ResponseEntity<>(result, HttpStatus.OK); - } else { - return new ResponseEntity<>(result, HttpStatus.BAD_REQUEST); - } - } } } } @@ -379,26 +372,23 @@ public class Profile { } } if (activity instanceof Delete) { - if (activity.getObject() instanceof String) { - // Delete gone user - // TODO: check if it is really deleted and remove copy-paste - if (activity.getActor().equals(activity.getObject())) { - return new ResponseEntity<>(CommandResult.fromString("Delete request accepted"), - HttpStatus.ACCEPTED); - } + // Delete gone user + // TODO: check if it is really deleted and remove copy-paste + if (activity.getActor().equals(activity.getObject().getUrl())) { + return new ResponseEntity<>(CommandResult.fromString("Delete request accepted"), + HttpStatus.ACCEPTED); } - Map<String, Object> tombstone = (Map<String, Object>) activity.getObject(); - if (tombstone.get("type").equals("Tombstone")) { + + if (activity.getObject() instanceof Tombstone) { + Tombstone tombstone = (Tombstone) activity.getObject(); URI actor = URI.create(activity.getActor()); - URI reply = URI.create((String) tombstone.get("id")); + URI reply = URI.create((String) tombstone.getId()); messagesService.deleteReply(actor, reply); return new ResponseEntity<>(CommandResult.fromString("Delete request accepted"), HttpStatus.OK); } } if (activity instanceof Like || activity instanceof Announce) { - String messageUri = activity.getObject() instanceof String ? (String) activity.getObject() - : activity.getObject() instanceof Context ? ((Context) activity.getObject()).getId() - : (String) ((Map) activity.getObject()).get("id"); + String messageUri = activity.getObject().getId(); applicationEventPublisher.publishEvent(new AnnounceEvent(this, activity.getActor(), messageUri)); return new ResponseEntity<>(CommandResult.fromString("Like/announce request accepted"), HttpStatus.OK); } @@ -411,12 +401,9 @@ public class Profile { return new ResponseEntity<>(CommandResult.fromString("Unknown activity"), HttpStatus.NOT_IMPLEMENTED); } if (activity instanceof Delete) { - if (activity.getObject() instanceof String) { - // Delete gone user - if (activity.getActor().equals(activity.getObject())) { - return new ResponseEntity<>(CommandResult.fromString("Delete request accepted"), - HttpStatus.ACCEPTED); - } + // Delete gone user + if (activity.getActor().equals(activity.getObject().getId())) { + return new ResponseEntity<>(CommandResult.fromString("Delete request accepted"), HttpStatus.ACCEPTED); } } return new ResponseEntity<>(CommandResult.fromString("Can not authenticate"), HttpStatus.UNAUTHORIZED); diff --git a/src/main/java/com/juick/www/api/activity/helpers/ContextDeserializer.java b/src/main/java/com/juick/www/api/activity/helpers/ContextDeserializer.java new file mode 100644 index 00000000..367269ef --- /dev/null +++ b/src/main/java/com/juick/www/api/activity/helpers/ContextDeserializer.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2008-2021, Juick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.juick.www.api.activity.helpers; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.juick.www.api.activity.model.Context; + +import java.io.IOException; + +public class ContextDeserializer extends JsonDeserializer<Context> { + @Override + public Context deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + JsonToken jsonToken = p.getCurrentToken(); + if (jsonToken == JsonToken.VALUE_STRING) { + String id = p.getText(); + return new Context(id); + } + return p.readValueAs(Context.class); + } +} diff --git a/src/main/java/com/juick/www/api/activity/model/Activity.java b/src/main/java/com/juick/www/api/activity/model/Activity.java index d2f905af..7cc0b13f 100644 --- a/src/main/java/com/juick/www/api/activity/model/Activity.java +++ b/src/main/java/com/juick/www/api/activity/model/Activity.java @@ -19,6 +19,8 @@ package com.juick.www.api.activity.model; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.juick.www.api.activity.helpers.ActivityIdDeserializer; +import com.juick.www.api.activity.helpers.ContextDeserializer; + import org.apache.commons.lang3.StringUtils; import java.util.UUID; @@ -27,7 +29,7 @@ public abstract class Activity extends Context { @JsonDeserialize(using = ActivityIdDeserializer.class) private String actor; - private Object object; + private Context object; public String getActor() { return actor; @@ -40,11 +42,12 @@ public abstract class Activity extends Context { } } - public Object getObject() { + @JsonDeserialize(using = ContextDeserializer.class) + public Context getObject() { return object; } - public void setObject(Object object) { + public void setObject(Context object) { this.object = object; } } 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 d7b23539..edfa89b1 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 @@ -30,7 +30,7 @@ import java.util.List; import java.util.Map; @JsonIgnoreProperties(ignoreUnknown = true) -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property="type") +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property="type", defaultImpl = Context.class) @JsonSubTypes({ @JsonSubTypes.Type(value = Create.class, name = "Create"), @JsonSubTypes.Type(value = Update.class, name = "Update"), @@ -55,7 +55,7 @@ import java.util.Map; @JsonSubTypes.Type(value = Person.class, name = "Person"), @JsonSubTypes.Type(value = Application.class, name = "Application") }) -public abstract class Context { +public class Context { private List<Object> context; @@ -120,6 +120,12 @@ public abstract class Context { return response; } + public Context() {} + + public Context(String id) { + setId(id); + } + public String getUrl() { return url; } 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 66470b5c..7889b172 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 @@ -26,7 +26,7 @@ public class Note extends Context { private String content; private String attributedTo; private String inReplyTo; - private List<Image> attachment; + private List<Context> attachment; private List<String> to; private List<String> cc; private boolean sensitive; @@ -48,11 +48,11 @@ public class Note extends Context { } @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY) - public List<Image> getAttachment() { + public List<Context> getAttachment() { return attachment; } - public void setAttachment(List<Image> attachment) { + public void setAttachment(List<Context> attachment) { this.attachment = attachment; } diff --git a/src/main/java/com/juick/www/api/activity/model/objects/Tombstone.java b/src/main/java/com/juick/www/api/activity/model/objects/Tombstone.java new file mode 100644 index 00000000..1a229299 --- /dev/null +++ b/src/main/java/com/juick/www/api/activity/model/objects/Tombstone.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2008-2021, Juick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.juick.www.api.activity.model.objects; + +import com.juick.www.api.activity.model.Context; + +public class Tombstone extends Context { + +}
\ No newline at end of file |