Fix visit bug (#1414)

* fix: fix visit bug #1381

* fix checkstyle

* fix: fix visit bug #1381

* fix: modify the article status check

* fix: Modify the url build method

* delete public article verification

Co-authored-by: 袁智翔(相北) <xiangbei.yzx@alibaba-inc.com>
pull/1426/head
zhixiangyuan 2021-07-12 18:55:10 +08:00 committed by GitHub
parent 02e4b88288
commit 189f7be47e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 5 deletions

View File

@ -2,12 +2,16 @@ package run.halo.app.controller.admin.api;
import static org.springframework.data.domain.Sort.Direction.DESC;
import cn.hutool.core.util.IdUtil;
import io.swagger.annotations.ApiOperation;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.validation.Valid;
import org.apache.http.client.utils.URIBuilder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
@ -20,10 +24,12 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import run.halo.app.cache.AbstractStringCacheStore;
import run.halo.app.model.dto.post.BasePostDetailDTO;
import run.halo.app.model.dto.post.BasePostMinimalDTO;
import run.halo.app.model.dto.post.BasePostSimpleDTO;
import run.halo.app.model.entity.Post;
import run.halo.app.model.enums.PostPermalinkType;
import run.halo.app.model.enums.PostStatus;
import run.halo.app.model.params.PostContentParam;
import run.halo.app.model.params.PostParam;
@ -46,12 +52,15 @@ public class PostController {
private final PostService postService;
private final AbstractStringCacheStore cacheStore;
private final OptionService optionService;
public PostController(PostService postService,
AbstractStringCacheStore cacheStore,
OptionService optionService) {
this.postService = postService;
this.cacheStore = cacheStore;
this.optionService = optionService;
}
@ -172,13 +181,18 @@ public class PostController {
@GetMapping(value = {"preview/{postId:\\d+}", "{postId:\\d+}/preview"})
@ApiOperation("Gets a post preview link")
public String preview(@PathVariable("postId") Integer postId)
throws UnsupportedEncodingException {
throws UnsupportedEncodingException, URISyntaxException {
Post post = postService.getById(postId);
post.setSlug(URLEncoder.encode(post.getSlug(), StandardCharsets.UTF_8.name()));
BasePostMinimalDTO postMinimalDTO = postService.convertToMinimal(post);
String token = IdUtil.simpleUUID();
// cache preview token
cacheStore.putAny(token, token, 10, TimeUnit.MINUTES);
StringBuilder previewUrl = new StringBuilder();
if (!optionService.isEnabledAbsolutePath()) {
@ -188,6 +202,8 @@ public class PostController {
previewUrl.append(postMinimalDTO.getFullPath());
// build preview post url and return
return previewUrl.toString();
return new URIBuilder(previewUrl.toString())
.addParameter("token", token)
.build().toString();
}
}

View File

@ -3,6 +3,7 @@ package run.halo.app.controller.content.model;
import static run.halo.app.model.support.HaloConst.POST_PASSWORD_TEMPLATE;
import static run.halo.app.model.support.HaloConst.SUFFIX_FTL;
import cn.hutool.core.util.StrUtil;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
@ -13,6 +14,8 @@ import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import run.halo.app.cache.AbstractStringCacheStore;
import run.halo.app.exception.ForbiddenException;
import run.halo.app.exception.NotFoundException;
import run.halo.app.model.entity.Category;
import run.halo.app.model.entity.Post;
import run.halo.app.model.entity.PostMeta;
@ -85,9 +88,27 @@ public class PostModel {
}
public String content(Post post, String token, Model model) {
if (PostStatus.RECYCLE.equals(post.getStatus())) {
// Articles in the recycle bin are not allowed to be accessed.
throw new NotFoundException("查询不到该文章的信息");
} else if (StrUtil.isNotEmpty(token)) {
// If the token is not empty, it means it is an admin request,
// then verify the token.
// verify token
String cachedToken = cacheStore.getAny(token, String.class)
.orElseThrow(() -> new ForbiddenException("您没有该文章的访问权限"));
if (!cachedToken.equals(token)) {
throw new ForbiddenException("您没有该文章的访问权限");
}
} else if (PostStatus.DRAFT.equals(post.getStatus())) {
// Drafts are not allowed bo be accessed by outsiders.
throw new NotFoundException("查询不到该文章的信息");
} else if (PostStatus.INTIMATE.equals(post.getStatus())
&& !authenticationService.postAuthentication(post, null)
) {
// Encrypted articles must has the correct password before they can be accessed.
if (post.getStatus().equals(PostStatus.INTIMATE)
&& !authenticationService.postAuthentication(post, null)) {
model.addAttribute("slug", post.getSlug());
model.addAttribute("type", EncryptTypeEnum.POST.getName());
if (themeService.templateExists(POST_PASSWORD_TEMPLATE + SUFFIX_FTL)) {