aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/juick/server/api/Service.java
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2020-04-03 23:53:23 +0300
committerGravatar Vitaly Takmazov2020-04-03 23:53:23 +0300
commit7a2f89266c8f6337e4e81a2fd8488e0f80f4f9bd (patch)
tree3b83cf2edb18b224e6e0b7924624310d68acc93a /src/main/java/com/juick/server/api/Service.java
parent1b93e5b16ee5bc7253f3b06639fb9e9abb46acd0 (diff)
Reorganize layout and code cleanup
Diffstat (limited to 'src/main/java/com/juick/server/api/Service.java')
-rw-r--r--src/main/java/com/juick/server/api/Service.java223
1 files changed, 0 insertions, 223 deletions
diff --git a/src/main/java/com/juick/server/api/Service.java b/src/main/java/com/juick/server/api/Service.java
deleted file mode 100644
index d056d9b0..00000000
--- a/src/main/java/com/juick/server/api/Service.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2008-2019, Juick
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package com.juick.server.api;
-
-import com.juick.model.Message;
-import com.juick.model.User;
-import com.juick.model.CommandResult;
-import com.juick.server.CommandsManager;
-import com.juick.server.EmailManager;
-import com.juick.server.ServerManager;
-import com.juick.server.util.HttpBadRequestException;
-import com.juick.server.util.HttpForbiddenException;
-import com.juick.service.EmailService;
-import com.juick.service.MessagesService;
-import com.juick.service.UserService;
-import com.juick.service.component.AccountVerificationEvent;
-import com.juick.service.security.annotation.Visitor;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.mail.util.MimeMessageParser;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.http.HttpStatus;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.ResponseStatus;
-import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
-import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
-import springfox.documentation.annotations.ApiIgnore;
-
-import javax.inject.Inject;
-import javax.mail.Session;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Paths;
-import java.util.*;
-
-@Controller
-public class Service {
- private static Logger logger = LoggerFactory.getLogger("Session");
- @Inject
- private UserService userService;
- @Inject
- private EmailService emailService;
- @Inject
- private MessagesService messagesService;
- @Inject
- private CommandsManager commandsManager;
- @Inject
- private ApplicationEventPublisher applicationEventPublisher;
- @Value("${api_user:juick}")
- private String serviceUser;
- @Value("${upload_tmp_dir:#{systemEnvironment['TEMP'] ?: '/tmp'}}")
- private String tmpDir;
- @Value("${banned_emails:}")
- private String[] ignoredEmails;
- @Inject
- private ServerManager serverManager;
-
- private Session session = Session.getDefaultInstance(new Properties());
-
- @ApiIgnore
- @PostMapping("/api/mail")
- @ResponseStatus(value = HttpStatus.OK)
- public void processMail(@Visitor User current, InputStream data) throws Exception {
- if (current.getName().equals(serviceUser)) {
- MimeMessage msg = new MimeMessage(session, data);
- String[] returnPaths = msg.getHeader("Return-Path");
- if (returnPaths != null) {
- logger.info("got msg with return path {}", returnPaths[0]);
- if (returnPaths[0].equals("<>")) {
- return;
- }
- }
- 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";
- }
- 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) {
- 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]);
- }
- 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));
- }
- }
- } else {
- throw new HttpForbiddenException();
- }
- }
- @ApiIgnore
- @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()
- : ((InternetAddress) msg.getFrom()[0]).getAddress();
-
- User visitor = userService.getUserByEmail(from);
- if (!visitor.isAnonymous()) {
- if (!emailService.disableEmail(visitor, from)) {
- throw new HttpBadRequestException();
- }
- }
- } else {
- throw new HttpForbiddenException();
- }
- }
- private void endSession(SseEmitter 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) throws IOException {
- logger.info("{} connected", visitor.getName());
- if (!visitor.isAnonymous()) {
- userService.updateLastSeen(visitor);
- }
- SseEmitter emitter = new SseEmitter(600000L);
- serverManager.getSessions().add(new ServerManager.EventSession(visitor, emitter));
-
- emitter.onCompletion(() -> endSession(emitter));
- emitter.onTimeout(() -> endSession(emitter));
-
- return emitter;
- }
- @ExceptionHandler(AsyncRequestTimeoutException.class)
- public void eventErrorHandler(Exception ex) {
- logger.debug("SSE timeout", ex);
- }
-}