diff --git a/src/main/java/run/halo/app/model/params/CommentParam.java b/src/main/java/run/halo/app/model/params/CommentParam.java index 56039821690daa30d5c1f64e69bc5f28c97b61b9..7731d9450bc8c2ff742ec31e41044793c616836e 100644 --- a/src/main/java/run/halo/app/model/params/CommentParam.java +++ b/src/main/java/run/halo/app/model/params/CommentParam.java @@ -1,5 +1,6 @@ package run.halo.app.model.params; +import org.hibernate.validator.constraints.URL; import run.halo.app.model.dto.base.InputConverter; import run.halo.app.model.entity.Comment; import lombok.Data; diff --git a/src/main/java/run/halo/app/service/CommentService.java b/src/main/java/run/halo/app/service/CommentService.java index 21e787d72e797175d8df1e44ae6ec71bb5c57399..a9157176a55e0bec2bed64bdcd1e7033f4b9d61f 100644 --- a/src/main/java/run/halo/app/service/CommentService.java +++ b/src/main/java/run/halo/app/service/CommentService.java @@ -1,18 +1,18 @@ package run.halo.app.service; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; import run.halo.app.model.entity.Comment; import run.halo.app.model.enums.CommentStatus; +import run.halo.app.model.params.CommentParam; import run.halo.app.model.params.CommentQuery; +import run.halo.app.model.vo.CommentVO; import run.halo.app.model.vo.CommentWithParentVO; import run.halo.app.model.vo.CommentWithPostVO; -import run.halo.app.model.vo.CommentVO; import run.halo.app.service.base.CrudService; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import javax.servlet.http.HttpServletRequest; import java.util.Collection; import java.util.List; import java.util.Map; @@ -54,7 +54,7 @@ public interface CommentService extends CrudService { * Pages comments. * * @param commentQuery comment query must not be null - * @param pageable page info must not be null + * @param pageable page info must not be null * @return a page of comment */ @NonNull @@ -81,12 +81,11 @@ public interface CommentService extends CrudService { /** * Creates a comment by comment param. * - * @param comment comment must not be null - * @param request http servlet request must not be null + * @param commentParam comment param must not be null * @return created comment */ @NonNull - Comment createBy(@NonNull Comment comment, @NonNull HttpServletRequest request); + Comment createBy(@NonNull CommentParam commentParam); /** * Lists comment vos by post id. diff --git a/src/main/java/run/halo/app/service/impl/CommentServiceImpl.java b/src/main/java/run/halo/app/service/impl/CommentServiceImpl.java index 2562db02414e4f510fb2173e3a43868069fd4cb5..a88b59f016f6b0d2d5f5c00049c2adb76070a446 100644 --- a/src/main/java/run/halo/app/service/impl/CommentServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/CommentServiceImpl.java @@ -1,9 +1,7 @@ package run.halo.app.service.impl; -import cn.hutool.core.util.URLUtil; -import cn.hutool.crypto.SecureUtil; -import cn.hutool.extra.servlet.ServletUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.domain.*; @@ -19,12 +17,16 @@ import org.springframework.web.util.HtmlUtils; import run.halo.app.event.comment.CommentNewEvent; import run.halo.app.event.comment.CommentPassEvent; import run.halo.app.event.comment.CommentReplyEvent; +import run.halo.app.exception.NotFoundException; import run.halo.app.model.dto.post.PostMinimalOutputDTO; import run.halo.app.model.entity.Comment; import run.halo.app.model.entity.Post; +import run.halo.app.model.entity.User; import run.halo.app.model.enums.CommentStatus; +import run.halo.app.model.params.CommentParam; import run.halo.app.model.params.CommentQuery; import run.halo.app.model.projection.CommentCountProjection; +import run.halo.app.model.properties.BlogProperties; import run.halo.app.model.properties.CommentProperties; import run.halo.app.model.support.CommentPage; import run.halo.app.model.vo.CommentVO; @@ -37,11 +39,11 @@ import run.halo.app.security.context.SecurityContextHolder; import run.halo.app.service.CommentService; import run.halo.app.service.OptionService; import run.halo.app.service.base.AbstractCrudService; -import run.halo.app.utils.OwoUtil; import run.halo.app.utils.ServiceUtils; +import run.halo.app.utils.ServletUtils; +import run.halo.app.utils.ValidationUtils; import javax.persistence.criteria.Predicate; -import javax.servlet.http.HttpServletRequest; import java.util.*; import java.util.stream.Collectors; @@ -149,53 +151,65 @@ public class CommentServiceImpl extends AbstractCrudService imple } @Override - public Comment createBy(Comment comment, HttpServletRequest request) { - Assert.notNull(comment, "Comment must not be null"); - Assert.notNull(request, "Http servlet request must not be null"); - - // Set some default value - comment.setContent(OwoUtil.parseOwo(formatContent(comment.getContent()))); - comment.setIpAddress(ServletUtil.getClientIP(request)); - comment.setUserAgent(ServletUtil.getHeaderIgnoreCase(request, HttpHeaders.USER_AGENT)); - + public Comment createBy(CommentParam commentParam) { + Assert.notNull(commentParam, "Comment param must not be null"); // Check user login status and set this field Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication != null) { + User user = authentication.getDetail().getUser(); + commentParam.setAuthor(StringUtils.isEmpty(user.getNickname()) ? user.getUsername() : user.getNickname()); + commentParam.setEmail(user.getEmail()); + commentParam.setAuthorUrl(optionService.getByPropertyOfNullable(BlogProperties.BLOG_URL)); + } + + // Validate the comment param manually + ValidationUtils.validate(commentParam); + + // Check post id + boolean isPostExist = postRepository.existsById(commentParam.getPostId()); + if (!isPostExist) { + throw new NotFoundException("The post with id " + commentParam.getPostId() + " was not found"); + } + + // Check parent id + if (!ServiceUtils.isEmptyId(commentParam.getParentId())) { + mustExistById(commentParam.getParentId()); + } + + // Convert to comment + Comment comment = commentParam.convertTo(); + + // Set some default values + comment.setIpAddress(ServletUtils.getRequestIp()); + comment.setUserAgent(ServletUtils.getHeaderIgnoreCase(HttpHeaders.USER_AGENT)); + comment.setGavatarMd5(DigestUtils.md5Hex(comment.getEmail())); + if (authentication != null) { - // If the user is login + // Comment of blogger comment.setIsAdmin(true); comment.setStatus(CommentStatus.PUBLISHED); } else { + // Comment of guest // Handle comment status Boolean needAudit = optionService.getByPropertyOrDefault(CommentProperties.NEW_NEED_CHECK, Boolean.class, true); - if (needAudit) { - comment.setStatus(CommentStatus.AUDITING); - } else { - comment.setStatus(CommentStatus.PUBLISHED); - } - } - - comment.setAuthor(HtmlUtils.htmlEscape(comment.getAuthor())); - comment.setGavatarMd5(SecureUtil.md5(comment.getEmail())); - - if (StringUtils.isNotBlank(comment.getAuthorUrl())) { - // Normalize the author url and set it - comment.setAuthorUrl(URLUtil.normalize(comment.getAuthorUrl())); + comment.setStatus(needAudit ? CommentStatus.AUDITING : CommentStatus.PUBLISHED); } + // Create comment Comment createdComment = create(comment); - // TODO Handle email sending - - if (createdComment.getParentId() == null || createdComment.getParentId() == 0) { - // New comment - eventPublisher.publishEvent(new CommentNewEvent(this, createdComment.getId())); + if (ServiceUtils.isEmptyId(createdComment.getParentId())) { + if (authentication == null) { + // New comment of guest + eventPublisher.publishEvent(new CommentNewEvent(this, createdComment.getId())); + } } else { // Reply comment eventPublisher.publishEvent(new CommentReplyEvent(this, createdComment.getId())); } - return createdComment; } diff --git a/src/main/java/run/halo/app/utils/ServiceUtils.java b/src/main/java/run/halo/app/utils/ServiceUtils.java index cb17645e4a8a7d8c4038c6c6ae21fd5812d08bdf..26ec3cae8b069bc222153c185f7ec2a05bb8e7d8 100644 --- a/src/main/java/run/halo/app/utils/ServiceUtils.java +++ b/src/main/java/run/halo/app/utils/ServiceUtils.java @@ -1,5 +1,6 @@ package run.halo.app.utils; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -105,4 +106,14 @@ public class ServiceUtils { return resultMap; } + + /** + * Checks if the given number id is empty id. + * + * @param id the given number id + * @return true if the given number id is empty id; false otherwise + */ + public static boolean isEmptyId(@Nullable Number id) { + return id == null || id.longValue() <= 0; + } } diff --git a/src/main/java/run/halo/app/utils/ServletUtils.java b/src/main/java/run/halo/app/utils/ServletUtils.java index bc5c860676e2f1927ba7ee6cdc6b56a290d59b49..9329f3032b1cb09335e09ac83c68ea3bef5b6ec7 100644 --- a/src/main/java/run/halo/app/utils/ServletUtils.java +++ b/src/main/java/run/halo/app/utils/ServletUtils.java @@ -43,4 +43,15 @@ public class ServletUtils { return getCurrentRequest().map(ServletUtil::getClientIP).orElse(null); } + /** + * Gets request header. + * + * @param header http header name + * @return http header of null + */ + @Nullable + public static String getHeaderIgnoreCase(String header) { + return getCurrentRequest().map(request -> ServletUtil.getHeaderIgnoreCase(request, header)).orElse(null); + } + } diff --git a/src/main/java/run/halo/app/web/controller/admin/api/CommentController.java b/src/main/java/run/halo/app/web/controller/admin/api/CommentController.java index 202c77bc680db25d85714b9ab22cf3a4d9864936..b110847f6daf126e5b751a3c6406e172a92ce40f 100644 --- a/src/main/java/run/halo/app/web/controller/admin/api/CommentController.java +++ b/src/main/java/run/halo/app/web/controller/admin/api/CommentController.java @@ -1,25 +1,18 @@ package run.halo.app.web.controller.admin.api; import io.swagger.annotations.ApiOperation; -import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; import org.springframework.web.bind.annotation.*; import run.halo.app.model.dto.CommentDTO; import run.halo.app.model.entity.Comment; -import run.halo.app.model.entity.User; import run.halo.app.model.enums.CommentStatus; import run.halo.app.model.params.CommentParam; import run.halo.app.model.params.CommentQuery; -import run.halo.app.model.properties.BlogProperties; import run.halo.app.model.vo.CommentWithPostVO; import run.halo.app.service.CommentService; -import run.halo.app.service.OptionService; -import run.halo.app.service.PostService; -import run.halo.app.utils.ValidationUtils; -import javax.servlet.http.HttpServletRequest; import java.util.List; import static org.springframework.data.domain.Sort.Direction.DESC; @@ -36,16 +29,8 @@ public class CommentController { private final CommentService commentService; - private final PostService postService; - - private final OptionService optionService; - - public CommentController(CommentService commentService, - PostService postService, - OptionService optionService) { + public CommentController(CommentService commentService) { this.commentService = commentService; - this.postService = postService; - this.optionService = optionService; } @GetMapping @@ -68,24 +53,9 @@ public class CommentController { } @PostMapping - public CommentDTO createBy(@RequestBody CommentParam commentParam, HttpServletRequest request, User user) { - // Set some default info - commentParam.setAuthor(StringUtils.isEmpty(user.getNickname()) ? user.getUsername() : user.getNickname()); - commentParam.setEmail(user.getEmail()); - commentParam.setAuthorUrl(optionService.getByPropertyOfNullable(BlogProperties.BLOG_URL)); - - // Validate the comment param manually - ValidationUtils.validate(commentParam); - - // Check post id - postService.mustExistById(commentParam.getPostId()); - - // Check parent id - if (commentParam.getParentId() != null && commentParam.getParentId() > 0) { - commentService.mustExistById(commentParam.getParentId()); - } - - return new CommentDTO().convertFrom(commentService.createBy(commentParam.convertTo(), request)); + @ApiOperation("Creates a comment (new or reply)") + public CommentDTO createBy(@RequestBody CommentParam commentParam) { + return new CommentDTO().convertFrom(commentService.createBy(commentParam)); } @PutMapping("{commentId:\\d+}/status/{status}") diff --git a/src/main/java/run/halo/app/web/controller/content/api/CommentController.java b/src/main/java/run/halo/app/web/controller/content/api/CommentController.java index d331eeafef7809c7cfa713507b12f0b0bfbac8fa..f9d8411880768be0feaf3c5a5c7ec1f7aa4ab43b 100644 --- a/src/main/java/run/halo/app/web/controller/content/api/CommentController.java +++ b/src/main/java/run/halo/app/web/controller/content/api/CommentController.java @@ -1,23 +1,13 @@ package run.halo.app.web.controller.content.api; import io.swagger.annotations.ApiOperation; -import run.halo.app.model.dto.CommentDTO; -import run.halo.app.model.entity.User; -import run.halo.app.model.params.CommentParam; -import run.halo.app.model.properties.BlogProperties; -import run.halo.app.security.authentication.Authentication; -import run.halo.app.security.context.SecurityContextHolder; -import run.halo.app.service.CommentService; -import run.halo.app.service.OptionService; -import run.halo.app.service.PostService; -import run.halo.app.utils.ValidationUtils; -import org.apache.commons.lang3.StringUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; +import run.halo.app.model.dto.CommentDTO; +import run.halo.app.model.params.CommentParam; +import run.halo.app.service.CommentService; /** * Portal comment controller. @@ -31,42 +21,13 @@ public class CommentController { private final CommentService commentService; - private final OptionService optionService; - - private final PostService postService; - - public CommentController(CommentService commentService, - OptionService optionService, - PostService postService) { + public CommentController(CommentService commentService) { this.commentService = commentService; - this.optionService = optionService; - this.postService = postService; } @PostMapping @ApiOperation("Comments a post") - public CommentDTO comment(@RequestBody CommentParam commentParam, HttpServletRequest request) { - // Get authentication - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (authentication != null) { - User user = authentication.getDetail().getUser(); - // If the admin is login - commentParam.setAuthor(StringUtils.isEmpty(user.getNickname()) ? user.getUsername() : user.getNickname()); - commentParam.setEmail(user.getEmail()); - commentParam.setAuthorUrl(optionService.getByPropertyOfNullable(BlogProperties.BLOG_URL)); - } - - // Validate the comment param manually - ValidationUtils.validate(commentParam); - - // Check post id - postService.mustExistById(commentParam.getPostId()); - - // Check parent id - if (commentParam.getParentId() != null && commentParam.getParentId() > 0) { - commentService.mustExistById(commentParam.getParentId()); - } - - return new CommentDTO().convertFrom(commentService.createBy(commentParam.convertTo(), request)); + public CommentDTO comment(@RequestBody CommentParam commentParam) { + return new CommentDTO().convertFrom(commentService.createBy(commentParam)); } }