mirror of https://github.com/halo-dev/halo
Remap RequestNotPermittedException with RateLimitExceededException (#4119)
parent
8c05a6d30e
commit
ecc617c709
|
@ -0,0 +1,15 @@
|
|||
package run.halo.app.infra.exception;
|
||||
|
||||
import java.net.URI;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
public class RateLimitExceededException extends ResponseStatusException {
|
||||
|
||||
public RateLimitExceededException(@Nullable Throwable cause) {
|
||||
super(HttpStatus.TOO_MANY_REQUESTS, "You have exceeded your quota", cause);
|
||||
setType(URI.create(Exceptions.REQUEST_NOT_PERMITTED_TYPE));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package run.halo.app.security.authentication.login;
|
||||
|
||||
import static org.springframework.http.HttpStatus.TOO_MANY_REQUESTS;
|
||||
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON;
|
||||
import static run.halo.app.infra.exception.Exceptions.createErrorResponse;
|
||||
|
@ -39,6 +38,7 @@ import org.springframework.web.reactive.function.server.ServerResponse;
|
|||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.infra.exception.RateLimitExceededException;
|
||||
import run.halo.app.infra.utils.IpAddressUtils;
|
||||
import run.halo.app.security.AdditionalWebFilter;
|
||||
|
||||
|
@ -136,9 +136,9 @@ public class UsernamePasswordAuthenticator implements AdditionalWebFilter {
|
|||
return RateLimiterOperator.of(rateLimiter);
|
||||
}
|
||||
|
||||
private Mono<Void> handleRequestNotPermitted(RequestNotPermitted e,
|
||||
private Mono<Void> handleRateLimitExceededException(RateLimitExceededException e,
|
||||
ServerWebExchange exchange) {
|
||||
var errorResponse = createErrorResponse(e, TOO_MANY_REQUESTS, exchange, messageSource);
|
||||
var errorResponse = createErrorResponse(e, null, exchange, messageSource);
|
||||
return writeErrorResponse(errorResponse, exchange);
|
||||
}
|
||||
|
||||
|
@ -168,8 +168,9 @@ public class UsernamePasswordAuthenticator implements AdditionalWebFilter {
|
|||
WebFilterExchange webFilterExchange) {
|
||||
return super.onAuthenticationSuccess(authentication, webFilterExchange)
|
||||
.transformDeferred(createIPBasedRateLimiter(webFilterExchange.getExchange()))
|
||||
.onErrorResume(RequestNotPermitted.class,
|
||||
e -> handleRequestNotPermitted(e, webFilterExchange.getExchange()));
|
||||
.onErrorMap(RequestNotPermitted.class, RateLimitExceededException::new)
|
||||
.onErrorResume(RateLimitExceededException.class,
|
||||
e -> handleRateLimitExceededException(e, webFilterExchange.getExchange()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,8 +231,9 @@ public class UsernamePasswordAuthenticator implements AdditionalWebFilter {
|
|||
)
|
||||
.flatMap(matchResult -> handleAuthenticationException(exception, exchange))
|
||||
.transformDeferred(createIPBasedRateLimiter(exchange))
|
||||
.onErrorResume(RequestNotPermitted.class,
|
||||
e -> handleRequestNotPermitted(e, exchange));
|
||||
.onErrorMap(RequestNotPermitted.class, RateLimitExceededException::new)
|
||||
.onErrorResume(RateLimitExceededException.class,
|
||||
e -> handleRateLimitExceededException(e, exchange));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuil
|
|||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
|
||||
import io.github.resilience4j.ratelimiter.RequestNotPermitted;
|
||||
import io.github.resilience4j.reactor.ratelimiter.operator.RateLimiterOperator;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import io.swagger.v3.oas.annotations.media.ArraySchema;
|
||||
|
@ -50,6 +51,7 @@ 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.exception.RateLimitExceededException;
|
||||
import run.halo.app.infra.utils.HaloUtils;
|
||||
import run.halo.app.infra.utils.IpAddressUtils;
|
||||
import run.halo.app.theme.finders.CommentFinder;
|
||||
|
@ -157,8 +159,9 @@ public class CommentFinderEndpoint implements CustomEndpoint {
|
|||
comment.getSpec().setUserAgent(HaloUtils.userAgentFrom(request));
|
||||
return commentService.create(comment);
|
||||
})
|
||||
.flatMap(comment -> ServerResponse.ok().bodyValue(comment))
|
||||
.transformDeferred(createIpBasedRateLimiter(request))
|
||||
.flatMap(comment -> ServerResponse.ok().bodyValue(comment));
|
||||
.onErrorMap(RequestNotPermitted.class, RateLimitExceededException::new);
|
||||
}
|
||||
|
||||
private <T> RateLimiterOperator<T> createIpBasedRateLimiter(ServerRequest request) {
|
||||
|
|
|
@ -18,7 +18,7 @@ problemDetail.title.run.halo.app.infra.exception.ThemeUpgradeException=Theme Upg
|
|||
problemDetail.title.run.halo.app.infra.exception.PluginInstallationException=Plugin Install Error
|
||||
problemDetail.title.run.halo.app.infra.exception.PluginAlreadyExistsException=Plugin Already Exists Error
|
||||
problemDetail.title.run.halo.app.infra.exception.DuplicateNameException=Duplicate Name Error
|
||||
problemDetail.title.io.github.resilience4j.ratelimiter.RequestNotPermitted=Request Not Permitted
|
||||
problemDetail.title.run.halo.app.infra.exception.RateLimitExceededException=Request Not Permitted
|
||||
problemDetail.title.internalServerError=Internal Server Error
|
||||
|
||||
# Detail definitions
|
||||
|
@ -36,7 +36,7 @@ problemDetail.run.halo.app.extension.exception.SchemaViolationException={1} of s
|
|||
problemDetail.run.halo.app.infra.exception.AttachmentAlreadyExistsException=File {0} already exists, please rename it and try again.
|
||||
problemDetail.run.halo.app.infra.exception.DuplicateNameException=Duplicate name detected, please rename it and retry.
|
||||
problemDetail.run.halo.app.infra.exception.PluginAlreadyExistsException=Plugin {0} already exists.
|
||||
problemDetail.io.github.resilience4j.ratelimiter.RequestNotPermitted=API rate limit exceeded, please try again later.
|
||||
problemDetail.run.halo.app.infra.exception.RateLimitExceededException=API rate limit exceeded, please try again later.
|
||||
|
||||
problemDetail.user.signUpFailed.disallowed=System does not allow new users to register.
|
||||
problemDetail.user.duplicateName=The username {0} already exists, please rename it and retry.
|
||||
|
|
|
@ -6,14 +6,14 @@ problemDetail.title.run.halo.app.infra.exception.AttachmentAlreadyExistsExceptio
|
|||
problemDetail.title.run.halo.app.infra.exception.DuplicateNameException=名称重复
|
||||
problemDetail.title.run.halo.app.infra.exception.PluginAlreadyExistsException=插件已存在
|
||||
problemDetail.title.run.halo.app.infra.exception.ThemeInstallationException=主题安装失败
|
||||
problemDetail.title.io.github.resilience4j.ratelimiter.RequestNotPermitted=请求限制
|
||||
problemDetail.title.run.halo.app.infra.exception.RateLimitExceededException=请求限制
|
||||
problemDetail.title.internalServerError=服务器内部错误
|
||||
|
||||
problemDetail.org.springframework.security.authentication.BadCredentialsException=用户名或密码错误。
|
||||
problemDetail.run.halo.app.infra.exception.AttachmentAlreadyExistsException=文件 {0} 已存在,建议更名后重试。
|
||||
problemDetail.run.halo.app.infra.exception.DuplicateNameException=检测到有重复的名称,请重命名后重试。
|
||||
problemDetail.run.halo.app.infra.exception.PluginAlreadyExistsException=插件 {0} 已经存。
|
||||
problemDetail.io.github.resilience4j.ratelimiter.RequestNotPermitted=请求过于频繁,请稍候再试。
|
||||
problemDetail.run.halo.app.infra.exception.RateLimitExceededException=请求过于频繁,请稍候再试。
|
||||
|
||||
problemDetail.user.signUpFailed.disallowed=系统不允许注册新用户。
|
||||
problemDetail.user.duplicateName=用户名 {0} 已存在,请更换用户名后重试。
|
||||
|
|
Loading…
Reference in New Issue