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

refactor: default is approved to reply to comments on the console-side #3363

Merged
merged 9 commits into from
Feb 24, 2023
53 changes: 12 additions & 41 deletions src/main/java/run/halo/app/content/comment/ReplyServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
import run.halo.app.extension.Extension;
import run.halo.app.extension.ListResult;
import run.halo.app.extension.ReactiveExtensionClient;
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
import run.halo.app.infra.exception.AccessDeniedException;

/**
* A default implementation of {@link ReplyService}.
Expand All @@ -32,13 +30,12 @@
public class ReplyServiceImpl implements ReplyService {

private final ReactiveExtensionClient client;
private final SystemConfigurableEnvironmentFetcher environmentFetcher;
private final UserService userService;

@Override
public Mono<Reply> create(String commentName, Reply reply) {
return client.fetch(Comment.class, commentName)
.flatMap(comment -> {
return client.get(Comment.class, commentName)
.map(comment -> {
// Boolean allowNotification = reply.getSpec().getAllowNotification();
// TODO send notification if allowNotification is true
reply.getSpec().setCommentName(commentName);
Expand All @@ -51,28 +48,14 @@ public Mono<Reply> create(String commentName, Reply reply) {
if (reply.getSpec().getCreationTime() == null) {
reply.getSpec().setCreationTime(Instant.now());
}
return environmentFetcher.fetchComment()
.map(commentSetting -> {
if (Boolean.FALSE.equals(commentSetting.getEnable())) {
throw new AccessDeniedException(
"The comment function has been turned off.",
"problemDetail.comment.turnedOff", null);
}
if (checkReplyOwner(reply, commentSetting.getSystemUserOnly())) {
throw new AccessDeniedException("Allow only system users to comment.",
"problemDetail.comment.systemUsersOnly", null);
}
reply.getSpec().setApproved(
Boolean.FALSE.equals(commentSetting.getRequireReviewForNew()));
// fix https://github.com/halo-dev/halo/issues/2951
reply.getSpec().setHidden(false);

if (BooleanUtils.isTrue(reply.getSpec().getApproved())
&& reply.getSpec().getApprovedTime() == null) {
reply.getSpec().setApprovedTime(Instant.now());
}
return reply;
});
if (reply.getSpec().getApproved() == null) {
reply.getSpec().setApproved(false);
}
if (BooleanUtils.isTrue(reply.getSpec().getApproved())
&& reply.getSpec().getApprovedTime() == null) {
reply.getSpec().setApprovedTime(Instant.now());
}
return reply;
})
.flatMap(replyToUse -> {
if (replyToUse.getSpec().getOwner() != null) {
Expand All @@ -85,21 +68,9 @@ public Mono<Reply> create(String commentName, Reply reply) {
return replyToUse;
})
.switchIfEmpty(
Mono.error(new IllegalStateException("Reply owner must not be null.")));
Mono.error(new IllegalArgumentException("Reply owner must not be null.")));
})
.flatMap(client::create)
.switchIfEmpty(Mono.error(
new IllegalArgumentException(
String.format("Comment not found for name [%s].", commentName)))
);
}

private boolean checkReplyOwner(Reply reply, Boolean onlySystemUser) {
Comment.CommentOwner owner = reply.getSpec().getOwner();
if (Boolean.TRUE.equals(onlySystemUser)) {
return owner != null && Comment.CommentOwner.KIND_EMAIL.equals(owner.getKind());
}
return false;
.flatMap(client::create);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder;

import io.swagger.v3.oas.annotations.enums.ParameterIn;
import java.time.Instant;
import org.springdoc.core.fn.builders.schema.Builder;
import org.springdoc.webflux.core.fn.SpringdocRouteBuilder;
import org.springframework.http.MediaType;
Expand Down Expand Up @@ -116,8 +117,15 @@ Mono<ServerResponse> createReply(ServerRequest request) {
return request.bodyToMono(ReplyRequest.class)
.flatMap(replyRequest -> {
Reply reply = replyRequest.toReply();
// Create via console without audit
reply.getSpec().setApproved(true);
reply.getSpec().setApprovedTime(Instant.now());
reply.getSpec().setIpAddress(IpAddressUtils.getIpAddress(request));
reply.getSpec().setUserAgent(HaloUtils.userAgentFrom(request));
// fix gh-2951
if (reply.getSpec().getHidden() == null) {
reply.getSpec().setHidden(false);
}
return replyService.create(commentName, reply);
})
.flatMap(comment -> ServerResponse.ok().bodyValue(comment));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package run.halo.app.theme.endpoint;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
import static org.apache.commons.lang3.BooleanUtils.isFalse;
import static org.apache.commons.lang3.BooleanUtils.isTrue;
import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder;
import static org.springdoc.core.fn.builders.content.Builder.contentBuilder;
import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder;
Expand All @@ -9,6 +12,7 @@
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springdoc.core.fn.builders.schema.Builder;
import org.springdoc.webflux.core.fn.SpringdocRouteBuilder;
Expand All @@ -32,6 +36,8 @@
import run.halo.app.extension.Ref;
import run.halo.app.extension.router.IListRequest;
import run.halo.app.extension.router.QueryParamBuildUtil;
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
import run.halo.app.infra.exception.AccessDeniedException;
import run.halo.app.infra.utils.HaloUtils;
import run.halo.app.infra.utils.IpAddressUtils;
import run.halo.app.theme.finders.CommentFinder;
Expand All @@ -42,25 +48,13 @@
* Endpoint for {@link CommentFinder}.
*/
@Component
@RequiredArgsConstructor
public class CommentFinderEndpoint implements CustomEndpoint {

private final CommentFinder commentFinder;
private final CommentService commentService;
private final ReplyService replyService;

/**
* Construct a {@link CommentFinderEndpoint} instance.
*
* @param commentFinder comment finder
* @param commentService comment service to create comment
* @param replyService reply service to create reply
*/
public CommentFinderEndpoint(CommentFinder commentFinder, CommentService commentService,
ReplyService replyService) {
this.commentFinder = commentFinder;
this.commentService = commentService;
this.replyService = replyService;
}
private final SystemConfigurableEnvironmentFetcher environmentFetcher;

@Override
public RouterFunction<ServerResponse> endpoint() {
Expand Down Expand Up @@ -158,15 +152,41 @@ Mono<ServerResponse> createReply(ServerRequest request) {
Reply reply = replyRequest.toReply();
reply.getSpec().setIpAddress(IpAddressUtils.getIpAddress(request));
reply.getSpec().setUserAgent(HaloUtils.userAgentFrom(request));
return replyService.create(commentName, reply);
// fix gh-2951
reply.getSpec().setHidden(false);
return environmentFetcher.fetchComment()
.map(commentSetting -> {
if (isFalse(commentSetting.getEnable())) {
throw new AccessDeniedException(
"The comment function has been turned off.",
"problemDetail.comment.turnedOff", null);
}
if (checkReplyOwner(reply, commentSetting.getSystemUserOnly())) {
throw new AccessDeniedException("Allow only system users to comment.",
"problemDetail.comment.systemUsersOnly", null);
}
reply.getSpec()
.setApproved(isFalse(commentSetting.getRequireReviewForNew()));
return reply;
})
.defaultIfEmpty(reply);
})
.flatMap(reply -> replyService.create(commentName, reply))
.flatMap(comment -> ServerResponse.ok().bodyValue(comment));
}

