-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: John Niang <[email protected]>
- Loading branch information
Showing
63 changed files
with
4,101 additions
and
1,678 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 0 additions & 46 deletions
46
application/src/main/java/run/halo/app/core/extension/service/DefaultRoleBindingService.java
This file was deleted.
Oops, something went wrong.
16 changes: 0 additions & 16 deletions
16
application/src/main/java/run/halo/app/core/extension/service/RoleBindingService.java
This file was deleted.
Oops, something went wrong.
63 changes: 63 additions & 0 deletions
63
application/src/main/java/run/halo/app/infra/exception/RequestBodyValidationException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package run.halo.app.infra.exception; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Locale; | ||
import org.springframework.context.MessageSource; | ||
import org.springframework.context.MessageSourceResolvable; | ||
import org.springframework.http.ProblemDetail; | ||
import org.springframework.lang.Nullable; | ||
import org.springframework.validation.BindingResult; | ||
import org.springframework.web.server.ServerWebInputException; | ||
import org.springframework.web.util.BindErrorUtils; | ||
|
||
public class RequestBodyValidationException extends ServerWebInputException { | ||
|
||
private final BindingResult bindingResult; | ||
|
||
public RequestBodyValidationException(BindingResult bindingResult) { | ||
super("Validation failure", null, null, null, null); | ||
this.bindingResult = bindingResult; | ||
} | ||
|
||
@Override | ||
public ProblemDetail updateAndGetBody(MessageSource messageSource, Locale locale) { | ||
var detail = super.updateAndGetBody(messageSource, locale); | ||
detail.setProperty("errors", collectAllErrors(messageSource, locale)); | ||
return detail; | ||
} | ||
|
||
private List<String> collectAllErrors(MessageSource messageSource, Locale locale) { | ||
var globalErrors = resolveErrors(bindingResult.getGlobalErrors(), messageSource, locale); | ||
var fieldErrors = resolveErrors(bindingResult.getFieldErrors(), messageSource, locale); | ||
var errors = new ArrayList<String>(globalErrors.size() + fieldErrors.size()); | ||
errors.addAll(globalErrors); | ||
errors.addAll(fieldErrors); | ||
return errors; | ||
} | ||
|
||
@Override | ||
public Object[] getDetailMessageArguments(MessageSource messageSource, Locale locale) { | ||
return new Object[] { | ||
resolveErrors(bindingResult.getGlobalErrors(), messageSource, locale), | ||
resolveErrors(bindingResult.getFieldErrors(), messageSource, locale) | ||
}; | ||
} | ||
|
||
@Override | ||
public Object[] getDetailMessageArguments() { | ||
return new Object[] { | ||
resolveErrors(bindingResult.getGlobalErrors(), null, Locale.getDefault()), | ||
resolveErrors(bindingResult.getFieldErrors(), null, Locale.getDefault()) | ||
}; | ||
} | ||
|
||
private static List<String> resolveErrors( | ||
List<? extends MessageSourceResolvable> errors, | ||
@Nullable MessageSource messageSource, | ||
Locale locale) { | ||
return messageSource == null | ||
? BindErrorUtils.resolve(errors).values().stream().toList() | ||
: BindErrorUtils.resolve(errors, messageSource, locale).values().stream().toList(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
application/src/main/java/run/halo/app/security/ExceptionSecurityConfigurer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package run.halo.app.security; | ||
|
||
import org.springframework.security.access.AccessDeniedException; | ||
import org.springframework.security.config.web.server.ServerHttpSecurity; | ||
import org.springframework.security.oauth2.server.resource.web.access.server.BearerTokenServerAccessDeniedHandler; | ||
import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler; | ||
import org.springframework.security.web.server.authorization.ServerWebExchangeDelegatingServerAccessDeniedHandler; | ||
import org.springframework.security.web.server.authorization.ServerWebExchangeDelegatingServerAccessDeniedHandler.DelegateEntry; | ||
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.server.ServerWebExchange; | ||
import reactor.core.publisher.Mono; | ||
import run.halo.app.security.authentication.SecurityConfigurer; | ||
import run.halo.app.security.authentication.mfa.MfaAuthentication; | ||
import run.halo.app.security.authentication.mfa.MfaResponseHandler; | ||
|
||
@Component | ||
public class ExceptionSecurityConfigurer implements SecurityConfigurer { | ||
|
||
private final MfaResponseHandler mfaResponseHandler; | ||
|
||
public ExceptionSecurityConfigurer(MfaResponseHandler mfaResponseHandler) { | ||
this.mfaResponseHandler = mfaResponseHandler; | ||
} | ||
|
||
@Override | ||
public void configure(ServerHttpSecurity http) { | ||
http.exceptionHandling(exception -> { | ||
var mfaAccessDeniedHandler = new MfaAccessDeniedHandler(); | ||
var mfaEntry = | ||
new DelegateEntry(mfaAccessDeniedHandler.getMatcher(), mfaAccessDeniedHandler); | ||
var accessDeniedHandler = | ||
new ServerWebExchangeDelegatingServerAccessDeniedHandler(mfaEntry); | ||
accessDeniedHandler.setDefaultAccessDeniedHandler( | ||
new BearerTokenServerAccessDeniedHandler()); | ||
exception.authenticationEntryPoint(new DefaultServerAuthenticationEntryPoint()) | ||
.accessDeniedHandler(accessDeniedHandler); | ||
}); | ||
} | ||
|
||
private class MfaAccessDeniedHandler implements ServerAccessDeniedHandler { | ||
|
||
private final ServerWebExchangeMatcher matcher; | ||
|
||
private MfaAccessDeniedHandler() { | ||
matcher = exchange -> exchange.getPrincipal() | ||
.filter(MfaAuthentication.class::isInstance) | ||
.flatMap(a -> ServerWebExchangeMatcher.MatchResult.match()) | ||
.switchIfEmpty(Mono.defer(ServerWebExchangeMatcher.MatchResult::notMatch)); | ||
} | ||
|
||
@Override | ||
public Mono<Void> handle(ServerWebExchange exchange, AccessDeniedException denied) { | ||
return mfaResponseHandler.handle(exchange); | ||
} | ||
|
||
public ServerWebExchangeMatcher getMatcher() { | ||
return matcher; | ||
} | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
application/src/main/java/run/halo/app/security/LogoutSecurityConfigurer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package run.halo.app.security; | ||
|
||
import static org.springframework.security.config.web.server.SecurityWebFiltersOrder.LOGOUT_PAGE_GENERATING; | ||
import static run.halo.app.security.authentication.WebExchangeMatchers.ignoringMediaTypeAll; | ||
|
||
import java.net.URI; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.security.config.web.server.ServerHttpSecurity; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.web.server.WebFilterExchange; | ||
import org.springframework.security.web.server.authentication.logout.RedirectServerLogoutSuccessHandler; | ||
import org.springframework.security.web.server.authentication.logout.ServerLogoutSuccessHandler; | ||
import org.springframework.security.web.server.ui.LogoutPageGeneratingWebFilter; | ||
import org.springframework.stereotype.Component; | ||
import reactor.core.publisher.Mono; | ||
import run.halo.app.security.authentication.SecurityConfigurer; | ||
|
||
@Component | ||
public class LogoutSecurityConfigurer implements SecurityConfigurer { | ||
|
||
@Override | ||
public void configure(ServerHttpSecurity http) { | ||
http.logout(logout -> logout.logoutSuccessHandler(new LogoutSuccessHandler())); | ||
http.addFilterAt(new LogoutPageGeneratingWebFilter(), LOGOUT_PAGE_GENERATING); | ||
} | ||
|
||
public static class LogoutSuccessHandler implements ServerLogoutSuccessHandler { | ||
|
||
private final ServerLogoutSuccessHandler defaultHandler; | ||
|
||
public LogoutSuccessHandler() { | ||
var defaultHandler = new RedirectServerLogoutSuccessHandler(); | ||
defaultHandler.setLogoutSuccessUrl(URI.create("/console/?logout")); | ||
this.defaultHandler = defaultHandler; | ||
} | ||
|
||
@Override | ||
public Mono<Void> onLogoutSuccess(WebFilterExchange exchange, | ||
Authentication authentication) { | ||
return ignoringMediaTypeAll(MediaType.APPLICATION_JSON).matches(exchange.getExchange()) | ||
.flatMap(matchResult -> { | ||
if (matchResult.isMatch()) { | ||
var response = exchange.getExchange().getResponse(); | ||
response.setStatusCode(HttpStatus.NO_CONTENT); | ||
return response.setComplete(); | ||
} | ||
return defaultHandler.onLogoutSuccess(exchange, authentication); | ||
}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.