aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/juick/ActivityPubManager.java81
-rw-r--r--src/main/java/com/juick/config/ActivityPubConfig.java10
-rw-r--r--src/main/java/com/juick/www/api/Post.java7
-rw-r--r--src/main/java/com/juick/www/api/activity/Profile.java9
-rw-r--r--src/main/java/com/juick/www/api/activity/converters/UserToActorConverter.java16
-rw-r--r--src/main/java/com/juick/www/api/activity/helpers/ProfileUriBuilder.java88
-rw-r--r--src/test/java/com/juick/server/tests/ServerTests.java9
7 files changed, 137 insertions, 83 deletions
diff --git a/src/main/java/com/juick/ActivityPubManager.java b/src/main/java/com/juick/ActivityPubManager.java
index c909bd9b..16f310a7 100644
--- a/src/main/java/com/juick/ActivityPubManager.java
+++ b/src/main/java/com/juick/ActivityPubManager.java
@@ -59,6 +59,7 @@ import com.juick.util.HttpUtils;
import com.juick.util.MessageUtils;
import com.juick.util.formatters.PlainTextFormatter;
import com.juick.www.api.SystemActivity.ActivityType;
+import com.juick.www.api.activity.helpers.ProfileUriBuilder;
import com.juick.www.api.activity.model.Context;
import com.juick.www.api.activity.model.activities.Accept;
import com.juick.www.api.activity.model.activities.Announce;
@@ -76,7 +77,6 @@ import io.pebbletemplates.pebble.template.PebbleTemplate;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
@@ -90,8 +90,8 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
private MessagesService messagesService;
@Inject
private PebbleEngine pebbleEngine;
- @Value("${ap_base_uri:http://localhost:8080/}")
- private String baseUri;
+ @Inject
+ ProfileUriBuilder profileUriBuilder;
@Override
public void processFollowEvent(@Nonnull FollowEvent followEvent) {
@@ -137,7 +137,7 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
public void deleteMessageEvent(DeleteMessageEvent event) {
Message msg = event.getMessage();
User user = msg.getUser();
- String userUri = personUri(user);
+ String userUri = profileUriBuilder.personUri(user);
Note note = makeNote(msg);
Actor me = (Actor) signatureManager.getContext(URI.create(userUri)).get();
socialService.getFollowers(user).forEach(acct -> {
@@ -190,7 +190,7 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
public void processUpdateEvent(UpdateEvent event) {
String objectUri = event.getMessageUri();
User user = event.getUser();
- String userUri = personUri(user);
+ String userUri = profileUriBuilder.personUri(user);
Actor me = (Actor) signatureManager.getContext(URI.create(userUri)).get();
socialService.getFollowers(user).forEach(acct -> {
try {
@@ -222,7 +222,7 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
@Override
public void processUpdateUserEvent(UpdateUserEvent event) {
User user = event.getUser();
- String userUri = personUri(user);
+ String userUri = profileUriBuilder.personUri(user);
Actor me = (Actor) signatureManager.getContext(URI.create(userUri)).get();
socialService.getFollowers(user).forEach(acct -> {
try {
@@ -246,7 +246,7 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
return;
}
User user = msg.getUser();
- String userUri = personUri(user);
+ String userUri = profileUriBuilder.personUri(user);
Note note = makeNote(msg);
signatureManager.getContext(URI.create(userUri)).ifPresentOrElse((me) -> {
Set<String> subscribers = new HashSet<>(socialService.getFollowers(user));
@@ -281,72 +281,23 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
});
}
- public String inboxUri() {
- UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
- return uri.replacePath("/api/inbox").toUriString();
- }
-
- public String outboxUri(User user) {
- UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
- return uri.replacePath(String.format("/u/%s/blog/toc", user.getName())).toUriString();
- }
-
- public String personUri(User user) {
- if (user.getUri().toString().length() > 0) {
- return user.getUri().toASCIIString();
- }
- UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
- return uri.replacePath(String.format("/u/%s", user.getName())).toUriString();
- }
- public String personWebUri(User user) {
- UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
- return uri.replacePath(String.format("/%s/", user.getName())).toUriString();
- }
-
- public String followersUri(User user) {
- UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
- return uri.replacePath(String.format("/u/%s/followers/toc", user.getName())).toUriString();
- }
-
- public String followingUri(User user) {
- UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
- return uri.replacePath(String.format("/u/%s/following/toc", user.getName())).toUriString();
- }
- public String messageUri(Message msg) {
- return messageUri(msg.getMid(), msg.getRid());
- }
- public String messageUri(int mid, int rid) {
- UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
- uri.replacePath(String.format("/n/%d-%d", mid, rid));
- return uri.toUriString();
- }
- public String tagUri(Tag tag) {
- UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
- return uri.replacePath(String.format("/t/%s", tag.getName())).toUriString();
- }
-
- public String postId(String messageUri) {
- UriComponents uri = UriComponentsBuilder.fromUriString(messageUri).build();
- return uri.getPath().substring(uri.getPath().lastIndexOf('/') + 1).replace("-", "/");
- }
-
public Note makeNote(Message msg) {
Note note = new Note();
- note.setId(messageUri(msg));
+ note.setId(profileUriBuilder.messageUri(msg));
note.setUrl(PlainTextFormatter.formatUrl(msg));
- note.setAttributedTo(personUri(msg.getUser()));
+ note.setAttributedTo(profileUriBuilder.personUri(msg.getUser()));
if (MessageUtils.isReply(msg)) {
if (msg.getReplyToUri().toASCIIString().length() > 0) {
note.setInReplyTo(msg.getReplyToUri().toASCIIString());
} else {
- note.setInReplyTo(messageUri(msg.getMid(), msg.getReplyto()));
+ note.setInReplyTo(profileUriBuilder.messageUri(msg.getMid(), msg.getReplyto()));
}
}
if (MessageUtils.isPM(msg)) {
- note.setTo(Collections.singletonList(personUri(msg.getTo())));
+ note.setTo(Collections.singletonList(profileUriBuilder.personUri(msg.getTo())));
} else {
note.setTo(Collections.singletonList(Context.ACTIVITYSTREAMS_PUBLIC));
- note.setCc(Collections.singletonList(followersUri(msg.getUser())));
+ note.setCc(Collections.singletonList(profileUriBuilder.followersUri(msg.getUser())));
}
note.setPublished(msg.getCreated());
if (StringUtils.isNotBlank(msg.getAttachmentType())) {
@@ -356,7 +307,7 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
attachment.setMediaType(HttpUtils.mediaType(msg.getAttachmentType()));
note.setAttachment(Collections.singletonList(attachment));
}
- note.setTags(msg.getTags().stream().map(t -> new Hashtag(tagUri(t), t.getName())).collect(Collectors.toList()));
+ note.setTags(msg.getTags().stream().map(t -> new Hashtag(profileUriBuilder.tagUri(t), t.getName())).collect(Collectors.toList()));
if (msg.getReplyToUri() != null && msg.getReplyToUri().toASCIIString().length() > 0) {
Optional<Context> noteContext = signatureManager.getContext(msg.getReplyToUri());
if (noteContext.isPresent()) {
@@ -370,7 +321,7 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
}
}
} else if (MessageUtils.isReply(msg)) {
- note.getTags().add(new Mention(personWebUri(msg.getTo()), msg.getTo().getName()));
+ note.getTags().add(new Mention(profileUriBuilder.personWebUri(msg.getTo()), msg.getTo().getName()));
}
MessageUtils.getGlobalMentions(msg).forEach(m -> {
// @user@server.tld -> user@server.tld
@@ -390,7 +341,7 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
PebbleTemplate noteTemplate = pebbleEngine.getTemplate("layouts/note");
Map<String, Object> context = new HashMap<>();
context.put("msg", msg);
- context.put("baseUri", baseUri);
+ context.put("baseUri", profileUriBuilder.getBaseUri());
try {
Writer writer = new StringWriter();
noteTemplate.evaluate(writer, context);
@@ -412,7 +363,7 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
Note note = makeNote(message);
Announce announce = new Announce();
announce.setId(note.getId() + "#announce-" + user.getName());
- announce.setActor(personUri(user));
+ announce.setActor(profileUriBuilder.personUri(user));
announce.setTo(Collections.singletonList(Context.ACTIVITYSTREAMS_PUBLIC));
announce.setObject(note);
signatureManager.getContext(URI.create(announce.getActor())).ifPresentOrElse((ctx) -> {
diff --git a/src/main/java/com/juick/config/ActivityPubConfig.java b/src/main/java/com/juick/config/ActivityPubConfig.java
index 786e19c4..3570b97d 100644
--- a/src/main/java/com/juick/config/ActivityPubConfig.java
+++ b/src/main/java/com/juick/config/ActivityPubConfig.java
@@ -24,7 +24,9 @@ import com.juick.util.ActivityPubRequestInterceptor;
import com.juick.www.WebApp;
import com.juick.www.api.activity.converters.UserToActorConverter;
+import com.juick.www.api.activity.helpers.ProfileUriBuilder;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
@@ -45,6 +47,8 @@ public class ActivityPubConfig {
KeystoreManager keystoreManager;
@Inject
WebApp webApp;
+ @Value("${ap_base_uri:http://localhost:8080/}")
+ private String baseUri;
@Bean
MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {
@@ -80,6 +84,10 @@ public class ActivityPubConfig {
@Bean
UserToActorConverter userToActorConverter() {
- return new UserToActorConverter(activityPubManager(), keystoreManager, webApp);
+ return new UserToActorConverter(profileUriBuilder(), keystoreManager, webApp);
+ }
+ @Bean
+ ProfileUriBuilder profileUriBuilder() {
+ return new ProfileUriBuilder(baseUri);
}
}
diff --git a/src/main/java/com/juick/www/api/Post.java b/src/main/java/com/juick/www/api/Post.java
index 9faf883a..63c95f2a 100644
--- a/src/main/java/com/juick/www/api/Post.java
+++ b/src/main/java/com/juick/www/api/Post.java
@@ -23,9 +23,10 @@ import java.util.List;
import java.util.Optional;
import javax.inject.Inject;
+
+import com.juick.www.api.activity.helpers.ProfileUriBuilder;
import jakarta.validation.constraints.NotNull;
-import com.juick.ActivityPubManager;
import com.juick.CommandsManager;
import com.juick.model.CommandResult;
import com.juick.model.Message;
@@ -75,7 +76,7 @@ public class Post {
@Inject
ApplicationEventPublisher applicationEventPublisher;
@Inject
- ActivityPubManager activityPubManager;
+ ProfileUriBuilder profileUriBuilder;
@RequestMapping(value = "/api/post", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(value = HttpStatus.OK)
@@ -236,7 +237,7 @@ public class Post {
messagesService.getMessage(mid).orElseThrow(IllegalStateException::new)
: messagesService.getReply(mid, rid);
applicationEventPublisher.publishEvent(
- new UpdateEvent(this, author, activityPubManager.messageUri(mid, rid)));
+ new UpdateEvent(this, author, profileUriBuilder.messageUri(mid, rid)));
return CommandResult.build(result, "Message updated", StringUtils.EMPTY);
}
throw new HttpBadRequestException();
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 ff1227a3..5deba2cf 100644
--- a/src/main/java/com/juick/www/api/activity/Profile.java
+++ b/src/main/java/com/juick/www/api/activity/Profile.java
@@ -24,6 +24,7 @@ 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;
@@ -85,6 +86,8 @@ public class Profile {
@Inject
private ActivityPubManager activityPubManager;
@Inject
+ private ProfileUriBuilder profileUriBuilder;
+ @Inject
private ApplicationEventPublisher applicationEventPublisher;
@Inject
private CommandsManager commandsManager;
@@ -195,7 +198,7 @@ public class Profile {
Person follower = new Person();
follower.setName(a.getName());
follower.setPreferredUsername(a.getName());
- follower.setUrl(activityPubManager.personWebUri(a));
+ follower.setUrl(profileUriBuilder.personWebUri(a));
return follower;
}).collect(Collectors.toList()));
boolean hasNext = followers.size() <= 20 * page;
@@ -239,7 +242,7 @@ public class Profile {
Person follower = new Person();
follower.setName(a.getName());
follower.setPreferredUsername(a.getName());
- follower.setUrl(activityPubManager.personWebUri(a));
+ follower.setUrl(profileUriBuilder.personWebUri(a));
return follower;
}).collect(Collectors.toList()));
boolean hasNext = following.size() <= 20 * page;
@@ -301,7 +304,7 @@ public class Profile {
String inReplyTo = (String) note.getInReplyTo();
if (StringUtils.isNotBlank(inReplyTo)) {
if (inReplyTo.startsWith(baseUri)) {
- String postId = activityPubManager.postId(inReplyTo);
+ String postId = profileUriBuilder.postId(inReplyTo);
User user = new User();
user.setUri(URI.create(activity.getActor()));
String markdown = remarkConverter.convertFragment((String) note.getContent());
diff --git a/src/main/java/com/juick/www/api/activity/converters/UserToActorConverter.java b/src/main/java/com/juick/www/api/activity/converters/UserToActorConverter.java
index 405c27ab..435cb50d 100644
--- a/src/main/java/com/juick/www/api/activity/converters/UserToActorConverter.java
+++ b/src/main/java/com/juick/www/api/activity/converters/UserToActorConverter.java
@@ -1,8 +1,8 @@
package com.juick.www.api.activity.converters;
+import com.juick.www.api.activity.helpers.ProfileUriBuilder;
import org.springframework.core.convert.converter.Converter;
-import com.juick.ActivityPubManager;
import com.juick.KeystoreManager;
import com.juick.model.User;
import com.juick.www.WebApp;
@@ -18,15 +18,15 @@ import lombok.AllArgsConstructor;
@AllArgsConstructor
public class UserToActorConverter implements Converter<User, Actor> {
- private ActivityPubManager activityPubManager;
+ private ProfileUriBuilder profileUriBuilder;
private KeystoreManager keystoreManager;
private WebApp webApp;
@Override
public Actor convert(User user) {
Actor profile = user.isService() ? new Application() : new Person();
- profile.setId(activityPubManager.personUri(user));
- profile.setUrl(activityPubManager.personWebUri(user));
+ profile.setId(profileUriBuilder.personUri(user));
+ profile.setUrl(profileUriBuilder.personWebUri(user));
profile.setName(user.getName());
profile.setPreferredUsername(user.getName());
Key publicKey = new Key();
@@ -34,10 +34,10 @@ public class UserToActorConverter implements Converter<User, Actor> {
publicKey.setOwner(profile.getId());
publicKey.setPublicKeyPem(keystoreManager.getPublicKeyPem());
profile.setPublicKey(publicKey);
- profile.setInbox(activityPubManager.inboxUri());
- profile.setOutbox(activityPubManager.outboxUri(user));
- profile.setFollowers(activityPubManager.followersUri(user));
- profile.setFollowing(activityPubManager.followingUri(user));
+ profile.setInbox(profileUriBuilder.inboxUri());
+ profile.setOutbox(profileUriBuilder.outboxUri(user));
+ profile.setFollowers(profileUriBuilder.followersUri(user));
+ profile.setFollowing(profileUriBuilder.followingUri(user));
Image avatar = new Image();
avatar.setUrl(webApp.getAvatarUrl(user));
avatar.setMediaType("image/png");
diff --git a/src/main/java/com/juick/www/api/activity/helpers/ProfileUriBuilder.java b/src/main/java/com/juick/www/api/activity/helpers/ProfileUriBuilder.java
new file mode 100644
index 00000000..8f5e7566
--- /dev/null
+++ b/src/main/java/com/juick/www/api/activity/helpers/ProfileUriBuilder.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2008-2022, 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.juick.model.Message;
+import com.juick.model.Tag;
+import com.juick.model.User;
+import lombok.AllArgsConstructor;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+
+@AllArgsConstructor
+public class ProfileUriBuilder {
+ private String baseUri;
+
+ public String getBaseUri() {
+ return baseUri;
+ }
+
+ public String inboxUri() {
+ UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
+ return uri.replacePath("/api/inbox").toUriString();
+ }
+
+ public String outboxUri(User user) {
+ UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
+ return uri.replacePath(String.format("/u/%s/blog/toc", user.getName())).toUriString();
+ }
+
+ public String personUri(User user) {
+ if (user.getUri().toString().length() > 0) {
+ return user.getUri().toASCIIString();
+ }
+ UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
+ return uri.replacePath(String.format("/u/%s", user.getName())).toUriString();
+ }
+
+ public String personWebUri(User user) {
+ UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
+ return uri.replacePath(String.format("/%s/", user.getName())).toUriString();
+ }
+
+ public String followersUri(User user) {
+ UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
+ return uri.replacePath(String.format("/u/%s/followers/toc", user.getName())).toUriString();
+ }
+
+ public String followingUri(User user) {
+ UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
+ return uri.replacePath(String.format("/u/%s/following/toc", user.getName())).toUriString();
+ }
+
+ public String messageUri(Message msg) {
+ return messageUri(msg.getMid(), msg.getRid());
+ }
+
+ public String messageUri(int mid, int rid) {
+ UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
+ uri.replacePath(String.format("/n/%d-%d", mid, rid));
+ return uri.toUriString();
+ }
+
+ public String tagUri(Tag tag) {
+ UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
+ return uri.replacePath(String.format("/t/%s", tag.getName())).toUriString();
+ }
+
+ public String postId(String messageUri) {
+ UriComponents uri = UriComponentsBuilder.fromUriString(messageUri).build();
+ return uri.getPath().substring(uri.getPath().lastIndexOf('/') + 1)
+ .replace("-", "/");
+ }
+}
diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java
index 224743a7..796417c8 100644
--- a/src/test/java/com/juick/server/tests/ServerTests.java
+++ b/src/test/java/com/juick/server/tests/ServerTests.java
@@ -152,6 +152,7 @@ import com.juick.www.ad.models.Site;
import com.juick.www.api.SystemActivity;
import com.juick.www.api.Users;
import com.juick.www.api.activity.Profile;
+import com.juick.www.api.activity.helpers.ProfileUriBuilder;
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.Create;
@@ -289,6 +290,8 @@ public class ServerTests {
@Inject
private ActivityPubManager activityPubManager;
@Inject
+ private ProfileUriBuilder profileUriBuilder;
+ @Inject
private WebApp webApp;
@Inject
private RestTemplate apClient;
@@ -1485,7 +1488,7 @@ public class ServerTests {
Mockito.verify(activityListener, Mockito.times(1)).onApplicationEvent(updateEventCaptor.capture());
UpdateEvent updateEvent = updateEventCaptor.getValue();
assertThat(updateEvent.getUser(), is(ugnich));
- assertThat(activityPubManager.messageUri(original.getMid(), 0), is(updateEvent.getMessageUri()));
+ assertThat(profileUriBuilder.messageUri(original.getMid(), 0), is(updateEvent.getMessageUri()));
mockMvc.perform(post("/api/update").with(httpBasic(freefdName, freefdPassword))
.param("mid", String.valueOf(original.getMid())).param("body", "PEOPLE"))
.andExpect(status().is(403));
@@ -2124,9 +2127,9 @@ public class ServerTests {
json = jsonMapper.writeValueAsString(Context.build(note));
Note replyNote = new Note();
replyNote.setId("http://localhost:8080/n/2-1");
- replyNote.setInReplyTo(activityPubManager.messageUri(msg));
+ replyNote.setInReplyTo(profileUriBuilder.messageUri(msg));
replyNote.setAttributedTo("http://localhost:8080/u/freefd");
- replyNote.setTo(Collections.singletonList(activityPubManager.personUri(ugnich)));
+ replyNote.setTo(Collections.singletonList(profileUriBuilder.personUri(ugnich)));
replyNote.setContent("HI");
Create create = new Create();
create.setId(replyNote.getId());