mirror of https://github.com/halo-dev/halo
refactor: restrict author page access to users with post permission (#7279)
#### What type of PR is this? /kind improvement /area core /milestone 2.20.x #### What this PR does / why we need it: 仅对包含文章权限的用户生成作者页面 #### Which issue(s) this PR fixes: Fixes #7202 #### Does this PR introduce a user-facing change? ```release-note 仅对包含文章权限的用户生成作者页面 ```pull/7282/head
parent
5c2c298bc3
commit
2c4c876ef2
|
@ -26,6 +26,8 @@ public enum AuthorityUtils {
|
||||||
|
|
||||||
public static final String COMMENT_MANAGEMENT_ROLE_NAME = "role-template-manage-comments";
|
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.
|
* Converts an array of GrantedAuthority objects to a role set.
|
||||||
*
|
*
|
||||||
|
|
|
@ -5,6 +5,7 @@ import static org.springframework.web.reactive.function.server.RequestPredicates
|
||||||
import static run.halo.app.theme.router.PageUrlUtils.totalPage;
|
import static run.halo.app.theme.router.PageUrlUtils.totalPage;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Component;
|
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 org.springframework.web.server.i18n.LocaleContextResolver;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import run.halo.app.core.extension.User;
|
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.extension.ReactiveExtensionClient;
|
||||||
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
|
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
|
||||||
import run.halo.app.infra.SystemSetting;
|
import run.halo.app.infra.SystemSetting;
|
||||||
import run.halo.app.infra.exception.NotFoundException;
|
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.DefaultTemplateEnum;
|
||||||
import run.halo.app.theme.finders.PostFinder;
|
import run.halo.app.theme.finders.PostFinder;
|
||||||
import run.halo.app.theme.finders.vo.ListedPostVo;
|
import run.halo.app.theme.finders.vo.ListedPostVo;
|
||||||
|
@ -42,6 +45,7 @@ public class AuthorPostsRouteFactory implements RouteFactory {
|
||||||
|
|
||||||
private final PostFinder postFinder;
|
private final PostFinder postFinder;
|
||||||
private final ReactiveExtensionClient client;
|
private final ReactiveExtensionClient client;
|
||||||
|
private final RoleService roleService;
|
||||||
private SystemConfigurableEnvironmentFetcher environmentFetcher;
|
private SystemConfigurableEnvironmentFetcher environmentFetcher;
|
||||||
|
|
||||||
private final TitleVisibilityIdentifyCalculator titleVisibilityIdentifyCalculator;
|
private final TitleVisibilityIdentifyCalculator titleVisibilityIdentifyCalculator;
|
||||||
|
@ -58,16 +62,31 @@ public class AuthorPostsRouteFactory implements RouteFactory {
|
||||||
HandlerFunction<ServerResponse> handlerFunction() {
|
HandlerFunction<ServerResponse> handlerFunction() {
|
||||||
return request -> {
|
return request -> {
|
||||||
String name = request.pathVariable("name");
|
String name = request.pathVariable("name");
|
||||||
return ServerResponse.ok()
|
return hasPostManageRole(name)
|
||||||
.render(DefaultTemplateEnum.AUTHOR.getValue(),
|
.flatMap(hasPostManageRole -> {
|
||||||
Map.of("author", getByName(name),
|
if (hasPostManageRole) {
|
||||||
"posts", postList(request, name),
|
return ServerResponse.ok()
|
||||||
ModelConst.TEMPLATE_ID, DefaultTemplateEnum.AUTHOR.getValue()
|
.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<Boolean> hasPostManageRole(String username) {
|
||||||
|
return roleService.getRolesByUsername(username)
|
||||||
|
.collectList()
|
||||||
|
.flatMap(roles -> roleService.contains(roles,
|
||||||
|
Set.of(AuthorityUtils.POST_CONTRIBUTOR_ROLE_NAME))
|
||||||
|
)
|
||||||
|
.defaultIfEmpty(false);
|
||||||
|
}
|
||||||
|
|
||||||
private Mono<UrlContextListResult<ListedPostVo>> postList(ServerRequest request, String name) {
|
private Mono<UrlContextListResult<ListedPostVo>> postList(ServerRequest request, String name) {
|
||||||
String path = request.path();
|
String path = request.path();
|
||||||
int pageNum = pageNumInPathVariable(request);
|
int pageNum = pageNumInPathVariable(request);
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package run.halo.app.theme.router.factories;
|
package run.halo.app.theme.router.factories;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
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 static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -30,7 +33,10 @@ class AuthorPostsRouteFactoryTest extends RouteFactoryTestSuite {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void create() {
|
void create() {
|
||||||
RouterFunction<ServerResponse> routerFunction = authorPostsRouteFactory.create(null);
|
var spyAuthorRoute = spy(authorPostsRouteFactory);
|
||||||
|
doReturn(Mono.just(true)).when(spyAuthorRoute).hasPostManageRole(anyString());
|
||||||
|
|
||||||
|
RouterFunction<ServerResponse> routerFunction = spyAuthorRoute.create(null);
|
||||||
WebTestClient webClient = getWebTestClient(routerFunction);
|
WebTestClient webClient = getWebTestClient(routerFunction);
|
||||||
|
|
||||||
when(client.fetch(eq(User.class), eq("fake-user")))
|
when(client.fetch(eq(User.class), eq("fake-user")))
|
||||||
|
|
Loading…
Reference in New Issue