aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2021-03-24 20:22:07 +0300
committerGravatar Vitaly Takmazov2021-03-24 20:22:07 +0300
commitea50fabc95fe0d2a6ac517f3c61bfba6c220e018 (patch)
treefff9766ef294ed64ff0fa18022e2631d10740108 /src/main
parent44411d8ecea4e8676dd2d4d0237c9cd4fd2ec981 (diff)
Service: handle invalid from headers in emails
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/juick/www/api/Service.java157
1 files changed, 86 insertions, 71 deletions
diff --git a/src/main/java/com/juick/www/api/Service.java b/src/main/java/com/juick/www/api/Service.java
index c3ce1242..3844d003 100644
--- a/src/main/java/com/juick/www/api/Service.java
+++ b/src/main/java/com/juick/www/api/Service.java
@@ -51,6 +51,7 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import javax.inject.Inject;
import javax.mail.Session;
+import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.FileOutputStream;
@@ -98,96 +99,108 @@ public class Service {
return;
}
}
- if (msg.getFrom() == null || msg.getFrom().length == 0) {
- logger.info("Missing from/sender headers");
- return;
- }
- String from = ((InternetAddress) msg.getFrom()[0]).getAddress();
+ try {
+ var messageAddresses = msg.getFrom();
+ if (messageAddresses == null || messageAddresses.length == 0) {
+ logger.info("Missing from/sender headers");
+ return;
+ }
+ String from = ((InternetAddress) messageAddresses[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 -> {
+ 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";
+ }
+ attachmentFName[0] = DigestUtils.md5Hex(UUID.randomUUID().toString()) + "."
+ + attachmentType;
try {
- body[0] = IOUtils.toString(a.getInputStream(), StandardCharsets.UTF_8);
- logger.info("got text: {}", body[0]);
+ 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";
+ String[] inReplyToHeaders = msg.getHeader("In-Reply-To");
+ if (inReplyToHeaders != null && inReplyToHeaders.length > 0) {
+ int mid, rid;
+ var originalMessage = messagesService.findMessageByProperty("messageId", inReplyToHeaders[0]);
+ if (originalMessage.isPresent()) {
+ mid = originalMessage.get().getLeft();
+ rid = originalMessage.get().getRight();
+ } else {
+ Scanner inReplyToScanner = new Scanner(inReplyToHeaders[0].trim())
+ .useDelimiter(EmailManager.MSGID_PATTERN);
+ mid = Integer.parseInt(inReplyToScanner.next());
+ 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]);
}
- 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);
+ URI attachmentUri = StringUtils.isNotEmpty(attachmentFName[0])
+ ? URI.create(String.format("juick://%s", attachmentFName[0]))
+ : URI.create(StringUtils.EMPTY);
+ CommandResult result = commandsManager.processCommand(visitor, body[0], attachmentUri);
+ if (result.getNewMessage().isPresent()) {
+ String[] messageIds = msg.getHeader("Message-Id");
+ if (messageIds.length == 1) {
+ Message message = result.getNewMessage().get();
+ messagesService.setMessageProperty(message.getMid(), message.getRid(), "messageId",
+ messageIds[0]);
+ } else {
+ logger.warn("Wrong number of Message-Id headers");
+ }
}
- });
- String[] inReplyToHeaders = msg.getHeader("In-Reply-To");
- if (inReplyToHeaders != null && inReplyToHeaders.length > 0) {
- int mid, rid;
- var originalMessage = messagesService.findMessageByProperty("messageId", inReplyToHeaders[0]);
- if (originalMessage.isPresent()) {
- mid = originalMessage.get().getLeft();
- rid = originalMessage.get().getRight();
- } else {
- Scanner inReplyToScanner = new Scanner(inReplyToHeaders[0].trim()).useDelimiter(EmailManager.MSGID_PATTERN);
- mid = Integer.parseInt(inReplyToScanner.next());
- rid = Integer.parseInt(inReplyToScanner.next());
+ } else {
+ if (!Arrays.asList(ignoredEmails).contains(from)) {
+ String verificationCode = RandomStringUtils.randomAlphanumeric(8).toUpperCase();
+ emailService.addVerificationCode(null, from, verificationCode);
+ applicationEventPublisher
+ .publishEvent(new AccountVerificationEvent(this, from, verificationCode));
}
- 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]);
- }
- URI attachmentUri = StringUtils.isNotEmpty(attachmentFName[0]) ? URI.create(String.format("juick://%s", attachmentFName[0]))
- : URI.create(StringUtils.EMPTY);
- CommandResult result = commandsManager.processCommand(visitor, body[0], attachmentUri);
- if (result.getNewMessage().isPresent()) {
- String[] messageIds = msg.getHeader("Message-Id");
- if (messageIds.length == 1) {
- Message message = result.getNewMessage().get();
- messagesService.setMessageProperty(message.getMid(), message.getRid(), "messageId", messageIds[0]);
- } else {
- logger.warn("Wrong number of Message-Id headers");
- }
- }
- } else {
- if (!Arrays.asList(ignoredEmails).contains(from)) {
- String verificationCode = RandomStringUtils.randomAlphanumeric(8).toUpperCase();
- emailService.addVerificationCode(null, from, verificationCode);
- applicationEventPublisher.publishEvent(new AccountVerificationEvent(this, from, verificationCode));
}
+ } catch (AddressException e) {
+ logger.info("Got email with invalid from address");
}
} else {
throw new HttpForbiddenException();
}
}
+
@Hidden
@PostMapping("/api/mail/unsubscribe")
@ResponseStatus(value = HttpStatus.OK)
public void processMailUnsubscribe(@Visitor User current, InputStream data) throws Exception {
if (current.getName().equals(serviceUser)) {
MimeMessage msg = new MimeMessage(session, data);
- String from = msg.getFrom() == null || msg.getFrom().length > 1 ? ((InternetAddress) msg.getSender()).getAddress()
+ String from = msg.getFrom() == null || msg.getFrom().length > 1
+ ? ((InternetAddress) msg.getSender()).getAddress()
: ((InternetAddress) msg.getFrom()[0]).getAddress();
User visitor = userService.getUserByEmail(from);
@@ -200,11 +213,12 @@ public class Service {
throw new HttpForbiddenException();
}
}
+
private void endSession(SseEmitter emitter) {
- serverManager.getSessions().stream()
- .filter(s -> s.getEmitter().equals(emitter))
+ serverManager.getSessions().stream().filter(s -> s.getEmitter().equals(emitter))
.forEach(session -> serverManager.getSessions().remove(session));
}
+
@GetMapping("/api/events")
public SseEmitter handle(@Visitor User visitor) {
logger.info("{} connected", visitor.getName());
@@ -219,6 +233,7 @@ public class Service {
return emitter;
}
+
@ExceptionHandler(AsyncRequestTimeoutException.class)
public void eventErrorHandler(Exception ex) {
logger.debug("SSE timeout", ex);