fix: NPE when deleting category (#1806)

pull/1811/head
guqing 2022-04-01 15:37:43 +08:00 committed by GitHub
parent 7d9da09b49
commit 32f24626b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 105 additions and 3 deletions

View File

@ -59,14 +59,22 @@ public class ContentAuthenticationManager {
@EventListener(CategoryUpdatedEvent.class)
public void categoryUpdatedListener(CategoryUpdatedEvent event) {
Category category = event.getCategory();
// updated category is null when remove event emited
if (category == null) {
category = event.getBeforeUpdated();
}
if (category != null) {
categoryAuthentication.clearByResourceId(category.getId());
}
}
@EventListener(PostUpdatedEvent.class)
public void postUpdatedListener(PostUpdatedEvent event) {
Post post = event.getPost();
if (post != null) {
postAuthentication.clearByResourceId(post.getId());
}
}
private PostAuthentication authenticatePost(ContentAuthenticationRequest authRequest) {
Post post = postService.getById(authRequest.getId());

View File

@ -25,7 +25,6 @@ public class LevelCacheStoreTest {
@BeforeEach
void setUp() throws IOException {
String testDir = FileUtils.createTempDirectory().toString();
System.out.println(testDir);
haloProperties.setWorkDir(testDir + FILE_SEPARATOR);
cacheStore = new LevelCacheStore(haloProperties);
cacheStore.init();

View File

@ -0,0 +1,95 @@
package run.halo.app.service.impl;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.springframework.test.annotation.DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.event.RecordApplicationEvents;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import run.halo.app.cache.AbstractStringCacheStore;
import run.halo.app.controller.content.auth.CategoryAuthentication;
import run.halo.app.exception.NotFoundException;
import run.halo.app.model.entity.Category;
import run.halo.app.service.CategoryService;
/**
* @author guqing
* @date 2022-04-01
*/
@SpringBootTest
@RecordApplicationEvents
@DirtiesContext(classMode = BEFORE_EACH_TEST_METHOD)
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
public class CategoryIntegrationTest {
@Autowired
private CategoryService categoryService;
@Autowired
private CategoryAuthentication categoryAuthentication;
@Autowired
private AbstractStringCacheStore abstractStringCacheStore;
@BeforeEach
public void setUp() {
Category category1 = new Category();
category1.setId(1);
category1.setName("category-1");
category1.setSlug("category-1");
category1.setPassword("123");
category1.setParentId(0);
Category category2 = new Category();
category2.setId(2);
category2.setName("category-2");
category2.setSlug("category-2");
category2.setParentId(1);
categoryService.create(category1);
categoryService.create(category2);
}
@Test
public void authenticationAfterRemove() {
Category category = categoryService.getById(1);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestedSessionId("mock_session_id");
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
boolean authenticated = categoryAuthentication.isAuthenticated(category.getId());
assertThat(authenticated).isFalse();
// set authenticated flag is true for No.2 category
categoryAuthentication.setAuthenticated(2, true);
assertThat(categoryAuthentication.isAuthenticated(2)).isTrue();
// set authenticated flag is true for No.1 category
categoryAuthentication.setAuthenticated(category.getId(), true);
assertThat(categoryAuthentication.isAuthenticated(category.getId())).isTrue();
// remove category and category-post relationships
categoryService.removeCategoryAndPostCategoryBy(category.getId());
// authenticated cache flag is cleared by authentication manager
String authenticationCacheKey =
categoryAuthentication.buildCacheKey(request.getRequestedSessionId(),
categoryAuthentication.getPrincipal().toString(), String.valueOf(category.getId()));
assertThat(abstractStringCacheStore.get(authenticationCacheKey)).isEmpty();
// isAuthenticated method will be throw NotFoundException because of category has been
// removed.
assertThatThrownBy(() -> categoryAuthentication.isAuthenticated(category.getId()))
.isInstanceOf(NotFoundException.class);
// bug other cache flags will not be affected
assertThat(categoryAuthentication.isAuthenticated(2)).isTrue();
}
}