From 70dd7231b9534b709f0c14317f63bed0c3a296ab Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Fri, 16 Mar 2018 16:26:21 +0300 Subject: server: process email only from service user --- .../src/main/java/com/juick/server/api/Post.java | 132 +++++++++++---------- .../java/com/juick/server/tests/ServerTests.java | 28 +++++ 2 files changed, 98 insertions(+), 62 deletions(-) diff --git a/juick-server/src/main/java/com/juick/server/api/Post.java b/juick-server/src/main/java/com/juick/server/api/Post.java index 72ca8439..4405c889 100644 --- a/juick-server/src/main/java/com/juick/server/api/Post.java +++ b/juick-server/src/main/java/com/juick/server/api/Post.java @@ -39,6 +39,7 @@ import rocks.xmpp.addr.Jid; import rocks.xmpp.core.stanza.model.Message; import rocks.xmpp.extensions.nick.model.Nickname; import rocks.xmpp.extensions.oob.model.x.OobX; +import springfox.documentation.annotations.ApiIgnore; import javax.inject.Inject; import javax.mail.Session; @@ -75,6 +76,8 @@ public class Post { private String tmpDir; @Value("${img_path:#{systemEnvironment['TEMP'] ?: '/tmp'}}") private String imgDir; + @Value("${api_user:juick}") + private String serviceUser; @RequestMapping(value = "/post", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) @ResponseStatus(value = HttpStatus.OK) @@ -207,77 +210,82 @@ public class Post { Session session = Session.getDefaultInstance(new Properties()); + @ApiIgnore @PostMapping("/mail") @ResponseStatus(value = HttpStatus.OK) public void processMail(InputStream data) throws Exception { - MimeMessage msg = new MimeMessage(session, data); - logger.info("got msg {}", msg.toString()); - String from = msg.getFrom() == null || msg.getFrom().length > 1 ? ((InternetAddress) msg.getSender()).getAddress() - : ((InternetAddress) msg.getFrom()[0]).getAddress(); + if (UserUtils.getCurrentUser().getName().equals(serviceUser)) { + MimeMessage msg = new MimeMessage(session, data); + logger.info("got msg {}", msg.toString()); + String from = msg.getFrom() == null || msg.getFrom().length > 1 ? ((InternetAddress) msg.getSender()).getAddress() + : ((InternetAddress) msg.getFrom()[0]).getAddress(); - User visitor = userService.getUserByEmail(from); - if (!visitor.isAnonymous()) { - MimeMessageParser parser = new MimeMessageParser(msg); - parser.parse(); - final String[] body = {parser.getPlainContent()}; - if (body[0] == null) { - parser.getAttachmentList().stream() - .filter(a -> a.getContentType().equals("text/plain")).findFirst() - .ifPresent(a -> { - try { - body[0] = IOUtils.toString(a.getInputStream(), StandardCharsets.UTF_8); - logger.info("got text: {}", body[0]); - } catch (IOException e) { - logger.info("attachment error: {}", e); - } - }); - } - final String[] attachmentFName = new String[1]; - parser.getAttachmentList().stream().filter(a -> - a.getContentType().equals("image/jpeg") || a.getContentType().equals("image/png")) - .findFirst().ifPresent(a -> { - logger.info("got attachment: {}", a.getContentType()); - String attachmentType; - if (a.getContentType().equals("image/jpeg")) { - attachmentType = "jpg"; - } else { - attachmentType = "png"; + User visitor = userService.getUserByEmail(from); + if (!visitor.isAnonymous()) { + MimeMessageParser parser = new MimeMessageParser(msg); + parser.parse(); + final String[] body = {parser.getPlainContent()}; + if (body[0] == null) { + parser.getAttachmentList().stream() + .filter(a -> a.getContentType().equals("text/plain")).findFirst() + .ifPresent(a -> { + try { + body[0] = IOUtils.toString(a.getInputStream(), StandardCharsets.UTF_8); + logger.info("got text: {}", body[0]); + } catch (IOException e) { + logger.info("attachment error: {}", e); + } + }); } - attachmentFName[0] = DigestUtils.md5Hex(UUID.randomUUID().toString()) + "." + attachmentType; - try { - logger.info("got inputstream: {}", a.getInputStream()); - FileOutputStream fos = new FileOutputStream(Paths.get(tmpDir, attachmentFName[0]).toString()); - IOUtils.copy(a.getInputStream(), fos); - fos.close(); - } catch (IOException e) { - logger.info("attachment error: {}", e); + final String[] attachmentFName = new String[1]; + parser.getAttachmentList().stream().filter(a -> + a.getContentType().equals("image/jpeg") || a.getContentType().equals("image/png")) + .findFirst().ifPresent(a -> { + logger.info("got attachment: {}", a.getContentType()); + String attachmentType; + if (a.getContentType().equals("image/jpeg")) { + attachmentType = "jpg"; + } else { + attachmentType = "png"; + } + attachmentFName[0] = DigestUtils.md5Hex(UUID.randomUUID().toString()) + "." + attachmentType; + try { + logger.info("got inputstream: {}", a.getInputStream()); + FileOutputStream fos = new FileOutputStream(Paths.get(tmpDir, attachmentFName[0]).toString()); + IOUtils.copy(a.getInputStream(), fos); + fos.close(); + } catch (IOException e) { + logger.info("attachment error: {}", e); + } + }); + String[] inReplyToHeaders = msg.getHeader("In-Reply-To"); + if (inReplyToHeaders != null && inReplyToHeaders.length > 0) { + Scanner inReplyToScanner = new Scanner(inReplyToHeaders[0].trim()).useDelimiter(EmailManager.MSGID_PATTERN); + int mid = Integer.parseInt(inReplyToScanner.next()); + int rid = Integer.parseInt(inReplyToScanner.next()); + logger.info("Message is reply to #{}/{}", mid, rid); + body[0] = rid > 0 ? String.format("#%d/%d %s", mid, rid, body[0]) + : String.format("#%d %s", mid, body[0]); } - }); - String[] inReplyToHeaders = msg.getHeader("In-Reply-To"); - if (inReplyToHeaders != null && inReplyToHeaders.length > 0) { - Scanner inReplyToScanner = new Scanner(inReplyToHeaders[0].trim()).useDelimiter(EmailManager.MSGID_PATTERN); - int mid = Integer.parseInt(inReplyToScanner.next()); - int rid = Integer.parseInt(inReplyToScanner.next()); - logger.info("Message is reply to #{}/{}", mid, rid); - body[0] = rid > 0 ? String.format("#%d/%d %s", mid, rid, body[0]) - : String.format("#%d %s", mid, body[0]); - } - rocks.xmpp.core.stanza.model.Message xmsg = new rocks.xmpp.core.stanza.model.Message(); - xmsg.setType(rocks.xmpp.core.stanza.model.Message.Type.CHAT); - xmsg.setFrom(Jid.of(String.valueOf(visitor.getUid()), "uid.juick.com", "mail")); - xmsg.setTo(Jid.of("juick@juick.com/Juick")); - xmsg.setBody(body[0]); - try { - if (StringUtils.isNotEmpty(attachmentFName[0])) { - String attachmentUrl = String.format("juick://%s", attachmentFName[0]); - xmsg.addExtension(new OobX(new URI(attachmentUrl), "!!!!Juick!!")); + rocks.xmpp.core.stanza.model.Message xmsg = new rocks.xmpp.core.stanza.model.Message(); + xmsg.setType(rocks.xmpp.core.stanza.model.Message.Type.CHAT); + xmsg.setFrom(Jid.of(String.valueOf(visitor.getUid()), "uid.juick.com", "mail")); + xmsg.setTo(Jid.of("juick@juick.com/Juick")); + xmsg.setBody(body[0]); + try { + if (StringUtils.isNotEmpty(attachmentFName[0])) { + String attachmentUrl = String.format("juick://%s", attachmentFName[0]); + xmsg.addExtension(new OobX(new URI(attachmentUrl), "!!!!Juick!!")); + } + serverManager.sendMessage(xmsg); + } catch (URISyntaxException e1) { + logger.warn("attachment error", e1); } - serverManager.sendMessage(xmsg); - } catch (URISyntaxException e1) { - logger.warn("attachment error", e1); + } else { + logger.info("not registered: {}", from); } } else { - logger.info("not registered: {}", from); + throw new HttpForbiddenException(); } } } diff --git a/juick-server/src/test/java/com/juick/server/tests/ServerTests.java b/juick-server/src/test/java/com/juick/server/tests/ServerTests.java index 7d25a8ae..99453f32 100644 --- a/juick-server/src/test/java/com/juick/server/tests/ServerTests.java +++ b/juick-server/src/test/java/com/juick/server/tests/ServerTests.java @@ -455,4 +455,32 @@ public class ServerTests extends AbstractJUnit4SpringContextTests { assertEquals("should not have messages", 0, messagesService.getAll(user.getUid(), 0).size()); */ } + @Test + public void mailParserTest() throws Exception { + String mail = "MIME-Version: 1.0\n" + + "Received: by 10.176.0.242 with HTTP; Fri, 16 Mar 2018 05:31:50 -0700 (PDT)\n" + + "In-Reply-To: <2891710.100@juick.com>\n" + + "References: <2891710.0@juick.com> <2891710.100@juick.com>\n" + + "Date: Fri, 16 Mar 2018 15:31:50 +0300\n" + + "Delivered-To: vitalyster@gmail.com\n" + + "Message-ID: \n" + + "Subject: Re: New reply to TJ\n" + + "From: Vitaly Takmazov \n" + + "To: Juick \n" + + "Content-Type: multipart/alternative; boundary=\"001a11454886e42be5056786ca70\"\n" + + "\n" + + "--001a11454886e42be5056786ca70\n" + + "Content-Type: text/plain; charset=\"UTF-8\"\n" + + "\n" + + "s2313334\n" + + "\n" + + "--001a11454886e42be5056786ca70\n" + + "Content-Type: text/html; charset=\"UTF-8\"\n" + + "\n" + + "
s2313334
\n" + + "\n" + + "--001a11454886e42be5056786ca70--"; + mockMvc.perform(post("/mail").with(httpBasic(juickName, juickPassword)).content(mail)) + .andExpect(status().isOk()); + } } -- cgit v1.2.3