From 83789d52dfaebb0b66042f8098dda11305bb60ae Mon Sep 17 00:00:00 2001 From: ruibaby Date: Fri, 6 Sep 2019 16:57:26 +0800 Subject: [PATCH] Support set password to post. --- .../controller/admin/api/PostController.java | 4 +- .../controller/admin/api/SheetController.java | 4 +- .../content/ContentArchiveController.java | 61 ++++++- .../app/model/dto/post/BasePostSimpleDTO.java | 2 + .../run/halo/app/model/enums/JournalType.java | 4 +- .../run/halo/app/model/enums/PostStatus.java | 7 +- .../app/service/impl/BasePostServiceImpl.java | 5 + .../common/template/post_password.ftl | 169 ++++++++++++++++++ 8 files changed, 244 insertions(+), 12 deletions(-) create mode 100644 src/main/resources/templates/common/template/post_password.ftl diff --git a/src/main/java/run/halo/app/controller/admin/api/PostController.java b/src/main/java/run/halo/app/controller/admin/api/PostController.java index 7115c479d4..245b53f8f6 100644 --- a/src/main/java/run/halo/app/controller/admin/api/PostController.java +++ b/src/main/java/run/halo/app/controller/admin/api/PostController.java @@ -150,9 +150,9 @@ public void preview(@PathVariable("postId") Integer postId, cacheStore.putAny("preview-post-token-" + postId, token, 10, TimeUnit.MINUTES); // build preview post url - String url = String.format("%s/archives/%s?preview=true&token=%s", optionService.getBlogBaseUrl(), post.getUrl(), token); + String redirect = String.format("%s/archives/%s?preview=true&token=%s", optionService.getBlogBaseUrl(), post.getUrl(), token); // redirect to preview url - response.sendRedirect(url); + response.sendRedirect(redirect); } } diff --git a/src/main/java/run/halo/app/controller/admin/api/SheetController.java b/src/main/java/run/halo/app/controller/admin/api/SheetController.java index 13e0e5782c..8a3330a17d 100644 --- a/src/main/java/run/halo/app/controller/admin/api/SheetController.java +++ b/src/main/java/run/halo/app/controller/admin/api/SheetController.java @@ -123,9 +123,9 @@ public void preview(@PathVariable("sheetId") Integer sheetId, cacheStore.putAny("preview-sheet-token-" + sheetId, token, 10, TimeUnit.MINUTES); // build preview sheet url - String url = String.format("%s/s/%s?preview=true&token=%s", optionService.getBlogBaseUrl(), sheet.getUrl(), token); + String redirect = String.format("%s/s/%s?preview=true&token=%s", optionService.getBlogBaseUrl(), sheet.getUrl(), token); // redirect to preview url - response.sendRedirect(url); + response.sendRedirect(redirect); } } diff --git a/src/main/java/run/halo/app/controller/content/ContentArchiveController.java b/src/main/java/run/halo/app/controller/content/ContentArchiveController.java index 2824ca41f0..80a2c42314 100644 --- a/src/main/java/run/halo/app/controller/content/ContentArchiveController.java +++ b/src/main/java/run/halo/app/controller/content/ContentArchiveController.java @@ -1,6 +1,8 @@ package run.halo.app.controller.content; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.PageUtil; +import cn.hutool.crypto.digest.BCrypt; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -9,11 +11,9 @@ import org.springframework.data.web.SortDefault; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import run.halo.app.cache.StringCacheStore; +import run.halo.app.cache.lock.CacheLock; import run.halo.app.exception.ForbiddenException; import run.halo.app.model.entity.Category; import run.halo.app.model.entity.Post; @@ -111,10 +111,19 @@ public String archives(Model model, @GetMapping("{url}") public String post(@PathVariable("url") String url, @RequestParam(value = "preview", required = false, defaultValue = "false") boolean preview, + @RequestParam(value = "intimate", required = false, defaultValue = "false") boolean intimate, @RequestParam(value = "token", required = false) String token, Model model) { - Post post = postService.getBy(preview ? PostStatus.DRAFT : PostStatus.PUBLISHED, url); + Post post; + if (preview) { + post = postService.getBy(PostStatus.DRAFT, url); + } else if (intimate) { + post = postService.getBy(PostStatus.INTIMATE, url); + } else { + post = postService.getBy(PostStatus.PUBLISHED, url); + } + // if this is a preview url. if (preview) { // render markdown to html when preview post post.setFormatContent(MarkdownUtils.renderHtml(post.getOriginalContent())); @@ -127,6 +136,15 @@ public String post(@PathVariable("url") String url, } } + // if this is a intimate url. + if (intimate) { + // verify token + String cachedToken = cacheStore.getAny(token, String.class).orElseThrow(() -> new ForbiddenException("您没有该文章的访问权限")); + if (!cachedToken.equals(token)) { + throw new ForbiddenException("您没有该文章的访问权限"); + } + } + postService.getNextPost(post.getCreateTime()).ifPresent(nextPost -> model.addAttribute("nextPost", nextPost)); postService.getPrePost(post.getCreateTime()).ifPresent(prePost -> model.addAttribute("prePost", prePost)); @@ -145,4 +163,37 @@ public String post(@PathVariable("url") String url, return themeService.render("post"); } + + @GetMapping(value = "{url}/password") + public String password(@PathVariable("url") String url, + Model model) { + Post post = postService.getBy(PostStatus.INTIMATE, url); + if (null == post) { + throw new ForbiddenException("没有查询到该文章信息"); + } + + model.addAttribute("url", url); + return "common/template/post_password"; + } + + @PostMapping(value = "{url}/password") + @CacheLock + public String password(@PathVariable("url") String url, + @RequestParam(value = "password") String password) { + Post post = postService.getBy(PostStatus.INTIMATE, url); + if (null == post) { + throw new ForbiddenException("没有查询到该文章信息"); + } + + if (BCrypt.checkpw(password, post.getPassword())) { + String token = IdUtil.simpleUUID(); + cacheStore.putAny(token, token, 10, TimeUnit.SECONDS); + + String redirect = String.format("%s/archives/%s?intimate=true&token=%s", optionService.getBlogBaseUrl(), post.getUrl(), token); + return "redirect:" + redirect; + } else { + String redirect = String.format("%s/archives/%s/password", optionService.getBlogBaseUrl(), post.getUrl()); + return "redirect:" + redirect; + } + } } diff --git a/src/main/java/run/halo/app/model/dto/post/BasePostSimpleDTO.java b/src/main/java/run/halo/app/model/dto/post/BasePostSimpleDTO.java index 2f7e9afe9b..793bdabb4d 100644 --- a/src/main/java/run/halo/app/model/dto/post/BasePostSimpleDTO.java +++ b/src/main/java/run/halo/app/model/dto/post/BasePostSimpleDTO.java @@ -23,6 +23,8 @@ public class BasePostSimpleDTO extends BasePostMinimalDTO { private Boolean disallowComment; + private String password; + private String template; private Integer topPriority = 0; diff --git a/src/main/java/run/halo/app/model/enums/JournalType.java b/src/main/java/run/halo/app/model/enums/JournalType.java index 2b4b4ff28f..97386238be 100644 --- a/src/main/java/run/halo/app/model/enums/JournalType.java +++ b/src/main/java/run/halo/app/model/enums/JournalType.java @@ -13,9 +13,9 @@ public enum JournalType implements ValueEnum { PUBLIC(1), /** - * Private type. + * Intimate type. */ - PRIVATE(0); + INTIMATE(0); private final int value; diff --git a/src/main/java/run/halo/app/model/enums/PostStatus.java b/src/main/java/run/halo/app/model/enums/PostStatus.java index fedd6ecffa..9e5b4e3f62 100644 --- a/src/main/java/run/halo/app/model/enums/PostStatus.java +++ b/src/main/java/run/halo/app/model/enums/PostStatus.java @@ -20,7 +20,12 @@ public enum PostStatus implements ValueEnum { /** * Recycle status. */ - RECYCLE(2); + RECYCLE(2), + + /** + * Intimate status + */ + INTIMATE(3); private final int value; diff --git a/src/main/java/run/halo/app/service/impl/BasePostServiceImpl.java b/src/main/java/run/halo/app/service/impl/BasePostServiceImpl.java index b3389d63d4..1e5d2c178c 100644 --- a/src/main/java/run/halo/app/service/impl/BasePostServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/BasePostServiceImpl.java @@ -217,6 +217,11 @@ public POST createOrUpdateBy(POST post) { post.setFormatContent(MarkdownUtils.renderHtml(post.getOriginalContent())); } + // if password is not empty,change status to intimate + if (StringUtils.isNotEmpty(post.getPassword()) && post.getStatus() != PostStatus.DRAFT) { + post.setStatus(PostStatus.INTIMATE); + } + // Create or update post if (ServiceUtils.isEmptyId(post.getId())) { // The sheet will be created diff --git a/src/main/resources/templates/common/template/post_password.ftl b/src/main/resources/templates/common/template/post_password.ftl new file mode 100644 index 0000000000..2aeac03169 --- /dev/null +++ b/src/main/resources/templates/common/template/post_password.ftl @@ -0,0 +1,169 @@ + + + + + + + + 私密文章访问 - ${options.blog_title!} + + + +
+
+
+ + + + + +
+
+ +
+
+
+ + \ No newline at end of file