diff --git a/application/src/main/java/run/halo/app/security/authorization/AuthorityUtils.java b/application/src/main/java/run/halo/app/security/authorization/AuthorityUtils.java index 846830aa0..5243fba20 100644 --- a/application/src/main/java/run/halo/app/security/authorization/AuthorityUtils.java +++ b/application/src/main/java/run/halo/app/security/authorization/AuthorityUtils.java @@ -26,6 +26,8 @@ public enum AuthorityUtils { public static final String COMMENT_MANAGEMENT_ROLE_NAME = "role-template-manage-comments"; + public static final String POST_CONTRIBUTOR_ROLE_NAME = "role-template-post-contributor"; + /** * Converts an array of GrantedAuthority objects to a role set. * diff --git a/application/src/main/java/run/halo/app/theme/router/factories/AuthorPostsRouteFactory.java b/application/src/main/java/run/halo/app/theme/router/factories/AuthorPostsRouteFactory.java index 31fe7200b..985f3e24c 100644 --- a/application/src/main/java/run/halo/app/theme/router/factories/AuthorPostsRouteFactory.java +++ b/application/src/main/java/run/halo/app/theme/router/factories/AuthorPostsRouteFactory.java @@ -5,6 +5,7 @@ import static org.springframework.web.reactive.function.server.RequestPredicates import static run.halo.app.theme.router.PageUrlUtils.totalPage; import java.util.Map; +import java.util.Set; import lombok.AllArgsConstructor; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; @@ -16,10 +17,12 @@ import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.server.i18n.LocaleContextResolver; import reactor.core.publisher.Mono; import run.halo.app.core.extension.User; +import run.halo.app.core.user.service.RoleService; import run.halo.app.extension.ReactiveExtensionClient; import run.halo.app.infra.SystemConfigurableEnvironmentFetcher; import run.halo.app.infra.SystemSetting; import run.halo.app.infra.exception.NotFoundException; +import run.halo.app.security.authorization.AuthorityUtils; import run.halo.app.theme.DefaultTemplateEnum; import run.halo.app.theme.finders.PostFinder; import run.halo.app.theme.finders.vo.ListedPostVo; @@ -42,6 +45,7 @@ public class AuthorPostsRouteFactory implements RouteFactory { private final PostFinder postFinder; private final ReactiveExtensionClient client; + private final RoleService roleService; private SystemConfigurableEnvironmentFetcher environmentFetcher; private final TitleVisibilityIdentifyCalculator titleVisibilityIdentifyCalculator; @@ -58,16 +62,31 @@ public class AuthorPostsRouteFactory implements RouteFactory { HandlerFunction handlerFunction() { return request -> { String name = request.pathVariable("name"); - return ServerResponse.ok() - .render(DefaultTemplateEnum.AUTHOR.getValue(), - Map.of("author", getByName(name), - "posts", postList(request, name), - ModelConst.TEMPLATE_ID, DefaultTemplateEnum.AUTHOR.getValue() - ) - ); + return hasPostManageRole(name) + .flatMap(hasPostManageRole -> { + if (hasPostManageRole) { + return ServerResponse.ok() + .render(DefaultTemplateEnum.AUTHOR.getValue(), + Map.of("author", getByName(name), + "posts", postList(request, name), + ModelConst.TEMPLATE_ID, DefaultTemplateEnum.AUTHOR.getValue() + ) + ); + } + return Mono.error(new NotFoundException("Author page not found.")); + }); }; } + protected Mono hasPostManageRole(String username) { + return roleService.getRolesByUsername(username) + .collectList() + .flatMap(roles -> roleService.contains(roles, + Set.of(AuthorityUtils.POST_CONTRIBUTOR_ROLE_NAME)) + ) + .defaultIfEmpty(false); + } + private Mono> postList(ServerRequest request, String name) { String path = request.path(); int pageNum = pageNumInPathVariable(request); diff --git a/application/src/test/java/run/halo/app/theme/router/factories/AuthorPostsRouteFactoryTest.java b/application/src/test/java/run/halo/app/theme/router/factories/AuthorPostsRouteFactoryTest.java index c308ef854..3dec9b2cd 100644 --- a/application/src/test/java/run/halo/app/theme/router/factories/AuthorPostsRouteFactoryTest.java +++ b/application/src/test/java/run/halo/app/theme/router/factories/AuthorPostsRouteFactoryTest.java @@ -1,6 +1,9 @@ package run.halo.app.theme.router.factories; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import org.junit.jupiter.api.Test; @@ -30,7 +33,10 @@ class AuthorPostsRouteFactoryTest extends RouteFactoryTestSuite { @Test void create() { - RouterFunction routerFunction = authorPostsRouteFactory.create(null); + var spyAuthorRoute = spy(authorPostsRouteFactory); + doReturn(Mono.just(true)).when(spyAuthorRoute).hasPostManageRole(anyString()); + + RouterFunction routerFunction = spyAuthorRoute.create(null); WebTestClient webClient = getWebTestClient(routerFunction); when(client.fetch(eq(User.class), eq("fake-user")))