diff --git a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/exception/BizException.java b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/exception/BizException.java index 6a893d3c9..87c6126a8 100644 --- a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/exception/BizException.java +++ b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/exception/BizException.java @@ -1,9 +1,12 @@ package org.lowcoder.sdk.exception; import lombok.Getter; +import org.apache.commons.lang3.StringUtils; import org.lowcoder.sdk.util.LocaleUtils; +import org.springframework.http.HttpHeaders; import java.util.Locale; +import java.util.Map; @Getter public class BizException extends BaseException { @@ -11,6 +14,7 @@ public class BizException extends BaseException { private final BizError error; private final String messageKey; private final transient Object[] args; + private transient HttpHeaders headers; public BizException(BizError error, String messageKey, Object... args) { super(LocaleUtils.getMessage(Locale.ENGLISH, messageKey, args)); @@ -19,6 +23,11 @@ public BizException(BizError error, String messageKey, Object... args) { this.args = args; } + public BizException(BizError error, String messageKey, HttpHeaders headers, Object... args) { + this(error, messageKey, args); + this.headers = headers; + } + public int getHttpStatus() { return error == null ? 500 : error.getHttpErrorCode(); } @@ -36,4 +45,13 @@ public String getMessage(Locale locale) { return error == null ? super.getMessage() : LocaleUtils.getMessage(locale, messageKey, args); } + public void addHeader(String header, String value) { + if (StringUtils.isAnyBlank(header, value)) { + return; + } + if (headers == null) { + headers = new HttpHeaders(); + } + headers.add(header, value); + } } diff --git a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/util/ExceptionUtils.java b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/util/ExceptionUtils.java index 74517586a..1fcc233c8 100644 --- a/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/util/ExceptionUtils.java +++ b/server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/util/ExceptionUtils.java @@ -1,6 +1,7 @@ package org.lowcoder.sdk.util; import org.lowcoder.sdk.exception.*; +import org.springframework.http.HttpHeaders; import reactor.core.publisher.Mono; import static reactor.core.Exceptions.throwIfFatal; @@ -18,6 +19,10 @@ public static Mono ofError(BizError errorCode, String messageKey, Object. return Mono.error(new BizException(errorCode, messageKey, args)); } + public static Mono ofErrorWithHeaders(BizError errorCode, String messageKey, HttpHeaders headers, Object... args) { + return Mono.error(new BizException(errorCode, messageKey, headers, args)); + } + public static BizException ofException(BizError errorCode, String messageKey, Object... args) { return new BizException(errorCode, messageKey, args); } diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiServiceImpl.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiServiceImpl.java index 7b8643c70..9f3a8eb3c 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiServiceImpl.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiServiceImpl.java @@ -45,6 +45,7 @@ import org.lowcoder.sdk.plugin.common.QueryExecutor; import org.lowcoder.sdk.util.ExceptionUtils; import org.springframework.context.annotation.Lazy; +import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -59,8 +60,7 @@ import static org.lowcoder.domain.application.model.ApplicationStatus.NORMAL; import static org.lowcoder.domain.permission.model.ResourceAction.*; import static org.lowcoder.sdk.exception.BizError.*; -import static org.lowcoder.sdk.util.ExceptionUtils.deferredError; -import static org.lowcoder.sdk.util.ExceptionUtils.ofError; +import static org.lowcoder.sdk.util.ExceptionUtils.*; @RequiredArgsConstructor @Service @@ -474,18 +474,29 @@ public Mono checkApplicationPermissionWithReadableErrorMsg(S .flatMap(visitorId -> resourcePermissionService.checkUserPermissionStatusOnApplication(visitorId, applicationId, action, requestType)) .flatMap(permissionStatus -> { if (!permissionStatus.hasPermission()) { + + String orgId = applicationService.findById(applicationId) + .map(Application::getOrganizationId) + .onErrorReturn("") + .block(); + + HttpHeaders headers = new HttpHeaders(); + if (StringUtils.isNotBlank(orgId)) { + headers.add("X-ORG-ID", orgId); + } + if (permissionStatus.failByAnonymousUser()) { - return ofError(USER_NOT_SIGNED_IN, "USER_NOT_SIGNED_IN"); + return ofErrorWithHeaders(USER_NOT_SIGNED_IN, "USER_NOT_SIGNED_IN", headers); } if (permissionStatus.failByNotInOrg()) { - return ofError(NO_PERMISSION_TO_REQUEST_APP, "INSUFFICIENT_PERMISSION"); + return ofErrorWithHeaders(NO_PERMISSION_TO_REQUEST_APP, "INSUFFICIENT_PERMISSION", headers); } return suggestAppAdminSolutionService.getSuggestAppAdminNames(applicationId) .flatMap(names -> { String messageKey = action == EDIT_APPLICATIONS ? "NO_PERMISSION_TO_EDIT" : "NO_PERMISSION_TO_VIEW"; - return ofError(NO_PERMISSION_TO_REQUEST_APP, messageKey, names); + return ofErrorWithHeaders(NO_PERMISSION_TO_REQUEST_APP, messageKey, headers, names); }); } return Mono.just(permissionStatus.getPermission()); diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/exception/CustomErrorWebExceptionHandler.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/exception/CustomErrorWebExceptionHandler.java index 07f0785e9..f3084845c 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/exception/CustomErrorWebExceptionHandler.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/exception/CustomErrorWebExceptionHandler.java @@ -93,7 +93,12 @@ private Mono render(ServerRequest request) { } Locale locale = globalContextService.getClientLocale(request); - return ServerResponse.status(bizException.getError().getHttpErrorCode()) + + ServerResponse.BodyBuilder response = ServerResponse.status(bizException.getError().getHttpErrorCode()); + if (bizException.getHeaders() != null && !bizException.getHeaders().isEmpty()) { + response.headers(headersBuilder -> headersBuilder.addAll(bizException.getHeaders())); + } + return response .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue(ResponseView.error(bizException.getError().getBizErrorCode(), LocaleUtils.getMessage(locale, bizException.getMessageKey(), bizException.getArgs())))); diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/exception/GlobalExceptionHandler.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/exception/GlobalExceptionHandler.java index 75bea8ddb..edd37f469 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/exception/GlobalExceptionHandler.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/exception/GlobalExceptionHandler.java @@ -51,6 +51,9 @@ public Mono> catchBizException(BizException e, ServerWebExchange apiPerfHelper.perf(e.getError(), exchange.getRequest().getPath()); doLog(e, ctx, e.getError().logVerbose()); Locale locale = getLocale(ctx); + if (e.getHeaders() != null && !e.getHeaders().isEmpty()) { + exchange.getResponse().getHeaders().addAll(e.getHeaders()); + } return Mono.just(error(e.getBizErrorCode(), e.getMessage(locale))); }); }