改进脱敏 (#874)

* fixed typos

* 改进脱敏

* 改进脱敏

* 添加脱敏单元测试

Co-authored-by: Your Name <you@example.com>
pull/876/head
giveup 2020-05-27 23:29:00 +08:00 committed by GitHub
parent b40c3f7ed9
commit bc30ab7c03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 164 additions and 25 deletions

View File

@ -0,0 +1,15 @@
package run.halo.app.annotation;
import java.lang.annotation.*;
/**
* @author giveup
* @description SensitiveConceal
* @date 8:18 PM 26/5/2020
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SensitiveConceal {
}

View File

@ -0,0 +1,57 @@
package run.halo.app.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import run.halo.app.model.entity.BaseComment;
import run.halo.app.security.context.SecurityContextHolder;
/**
* @author giveup
* @description SensitiveMaskAspect
* @date 10:22 PM 25/5/2020
*/
@Aspect
@Component
public class SensitiveConcealAspect {
@Pointcut("@annotation(run.halo.app.annotation.SensitiveConceal)")
public void pointCut() {
}
private Object sensitiveMask(Object comment) {
if (comment instanceof BaseComment) {
((BaseComment) comment).setEmail("");
((BaseComment) comment).setIpAddress("");
}
return comment;
}
@Around("pointCut()")
public Object mask(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = joinPoint.proceed();
if (SecurityContextHolder.getContext().isAuthenticated()) {
return result;
}
if (result instanceof Iterable) {
((Iterable<?>) result).forEach(this::sensitiveMask);
}
return sensitiveMask(result);
}
}

View File

@ -73,8 +73,7 @@ public class JournalController {
public Page<CommentWithHasChildrenVO> listTopComments(@PathVariable("journalId") Integer journalId,
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
Page<CommentWithHasChildrenVO> result = journalCommentService.pageTopCommentsBy(journalId, CommentStatus.PUBLISHED, PageRequest.of(page, optionService.getCommentPageSize(), sort));
return journalCommentService.filterIpAddress(result);
return journalCommentService.pageTopCommentsBy(journalId, CommentStatus.PUBLISHED, PageRequest.of(page, optionService.getCommentPageSize(), sort));
}
@GetMapping("{journalId:\\d+}/comments/{commentParentId:\\d+}/children")
@ -84,8 +83,7 @@ public class JournalController {
// Find all children comments
List<JournalComment> postComments = journalCommentService.listChildrenBy(journalId, commentParentId, CommentStatus.PUBLISHED, sort);
// Convert to base comment dto
List<BaseCommentDTO> result = journalCommentService.convertTo(postComments);
return journalCommentService.filterIpAddress(result);
return journalCommentService.convertTo(postComments);
}
@GetMapping("{journalId:\\d+}/comments/tree_view")
@ -93,8 +91,7 @@ public class JournalController {
public Page<BaseCommentVO> listCommentsTree(@PathVariable("journalId") Integer journalId,
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
Page<BaseCommentVO> result = journalCommentService.pageVosBy(journalId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
return journalCommentService.filterIpAddress(result);
return journalCommentService.pageVosBy(journalId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
}
@GetMapping("{journalId:\\d+}/comments/list_view")
@ -102,8 +99,7 @@ public class JournalController {
public Page<BaseCommentWithParentVO> listComments(@PathVariable("journalId") Integer journalId,
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
Page<BaseCommentWithParentVO> result = journalCommentService.pageWithParentVoBy(journalId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
return journalCommentService.filterIpAddress(result);
return journalCommentService.pageWithParentVoBy(journalId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
}
@PostMapping("comments")

View File

@ -91,9 +91,7 @@ public class PostController {
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
Page<CommentWithHasChildrenVO> result = postCommentService.pageTopCommentsBy(postId, CommentStatus.PUBLISHED, PageRequest.of(page, optionService.getCommentPageSize(), sort));
return postCommentService.filterIpAddress(result);
return postCommentService.pageTopCommentsBy(postId, CommentStatus.PUBLISHED, PageRequest.of(page, optionService.getCommentPageSize(), sort));
}
@ -105,9 +103,7 @@ public class PostController {
List<PostComment> postComments = postCommentService.listChildrenBy(postId, commentParentId, CommentStatus.PUBLISHED, sort);
// Convert to base comment dto
List<BaseCommentDTO> result = postCommentService.convertTo(postComments);
return postCommentService.filterIpAddress(result);
return postCommentService.convertTo(postComments);
}
@GetMapping("{postId:\\d+}/comments/tree_view")
@ -115,8 +111,7 @@ public class PostController {
public Page<BaseCommentVO> listCommentsTree(@PathVariable("postId") Integer postId,
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
Page<BaseCommentVO> result = postCommentService.pageVosBy(postId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
return postCommentService.filterIpAddress(result);
return postCommentService.pageVosBy(postId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
}
@GetMapping("{postId:\\d+}/comments/list_view")
@ -125,7 +120,7 @@ public class PostController {
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
Page<BaseCommentWithParentVO> result = postCommentService.pageWithParentVoBy(postId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
return postCommentService.filterIpAddress(result);
return result;
}
@PostMapping("comments")

View File

@ -80,8 +80,7 @@ public class SheetController {
public Page<CommentWithHasChildrenVO> listTopComments(@PathVariable("sheetId") Integer sheetId,
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
Page<CommentWithHasChildrenVO> result = sheetCommentService.pageTopCommentsBy(sheetId, CommentStatus.PUBLISHED, PageRequest.of(page, optionService.getCommentPageSize(), sort));
return sheetCommentService.filterIpAddress(result);
return sheetCommentService.pageTopCommentsBy(sheetId, CommentStatus.PUBLISHED, PageRequest.of(page, optionService.getCommentPageSize(), sort));
}
@GetMapping("{sheetId:\\d+}/comments/{commentParentId:\\d+}/children")
@ -91,8 +90,7 @@ public class SheetController {
// Find all children comments
List<SheetComment> sheetComments = sheetCommentService.listChildrenBy(sheetId, commentParentId, CommentStatus.PUBLISHED, sort);
// Convert to base comment dto
List<BaseCommentDTO> result = sheetCommentService.convertTo(sheetComments);
return sheetCommentService.filterIpAddress(result);
return sheetCommentService.convertTo(sheetComments);
}
@ -101,8 +99,7 @@ public class SheetController {
public Page<BaseCommentVO> listCommentsTree(@PathVariable("sheetId") Integer sheetId,
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
Page<BaseCommentVO> result = sheetCommentService.pageVosBy(sheetId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
return sheetCommentService.filterIpAddress(result);
return sheetCommentService.pageVosBy(sheetId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
}
@GetMapping("{sheetId:\\d+}/comments/list_view")
@ -110,8 +107,7 @@ public class SheetController {
public Page<BaseCommentWithParentVO> listComments(@PathVariable("sheetId") Integer sheetId,
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
Page<BaseCommentWithParentVO> result = sheetCommentService.pageWithParentVoBy(sheetId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
return sheetCommentService.filterIpAddress(result);
return sheetCommentService.pageWithParentVoBy(sheetId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
}
@PostMapping("comments")

View File

@ -7,6 +7,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import run.halo.app.annotation.SensitiveConceal;
import run.halo.app.model.entity.BaseComment;
import run.halo.app.model.enums.CommentStatus;
import run.halo.app.model.projection.CommentChildrenCountProjection;
@ -33,6 +34,7 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
* @return a page of comment
*/
@NonNull
@SensitiveConceal
Page<COMMENT> findAllByStatus(@Nullable CommentStatus status, @NonNull Pageable pageable);
@ -43,6 +45,7 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
* @return a list of comment
*/
@NonNull
@SensitiveConceal
List<COMMENT> findAllByPostIdIn(@NonNull Collection<Integer> postIds);
/**
@ -52,6 +55,7 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
* @return a list of comment
*/
@NonNull
@SensitiveConceal
List<COMMENT> findAllByPostId(@NonNull Integer postId);
/**
@ -109,6 +113,7 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
* @return a list of comment
*/
@NonNull
@SensitiveConceal
List<COMMENT> findAllByPostIdAndStatus(Integer postId, CommentStatus status);
/**
@ -120,6 +125,7 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
* @return a page of comment
*/
@NonNull
@SensitiveConceal
Page<COMMENT> findAllByPostIdAndStatus(Integer postId, CommentStatus status, Pageable pageable);
/**
@ -131,6 +137,7 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
* @return a list of comment
*/
@NonNull
@SensitiveConceal
List<COMMENT> findAllByPostIdAndStatusAndParentId(@NonNull Integer postId, @NonNull CommentStatus status, @NonNull Long parentId);
/**
@ -141,6 +148,7 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
* @return a list of comment
*/
@NonNull
@SensitiveConceal
List<COMMENT> findAllByPostIdAndParentId(@NonNull Integer postId, @NonNull Long parentId);
/**
@ -151,6 +159,7 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
* @return a list of comment
*/
@NonNull
@SensitiveConceal
List<COMMENT> findAllByStatusAndParentIdIn(@NonNull CommentStatus status, @NonNull Collection<Long> parentIds);
/**
@ -159,6 +168,7 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
* @param parentIds parent id collection must not be null
* @return a list of comment
*/
@SensitiveConceal
List<COMMENT> findAllByParentIdIn(@NonNull Collection<Long> parentIds);
/**
@ -171,6 +181,7 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
* @return a page of comment
*/
@NonNull
@SensitiveConceal
Page<COMMENT> findAllByPostIdAndStatusAndParentId(Integer postId, CommentStatus status, Long parentId, Pageable pageable);

View File

@ -12,6 +12,7 @@ import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.lang.Nullable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import run.halo.app.annotation.SensitiveConceal;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
@ -71,6 +72,7 @@ public class BaseRepositoryImpl<DOMAIN, ID> extends SimpleJpaRepository<DOMAIN,
* @return a list of domains
*/
@Override
@SensitiveConceal
public List<DOMAIN> findAllByIdIn(Collection<ID> ids, Sort sort) {
Assert.notNull(ids, "The given Collection of Id's must not be null!");
Assert.notNull(sort, "Sort info must nto be null");
@ -93,6 +95,7 @@ public class BaseRepositoryImpl<DOMAIN, ID> extends SimpleJpaRepository<DOMAIN,
}
@Override
@SensitiveConceal
public Page<DOMAIN> findAllByIdIn(Collection<ID> ids, Pageable pageable) {
Assert.notNull(ids, "The given Collection of Id's must not be null!");
Assert.notNull(pageable, "Page info must nto be null");

View File

@ -287,6 +287,7 @@ public interface BaseCommentService<COMMENT extends BaseComment> extends CrudSer
*
* @param comment comment dto must not be null
*/
@Deprecated
<T extends BaseCommentDTO> T filterIpAddress(@NonNull T comment);
/**
@ -294,6 +295,7 @@ public interface BaseCommentService<COMMENT extends BaseComment> extends CrudSer
*
* @param comments comment dto list
*/
@Deprecated
<T extends BaseCommentDTO> List<T> filterIpAddress(@Nullable List<T> comments);
/**
@ -301,6 +303,7 @@ public interface BaseCommentService<COMMENT extends BaseComment> extends CrudSer
*
* @param commentPage comment page
*/
@Deprecated
<T extends BaseCommentDTO> Page<T> filterIpAddress(@NonNull Page<T> commentPage);
/**

View File

@ -564,6 +564,7 @@ public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment> extend
}
@Override
@Deprecated
public <T extends BaseCommentDTO> T filterIpAddress(@NonNull T comment) {
Assert.notNull(comment, "Base comment dto must not be null");
@ -592,6 +593,7 @@ public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment> extend
}
@Override
@Deprecated
public <T extends BaseCommentDTO> List<T> filterIpAddress(List<T> comments) {
if (CollectionUtils.isEmpty(comments)) {
return Collections.emptyList();
@ -603,6 +605,7 @@ public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment> extend
}
@Override
@Deprecated
public <T extends BaseCommentDTO> Page<T> filterIpAddress(Page<T> commentPage) {
Assert.notNull(commentPage, "Comment page must not be null");
commentPage.forEach(this::filterIpAddress);

View File

@ -0,0 +1,60 @@
package run.halo.app.aspect;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import run.halo.app.model.entity.PostComment;
import run.halo.app.model.entity.User;
import run.halo.app.security.authentication.AuthenticationImpl;
import run.halo.app.security.context.SecurityContextHolder;
import run.halo.app.security.context.SecurityContextImpl;
import run.halo.app.security.support.UserDetail;
import run.halo.app.service.PostCommentService;
import java.util.List;
/**
* @author giveup
* @description SensitiveConcealAspectTest
* @date 1:14 AM 27/5/2020
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SensitiveConcealAspectTest {
@Autowired
private PostCommentService postCommentService;
@Test
public void testGuest() {
List<PostComment> postComments = postCommentService.listBy(1);
for (PostComment postComment : postComments) {
Assert.assertEquals("", postComment.getIpAddress());
Assert.assertEquals("", postComment.getEmail());
}
}
@Test
public void testAdmin() {
SecurityContextHolder.setContext(new SecurityContextImpl(new AuthenticationImpl(new UserDetail(new User()))));
List<PostComment> postComments = postCommentService.listBy(1);
for (PostComment postComment : postComments) {
Assert.assertEquals("127.0.0.1", postComment.getIpAddress());
Assert.assertEquals("hi@halo.run", postComment.getEmail());
}
}
}