Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: comments from users with comment management permission could exempt from review #5529

Merged
merged 12 commits into from Mar 22, 2024
Expand Up @@ -5,6 +5,7 @@
import static run.halo.app.extension.index.query.QueryFactory.isNull;

import java.time.Instant;
import java.util.Set;
import java.util.function.Function;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.data.domain.Sort;
Expand All @@ -16,6 +17,7 @@
import reactor.core.publisher.Mono;
import run.halo.app.core.extension.User;
import run.halo.app.core.extension.content.Comment;
import run.halo.app.core.extension.service.RoleService;
import run.halo.app.core.extension.service.UserService;
import run.halo.app.extension.Extension;
import run.halo.app.extension.ListOptions;
Expand All @@ -30,6 +32,7 @@
import run.halo.app.metrics.CounterService;
import run.halo.app.metrics.MeterUtils;
import run.halo.app.plugin.ExtensionComponentsFinder;
import run.halo.app.security.authorization.AuthorityUtils;

/**
* Comment service implementation.
Expand All @@ -42,6 +45,7 @@ public class CommentServiceImpl implements CommentService {

private final ReactiveExtensionClient client;
private final UserService userService;
private final RoleService roleService;
private final ExtensionComponentsFinder extensionComponentsFinder;

private final SystemConfigurableEnvironmentFetcher environmentFetcher;
Expand All @@ -50,12 +54,14 @@ public class CommentServiceImpl implements CommentService {
public CommentServiceImpl(ReactiveExtensionClient client,
UserService userService, ExtensionComponentsFinder extensionComponentsFinder,
SystemConfigurableEnvironmentFetcher environmentFetcher,
CounterService counterService) {
CounterService counterService, RoleService roleService
) {
this.client = client;
this.userService = userService;
this.extensionComponentsFinder = extensionComponentsFinder;
this.environmentFetcher = environmentFetcher;
this.counterService = counterService;
this.roleService = roleService;
}

@Override
Expand Down Expand Up @@ -113,7 +119,21 @@ public Mono<Comment> create(Comment comment) {
}
// populate owner from current user
return fetchCurrentUser()
.map(this::toCommentOwner)
.flatMap(currentUser -> ReactiveSecurityContextHolder.getContext()
.flatMap(securityContext -> {
var authentication = securityContext.getAuthentication();
JohnNiang marked this conversation as resolved.
Show resolved Hide resolved
var roles = AuthorityUtils.authoritiesToRoles(
authentication.getAuthorities());
return roleService.contains(roles,
Set.of(AuthorityUtils.COMMENT_MANAGEMENT_ROLE_NAME))
.doOnNext(result -> {
if (result) {
comment.getSpec().setApproved(true);
comment.getSpec().setApprovedTime(Instant.now());
}
})
.thenReturn(toCommentOwner(currentUser));
}))
.map(owner -> {
comment.getSpec().setOwner(owner);
return comment;
Expand Down
Expand Up @@ -6,6 +6,7 @@
import static run.halo.app.extension.router.selector.SelectorUtil.labelAndFieldSelectorToPredicate;

import java.time.Instant;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import lombok.RequiredArgsConstructor;
Expand All @@ -19,6 +20,7 @@
import run.halo.app.core.extension.User;
import run.halo.app.core.extension.content.Comment;
import run.halo.app.core.extension.content.Reply;
import run.halo.app.core.extension.service.RoleService;
import run.halo.app.core.extension.service.UserService;
import run.halo.app.extension.Extension;
import run.halo.app.extension.ListOptions;
Expand All @@ -29,6 +31,7 @@
import run.halo.app.extension.router.selector.FieldSelector;
import run.halo.app.metrics.CounterService;
import run.halo.app.metrics.MeterUtils;
import run.halo.app.security.authorization.AuthorityUtils;

/**
* A default implementation of {@link ReplyService}.
Expand All @@ -42,6 +45,7 @@ public class ReplyServiceImpl implements ReplyService {

private final ReactiveExtensionClient client;
private final UserService userService;
private final RoleService roleService;
private final CounterService counterService;

@Override
Expand Down Expand Up @@ -75,10 +79,24 @@ public Mono<Reply> create(String commentName, Reply reply) {
}
// populate owner from current user
return fetchCurrentUser()
.map(user -> {
replyToUse.getSpec().setOwner(toCommentOwner(user));
return replyToUse;
})
.flatMap(user ->
ReactiveSecurityContextHolder.getContext()
.flatMap(securityContext -> {
var authentication = securityContext.getAuthentication();
var roles = AuthorityUtils.authoritiesToRoles(
authentication.getAuthorities());
return roleService.contains(roles,
Set.of(AuthorityUtils.COMMENT_MANAGEMENT_ROLE_NAME))
.doOnNext(result -> {
if (result) {
reply.getSpec().setApproved(true);
reply.getSpec().setApprovedTime(Instant.now());
}
replyToUse.getSpec().setOwner(toCommentOwner(user));
})
.thenReturn(replyToUse);
})
)
.switchIfEmpty(
Mono.error(new IllegalArgumentException("Reply owner must not be null.")));
})
Expand Down
Expand Up @@ -24,6 +24,8 @@ public enum AuthorityUtils {

public static final String ANONYMOUS_ROLE_NAME = "anonymous";

public static final String COMMENT_MANAGEMENT_ROLE_NAME = "role-template-manage-comments";

/**
* Converts an array of GrantedAuthority objects to a role set.
*
Expand Down
Expand Up @@ -10,6 +10,7 @@

import java.util.List;
import java.util.Map;
import java.util.Set;
import org.json.JSONException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -33,6 +34,7 @@
import run.halo.app.core.extension.User;
import run.halo.app.core.extension.content.Comment;
import run.halo.app.core.extension.content.Post;
import run.halo.app.core.extension.service.RoleService;
import run.halo.app.core.extension.service.UserService;
import run.halo.app.extension.ListOptions;
import run.halo.app.extension.ListResult;
Expand All @@ -46,6 +48,7 @@
import run.halo.app.metrics.CounterService;
import run.halo.app.metrics.MeterUtils;
import run.halo.app.plugin.ExtensionComponentsFinder;
import run.halo.app.security.authorization.AuthorityUtils;

/**
* Tests for {@link CommentServiceImpl}.
Expand All @@ -65,6 +68,9 @@ class CommentServiceImplTest {
@Mock
private UserService userService;

@Mock
private RoleService roleService;

@Mock
private ExtensionComponentsFinder extensionComponentsFinder;

Expand All @@ -90,6 +96,10 @@ void setUp() {
when(client.fetch(eq(User.class), eq("C-owner")))
.thenReturn(Mono.empty());

when(roleService.contains(Set.of("USER"),
Set.of(AuthorityUtils.COMMENT_MANAGEMENT_ROLE_NAME)))
.thenReturn(Mono.just(false));

PostCommentSubject postCommentSubject = Mockito.mock(PostCommentSubject.class);
when(extensionComponentsFinder.getExtensions(eq(CommentSubject.class)))
.thenReturn(List.of(postCommentSubject));
Expand Down