From a6b2c860762816b1958569de69ba1178cf7273aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B1=BC=E6=98=9F?= <1772580802@qq.com> Date: Fri, 12 Jun 2026 10:25:02 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=96=B0=E5=A2=9E=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 + .../config/SsoServerClientsProperties.java | 52 +++ .../controller/SsoDashboardController.java | 76 ++++ src/main/resources/static/index.html | 325 +++++++++++++++++- .../SsoDashboardControllerTest.java | 45 +++ 5 files changed, 499 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/ngskcloud/config/SsoServerClientsProperties.java create mode 100644 src/main/java/com/ngskcloud/controller/SsoDashboardController.java create mode 100644 src/test/java/com/ngskcloud/controller/SsoDashboardControllerTest.java diff --git a/pom.xml b/pom.xml index 76e2db5..00c78f0 100644 --- a/pom.xml +++ b/pom.xml @@ -257,6 +257,11 @@ + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0 + diff --git a/src/main/java/com/ngskcloud/config/SsoServerClientsProperties.java b/src/main/java/com/ngskcloud/config/SsoServerClientsProperties.java new file mode 100644 index 0000000..d293ff4 --- /dev/null +++ b/src/main/java/com/ngskcloud/config/SsoServerClientsProperties.java @@ -0,0 +1,52 @@ +package com.ngskcloud.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.LinkedHashMap; +import java.util.Map; + +@Component +@ConfigurationProperties(prefix = "sa-token.sso-server") +public class SsoServerClientsProperties { + + private Map clients = new LinkedHashMap<>(); + + public Map getClients() { + return clients; + } + + public void setClients(Map clients) { + this.clients = clients == null ? new LinkedHashMap<>() : clients; + } + + public static class Client { + private String client; + private String allowUrl; + private String secretKey; + + public String getClient() { + return client; + } + + public void setClient(String client) { + this.client = client; + } + + public String getAllowUrl() { + return allowUrl; + } + + public void setAllowUrl(String allowUrl) { + this.allowUrl = allowUrl; + } + + public String getSecretKey() { + return secretKey; + } + + public void setSecretKey(String secretKey) { + this.secretKey = secretKey; + } + } +} diff --git a/src/main/java/com/ngskcloud/controller/SsoDashboardController.java b/src/main/java/com/ngskcloud/controller/SsoDashboardController.java new file mode 100644 index 0000000..9e9d714 --- /dev/null +++ b/src/main/java/com/ngskcloud/controller/SsoDashboardController.java @@ -0,0 +1,76 @@ +package com.ngskcloud.controller; + +import com.ngskcloud.config.SsoServerClientsProperties; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.Instant; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/sso/dashboard") +public class SsoDashboardController { + + private final SsoServerClientsProperties properties; + + public SsoDashboardController(SsoServerClientsProperties properties) { + this.properties = properties; + } + + @GetMapping("/clients") + public DashboardClientsResponse clients() { + List clients = properties.getClients().entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .map(entry -> toView(entry.getKey(), entry.getValue())) + .toList(); + + return new DashboardClientsResponse(clients.size(), Instant.now().toString(), clients); + } + + private SsoClientView toView(String id, SsoServerClientsProperties.Client client) { + String name = valueOrFallback(client.getClient(), id); + String allowUrl = valueOrFallback(client.getAllowUrl(), "-"); + boolean secretConfigured = hasText(client.getSecretKey()); + String status = hasText(client.getClient()) && secretConfigured ? "CONFIGURED" : "INCOMPLETE"; + + return new SsoClientView( + id, + name, + allowUrl, + secretConfigured, + maskSecret(client.getSecretKey()), + status); + } + + private String maskSecret(String secretKey) { + if (!hasText(secretKey)) { + return ""; + } + if (secretKey.length() <= 10) { + return "****"; + } + return secretKey.substring(0, 7) + "****" + secretKey.substring(secretKey.length() - 3); + } + + private String valueOrFallback(String value, String fallback) { + return hasText(value) ? value : fallback; + } + + private boolean hasText(String value) { + return value != null && !value.trim().isEmpty(); + } + + public record DashboardClientsResponse(int total, String generatedAt, List clients) { + } + + public record SsoClientView( + String id, + String name, + String allowUrl, + boolean secretConfigured, + String secretPreview, + String status) { + } +} diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index 89bb8ba..01219e6 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -1,6 +1,323 @@ - + + + + + + SSO 接入平台看板 + + -

hello word!!!

-

this is a html page

+
+
+
+

SSO 接入平台看板

+

查看当前认证中心已配置的平台接入状态

+
+
+ +
+
+ +
+
+ 已配置平台 + 0 +
+
+ 密钥完整 + 0 +
+
+ 最后刷新 + -- +
+
+ +
+
+ + - \ No newline at end of file + diff --git a/src/test/java/com/ngskcloud/controller/SsoDashboardControllerTest.java b/src/test/java/com/ngskcloud/controller/SsoDashboardControllerTest.java new file mode 100644 index 0000000..c270b99 --- /dev/null +++ b/src/test/java/com/ngskcloud/controller/SsoDashboardControllerTest.java @@ -0,0 +1,45 @@ +package com.ngskcloud.controller; + +import com.ngskcloud.config.SsoServerClientsProperties; +import org.junit.jupiter.api.Test; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import java.util.LinkedHashMap; +import java.util.Map; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +class SsoDashboardControllerTest { + + @Test + void listsConfiguredClientsWithMaskedSecrets() throws Exception { + SsoServerClientsProperties.Client playedu = new SsoServerClientsProperties.Client(); + playedu.setClient("playedu-client"); + playedu.setAllowUrl("*"); + playedu.setSecretKey("SSO-C2-kQwIOrYvnXmSDkwEiFngrKidMcdrgKor"); + + SsoServerClientsProperties properties = new SsoServerClientsProperties(); + properties.setClients(new LinkedHashMap<>(Map.of("sso-client2", playedu))); + + MockMvc mockMvc = MockMvcBuilders + .standaloneSetup(new SsoDashboardController(properties)) + .build(); + + mockMvc.perform(get("/sso/dashboard/clients")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.total").value(1)) + .andExpect(jsonPath("$.clients[0].id").value("sso-client2")) + .andExpect(jsonPath("$.clients[0].name").value("playedu-client")) + .andExpect(jsonPath("$.clients[0].allowUrl").value("*")) + .andExpect(jsonPath("$.clients[0].secretConfigured").value(true)) + .andExpect(jsonPath("$.clients[0].secretPreview").value("SSO-C2-****Kor")) + .andExpect(jsonPath("$.clients[0].status").value("CONFIGURED")) + .andExpect(content().string(not(containsString("kQwIOrYvnXmSDkwEiFngrKidMcdrg")))); + } +}