From 809ef60e18bb8ab7c95db93b7777f3c0ffb30872 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Thu, 20 Dec 2018 09:41:32 +0300 Subject: HTTPSignatureAuthenticationFilter --- src/test/resources/mocks/activity/testfollow.json | 15 ++++++++++++ src/test/resources/mocks/activity/testuser.json | 27 ++++++++++++++++++++++ src/test/resources/test.p12 | Bin 0 -> 2386 bytes 3 files changed, 42 insertions(+) create mode 100644 src/test/resources/mocks/activity/testfollow.json create mode 100644 src/test/resources/mocks/activity/testuser.json create mode 100644 src/test/resources/test.p12 (limited to 'src/test/resources') diff --git a/src/test/resources/mocks/activity/testfollow.json b/src/test/resources/mocks/activity/testfollow.json new file mode 100644 index 00000000..e308e52e --- /dev/null +++ b/src/test/resources/mocks/activity/testfollow.json @@ -0,0 +1,15 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + { + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value" + } + ], + "id": "https://example.com/12345678", + "type": "Follow", + "actor": "https://example.com/u/testuser", + "object": "http://localhost:8080/u/ugnich" +} \ No newline at end of file diff --git a/src/test/resources/mocks/activity/testuser.json b/src/test/resources/mocks/activity/testuser.json new file mode 100644 index 00000000..95fc2aa9 --- /dev/null +++ b/src/test/resources/mocks/activity/testuser.json @@ -0,0 +1,27 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + { + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value" + } + ], + "id": "https://example.com/u/testuser", + "type": "Person", + "following": "https://example.com/u/testuser/following", + "followers": "https://example.com/u/testuser/followers", + "inbox": "https://example.com/u/testuser/inbox", + "outbox": "https://example.com/u/testuser/outbox", + "preferredUsername": "testuser", + "url": "https://example.com/@testuser", + "publicKey": { + "id": "https://example.com/u/testuser#main-key", + "owner": "https://example.com/u/testuser", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiHKRdKFFeT4P/MVlNbxC\nbbgXOkEdeQzvJB/wAJgSYbUwm9SzNFzttePQXk3/MWoK2awWUInZTduVHsWt8zU7\nO3d9PAW6YH6L1oDkjgMLAb9aUWV2ClQWMwsn88WKK9Rb1WOmd8BrXjPfmeFK2ypQ\n9eg8aKpH36WAXiiaTDfBupBZ0Ki2+E87BrWxpbUeDC1dkV+zbl8BMm7X0rp+reoC\nYUWMcjQMzhMmQOXUd4zwJIDPZDMdF4beq/y6WPSUTVgjs4kPDS1HT60ATnsUqyPE\n6tuGxG4j0msb4TTre87PKxMU5YPOxSiqNL0O/3u9/2shVPpjDa/uy9W+VaeBHbFm\nSQIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "endpoints": { + "sharedInbox": "https://example.com/inbox" + } +} \ No newline at end of file diff --git a/src/test/resources/test.p12 b/src/test/resources/test.p12 new file mode 100644 index 00000000..7f7457eb Binary files /dev/null and b/src/test/resources/test.p12 differ -- cgit v1.2.3 From 053300c67d2fe274f2f562712d8586e81700c085 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Wed, 30 Jan 2019 12:34:04 +0300 Subject: Corrected flow for federated user deletion --- .../java/com/juick/server/api/activity/Profile.java | 17 ++++++++++------- src/test/java/com/juick/server/tests/ServerTests.java | 14 ++++++++++++++ src/test/resources/delete_user.json | 1 + 3 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 src/test/resources/delete_user.json (limited to 'src/test/resources') diff --git a/src/main/java/com/juick/server/api/activity/Profile.java b/src/main/java/com/juick/server/api/activity/Profile.java index 84a3de33..b1d325f9 100644 --- a/src/main/java/com/juick/server/api/activity/Profile.java +++ b/src/main/java/com/juick/server/api/activity/Profile.java @@ -284,13 +284,6 @@ public class Profile { return new ResponseEntity<>(HttpStatus.OK); } } - if (activity instanceof Delete) { - if (activity.getObject() instanceof String) { - // Delete user - applicationEventPublisher.publishEvent(new DeleteUserEvent(this, (String)activity.getObject())); - return new ResponseEntity<>(HttpStatus.OK); - } - } if (activity instanceof Create) { if (activity.getObject() instanceof Map) { Map note = (Map) activity.getObject(); @@ -361,6 +354,16 @@ public class Profile { logger.warn("Unknown activity: {}", jsonMapper.writeValueAsString(activity)); return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); } + if (activity instanceof Delete) { + if (activity.getObject() instanceof String) { + // Delete gone user + if (activity.getActor().equals(activity.getObject())) { + if (signatureManager.getContext(URI.create(activity.getActor())).isEmpty()) { + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + } + } + } return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); } @PostMapping(value = "/u/", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java index f1087d8c..7fe39d0d 100644 --- a/src/test/java/com/juick/server/tests/ServerTests.java +++ b/src/test/java/com/juick/server/tests/ServerTests.java @@ -117,6 +117,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.StreamSupport; +import static com.juick.server.api.activity.model.Context.ACTIVITY_MEDIA_TYPE; import static junit.framework.TestCase.assertTrue; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; @@ -124,6 +125,7 @@ import static org.junit.Assert.*; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.test.web.client.ExpectedCount.times; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; @@ -1885,4 +1887,16 @@ public class ServerTests { tst = jsonMapper.readValue(result.getResponse().getContentAsString(), User.class); assertThat(tst.getReaders().size(), is(1)); } + @Test + public void federatedUserDeletionFlow() throws Exception { + String deleteJsonStr = IOUtils.toString(new ClassPathResource("delete_user.json").getURI(), StandardCharsets.UTF_8); + Delete delete = jsonMapper.readValue(deleteJsonStr, Delete.class); + restServiceServer = MockRestServiceServer.bindTo(apClient).build(); + restServiceServer.expect(times(1), requestTo((String)delete.getObject())) + .andRespond(withStatus(HttpStatus.GONE)); + mockMvc.perform(post("/api/inbox") + .contentType(ACTIVITY_MEDIA_TYPE) + .content(deleteJsonStr)) + .andExpect(status().isAccepted()); + } } diff --git a/src/test/resources/delete_user.json b/src/test/resources/delete_user.json new file mode 100644 index 00000000..b68db011 --- /dev/null +++ b/src/test/resources/delete_user.json @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","sensitive":"as:sensitive","movedTo":{"@id":"as:movedTo","@type":"@id"},"alsoKnownAs":{"@id":"as:alsoKnownAs","@type":"@id"},"Hashtag":"as:Hashtag","ostatus":"http://ostatus.org#","atomUri":"ostatus:atomUri","inReplyToAtomUri":"ostatus:inReplyToAtomUri","conversation":"ostatus:conversation","toot":"http://joinmastodon.org/ns#","Emoji":"toot:Emoji","focalPoint":{"@container":"@list","@id":"toot:focalPoint"},"featured":{"@id":"toot:featured","@type":"@id"},"schema":"http://schema.org#","PropertyValue":"schema:PropertyValue","value":"schema:value"}],"id":"https://example.com/users/deleted#delete","type":"Delete","actor":"https://example.com/users/deleted","to":["https://www.w3.org/ns/activitystreams#Public"],"object":"https://example.com/users/deleted","signature":{"type":"RsaSignature2017","creator":"https://mastodon.social/users/andoniserra#main-key","created":"2019-01-29T14:50:13Z","signatureValue":"svq8NDQeXb0widXDL1jygye+a536L4GFPTT+8euXgdHhzij6y5dIpT+s0I0ZheAIfHEe+k3N5XysQMvJ4Jmh8douWZ14DkZNai5luk4Ftg5v/RynYAY65UgsldTf9XUvAbSiRGAK4s2b8qE3zsQihEHRIUrzb2bgvhKUkr8FuuuNDDDSS9i9bxnzQp8DSVivqdW2zJYm3ARtW7sWKSXoSaiP2KxIfRPC6UdDDSFbRr3zHckxRjsPnfWr8VvhjxggzVYcp4ZIJDqJj0qoy1lyRIRTWaDJwZIjFX7JjE5OVoKBt++IcY6IARpTGVxV4GXeeFMB7/y1tMaZoold6VlqyQ=="}} \ No newline at end of file -- cgit v1.2.3 From 116d87c9473b8135d0466be149f070e067e8b810 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Sat, 23 Feb 2019 18:26:05 +0300 Subject: * Add text descriptions to ActivityPub error codes * Append ActivityPub attachments as urls * Added failing test for Hubzilla activity with Link as object --- .../com/juick/formatters/PlainTextFormatter.java | 8 + .../com/juick/server/api/activity/Profile.java | 67 +++++--- .../java/com/juick/server/tests/ServerTests.java | 21 +++ src/test/resources/hubzilla_activity.json | 185 +++++++++++++++++++++ 4 files changed, 254 insertions(+), 27 deletions(-) create mode 100644 src/test/resources/hubzilla_activity.json (limited to 'src/test/resources') diff --git a/src/main/java/com/juick/formatters/PlainTextFormatter.java b/src/main/java/com/juick/formatters/PlainTextFormatter.java index 378a523f..4cb07950 100644 --- a/src/main/java/com/juick/formatters/PlainTextFormatter.java +++ b/src/main/java/com/juick/formatters/PlainTextFormatter.java @@ -84,6 +84,14 @@ public class PlainTextFormatter { return "https://juick.com/m/" + jmsg.getMid(); } + public static String markdownUrl(String url, String description) { + if (StringUtils.isNotBlank(description)) { + return String.format("[%s](%s)", description, url); + } else { + return url; + } + } + public static String formatPostNumber(com.juick.Message jmsg) { if (jmsg.getRid() > 0) { return String.format("%d/%d", jmsg.getMid(), jmsg.getRid()); diff --git a/src/main/java/com/juick/server/api/activity/Profile.java b/src/main/java/com/juick/server/api/activity/Profile.java index bd8b9ea8..c26941ef 100644 --- a/src/main/java/com/juick/server/api/activity/Profile.java +++ b/src/main/java/com/juick/server/api/activity/Profile.java @@ -3,6 +3,7 @@ package com.juick.server.api.activity; import com.fasterxml.jackson.databind.ObjectMapper; import com.juick.Message; import com.juick.User; +import com.juick.formatters.PlainTextFormatter; import com.juick.model.CommandResult; import com.juick.server.ActivityPubManager; import com.juick.server.CommandsManager; @@ -259,7 +260,7 @@ public class Profile { } @PostMapping(value = "/api/inbox", consumes = {Context.LD_JSON_MEDIA_TYPE, Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE}) - public ResponseEntity processInbox(InputStream inboxData) throws Exception { + public ResponseEntity processInbox(InputStream inboxData) throws Exception { String inbox = IOUtils.toString(inboxData, StandardCharsets.UTF_8); logger.info("Inbox: {}", inbox); Activity activity = jsonMapper.readValue(inbox, Activity.class); @@ -269,7 +270,7 @@ public class Profile { Follow followRequest = (Follow) activity; applicationEventPublisher.publishEvent( new FollowEvent(this, followRequest)); - return new ResponseEntity<>(HttpStatus.ACCEPTED); + return new ResponseEntity<>(CommandResult.fromString("Follow request accepted"), HttpStatus.ACCEPTED); } if (activity instanceof Undo) { @@ -278,10 +279,10 @@ public class Profile { String objectObject = (String) object.get("object"); if (objectType.equals("Follow")) { applicationEventPublisher.publishEvent(new UndoFollowEvent(this, activity.getActor(), objectObject)); - return new ResponseEntity<>(HttpStatus.OK); + return new ResponseEntity<>(CommandResult.fromString("Undo follow request accepted"), HttpStatus.OK); } else if (objectType.equals("Like") || objectType.equals("Announce")) { applicationEventPublisher.publishEvent(new UndoAnnounceEvent(this, activity.getActor(), objectObject)); - return new ResponseEntity<>(HttpStatus.OK); + return new ResponseEntity<>(CommandResult.fromString("Undo like/announce request accepted"), HttpStatus.OK); } } if (activity instanceof Create) { @@ -290,7 +291,7 @@ public class Profile { if (note.get("type").equals("Note")) { URI noteId = URI.create((String) note.get("id")); if (messagesService.replyExists(noteId)) { - return new ResponseEntity<>(HttpStatus.OK); + return new ResponseEntity<>(CommandResult.fromString("Reply already exists"), HttpStatus.OK); } else { String inReplyTo = (String) note.get("inReplyTo"); if (StringUtils.isNotBlank(inReplyTo)) { @@ -298,38 +299,50 @@ public class Profile { String postId = activityPubManager.postId(inReplyTo); User user = new User(); user.setUri(URI.create(activity.getActor())); - String attachment = StringUtils.EMPTY; - if (note.get("attachment") != null && ((List) note.get("attachment")).size() > 0) { - Map attachmentObj = (Map) ((List) note.get("attachment")).get(0); - attachment = (String) attachmentObj.get("url"); - } - String markdown = remarkConverter.convertFragment((String)note.get("content")); - CommandResult result = commandsManager.processCommand(user, String.format("#%s %s", postId, markdown), URI.create(attachment)); + String markdown = remarkConverter.convertFragment((String) note.get("content")); + String commandBody = note.get("attachment") == null ? markdown : + ((List) note.get("attachment")).stream().map(attachmentObj -> { + Map attachment = (Map) attachmentObj; + String attachmentUrl = attachment.get("url"); + String attachmentName = attachment.get("name"); + return PlainTextFormatter.markdownUrl(attachmentUrl, attachmentName); + }).reduce((source, url) -> String.format("%s\n%s", source, url)) + .orElse(markdown); + + 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<>(HttpStatus.OK); + return new ResponseEntity<>(result, HttpStatus.OK); } else { - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + 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 attachment = StringUtils.EMPTY; - if (note.get("attachment") != null && ((List) note.get("attachment")).size() > 0) { - Map attachmentObj = (Map) ((List) note.get("attachment")).get(0); - attachment = (String) attachmentObj.get("url"); - } String markdown = remarkConverter.convertFragment((String)note.get("content")); - CommandResult result = commandsManager.processCommand(user, String.format("#%d/%d %s", reply.getMid(), reply.getRid(), markdown), URI.create(attachment)); + String commandBody = note.get("attachment") == null ? markdown : + ((List) note.get("attachment")).stream().map(attachmentObj -> { + Map attachment = (Map) attachmentObj; + String attachmentUrl = attachment.get("url"); + String attachmentName = attachment.get("name"); + return PlainTextFormatter.markdownUrl(attachmentUrl, attachmentName); + }).reduce((source, url) -> String.format("%s\n%s", source, url)) + .orElse(markdown); + 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<>(HttpStatus.OK); + return new ResponseEntity<>(result, HttpStatus.OK); } else { - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + return new ResponseEntity<>(result, HttpStatus.BAD_REQUEST); } } } @@ -344,25 +357,25 @@ public class Profile { URI actor = URI.create(activity.getActor()); URI reply = URI.create((String)tombstone.get("id")); messagesService.deleteReply(actor, reply); - return new ResponseEntity<>(HttpStatus.OK); + return new ResponseEntity<>(CommandResult.fromString("Delete request accepted"), HttpStatus.OK); } } if (activity instanceof Like || activity instanceof Announce) { applicationEventPublisher.publishEvent(new AnnounceEvent(this, activity.getActor(), (String)activity.getObject())); - return new ResponseEntity<>(HttpStatus.OK); + return new ResponseEntity<>(CommandResult.fromString("Like/announce request accepted"), HttpStatus.OK); } logger.warn("Unknown activity: {}", jsonMapper.writeValueAsString(activity)); - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + 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<>(HttpStatus.ACCEPTED); + return new ResponseEntity<>(CommandResult.fromString("Delete request accepted"), HttpStatus.ACCEPTED); } } } - return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + return new ResponseEntity<>(CommandResult.fromString("Can not authenticate"), HttpStatus.UNAUTHORIZED); } @PostMapping(value = "/u/", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public User fetchUser(@RequestParam URI uri) { diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java index 9e1e68ea..b1a71c65 100644 --- a/src/test/java/com/juick/server/tests/ServerTests.java +++ b/src/test/java/com/juick/server/tests/ServerTests.java @@ -44,6 +44,7 @@ import com.juick.server.util.ImageUtils; import com.juick.server.www.WebApp; import com.juick.service.*; import com.juick.service.component.MessageEvent; +import com.juick.test.util.MockUtils; import com.juick.util.DateFormattersHolder; import com.juick.util.MessageUtils; import com.mitchellbosecke.pebble.PebbleEngine; @@ -209,6 +210,8 @@ public class ServerTests { private Resource cmykJpeg; @Value("classpath:nojfif.jpg") private Resource nojfif; + @Value("classpath:hubzilla_activity.json") + private Resource hubzillaActivity; @Inject private KeystoreManager testKeystoreManager; @@ -1932,4 +1935,22 @@ public class ServerTests { .andExpect(status().isAccepted()); apClient.setRequestFactory(originalRequestFactory); } + + @Test + public void legacyAvatarEndpoint() throws Exception { + mockMvc.perform(get("/api/avatar") + .param("uname", "unknown")) + .andExpect(status().isOk()) + .andExpect(content().bytes(IOUtils.toByteArray(defaultAvatar.getInputStream()))); + } + @Test + public void federatedAttachmentsAsLinks() throws Exception { + int mid = messagesService.createMessage(ugnich.getUid(), "test", StringUtils.EMPTY, Collections.emptyList()); + Message testMessage = MockUtils.mockMessage(mid, freefd, "reply"); + } + @Test + public void hubzillaActor() throws Exception { + String activity = IOUtils.toString(hubzillaActivity.getInputStream(), StandardCharsets.UTF_8); + Create create = jsonMapper.readValue(activity, Create.class); + } } diff --git a/src/test/resources/hubzilla_activity.json b/src/test/resources/hubzilla_activity.json new file mode 100644 index 00000000..b25aca87 --- /dev/null +++ b/src/test/resources/hubzilla_activity.json @@ -0,0 +1,185 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + "https://ussr.win/apschema/v1.2" + ], + "type": "Create", + "id": "https://ussr.win/activity/e46a6100e4ba83d602eab5fe0e035405a32d7d36094c95dc85c5c9fcd3d93ab2%40ussr.win", + "published": "2019-02-14T11:23:29Z", + "updated": "2019-02-14T11:38:48Z", + "actor": { + "type": "Person", + "id": "https://ussr.win/channel/zlax", + "preferredUsername": "zlax", + "name": "ivan zlax", + "icon": { + "type": "Image", + "mediaType": "image/jpeg", + "url": "https://ussr.win/photo/profile/l/2", + "height": 300, + "width": 300 + }, + "url": { + "type": "Link", + "mediaType": "text/html", + "href": "https://ussr.win/channel/zlax" + }, + "inbox": "https://ussr.win/inbox/zlax", + "outbox": "https://ussr.win/outbox/zlax", + "followers": "https://ussr.win/followers/zlax", + "following": "https://ussr.win/following/zlax", + "endpoints": { + "sharedInbox": "https://ussr.win/inbox" + }, + "publicKey": { + "id": "https://ussr.win/channel/zlax/public_key_pem", + "owner": "https://ussr.win/channel/zlax", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtFSIKFVzo+9NzzY0xho9\nA8CqO0j12f3HEOZUDBDj1NBbQ6Cj1p1f5mB1AlRr+a05fqpraCWIJyCXVTtdyjem\niQ/ObT2PuZIhAY04/ptv78S9EM9ImZi2aDNWp2nWQu23dJajb2TMpIxGNS1M3DVR\ngXwRVEVIEEDzftWx7vF4335/2uJvPfwTzKI3pR972xp1iZCd/G3BtYzUW4swIFSu\n+5ZLKhgwO6A4Ge5+sn2k6x+K56YCgeEEQheOg+PbggIQ68xfvYCQyfuShqAXEadv\nOvQ1dN8WO+tgKqYDRQgILIONB8/2/XXMoQbSVRZs2GmLKXHhIeVKiSZ1vKwHsPx1\nCYUayQo/BB1JpbjkmyDQcHAX+KZ7PQUhpQn976f6Ycp5rznvBH5Zm96VKySaGMy7\nGWefafOfcCNfVZpq17gPPfSbC0XOHdvm6T1e1OPwFl/ho9HxatbA60DIDEd7xf4V\nq9aTSZ2MeQW5JXaxJXSgwucPZ9mhVfucFtCyLdlHZ7gA5yJ+pyYmMe8pjCSNWztD\nUOoJC46vv2l1RbMGTJy2AY9ZuPvyrmJHlsRsTYcmDYRFSk6sgGi1eswSDHlruE3u\nKG4E0nsA8qxzgzpCViQV4DIgXhMInBwo7ZhSyWD+tF2a4tpXorHqmg35x/aqJlaq\nE2xF+yrfh/Kx8O+7P6C1aGcCAwEAAQ==\n-----END PUBLIC KEY-----\n" + }, + "nomadicLocations": [ + { + "id": "https://ussr.win/locs/zlax", + "type": "nomadicLocation", + "locationAddress": "acct:zlax@ussr.win", + "locationPrimary": true, + "locationDeleted": false + } + ] + }, + "object": { + "type": "Note", + "id": "https://ussr.win/item/e46a6100e4ba83d602eab5fe0e035405a32d7d36094c95dc85c5c9fcd3d93ab2%40ussr.win", + "published": "2019-02-14T11:23:29Z", + "updated": "2019-02-14T11:38:48Z", + "url": { + "type": "text/html", + "rel": "alternate", + "href": "https://ussr.win/channel/zlax/?f=&mid=e46a6100e4ba83d602eab5fe0e035405a32d7d36094c95dc85c5c9fcd3d93ab2@ussr.win" + }, + "attributedTo": "https://ussr.win/channel/zlax", + "content": "#^https://twitter.com/Dalatrm/status/1095677403198906369
#^https://twitter.com/Dalatrm/status/1095677401433022466
\"Image/photo\"

\"Image/photo\"
Продюсер BBC признал постановочными сцены после химатаки в Сирии
#^https://www.vedomosti.ru/politics/news/2019/02/14/794104-bbc-himataki
Сцены в госпитале сирийского города Дума после предполагаемой химической атаки были постановочными для достижения «максимального эффекта». Об этом в своем твиттере написал продюсер BBC по Сирии Риам Далати. «Спустя почти шесть месяцев расследования я могу подтвердить без тени сомнения, что сцены в госпитале Думы были постановочные. Погибших в больнице не было», — признал он.

Сам факт химической атаки, якобы имевшей место 7 апреля 2018 г., пока не подтвержден Организацией по запрещению химического оружия (ОЗХО). «Атака была, зарин не использовался, но мы должны дождаться, когда ОЗХО подтвердит, использовался ли хлор или что-то еще. Однако все остальное вокруг атаки было создано для максимального эффекта», — написал Далати.

Информацию о применении в сирийской Думе химического оружия с использованием хлора и нервно-паралитического агента распространили общественные организации, в том числе «Белые каски». По данным организации, жертвами атаки стали около 70 человек.

#bbc #capitalism #conspiracy #history #hoax #metaprogramming #revision #syria #terrorism #uk #war #whitehelments", + "actor": { + "type": "Person", + "id": "https://ussr.win/channel/zlax", + "preferredUsername": "zlax", + "name": "ivan zlax", + "icon": { + "type": "Image", + "mediaType": "image/jpeg", + "url": "https://ussr.win/photo/profile/l/2", + "height": 300, + "width": 300 + }, + "url": { + "type": "Link", + "mediaType": "text/html", + "href": "https://ussr.win/channel/zlax" + }, + "inbox": "https://ussr.win/inbox/zlax", + "outbox": "https://ussr.win/outbox/zlax", + "followers": "https://ussr.win/followers/zlax", + "following": "https://ussr.win/following/zlax", + "endpoints": { + "sharedInbox": "https://ussr.win/inbox" + }, + "publicKey": { + "id": "https://ussr.win/channel/zlax/public_key_pem", + "owner": "https://ussr.win/channel/zlax", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtFSIKFVzo+9NzzY0xho9\nA8CqO0j12f3HEOZUDBDj1NBbQ6Cj1p1f5mB1AlRr+a05fqpraCWIJyCXVTtdyjem\niQ/ObT2PuZIhAY04/ptv78S9EM9ImZi2aDNWp2nWQu23dJajb2TMpIxGNS1M3DVR\ngXwRVEVIEEDzftWx7vF4335/2uJvPfwTzKI3pR972xp1iZCd/G3BtYzUW4swIFSu\n+5ZLKhgwO6A4Ge5+sn2k6x+K56YCgeEEQheOg+PbggIQ68xfvYCQyfuShqAXEadv\nOvQ1dN8WO+tgKqYDRQgILIONB8/2/XXMoQbSVRZs2GmLKXHhIeVKiSZ1vKwHsPx1\nCYUayQo/BB1JpbjkmyDQcHAX+KZ7PQUhpQn976f6Ycp5rznvBH5Zm96VKySaGMy7\nGWefafOfcCNfVZpq17gPPfSbC0XOHdvm6T1e1OPwFl/ho9HxatbA60DIDEd7xf4V\nq9aTSZ2MeQW5JXaxJXSgwucPZ9mhVfucFtCyLdlHZ7gA5yJ+pyYmMe8pjCSNWztD\nUOoJC46vv2l1RbMGTJy2AY9ZuPvyrmJHlsRsTYcmDYRFSk6sgGi1eswSDHlruE3u\nKG4E0nsA8qxzgzpCViQV4DIgXhMInBwo7ZhSyWD+tF2a4tpXorHqmg35x/aqJlaq\nE2xF+yrfh/Kx8O+7P6C1aGcCAwEAAQ==\n-----END PUBLIC KEY-----\n" + }, + "nomadicLocations": [ + { + "id": "https://ussr.win/locs/zlax", + "type": "nomadicLocation", + "locationAddress": "acct:zlax@ussr.win", + "locationPrimary": true, + "locationDeleted": false + } + ] + }, + "tag": [ + { + "id": "https://ussr.win/search?tag=metaprogramming", + "name": "#metaprogramming" + }, + { + "id": "https://ussr.win/search?tag=whitehelments", + "name": "#whitehelments" + }, + { + "id": "https://ussr.win/search?tag=capitalism", + "name": "#capitalism" + }, + { + "id": "https://ussr.win/search?tag=conspiracy", + "name": "#conspiracy" + }, + { + "id": "https://ussr.win/search?tag=terrorism", + "name": "#terrorism" + }, + { + "id": "https://ussr.win/search?tag=revision", + "name": "#revision" + }, + { + "id": "https://ussr.win/search?tag=history", + "name": "#history" + }, + { + "id": "https://ussr.win/search?tag=syria", + "name": "#syria" + }, + { + "id": "https://ussr.win/search?tag=hoax", + "name": "#hoax" + }, + { + "id": "https://ussr.win/search?tag=bbc", + "name": "#bbc" + }, + { + "id": "https://ussr.win/search?tag=war", + "name": "#war" + }, + { + "id": "https://ussr.win/search?tag=uk", + "name": "#uk" + } + ], + "attachment": [ + { + "type": "Image", + "url": "https://ussr.win/photo/6776e315a9692860af53c19518e524f50ab047a4317435403532c922a7c484d4-2.jpg" + }, + { + "type": "Image", + "url": "https://ussr.win/photo/afb21af40be39ad19589dec5dfa0161b2364b59331bba95aae823e68b3acfbf3-2.jpg" + } + ], + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "cc": [ + "https://ussr.win/followers/zlax" + ] + }, + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "cc": [ + "https://ussr.win/followers/zlax" + ], + "signature": { + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1" + ], + "type": "RsaSignature2017", + "nonce": "c4f8b31f4277d4322a528697d550aefd78a4a7709f0da25285032f7529d3f550", + "creator": "https://ussr.win/channel/zlax/public_key_pem", + "created": "2019-02-14T11:39:01Z", + "signatureValue": "WnXFcSm3nR1Su4QwSVJq6vQ7xdtPQTfs5iTMcAcxasoGHphJaAZRISV1QRPuMhw5jap4Lmb4ZaFRfqGm4M4HND+mI06dC2HlgCh0vnNvGsbcDa2RybSnIUo/xswEa/Mcpf6uy2dcLwaZY6tXOkkJmtZOseN54CUO3bQHbd3KmSiqkvREMXv2+qrVJhohZ4R9tLXamUTkoJmq1wSS2s8XSUlmO2v+Th3OAEoHeiS1SehglvIzua83IKlU2/iAs8akGVyYng5uLO7YeUsmiKHggef1ss8XKcNuhaAW8b3DUTnUwBZCPiiCoeXEQMfYdciCtTAKARHLr5RlHPE7etf1Fqk9Pozo/b2EDpfTxbZ26ZKY02pl4g82u95L43hTmCLbZ+wbKt5M0uHRld+/WkJrkIVS2Vj0MJ84Pp94Ij5A0MaXnBDiIj8YpvbRWWVEdXWKs/N8Dy0c11NiHCPhurZTMQDwv96bBphLQGlTp4USYjbKlS95JyyxbfjRbbubM4Q3MGsZFWbRi7C0exvZiw8zHBGn3hnbnZsDdlDax2weuXsSzHPlw8DxG6XEXZy3GWuK4LlQCVXaa9AcSd9LODVIrxaelr0pdW38a2rot1rlkGHdYPR8oD5zV3fj4kWs3n68mU9VJRTvubbX1zKV8EIX9UvVJ6wuRHqyVOFKJPkKloc=" + } +} \ No newline at end of file -- cgit v1.2.3 From c6007957456199945cd0511861d54e24c8873fb7 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Sat, 23 Feb 2019 19:58:12 +0300 Subject: Add activity json failed on production to tests --- src/test/java/com/juick/server/tests/ServerTests.java | 13 ++++++++----- src/test/resources/note_document.json | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 src/test/resources/note_document.json (limited to 'src/test/resources') diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java index b1a71c65..a4b3f95c 100644 --- a/src/test/java/com/juick/server/tests/ServerTests.java +++ b/src/test/java/com/juick/server/tests/ServerTests.java @@ -25,16 +25,15 @@ import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.css.StyleElement; import com.gargoylesoftware.htmlunit.html.DomElement; import com.gargoylesoftware.htmlunit.html.HtmlPage; +import com.github.jsonldjava.core.JsonLdOptions; +import com.github.jsonldjava.core.JsonLdProcessor; +import com.github.jsonldjava.utils.JsonUtils; import com.jayway.jsonpath.JsonPath; import com.juick.*; import com.juick.model.*; import com.juick.server.*; import com.juick.server.api.activity.model.Context; -import com.juick.server.api.activity.model.activities.Create; -import com.juick.server.api.activity.model.activities.Delete; -import com.juick.server.api.activity.model.activities.Follow; -import com.juick.server.api.activity.model.activities.Like; -import com.juick.server.api.activity.model.activities.Undo; +import com.juick.server.api.activity.model.activities.*; import com.juick.server.api.activity.model.objects.Note; import com.juick.server.api.activity.model.objects.Person; import com.juick.server.api.webfinger.model.Account; @@ -212,6 +211,8 @@ public class ServerTests { private Resource nojfif; @Value("classpath:hubzilla_activity.json") private Resource hubzillaActivity; + @Value("classpath:note_document.json") + private Resource noteWithDocument; @Inject private KeystoreManager testKeystoreManager; @@ -1947,6 +1948,8 @@ public class ServerTests { public void federatedAttachmentsAsLinks() throws Exception { int mid = messagesService.createMessage(ugnich.getUid(), "test", StringUtils.EMPTY, Collections.emptyList()); Message testMessage = MockUtils.mockMessage(mid, freefd, "reply"); + String activity = IOUtils.toString(noteWithDocument.getInputStream(), StandardCharsets.UTF_8); + Announce announce = jsonMapper.readValue(activity, Announce.class); } @Test public void hubzillaActor() throws Exception { diff --git a/src/test/resources/note_document.json b/src/test/resources/note_document.json new file mode 100644 index 00000000..4ae4a2ad --- /dev/null +++ b/src/test/resources/note_document.json @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","sensitive":"as:sensitive","movedTo":{"@id":"as:movedTo","@type":"@id"},"alsoKnownAs":{"@id":"as:alsoKnownAs","@type":"@id"},"Hashtag":"as:Hashtag","ostatus":"http://ostatus.org#","atomUri":"ostatus:atomUri","inReplyToAtomUri":"ostatus:inReplyToAtomUri","conversation":"ostatus:conversation","toot":"http://joinmastodon.org/ns#","Emoji":"toot:Emoji","focalPoint":{"@container":"@list","@id":"toot:focalPoint"},"featured":{"@id":"toot:featured","@type":"@id"},"schema":"http://schema.org#","PropertyValue":"schema:PropertyValue","value":"schema:value"}],"id":"https://mastodon.social/users/armitage/statuses/101641036945418885/activity","type":"Announce","actor":"https://mastodon.social/users/armitage","published":"2019-02-23T10:52:22Z","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://juick.com/u/netneladno","https://mastodon.social/users/armitage/followers"],"atomUri":"https://mastodon.social/users/armitage/statuses/101641036945418885/activity","object":{"id":"https://juick.com/n/2936427-0","type":"Note","summary":null,"inReplyTo":null,"published":"2019-02-23T10:13:59Z","url":"https://juick.com/m/2936427","attributedTo":"https://juick.com/u/netneladno","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://mastodon.social/users/netneladno/followers"],"sensitive":false,"atomUri":null,"inReplyToAtomUri":null,"conversation":"tag:mastodon.social,2019-02-23:objectId=86866293:objectType=Conversation","content":"\u003cp\u003e\u003c/p\u003e\n","attachment":[{"type":"Document","mediaType":"image/jpeg","url":"https://i.juick.com/photos-1024/2936427.jpg","name":null}],"tag":[]},"signature":{"type":"RsaSignature2017","creator":"https://mastodon.social/users/armitage#main-key","created":"2019-02-23T10:52:22Z","signatureValue":"hEbN5wumGY98T/t5ZbgBLxQNEHX6PJgO9dGwIdTq0T+GJ518J3duhHlhljBQkGgnH/68aSBWHxDQ+57YRVlR6lukvl0hKCg8Rx1NOYhtU+9OH//MH2uMt/XXh2pE1dv+RVA7GS4zkCMjKKMhY6WNzbJQS4FfvaCmmEn6gqiCSXbo1lLo4bkhBRyfpAH8Z9Z8/wEbRAl0qCVZlim8ELOZ8rWVfnmgF3gGDWwpgzSEqIbxEytpHtNeYC+ZC3FVlxMAomvxuyj2XCv6B854ol5UQ30O8MLVNiTCoUa/7w6k/I3pmN1etpJ53XD8Si0Qg6QKHO8R3Wp6S9LSoF0Hj/GiDQ=="}} \ No newline at end of file -- cgit v1.2.3 From 0682e5c1a3f71c3bbb23ac646d2a4e54a472ac06 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Sat, 23 Feb 2019 21:32:34 +0300 Subject: Announce object may be Context --- src/main/java/com/juick/server/api/activity/Profile.java | 4 +++- src/test/java/com/juick/server/tests/ServerTests.java | 2 +- src/test/resources/announce.json | 1 + src/test/resources/note_document.json | 1 - 4 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 src/test/resources/announce.json delete mode 100644 src/test/resources/note_document.json (limited to 'src/test/resources') diff --git a/src/main/java/com/juick/server/api/activity/Profile.java b/src/main/java/com/juick/server/api/activity/Profile.java index c26941ef..f5d8025c 100644 --- a/src/main/java/com/juick/server/api/activity/Profile.java +++ b/src/main/java/com/juick/server/api/activity/Profile.java @@ -361,7 +361,9 @@ public class Profile { } } if (activity instanceof Like || activity instanceof Announce) { - applicationEventPublisher.publishEvent(new AnnounceEvent(this, activity.getActor(), (String)activity.getObject())); + String messageUri = activity.getObject() instanceof String ? (String) activity.getObject() + : ((Context) activity.getObject()).getId(); + applicationEventPublisher.publishEvent(new AnnounceEvent(this, activity.getActor(), messageUri)); return new ResponseEntity<>(CommandResult.fromString("Like/announce request accepted"), HttpStatus.OK); } logger.warn("Unknown activity: {}", jsonMapper.writeValueAsString(activity)); diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java index a4b3f95c..9569c45d 100644 --- a/src/test/java/com/juick/server/tests/ServerTests.java +++ b/src/test/java/com/juick/server/tests/ServerTests.java @@ -211,7 +211,7 @@ public class ServerTests { private Resource nojfif; @Value("classpath:hubzilla_activity.json") private Resource hubzillaActivity; - @Value("classpath:note_document.json") + @Value("classpath:announce.json") private Resource noteWithDocument; @Inject diff --git a/src/test/resources/announce.json b/src/test/resources/announce.json new file mode 100644 index 00000000..4ae4a2ad --- /dev/null +++ b/src/test/resources/announce.json @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","sensitive":"as:sensitive","movedTo":{"@id":"as:movedTo","@type":"@id"},"alsoKnownAs":{"@id":"as:alsoKnownAs","@type":"@id"},"Hashtag":"as:Hashtag","ostatus":"http://ostatus.org#","atomUri":"ostatus:atomUri","inReplyToAtomUri":"ostatus:inReplyToAtomUri","conversation":"ostatus:conversation","toot":"http://joinmastodon.org/ns#","Emoji":"toot:Emoji","focalPoint":{"@container":"@list","@id":"toot:focalPoint"},"featured":{"@id":"toot:featured","@type":"@id"},"schema":"http://schema.org#","PropertyValue":"schema:PropertyValue","value":"schema:value"}],"id":"https://mastodon.social/users/armitage/statuses/101641036945418885/activity","type":"Announce","actor":"https://mastodon.social/users/armitage","published":"2019-02-23T10:52:22Z","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://juick.com/u/netneladno","https://mastodon.social/users/armitage/followers"],"atomUri":"https://mastodon.social/users/armitage/statuses/101641036945418885/activity","object":{"id":"https://juick.com/n/2936427-0","type":"Note","summary":null,"inReplyTo":null,"published":"2019-02-23T10:13:59Z","url":"https://juick.com/m/2936427","attributedTo":"https://juick.com/u/netneladno","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://mastodon.social/users/netneladno/followers"],"sensitive":false,"atomUri":null,"inReplyToAtomUri":null,"conversation":"tag:mastodon.social,2019-02-23:objectId=86866293:objectType=Conversation","content":"\u003cp\u003e\u003c/p\u003e\n","attachment":[{"type":"Document","mediaType":"image/jpeg","url":"https://i.juick.com/photos-1024/2936427.jpg","name":null}],"tag":[]},"signature":{"type":"RsaSignature2017","creator":"https://mastodon.social/users/armitage#main-key","created":"2019-02-23T10:52:22Z","signatureValue":"hEbN5wumGY98T/t5ZbgBLxQNEHX6PJgO9dGwIdTq0T+GJ518J3duhHlhljBQkGgnH/68aSBWHxDQ+57YRVlR6lukvl0hKCg8Rx1NOYhtU+9OH//MH2uMt/XXh2pE1dv+RVA7GS4zkCMjKKMhY6WNzbJQS4FfvaCmmEn6gqiCSXbo1lLo4bkhBRyfpAH8Z9Z8/wEbRAl0qCVZlim8ELOZ8rWVfnmgF3gGDWwpgzSEqIbxEytpHtNeYC+ZC3FVlxMAomvxuyj2XCv6B854ol5UQ30O8MLVNiTCoUa/7w6k/I3pmN1etpJ53XD8Si0Qg6QKHO8R3Wp6S9LSoF0Hj/GiDQ=="}} \ No newline at end of file diff --git a/src/test/resources/note_document.json b/src/test/resources/note_document.json deleted file mode 100644 index 4ae4a2ad..00000000 --- a/src/test/resources/note_document.json +++ /dev/null @@ -1 +0,0 @@ -{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","sensitive":"as:sensitive","movedTo":{"@id":"as:movedTo","@type":"@id"},"alsoKnownAs":{"@id":"as:alsoKnownAs","@type":"@id"},"Hashtag":"as:Hashtag","ostatus":"http://ostatus.org#","atomUri":"ostatus:atomUri","inReplyToAtomUri":"ostatus:inReplyToAtomUri","conversation":"ostatus:conversation","toot":"http://joinmastodon.org/ns#","Emoji":"toot:Emoji","focalPoint":{"@container":"@list","@id":"toot:focalPoint"},"featured":{"@id":"toot:featured","@type":"@id"},"schema":"http://schema.org#","PropertyValue":"schema:PropertyValue","value":"schema:value"}],"id":"https://mastodon.social/users/armitage/statuses/101641036945418885/activity","type":"Announce","actor":"https://mastodon.social/users/armitage","published":"2019-02-23T10:52:22Z","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://juick.com/u/netneladno","https://mastodon.social/users/armitage/followers"],"atomUri":"https://mastodon.social/users/armitage/statuses/101641036945418885/activity","object":{"id":"https://juick.com/n/2936427-0","type":"Note","summary":null,"inReplyTo":null,"published":"2019-02-23T10:13:59Z","url":"https://juick.com/m/2936427","attributedTo":"https://juick.com/u/netneladno","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://mastodon.social/users/netneladno/followers"],"sensitive":false,"atomUri":null,"inReplyToAtomUri":null,"conversation":"tag:mastodon.social,2019-02-23:objectId=86866293:objectType=Conversation","content":"\u003cp\u003e\u003c/p\u003e\n","attachment":[{"type":"Document","mediaType":"image/jpeg","url":"https://i.juick.com/photos-1024/2936427.jpg","name":null}],"tag":[]},"signature":{"type":"RsaSignature2017","creator":"https://mastodon.social/users/armitage#main-key","created":"2019-02-23T10:52:22Z","signatureValue":"hEbN5wumGY98T/t5ZbgBLxQNEHX6PJgO9dGwIdTq0T+GJ518J3duhHlhljBQkGgnH/68aSBWHxDQ+57YRVlR6lukvl0hKCg8Rx1NOYhtU+9OH//MH2uMt/XXh2pE1dv+RVA7GS4zkCMjKKMhY6WNzbJQS4FfvaCmmEn6gqiCSXbo1lLo4bkhBRyfpAH8Z9Z8/wEbRAl0qCVZlim8ELOZ8rWVfnmgF3gGDWwpgzSEqIbxEytpHtNeYC+ZC3FVlxMAomvxuyj2XCv6B854ol5UQ30O8MLVNiTCoUa/7w6k/I3pmN1etpJ53XD8Si0Qg6QKHO8R3Wp6S9LSoF0Hj/GiDQ=="}} \ No newline at end of file -- cgit v1.2.3 From 32a92d0a8d3c99c3df4abf0aad147f868fd36775 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Sat, 23 Feb 2019 22:52:45 +0300 Subject: Fix activity id deserializer --- .../juick/server/api/activity/helpers/ActivityIdDeserializer.java | 2 +- src/test/java/com/juick/server/tests/ServerTests.java | 5 +++++ src/test/resources/hubzilla_follow.json | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/hubzilla_follow.json (limited to 'src/test/resources') diff --git a/src/main/java/com/juick/server/api/activity/helpers/ActivityIdDeserializer.java b/src/main/java/com/juick/server/api/activity/helpers/ActivityIdDeserializer.java index de43dd5c..ba8cfb87 100644 --- a/src/main/java/com/juick/server/api/activity/helpers/ActivityIdDeserializer.java +++ b/src/main/java/com/juick/server/api/activity/helpers/ActivityIdDeserializer.java @@ -13,7 +13,7 @@ public class ActivityIdDeserializer extends JsonDeserializer { @Override public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonToken jsonToken = p.getCurrentToken(); - if (jsonToken == JsonToken.VALUE_EMBEDDED_OBJECT) { + if (jsonToken == JsonToken.START_OBJECT) { JsonNode node = p.getCodec().readTree(p); return node.get("id").textValue(); } diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java index 9569c45d..a509b36d 100644 --- a/src/test/java/com/juick/server/tests/ServerTests.java +++ b/src/test/java/com/juick/server/tests/ServerTests.java @@ -211,6 +211,8 @@ public class ServerTests { private Resource nojfif; @Value("classpath:hubzilla_activity.json") private Resource hubzillaActivity; + @Value("classpath:hubzilla_follow.json") + private Resource hubzillaFollow; @Value("classpath:announce.json") private Resource noteWithDocument; @@ -1955,5 +1957,8 @@ public class ServerTests { public void hubzillaActor() 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); + Follow follow = jsonMapper.readValue(followData, Follow.class); + assertThat(follow.getActor(), is("https://ussr.win/channel/zlax")); } } diff --git a/src/test/resources/hubzilla_follow.json b/src/test/resources/hubzilla_follow.json new file mode 100644 index 00000000..fff33c36 --- /dev/null +++ b/src/test/resources/hubzilla_follow.json @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://ussr.win/apschema/v1.3"],"id":"https://ussr.win/follow/1216","type":"Follow","actor":{"type":"Person","id":"https://ussr.win/channel/zlax","preferredUsername":"zlax","name":"ivan zlax","icon":{"type":"Image","mediaType":"image/jpeg","url":"https://ussr.win/photo/profile/l/2","height":300,"width":300},"url":{"type":"Link","mediaType":"text/html","href":"https://ussr.win/channel/zlax"},"inbox":"https://ussr.win/inbox/zlax","outbox":"https://ussr.win/outbox/zlax","followers":"https://ussr.win/followers/zlax","following":"https://ussr.win/following/zlax","endpoints":{"sharedInbox":"https://ussr.win/inbox"},"publicKey":{"id":"https://ussr.win/channel/zlax/public_key_pem","owner":"https://ussr.win/channel/zlax","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtFSIKFVzo+9NzzY0xho9\nA8CqO0j12f3HEOZUDBDj1NBbQ6Cj1p1f5mB1AlRr+a05fqpraCWIJyCXVTtdyjem\niQ/ObT2PuZIhAY04/ptv78S9EM9ImZi2aDNWp2nWQu23dJajb2TMpIxGNS1M3DVR\ngXwRVEVIEEDzftWx7vF4335/2uJvPfwTzKI3pR972xp1iZCd/G3BtYzUW4swIFSu\n+5ZLKhgwO6A4Ge5+sn2k6x+K56YCgeEEQheOg+PbggIQ68xfvYCQyfuShqAXEadv\nOvQ1dN8WO+tgKqYDRQgILIONB8/2/XXMoQbSVRZs2GmLKXHhIeVKiSZ1vKwHsPx1\nCYUayQo/BB1JpbjkmyDQcHAX+KZ7PQUhpQn976f6Ycp5rznvBH5Zm96VKySaGMy7\nGWefafOfcCNfVZpq17gPPfSbC0XOHdvm6T1e1OPwFl/ho9HxatbA60DIDEd7xf4V\nq9aTSZ2MeQW5JXaxJXSgwucPZ9mhVfucFtCyLdlHZ7gA5yJ+pyYmMe8pjCSNWztD\nUOoJC46vv2l1RbMGTJy2AY9ZuPvyrmJHlsRsTYcmDYRFSk6sgGi1eswSDHlruE3u\nKG4E0nsA8qxzgzpCViQV4DIgXhMInBwo7ZhSyWD+tF2a4tpXorHqmg35x/aqJlaq\nE2xF+yrfh/Kx8O+7P6C1aGcCAwEAAQ==\n-----END PUBLIC KEY-----\n"},"nomadicLocations":[{"id":"https://ussr.win/locs/zlax","type":"nomadicLocation","locationAddress":"acct:zlax@ussr.win","locationPrimary":true,"locationDeleted":false}]},"object":"https://juick.com/u/netneladno","to":["https://juick.com/u/netneladno"],"signature":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],"type":"RsaSignature2017","nonce":"1ee5df16edb30d1944fcb07859849ee4293da98c13322c13e2f929b822da91a7","creator":"https://ussr.win/channel/zlax/public_key_pem","created":"2019-02-23T11:09:56Z","signatureValue":"M6551dhNfk0vsSQ6hYvxXVURb7NviNk8ExYBLsax6uYr1oyV/zQJuUtoqufr47t/2NvfzLVn0criLAKbF586siIFd2YBO4wPWtSDPPAWgaQxDrCzRG4PimuavgT0ghIKzmmMnCG6BLC4O0+ohKPUFzaOHgsgdM++TY21OdLQUaauwYkvn9eWYGXzkS5LEnxEKuFpQarOtzChpP9btI9P3iDDRaOqTTlDw0w1xZ8/LqqPCqoA5W8NS+xSyhHsvFi1ApNinFQNM5+e1Gj09Lvtumn2rQE9Smn8sXG9jp5MSBKFdmuG20PDqidfQ3uvZm5qPdwfJnWjZ2VD00aOSji3ahcHJWkbxpNQki2TBb6u2FDABPlUsBvJ2Z23Ubdm+kcjNklmlZeAgcTvWoZhlzushlGjukRwMymRJZXQNIAgVoKbWhvm2w8NX1cQWs1XS211IPl44sT33T5ZoDNMiDPru+XtHWXrZxA2jpLrHec18bZ15y66KTi67s8QNoYn7cUSqETtch7Vuixw2oxQZNfDj0yhthbi7+lFoqB1Ilo37rJx/9wMY9O271n4rBmuSoHmMDVUSZBZxPjpzvm3zS/NjxczwNJ8a8hZSGcDvViHf2Lcqj+qt+DBbI1jtPGRTieR6pVRjxa7MjjZipDMhYczn13poKQ4KK3lYakyaNhjgHg="}} \ No newline at end of file -- cgit v1.2.3 From dafee9c471e154e375cca19f5e96c9c6fc89033f Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Tue, 26 Feb 2019 14:48:02 +0300 Subject: Display federated likes --- src/main/java/com/juick/Message.java | 6 ++--- .../java/com/juick/service/MessagesService.java | 2 +- .../com/juick/service/MessagesServiceImpl.java | 14 ++++++++--- src/main/resources/schema.sql | 2 +- src/main/resources/templates/views/thread.html | 6 ++++- .../java/com/juick/server/tests/ServerTests.java | 29 ++++++++++++++-------- src/test/resources/data.sql | 1 + 7 files changed, 39 insertions(+), 21 deletions(-) (limited to 'src/test/resources') diff --git a/src/main/java/com/juick/Message.java b/src/main/java/com/juick/Message.java index 00527b41..617ed834 100644 --- a/src/main/java/com/juick/Message.java +++ b/src/main/java/com/juick/Message.java @@ -81,7 +81,7 @@ public class Message implements Comparable { private URI replyToUri; private boolean html; - private Set recommendations; + private Set recommendations; private List entities; @@ -333,11 +333,11 @@ public class Message implements Comparable { this.service = service; } - public Set getRecommendations() { + public Set getRecommendations() { return recommendations; } - public void setRecommendations(Set recommendations) { + public void setRecommendations(Set recommendations) { this.recommendations = recommendations; } diff --git a/src/main/java/com/juick/service/MessagesService.java b/src/main/java/com/juick/service/MessagesService.java index 4bcdba46..37da98a8 100644 --- a/src/main/java/com/juick/service/MessagesService.java +++ b/src/main/java/com/juick/service/MessagesService.java @@ -68,7 +68,7 @@ public interface MessagesService { User getMessageAuthor(int mid); - List getMessageRecommendations(int mid); + List getMessageRecommendations(int mid); List getAll(int visitorUid, int before); diff --git a/src/main/java/com/juick/service/MessagesServiceImpl.java b/src/main/java/com/juick/service/MessagesServiceImpl.java index c3d319d5..01e96d6e 100644 --- a/src/main/java/com/juick/service/MessagesServiceImpl.java +++ b/src/main/java/com/juick/service/MessagesServiceImpl.java @@ -477,15 +477,21 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ @Transactional(readOnly = true) @Override - public List getMessageRecommendations(final int mid) { - return getJdbcTemplate().queryForList( - "SELECT DISTINCT users.nick FROM favorites " + + public List getMessageRecommendations(final int mid) { + return getJdbcTemplate().query( + "SELECT DISTINCT users.id, users.nick, favorites.user_uri FROM favorites " + "INNER JOIN users ON (favorites.message_id = ? AND favorites.user_id = users.id) " + "INNER JOIN messages m ON favorites.message_id=m.message_id WHERE favorites.like_id=1 " + "AND NOT EXISTS (SELECT 1 FROM bl_users WHERE " + "(user_id = favorites.user_id AND bl_user_id = m.user_id) " + "OR (user_id = m.user_id AND bl_user_id = favorites.user_id))", - String.class, mid); + (rs, rowNum) -> { + User user = new User(); + user.setUid(rs.getInt(1)); + user.setName(rs.getString(2)); + user.setUri(URI.create(rs.getString(3))); + return user; + }, mid); } @Transactional(readOnly = true) diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 2e8fad9b..423fc375 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -258,7 +258,7 @@ CREATE TABLE IF NOT EXISTS `useroptions` ( ); CREATE TABLE IF NOT EXISTS `users` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id` int(10) unsigned NOT NULL AUTO_INCREMENT(0), `nick` char(64) NOT NULL, `passw` char(32) NOT NULL, `lang` enum('en','ru','fr','fa','__') NOT NULL DEFAULT '__', diff --git a/src/main/resources/templates/views/thread.html b/src/main/resources/templates/views/thread.html index 47dfd000..90c9d4a0 100644 --- a/src/main/resources/templates/views/thread.html +++ b/src/main/resources/templates/views/thread.html @@ -99,7 +99,11 @@ {% if recomm is not empty %}
{{ i18n("messages","message.recommendedBy") }} {% for rec in recomm %} - @{{ rec }}{% if loop.index < (loop.length - 1) %}, {% endif %} + {% if rec.uri.toString() is empty %} + @{{ rec.name }}{% if loop.index < (loop.length - 1) %}, {% endif %} + {% else %} + @{{ rec.name }}{% if loop.index < (loop.length - 1) %}, {% endif %} + {% endif %} {% endfor %} {% if msg.likes > recomm.size() %}  {{ i18n("messages","message.recommendedOthers", msg.likes - recomm.size()) }} diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java index 5c421f07..c8f07d06 100644 --- a/src/test/java/com/juick/server/tests/ServerTests.java +++ b/src/test/java/com/juick/server/tests/ServerTests.java @@ -26,12 +26,12 @@ import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.css.StyleElement; import com.gargoylesoftware.htmlunit.html.DomElement; import com.gargoylesoftware.htmlunit.html.HtmlPage; -import com.github.jsonldjava.core.JsonLdOptions; -import com.github.jsonldjava.core.JsonLdProcessor; -import com.github.jsonldjava.utils.JsonUtils; import com.jayway.jsonpath.JsonPath; import com.juick.*; -import com.juick.model.*; +import com.juick.model.AnonymousUser; +import com.juick.model.CommandResult; +import com.juick.model.PrivateChats; +import com.juick.model.TagStats; import com.juick.server.*; import com.juick.server.api.activity.model.Context; import com.juick.server.api.activity.model.activities.*; @@ -104,7 +104,6 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.*; -import java.net.ConnectException; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; @@ -901,7 +900,7 @@ public class ServerTests { mockMvc.perform(get("/api/thread?mid=" + mid + "&hash=" + freefdHash)) .andExpect(status().isOk()) .andExpect(jsonPath("$[0].recommendations.length()", is(1))) - .andExpect(jsonPath("$[0].recommendations[0]", is(freefdName))); + .andExpect(jsonPath("$[0].recommendations[0].uname", is(freefdName))); mockMvc.perform(post("/api/like?mid=" + freefdMid + "&hash=" + freefdHash)) .andExpect(status().isForbidden()); } @@ -1354,11 +1353,18 @@ public class ServerTests { assertThat(messagesService.recommendMessage(mid, ermineId), is(MessagesService.RecommendStatus.Added)); assertThat(messagesService.recommendMessage(mid, fmapId), is(MessagesService.RecommendStatus.Added)); assertThat(messagesService.recommendMessage(mid, pogoId), is(MessagesService.RecommendStatus.Added)); - assertThat(messagesService.getMessage(mid).get().getLikes(), is(3)); - assertThat(CollectionUtils.isEqualCollection(messagesService.getMessageRecommendations(mid), Arrays.asList("fmap", "ermine", "pogo")), is(true)); - privacyQueriesService.blacklistUser(userService.getUserByName("monstreek"), userService.getUserByName("pogo")); - assertThat(messagesService.getMessage(mid).get().getLikes(), is(3)); - assertThat(CollectionUtils.isEqualCollection(messagesService.getMessageRecommendations(mid), Arrays.asList("fmap", "ermine")), is(true)); + jdbcTemplate.update("INSERT INTO favorites(user_id, user_uri, message_id, like_id, ts) " + + "values (0, 'http://example.com/u/test', ?, 1, now())", mid); + assertThat(messagesService.getMessage(mid).get().getLikes(), is(4)); + assertThat(CollectionUtils.isEqualCollection(messagesService.getMessageRecommendations(mid) + .stream().map(User::getName).collect(Collectors.toList()), + Arrays.asList("fmap", "ermine", "pogo", "Anonymous")), is(true)); + privacyQueriesService.blacklistUser(userService.getUserByName("monstreek"), + userService.getUserByName("pogo")); + assertThat(messagesService.getMessage(mid).get().getLikes(), is(4)); + assertThat(CollectionUtils.isEqualCollection(messagesService.getMessageRecommendations(mid) + .stream().map(User::getName).collect(Collectors.toList()), + Arrays.asList("fmap", "ermine", "Anonymous")), is(true)); } @Test public void bannedUserShouldNotBeVisibleToOthers() { @@ -1708,6 +1714,7 @@ public class ServerTests { replyNote.setTo(Collections.singletonList(activityPubManager.personUri(ugnich))); replyNote.setContent("HI"); Create create = new Create(); + create.setId(replyNote.getId()); create.setActor("http://localhost:8080/u/freefd"); create.setObject(replyNote); signatureManager.post((Person) signatureManager.getContext(URI.create("http://localhost:8080/u/freefd")).get(), diff --git a/src/test/resources/data.sql b/src/test/resources/data.sql index 102b11f4..aff3e286 100644 --- a/src/test/resources/data.sql +++ b/src/test/resources/data.sql @@ -1,3 +1,4 @@ +INSERT INTO users(id, nick, passw) VALUES(0, 'Anonymous', 'password'); INSERT INTO tags(tag_id, name) VALUES(2, 'juick'); INSERT INTO reactions (like_id, description) VALUES (1, 'like'); INSERT INTO reactions (like_id, description) VALUES (2, 'love'); -- cgit v1.2.3 From e1e416608c2ed864cb7d93fc582dd267aa5a0b5e Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Fri, 1 Mar 2019 10:08:00 +0300 Subject: ImageUtils catch IOException from apache-imaging --- src/main/java/com/juick/server/util/ImageUtils.java | 2 +- src/test/java/com/juick/server/tests/ServerTests.java | 9 +++++++++ src/test/resources/2936611-57.jpg | Bin 0 -> 101818 bytes 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/2936611-57.jpg (limited to 'src/test/resources') diff --git a/src/main/java/com/juick/server/util/ImageUtils.java b/src/main/java/com/juick/server/util/ImageUtils.java index d16faf8f..2f5d3292 100644 --- a/src/main/java/com/juick/server/util/ImageUtils.java +++ b/src/main/java/com/juick/server/util/ImageUtils.java @@ -108,7 +108,7 @@ public class ImageUtils { } } } - } catch (ImageReadException e) { + } catch (ImageReadException | IOException e) { // failed to read metadata. // nothing to do here, return image as is. } diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java index c8f07d06..a0d10988 100644 --- a/src/test/java/com/juick/server/tests/ServerTests.java +++ b/src/test/java/com/juick/server/tests/ServerTests.java @@ -215,6 +215,8 @@ public class ServerTests { private Resource hubzillaFollow; @Value("classpath:announce.json") private Resource noteWithDocument; + @Value("classpath:2936611-57.jpg") + private Resource jpegNoJfifTiff; @Inject private KeystoreManager testKeystoreManager; @@ -1177,6 +1179,13 @@ public class ServerTests { assertThat(postJpgiPhone.getNewMessage().get().getAttachment().getHeight(), is(1280)); assertThat(postJpgiPhone.getNewMessage().get().getAttachment().getMedium().getHeight(), is(1024)); assertThat(postJpgiPhone.getNewMessage().get().getAttachment().getSmall().getHeight(), is(512)); + CommandResult postNojfifTiff = commandsManager.processCommand(ugnich, "YO2", jpegNoJfifTiff.getURI()); + assertThat(postNojfifTiff.getNewMessage().isPresent(), is(true)); + int mid2 = postNojfifTiff.getNewMessage().get().getMid(); + File originalFile2 = Paths.get(imgDir, "p", String.format("%d.jpg", mid2)).toFile(); + assertThat(originalFile2.exists(), is(true)); + File mediumFile2 = Paths.get(imgDir, "photos-1024", String.format("%d.jpg", mid2)).toFile(); + assertThat(mediumFile2.exists(), is(true)); } @Test public void changeExtensionWhenReceiveFileWithWrongContentType() throws Exception { diff --git a/src/test/resources/2936611-57.jpg b/src/test/resources/2936611-57.jpg new file mode 100644 index 00000000..af4f9c91 Binary files /dev/null and b/src/test/resources/2936611-57.jpg differ -- cgit v1.2.3