M3 fix: /sync 端点改 Mono 返回(WebFlux 禁 block)
CodeQL Advanced / Analyze (actions) (push) Canceled after 0s
CodeQL Advanced / Analyze (java-kotlin) (push) Canceled after 0s
CodeQL Advanced / Analyze (javascript-typescript) (push) Canceled after 0s
CodeQL Advanced / Analyze (python) (push) Canceled after 0s
Docker Image Build & Push / manifest (push) Canceled after 0s
Docker Image Build & Push / build-and-push-arm (push) Canceled after 0s
Docker Image Build & Push / build-and-push-amd (push) Canceled after 0s
Gateway Docker Image CI / Build and Push Gateway Docker Image (push) Canceled after 0s

This commit is contained in:
figmar
2026-08-31 14:11:43 +08:00
parent ab1255a1eb
commit 8e5121ed0d
@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@@ -57,30 +58,28 @@ public class CasdoorSsoConfigController {
} }
/** /**
* 手动全量同步(admin only)。 * 手动全量同步(admin only)。WebFlux 事件循环线程不可 block,返回 Mono。
*/ */
@PostMapping("/sync") @PostMapping("/sync")
public ResponseEntity<Response<Map<String, Object>>> sync(ServerWebExchange exchange) { public Mono<ResponseEntity<Response<Map<String, Object>>>> sync(ServerWebExchange exchange) {
if (!props.isEnabled() || !props.isAccountOnly()) { if (!props.isEnabled() || !props.isAccountOnly()) {
return ResponseEntity.status(HttpStatus.FORBIDDEN) return Mono.just(ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(new Response<>("casdoor.disabled", "Casdoor 账号同步未启用", null)); .body(new Response<>("casdoor.disabled", "Casdoor 账号同步未启用", null)));
} }
String username = currentUsername(exchange); String username = currentUsername(exchange);
if (username == null || !isAdmin(username)) { if (username == null || !isAdmin(username)) {
log.warn("casdoor sync rejected: caller={}", username); log.warn("casdoor sync rejected: caller={}", username);
return ResponseEntity.status(HttpStatus.FORBIDDEN) return Mono.just(ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(new Response<>("casdoor.forbidden", "仅管理员可触发账号同步", null)); .body(new Response<>("casdoor.forbidden", "仅管理员可触发账号同步", null)));
} }
return syncService.syncFull() return syncService.syncFull()
.map(summary -> ResponseEntity.ok(Response.ok(summary))) .map(summary -> ResponseEntity.ok(Response.ok(summary)))
.onErrorResume(e -> { .onErrorResume(e -> {
log.error("casdoor manual sync failed: {}", e.getMessage()); log.error("casdoor manual sync failed: {}", e.getMessage());
return reactor.core.publisher.Mono.just( return Mono.just(ResponseEntity.status(HttpStatus.BAD_GATEWAY)
ResponseEntity.status(HttpStatus.BAD_GATEWAY) .body(new Response<>("casdoor.sync_failed",
.body(new Response<>("casdoor.sync_failed", "同步失败: " + e.getMessage(), null)));
"同步失败: " + e.getMessage(), null))); });
})
.block();
} }
private String currentUsername(ServerWebExchange exchange) { private String currentUsername(ServerWebExchange exchange) {