private boolean checkReplyOwner(Reply reply, Boolean onlySystemUser) {
Comment.CommentOwner owner = reply.getSpec().getOwner();
if (isTrue(onlySystemUser)) {
return owner != null && Comment.CommentOwner.KIND_EMAIL.equals(owner.getKind());
}
return false;
}

Mono<ServerResponse> listComments(ServerRequest request) {
CommentQuery commentQuery = new CommentQuery(request.queryParams());
return commentFinder.list(commentQuery.toRef(), commentQuery.getPage(),
commentQuery.getSize())
commentQuery.getSize())
.flatMap(list -> ServerResponse.ok().bodyValue(list));
}

Expand Down Expand Up @@ -196,7 +216,7 @@ public String getGroup() {
return queryParams.getFirst("group");
}

@Schema(required = true, description = "The comment subject version.")
@Schema(requiredMode = REQUIRED, description = "The comment subject version.")
public String getVersion() {
return emptyToNull(queryParams.getFirst("version"));
}
Expand All @@ -206,7 +226,7 @@ public String getVersion() {
*
* @return comment subject ref kind
*/
@Schema(required = true, description = "The comment subject kind.")
@Schema(requiredMode = REQUIRED, description = "The comment subject kind.")
public String getKind() {
String kind = emptyToNull(queryParams.getFirst("kind"));
if (kind == null) {
Expand All @@ -220,7 +240,7 @@ public String getKind() {
*
* @return comment subject ref name
*/
@Schema(required = true, description = "The comment subject name.")
@Schema(requiredMode = REQUIRED, description = "The comment subject name.")
public String getName() {
String name = emptyToNull(queryParams.getFirst("name"));
if (name == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand All @@ -26,6 +27,7 @@
import run.halo.app.core.extension.content.Reply;
import run.halo.app.extension.ListResult;
import run.halo.app.extension.Ref;
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
import run.halo.app.theme.finders.CommentFinder;

/**
Expand All @@ -42,6 +44,9 @@ class CommentFinderEndpointTest {
@Mock
private CommentService commentService;

@Mock
private SystemConfigurableEnvironmentFetcher environmentFetcher;

@Mock
private ReplyService replyService;

Expand All @@ -52,6 +57,7 @@ class CommentFinderEndpointTest {

@BeforeEach
void setUp() {
lenient().when(environmentFetcher.fetchComment()).thenReturn(Mono.empty());
webTestClient = WebTestClient
.bindToRouterFunction(commentFinderEndpoint.endpoint())
.build();
Expand Down