Skip to content

Fix plugin endpoint invocation #1356

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

Merged
merged 2 commits into from
Nov 28, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -34,4 +34,6 @@ private NewUrl() {
public static final String MATERIAL_URL = PREFIX + "/materials";
public static final String CONTACT_SYNC = PREFIX + "/sync";
public static final String NPM_REGISTRY = PREFIX + "/npm";

public static final String PLUGINS_URL = PREFIX + "/plugins";
}
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ public enum BizError {

// 5000 - 5100 general errorCode
INTERNAL_SERVER_ERROR(500, 5000, VERBOSE),
NOT_AUTHORIZED(500, 5001),
NOT_AUTHORIZED(401, 5001),
INVALID_PARAMETER(500, 5002),
UNSUPPORTED_OPERATION(400, 5003),
DUPLICATE_KEY(409, 5004, VERBOSE),
@@ -113,6 +113,7 @@ public enum BizError {
PLUGIN_EXECUTION_TIMEOUT(504, 5800),
INVALID_DATASOURCE_TYPE(500, 5801),
PLUGIN_EXECUTION_TIMEOUT_WITHOUT_TIME(504, 5802, VERBOSE),
PLUGIN_ENDPOINT_ERROR(500, 5850),

// business related, code range 5900 - 5999
NOT_RELEASE(423, 5901),
Original file line number Diff line number Diff line change
@@ -8,7 +8,9 @@
import java.util.Map;
import java.util.concurrent.TimeoutException;

import org.apache.commons.lang3.StringUtils;
import org.lowcoder.api.framework.view.ResponseView;
import org.lowcoder.infra.constant.NewUrl;
import org.lowcoder.infra.util.LogUtils;
import org.lowcoder.sdk.exception.BaseException;
import org.lowcoder.sdk.exception.BizError;
@@ -26,6 +28,7 @@
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.support.WebExchangeBindException;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException;

@@ -133,6 +136,23 @@ public Mono<ResponseView<?>> catchServerException(ServerException e, ServerWebEx
});
}

@ExceptionHandler
@ResponseBody
public Mono<ResponseView<?>> catchResponseStatusException(ResponseStatusException e, ServerWebExchange exchange) {
if (StringUtils.startsWith(exchange.getRequest().getPath().toString(), NewUrl.PLUGINS_URL + "/")) {
BizError bizError = BizError.PLUGIN_ENDPOINT_ERROR;
exchange.getResponse().setStatusCode(e.getStatusCode());
return Mono.deferContextual(ctx -> {
apiPerfHelper.perf(bizError, exchange.getRequest().getPath());
doLog(e, ctx, bizError.logVerbose());
return Mono.just(error(bizError.getBizErrorCode(), e.getMessage() + " - path: " + exchange.getRequest().getPath()));
});

} else {
return catchException(e, exchange);
}
}

@ExceptionHandler
@ResponseBody
public Mono<ResponseView<?>> catchException(java.lang.Exception e, ServerWebExchange exchange) {
Original file line number Diff line number Diff line change
@@ -132,7 +132,10 @@ public Mono<ServerResponse> runPluginEndpointMethod(PluginEndpoint endpoint, End
});

return decisionMono.<EndpointResponse>handle((authorizationDecision, sink) -> {
if(!authorizationDecision.isGranted()) sink.error(new BizException(NOT_AUTHORIZED, "NOT_AUTHORIZED"));
if(!authorizationDecision.isGranted()) {
sink.error(new BizException(NOT_AUTHORIZED, "NOT_AUTHORIZED"));
return;
}
try {
sink.next((EndpointResponse) handler.invoke(endpoint, PluginServerRequest.fromServerRequest(request)));
} catch (IllegalAccessException | InvocationTargetException e) {
Original file line number Diff line number Diff line change
@@ -31,11 +31,12 @@ public PluginAuthorizationManager()
public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, MethodInvocation invocation)
{
log.info("Checking plugin reactive endpoint invocation security for {}", invocation.getMethod().getName());

EndpointExtension endpointExtension = (EndpointExtension)invocation.getArguments()[1];
if (endpointExtension == null || StringUtils.isBlank(endpointExtension.authorize()))
{
return Mono.empty();
log.debug("Authorization expression is empty, proceeding without authorization - authorization granted.");
return Mono.just(new AuthorizationDecision(true));
}

Expression authorizeExpression = this.expressionHandler.getExpressionParser()