aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/juick/www/api/Post.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/juick/www/api/Post.java')
-rw-r--r--src/main/java/com/juick/www/api/Post.java238
1 files changed, 238 insertions, 0 deletions
diff --git a/src/main/java/com/juick/www/api/Post.java b/src/main/java/com/juick/www/api/Post.java
new file mode 100644
index 00000000..3c1fbf6b
--- /dev/null
+++ b/src/main/java/com/juick/www/api/Post.java
@@ -0,0 +1,238 @@
+/*
+ * 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.www.api;
+
+import com.juick.model.Message;
+import com.juick.model.Reaction;
+import com.juick.model.Status;
+import com.juick.model.User;
+import com.juick.model.CommandResult;
+import com.juick.server.ActivityPubManager;
+import com.juick.server.CommandsManager;
+import com.juick.server.util.HttpBadRequestException;
+import com.juick.server.util.HttpForbiddenException;
+import com.juick.server.util.HttpNotFoundException;
+import com.juick.server.util.HttpUtils;
+import com.juick.service.MessagesService;
+import com.juick.service.UserService;
+import com.juick.service.activities.UpdateEvent;
+import com.juick.service.security.annotation.Visitor;
+import org.apache.commons.lang3.StringUtils;
+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.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.inject.Inject;
+import javax.validation.constraints.NotNull;
+import java.net.URI;
+import java.net.URL;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Created by vt on 24/11/2016.
+ */
+@RestController
+public class Post {
+ private final static Logger logger = LoggerFactory.getLogger("API");
+
+ @Inject
+ private UserService userService;
+ @Inject
+ private MessagesService messagesService;
+ @Value("${upload_tmp_dir:#{systemEnvironment['TEMP'] ?: '/tmp'}}")
+ private String tmpDir;
+ @Inject
+ CommandsManager commandsManager;
+ @Inject
+ ApplicationEventPublisher applicationEventPublisher;
+ @Inject
+ ActivityPubManager activityPubManager;
+
+ @RequestMapping(value = "/api/post", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ public CommandResult doPostMessage(
+ @Visitor User visitor,
+ @RequestParam(required = false, defaultValue = StringUtils.EMPTY) String body,
+ @RequestParam(required = false) String img,
+ @RequestParam(required = false) MultipartFile attach) throws Exception {
+ body = body.replace("\r", StringUtils.EMPTY);
+
+ URI attachmentFName = HttpUtils.receiveMultiPartFile(attach, tmpDir);
+
+ if (StringUtils.isBlank(attachmentFName.toString()) && img != null && img.length() > 10) {
+ URI juickUri = URI.create(img);
+ if (juickUri.getScheme().equals("juick")) {
+ attachmentFName = juickUri;
+ } else {
+ try {
+ URL imgUrl = new URL(img);
+ attachmentFName = HttpUtils.downloadImage(imgUrl, tmpDir);
+ } catch (Exception e) {
+ logger.error("DOWNLOAD ERROR", e);
+ throw new HttpBadRequestException();
+ }
+ }
+ }
+ if (StringUtils.isBlank(body) && StringUtils.isBlank(attachmentFName.toString())) {
+ // Should be there for compatibility
+ throw new HttpBadRequestException();
+ }
+ return commandsManager.processCommand(visitor, body, attachmentFName);
+ }
+
+ @RequestMapping(value = "/api/comment", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
+ public CommandResult doPostComment(
+ @Visitor User visitor,
+ @RequestParam(defaultValue = "0") int mid,
+ @RequestParam(defaultValue = "0") int rid,
+ @RequestParam(required = false, defaultValue = StringUtils.EMPTY) final String body,
+ @RequestParam(required = false) String img,
+ @RequestParam(required = false) MultipartFile attach)
+ throws Exception {
+ if (mid == 0) {
+ throw new HttpBadRequestException();
+ }
+ Optional<Message> message = messagesService.getMessage(mid);
+ if (message.isEmpty()) {
+ throw new HttpNotFoundException();
+ }
+
+ Message msg = message.get();
+
+ Message reply = null;
+ if (rid > 0) {
+ reply = messagesService.getReply(mid, rid);
+ if (reply == null) {
+ throw new HttpNotFoundException();
+ }
+ }
+
+ if ((msg.ReadOnly && msg.getUser().getUid() != visitor.getUid())
+ || userService.isInBLAny(msg.getUser().getUid(), visitor.getUid())
+ || (reply != null && userService.isInBLAny(reply.getUser().getUid(), visitor.getUid()))) {
+ // TODO: validator
+ throw new HttpForbiddenException();
+ }
+
+ URI attachmentFName = HttpUtils.receiveMultiPartFile(attach, tmpDir);
+
+ if (StringUtils.isBlank(attachmentFName.toString()) && img != null && img.length() > 10) {
+ try {
+ attachmentFName = HttpUtils.downloadImage(new URL(img), tmpDir);
+ } catch (Exception e) {
+ logger.error("DOWNLOAD ERROR", e);
+ throw new HttpBadRequestException();
+ }
+ }
+ if (StringUtils.isBlank(body) && StringUtils.isBlank(attachmentFName.toString())) {
+ // Should be there for compatibility
+ throw new HttpBadRequestException();
+ }
+ return commandsManager.processCommand(visitor, String.format("#%d/%d %s", mid, rid, body),
+ attachmentFName);
+ }
+
+ @PostMapping("/api/like")
+ @ResponseStatus(value = HttpStatus.OK)
+ public Status doPostRecomm(@Visitor User visitor, @RequestParam Integer mid) throws Exception {
+ Optional<Message> message = messagesService.getMessage(mid);
+ if (message.isEmpty()) {
+ throw new HttpNotFoundException();
+ }
+ Message msg = message.get();
+ if (msg.getUser().getUid() == visitor.getUid()) {
+ throw new HttpForbiddenException();
+ }
+ CommandResult status = commandsManager.processCommand(visitor, String.format("! #%d", mid),
+ URI.create(StringUtils.EMPTY));
+ return Status.getStatus(status.getText());
+ }
+
+ @PostMapping("/api/subscribe")
+ @ResponseStatus(value = HttpStatus.OK)
+ public Status doPostSubscribe(@Visitor User visitor,
+ @RequestParam Integer mid) throws Exception {
+ Optional<Message> message = messagesService.getMessage(mid);
+ if (message.isEmpty()) {
+ throw new HttpNotFoundException();
+ }
+ Message msg = message.get();
+ if (msg.getUser().getUid() == visitor.getUid()) {
+ throw new HttpForbiddenException();
+ }
+ CommandResult status = commandsManager.processCommand(visitor, String.format("S #%d", mid),
+ URI.create(StringUtils.EMPTY));
+ return Status.getStatus(status.getText());
+ }
+
+ @GetMapping("/api/reactions")
+ @ResponseStatus(value = HttpStatus.OK)
+ public List<Reaction> reactionsList() {
+ return messagesService.listReactions();
+ }
+
+ @PostMapping("/api/react")
+ @ResponseStatus(value = HttpStatus.OK)
+ public Status doPostReact(
+ @Visitor User visitor,
+ @RequestParam Integer mid, @RequestParam @NotNull int reactionId,
+ @RequestParam(required = false, defaultValue = "1") int count) {
+
+ logger.info("got reaction with type: {}", reactionId);
+ Optional<Message> message = messagesService.getMessage(mid);
+ if (message.isEmpty()) {
+ throw new HttpNotFoundException();
+ }
+ Message msg = message.get();
+ if (msg.getUser().getUid() == visitor.getUid()) {
+ throw new HttpForbiddenException();
+ }
+ MessagesService.RecommendStatus recommendStatus = MessagesService.RecommendStatus.Error;
+ for (int i = 0; i < count; i++)
+ recommendStatus = messagesService.likeMessage(mid, visitor.getUid(),
+ reactionId);
+
+ return recommendStatus == MessagesService.RecommendStatus.Error ? Status.ERROR :Status.OK;
+ }
+
+ @PostMapping("/api/update")
+ public CommandResult updateMessage(@Visitor User visitor,
+ @RequestParam Integer mid,
+ @RequestParam(required = false, defaultValue = "0") Integer rid,
+ @RequestParam String body) {
+ User author = rid == 0 ? messagesService.getMessageAuthor(mid) : messagesService.getReply(mid, rid).getUser();
+ if (visitor.equals(author)) {
+ if (messagesService.updateMessage(mid, rid, body)) {
+ Message result = rid == 0 ?
+ messagesService.getMessage(mid).orElseThrow(IllegalStateException::new)
+ : messagesService.getReply(mid, rid);
+ applicationEventPublisher.publishEvent(
+ new UpdateEvent(this, author, activityPubManager.messageUri(mid, rid)));
+ return CommandResult.build(result, "Message updated", StringUtils.EMPTY);
+ }
+ throw new HttpBadRequestException();
+ }
+ throw new HttpForbiddenException();
+ }
+}