From 7d75cabd9ea4c80348d5e98ac08347a204c60fc4 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Tue, 20 Jun 2017 09:41:28 +0300 Subject: mail wip --- juick-api/build.gradle | 2 + .../src/main/java/com/juick/api/ApiServer.java | 2 + .../api/configuration/ApiAppConfiguration.java | 9 +++ .../api/configuration/ApiMvcConfiguration.java | 6 -- .../main/java/com/juick/api/controllers/Post.java | 82 ++++++++++++++++++++++ .../main/java/com/juick/server/util/HttpUtils.java | 2 +- .../main/java/com/juick/service/UserService.java | 2 + .../java/com/juick/service/UserServiceImpl.java | 15 ++++ 8 files changed, 113 insertions(+), 7 deletions(-) diff --git a/juick-api/build.gradle b/juick-api/build.gradle index a1440240..bcf4bd25 100644 --- a/juick-api/build.gradle +++ b/juick-api/build.gradle @@ -15,6 +15,8 @@ dependencies { compile "org.springframework:spring-websocket:${rootProject.springFrameworkVersion}" compile 'com.github.pengrad:java-telegram-bot-api:3.0.1' + compile 'org.apache.commons:commons-email:1.4' + compile 'org.imgscalr:imgscalr-lib:4.2' providedRuntime 'mysql:mysql-connector-java:5.1.40' testCompile project(path: ':juick-server', configuration: 'testArtifacts') diff --git a/juick-api/src/main/java/com/juick/api/ApiServer.java b/juick-api/src/main/java/com/juick/api/ApiServer.java index 097dda58..b4a7be74 100644 --- a/juick-api/src/main/java/com/juick/api/ApiServer.java +++ b/juick-api/src/main/java/com/juick/api/ApiServer.java @@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Value; import rocks.xmpp.core.XmppException; import rocks.xmpp.core.session.Extension; import rocks.xmpp.core.session.XmppSessionConfiguration; +import rocks.xmpp.core.session.debug.LogbackDebugger; import rocks.xmpp.extensions.component.accept.ExternalComponent; import javax.annotation.PostConstruct; @@ -71,6 +72,7 @@ public class ApiServer implements AutoCloseable { public void setupXmppComponent(final String host, final int port, final String jid, final String password) { XmppSessionConfiguration configuration = XmppSessionConfiguration.builder() + .debugger(LogbackDebugger.class) .extensions(Extension.of(com.juick.Message.class)) .build(); setXmpp(ExternalComponent.create(jid, password, configuration, host, port)); diff --git a/juick-api/src/main/java/com/juick/api/configuration/ApiAppConfiguration.java b/juick-api/src/main/java/com/juick/api/configuration/ApiAppConfiguration.java index b6ba9282..cbf7d05c 100644 --- a/juick-api/src/main/java/com/juick/api/configuration/ApiAppConfiguration.java +++ b/juick-api/src/main/java/com/juick/api/configuration/ApiAppConfiguration.java @@ -1,9 +1,11 @@ package com.juick.api.configuration; +import com.juick.api.ApiServer; import com.juick.api.TGBot; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; +import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.web.socket.client.WebSocketConnectionManager; import org.springframework.web.socket.client.standard.StandardWebSocketClient; @@ -15,6 +17,7 @@ import javax.inject.Inject; */ @Configuration @EnableScheduling +@EnableAsync @PropertySource("classpath:juick.conf") public class ApiAppConfiguration { @Inject @@ -33,4 +36,10 @@ public class ApiAppConfiguration { public StandardWebSocketClient client() { return new StandardWebSocketClient(); } + + @Bean + public ApiServer apiServer() { + return new ApiServer(); + } + } diff --git a/juick-api/src/main/java/com/juick/api/configuration/ApiMvcConfiguration.java b/juick-api/src/main/java/com/juick/api/configuration/ApiMvcConfiguration.java index adff42a7..37c07434 100644 --- a/juick-api/src/main/java/com/juick/api/configuration/ApiMvcConfiguration.java +++ b/juick-api/src/main/java/com/juick/api/configuration/ApiMvcConfiguration.java @@ -2,7 +2,6 @@ package com.juick.api.configuration; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; -import com.juick.api.ApiServer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -23,11 +22,6 @@ import java.util.List; @ComponentScan(basePackages = {"com.juick.api.controllers"}) public class ApiMvcConfiguration extends WebMvcConfigurationSupport { - @Bean - public ApiServer apiServer() { - return new ApiServer(); - } - @Override public RequestMappingHandlerMapping requestMappingHandlerMapping() { RequestMappingHandlerMapping mapping = super.requestMappingHandlerMapping(); diff --git a/juick-api/src/main/java/com/juick/api/controllers/Post.java b/juick-api/src/main/java/com/juick/api/controllers/Post.java index 45eb31e7..cbd5ac0c 100644 --- a/juick-api/src/main/java/com/juick/api/controllers/Post.java +++ b/juick-api/src/main/java/com/juick/api/controllers/Post.java @@ -11,7 +11,10 @@ import com.juick.service.MessagesService; import com.juick.service.SubscriptionService; import com.juick.service.UserService; import com.juick.util.UserUtils; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.mail.util.MimeMessageParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; @@ -25,10 +28,21 @@ import rocks.xmpp.extensions.nick.model.Nickname; import rocks.xmpp.extensions.oob.model.x.OobX; import javax.inject.Inject; +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Properties; +import java.util.UUID; /** * Created by vt on 24/11/2016. @@ -193,4 +207,72 @@ public class Post { } return jmsg; } + + Session session = Session.getDefaultInstance(new Properties()); + + @PostMapping("/mail") + @ResponseStatus(value = HttpStatus.OK) + public void processMail(HttpServletRequest req) throws Exception { + String data = IOUtils.toString(req.getInputStream(), StandardCharsets.UTF_8); + logger.info("got data: {}", data); + MimeMessage msg = new MimeMessage(session, IOUtils.toInputStream(data, StandardCharsets.UTF_8)); + String from = msg.getFrom().length > 1 ? ((InternetAddress) msg.getSender()).getAddress() + : ((InternetAddress) msg.getFrom()[0]).getAddress(); + logger.info("got msg from {}", from); + 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 { + logger.info("got inputstream: {}", a.getInputStream()); + FileOutputStream fos = new FileOutputStream("/var/www/juick.com/i/tmp/" + attachmentFName[0]); + IOUtils.copy(a.getInputStream(), fos); + fos.close(); + } catch (IOException e) { + logger.info("attachment error: {}", e); + } + }); + 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!!")); + } + apiServer.getXmpp().sendMessage(xmsg); + } catch (URISyntaxException e1) { + logger.warn("attachment error", e1); + } + } else { + logger.info("not registered: {}", from); + } + } } diff --git a/juick-server/src/main/java/com/juick/server/util/HttpUtils.java b/juick-server/src/main/java/com/juick/server/util/HttpUtils.java index c305093c..31a68962 100644 --- a/juick-server/src/main/java/com/juick/server/util/HttpUtils.java +++ b/juick-server/src/main/java/com/juick/server/util/HttpUtils.java @@ -81,7 +81,7 @@ public class HttpUtils { throw new Exception("Wrong file type"); } - attachmentFName = UUID.randomUUID().toString() + "." + attachmentType; + attachmentFName = DigestUtils.md5Hex(UUID.randomUUID().toString()) + "." + attachmentType; fos = new FileOutputStream(Paths.get(tmpDir, attachmentFName).toString()); byte[] buffer = new byte[10240]; int len; diff --git a/juick-server/src/main/java/com/juick/service/UserService.java b/juick-server/src/main/java/com/juick/service/UserService.java index 661f386c..7f4bb1fe 100644 --- a/juick-server/src/main/java/com/juick/service/UserService.java +++ b/juick-server/src/main/java/com/juick/service/UserService.java @@ -30,6 +30,8 @@ public interface UserService { User getFullyUserByName(String username); + User getUserByEmail(String email); + List getFullyUsersByNames(Collection usernames); User getUserByJID(String jid); diff --git a/juick-server/src/main/java/com/juick/service/UserServiceImpl.java b/juick-server/src/main/java/com/juick/service/UserServiceImpl.java index 0b8ed13b..1fc72525 100644 --- a/juick-server/src/main/java/com/juick/service/UserServiceImpl.java +++ b/juick-server/src/main/java/com/juick/service/UserServiceImpl.java @@ -141,6 +141,21 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { return null; } + @Override + @Transactional(readOnly = true) + public User getUserByEmail(String email) { + if (StringUtils.isNotBlank(email)) { + List list = getJdbcTemplate().query( + "SELECT id, nick, banned, lang FROM users WHERE id = (SELECT user_id FROM emails WHERE email = ?)", + new UserMapper(), + email); + + if (!list.isEmpty()) + return list.get(0); + } + return AnonymousUser.INSTANCE; + } + @Transactional(readOnly = true) @Override public List getFullyUsersByNames(final Collection usernames) { -- cgit v1.2.3