From e17ac99c67e5069745f3f19a91c18b6d3288b6e9 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Wed, 4 Jan 2023 20:42:34 +0300 Subject: ActivityPub: cleanup media types and redirects --- .../java/com/juick/www/api/activity/Profile.java | 36 +++++++++++----------- .../com/juick/www/api/activity/model/Context.java | 3 +- .../java/com/juick/www/api/webfinger/Resource.java | 3 +- src/main/java/com/juick/www/controllers/Site.java | 21 +++++-------- .../java/com/juick/server/tests/ServerTests.java | 4 ++- 5 files changed, 32 insertions(+), 35 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 43a797fb..fba39954 100644 --- a/src/main/java/com/juick/www/api/activity/Profile.java +++ b/src/main/java/com/juick/www/api/activity/Profile.java @@ -103,8 +103,8 @@ public class Profile { @Inject private ConversionService conversionService; - @GetMapping(value = "/u/{userName}", produces = { Context.LD_JSON_MEDIA_TYPE, - Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE, Context.FALLBACK_JSON_MEDIA_TYPE }) + @GetMapping(value = "/u/{userName}", produces = { Context.LD_JSON_MEDIA_TYPE, Context.ACTIVITY_MEDIA_TYPE, + Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE }) public Actor getUser(@PathVariable String userName) { User user = userService.getUserByName(userName); if (!user.isAnonymous()) { @@ -116,8 +116,8 @@ public class Profile { throw new HttpNotFoundException(); } - @GetMapping(value = "/u/{userName}/blog/toc", produces = { Context.LD_JSON_MEDIA_TYPE, - Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE }) + @GetMapping(value = "/u/{userName}/blog/toc", produces = { Context.LD_JSON_MEDIA_TYPE, Context.ACTIVITY_MEDIA_TYPE, + Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE }) public OrderedCollection getOutbox(@PathVariable String userName) { User user = userService.getUserByName(userName); if (!user.isAnonymous()) { @@ -131,8 +131,8 @@ public class Profile { throw new HttpNotFoundException(); } - @GetMapping(value = "/u/{userName}/blog", produces = { Context.LD_JSON_MEDIA_TYPE, - Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE }) + @GetMapping(value = "/u/{userName}/blog", produces = { Context.LD_JSON_MEDIA_TYPE, Context.ACTIVITY_MEDIA_TYPE, + Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE }) public OrderedCollectionPage getOutboxPage(@ModelAttribute User visitor, @PathVariable String userName, @RequestParam(required = false, defaultValue = "0") int before) { User user = userService.getUserByName(userName); @@ -165,8 +165,8 @@ public class Profile { throw new HttpNotFoundException(); } - @GetMapping(value = "/u/{userName}/followers/toc", produces = { Context.LD_JSON_MEDIA_TYPE, - Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE }) + @GetMapping(value = "/u/{userName}/followers/toc", produces = { Context.LD_JSON_MEDIA_TYPE, Context.ACTIVITY_MEDIA_TYPE, + Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE }) public OrderedCollection getFollowers(@PathVariable String userName) { User user = userService.getUserByName(userName); if (!user.isAnonymous()) { @@ -180,8 +180,8 @@ public class Profile { throw new HttpNotFoundException(); } - @GetMapping(value = "/u/{userName}/followers", produces = { Context.LD_JSON_MEDIA_TYPE, - Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE }) + @GetMapping(value = "/u/{userName}/followers", produces = { Context.LD_JSON_MEDIA_TYPE, Context.ACTIVITY_MEDIA_TYPE, + Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE }) public OrderedCollectionPage getFollowersPage(@PathVariable String userName, @RequestParam(required = false, defaultValue = "0") int page) { User user = userService.getUserByName(userName); @@ -209,8 +209,8 @@ public class Profile { throw new HttpNotFoundException(); } - @GetMapping(value = "/u/{userName}/following/toc", produces = { Context.LD_JSON_MEDIA_TYPE, - Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE }) + @GetMapping(value = "/u/{userName}/following/toc", produces = { Context.LD_JSON_MEDIA_TYPE, Context.ACTIVITY_MEDIA_TYPE, + Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE }) public OrderedCollection getFollowing(@PathVariable String userName) { User user = userService.getUserByName(userName); if (!user.isAnonymous()) { @@ -224,8 +224,8 @@ public class Profile { throw new HttpNotFoundException(); } - @GetMapping(value = "/u/{userName}/following", produces = { Context.LD_JSON_MEDIA_TYPE, - Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE }) + @GetMapping(value = "/u/{userName}/following", produces = { Context.LD_JSON_MEDIA_TYPE, Context.ACTIVITY_MEDIA_TYPE, + Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE }) public OrderedCollectionPage getFollowingPage(@PathVariable String userName, @RequestParam(required = false, defaultValue = "0") int page) { User user = userService.getUserByName(userName); @@ -253,8 +253,8 @@ public class Profile { throw new HttpNotFoundException(); } - @GetMapping(value = "/n/{mid}-{rid}", produces = { Context.LD_JSON_MEDIA_TYPE, - Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE }) + @GetMapping(value = "/n/{mid}-{rid}", produces = { Context.LD_JSON_MEDIA_TYPE, Context.ACTIVITY_MEDIA_TYPE, + Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE }) public Context showNote(@PathVariable int mid, @PathVariable int rid) { try { Message message = rid > 0 ? messagesService.getReply(mid, rid) : messagesService.getMessage(mid).get(); @@ -280,8 +280,8 @@ public class Profile { } @CacheEvict(cacheNames = "profiles", key = "{ #visitor.uri }") - @PostMapping(value = "/api/inbox", consumes = { Context.LD_JSON_MEDIA_TYPE, - Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE }) + @PostMapping(value = "/api/inbox", consumes = { Context.LD_JSON_MEDIA_TYPE, Context.ACTIVITY_MEDIA_TYPE, + Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity processInbox(@ModelAttribute User visitor, InputStream inboxData) throws Exception { String inbox = IOUtils.toString(inboxData, StandardCharsets.UTF_8); 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 5a66b3b3..950c8f63 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 @@ -96,8 +96,7 @@ public class Context implements Serializable { public final static String ACTIVITY_STREAMS_URI = "https://www.w3.org/ns/activitystreams"; public final static String SECURITY_URI = "https://w3id.org/security/v1"; - public final static String LD_JSON_MEDIA_TYPE = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""; - public final static String FALLBACK_JSON_MEDIA_TYPE = "application/json; profile=\"https://www.w3.org/ns/activitystreams\""; + public final static String LD_JSON_MEDIA_TYPE = "application/ld+json"; public final static String ACTIVITY_MEDIA_TYPE = "application/activity+json"; public final static String ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE = ACTIVITY_MEDIA_TYPE + "; profile=\"https://www.w3.org/ns/activitystreams\""; public final static String ACTIVITYSTREAMS_PUBLIC = "https://www.w3.org/ns/activitystreams#Public"; diff --git a/src/main/java/com/juick/www/api/webfinger/Resource.java b/src/main/java/com/juick/www/api/webfinger/Resource.java index bc478b24..34878b69 100644 --- a/src/main/java/com/juick/www/api/webfinger/Resource.java +++ b/src/main/java/com/juick/www/api/webfinger/Resource.java @@ -24,6 +24,7 @@ import com.juick.www.api.webfinger.model.Link; import com.juick.util.HttpNotFoundException; import com.juick.service.UserService; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -45,7 +46,7 @@ public class Resource { private String baseUri; @GetMapping(value = "/.well-known/webfinger", produces = { - "application/jrd+json;charset=utf-8", Context.FALLBACK_JSON_MEDIA_TYPE }) + "application/jrd+json", MediaType.APPLICATION_JSON_VALUE }) public Account getWebResource(@RequestParam String resource) { if (resource.startsWith("acct:")) { try { diff --git a/src/main/java/com/juick/www/controllers/Site.java b/src/main/java/com/juick/www/controllers/Site.java index e8acc650..cbc14496 100644 --- a/src/main/java/com/juick/www/controllers/Site.java +++ b/src/main/java/com/juick/www/controllers/Site.java @@ -477,11 +477,16 @@ public class Site { return "views/pm_sent"; } - @GetMapping(value = "/{uname}/{mid}", produces = { MediaType.TEXT_HTML_VALUE, Context.ACTIVITY_MEDIA_TYPE, - Context.LD_JSON_MEDIA_TYPE }) + @GetMapping(value = "/{uname}/{mid}", produces = { Context.LD_JSON_MEDIA_TYPE, Context.ACTIVITY_MEDIA_TYPE, + Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE }) + public String threadRedirect(@PathVariable int mid) { + String linkedDataLocation = "/n/" + mid + "-0"; + return "redirect:" + linkedDataLocation; + } + + @GetMapping(value = "/{uname}/{mid}", consumes = MediaType.ALL_VALUE, produces = MediaType.TEXT_HTML_VALUE) protected String threadAction(@ModelAttribute User visitor, ModelMap model, @PathVariable String uname, @PathVariable int mid, - @RequestHeader(name = HttpHeaders.ACCEPT, required = false) String acceptHeader, @CookieValue(name = "sape_cookie", required = false, defaultValue = StringUtils.EMPTY) String sapeCookie) { if (!messagesService.canViewThread(mid, visitor.getUid())) { throw new HttpForbiddenException(); @@ -499,16 +504,6 @@ public class Site { if (user.isAnonymous() || !msg.getUser().equals(user)) { return String.format("redirect:/%s/%d", msg.getUser().getName(), mid); } - String linkedDataLocation = "/n/" + mid + "-0"; - if (StringUtils.isNotBlank(acceptHeader)) { - var mediaTypes = MediaType.parseMediaTypes(acceptHeader); - var isLinkedDataRequest = (mediaTypes.stream().anyMatch(mediaType -> !mediaType.isWildcardType() - && (mediaType.isCompatibleWith(MediaType.valueOf(Context.ACTIVITY_MEDIA_TYPE)) - || mediaType.isCompatibleWith(MediaType.valueOf(Context.LD_JSON_MEDIA_TYPE))))); - if (isLinkedDataRequest) { - return "redirect:" + linkedDataLocation; - } - } msg.VisitorCanComment = !visitor.isAnonymous(); msg.getUser().setAvatar(webApp.getAvatarWebPath(msg.getUser())); List replies = messagesService.getReplies(visitor, msg.getMid()); diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java index 6e4bbcb5..51ffb876 100644 --- a/src/test/java/com/juick/server/tests/ServerTests.java +++ b/src/test/java/com/juick/server/tests/ServerTests.java @@ -2683,7 +2683,9 @@ public class ServerTests { var htmlUri = String.format("/ugnich/%d", mid); var ldUri = String.format("/n/%d-0", mid); mockMvc.perform(get(htmlUri).accept(Context.LD_JSON_MEDIA_TYPE)).andExpect(status().is3xxRedirection()) - .andExpect(redirectedUrl(ldUri)); + .andExpect(redirectedUrl(ldUri)); + mockMvc.perform(get(htmlUri).accept(MediaType.APPLICATION_JSON)).andExpect(status().is3xxRedirection()) + .andExpect(redirectedUrl(ldUri)); } @Test -- cgit v1.2.3