From 155ab8f6d5091dc406a4bba504e46c7a87d75095 Mon Sep 17 00:00:00 2001 From: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com> Date: Tue, 28 Jul 2026 22:16:45 +0800 Subject: [PATCH] fix(auth): hide placeholder OAuth providers Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com> --- .../skillhub/service/AuthMethodCatalog.java | 7 ++-- .../controller/AuthControllerTest.java | 16 ++++------ .../service/AuthMethodCatalogTest.java | 32 +++++++++++++++++++ 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AuthMethodCatalog.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AuthMethodCatalog.java index cc927801..8c63cb9d 100644 --- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AuthMethodCatalog.java +++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/service/AuthMethodCatalog.java @@ -12,6 +12,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Locale; import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties; import org.springframework.stereotype.Service; @@ -56,16 +57,14 @@ public class AuthMethodCatalog { } /** - * Check if an OAuth provider has valid configuration (non-empty client-id that is not a placeholder). + * Checks whether an OAuth provider has a non-empty, non-placeholder client ID. */ private boolean isValidOAuthProvider(OAuth2ClientProperties.Registration registration) { String clientId = registration.getClientId(); if (clientId == null || clientId.isBlank()) { return false; } - // Filter out placeholder values used in dev/test configs - String lowerClientId = clientId.toLowerCase(); - return !lowerClientId.contains("placeholder") && !lowerClientId.contains("local-placeholder"); + return !clientId.toLowerCase(Locale.ROOT).contains("placeholder"); } public List listMethods(String returnTo) { diff --git a/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/AuthControllerTest.java b/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/AuthControllerTest.java index d79d368a..8e4118c6 100644 --- a/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/AuthControllerTest.java +++ b/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/AuthControllerTest.java @@ -150,13 +150,9 @@ class AuthControllerTest { mockMvc.perform(get("/api/v1/auth/providers")) .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value(0)) - .andExpect(jsonPath("$.data.length()").value(3)) - .andExpect(jsonPath("$.data[*].id", hasItems("github", "gitee", "gitlab"))) - .andExpect(jsonPath("$.data[*].authorizationUrl", hasItems( - "/oauth2/authorization/github", - "/oauth2/authorization/gitee", - "/oauth2/authorization/gitlab" - ))) + .andExpect(jsonPath("$.data.length()").value(1)) + .andExpect(jsonPath("$.data[*].id", hasItems("github"))) + .andExpect(jsonPath("$.data[*].authorizationUrl", hasItems("/oauth2/authorization/github"))) .andExpect(jsonPath("$.timestamp").isNotEmpty()) .andExpect(jsonPath("$.requestId").isNotEmpty()); } @@ -167,8 +163,7 @@ class AuthControllerTest { .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value(0)) .andExpect(jsonPath("$.data[*].authorizationUrl", hasItems( - "/oauth2/authorization/github?returnTo=%2Fdashboard%2Fpublish", - "/oauth2/authorization/gitee?returnTo=%2Fdashboard%2Fpublish" + "/oauth2/authorization/github?returnTo=%2Fdashboard%2Fpublish" ))); } @@ -177,7 +172,8 @@ class AuthControllerTest { mockMvc.perform(get("/api/v1/auth/methods").param("returnTo", "/dashboard/publish")) .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value(0)) - .andExpect(jsonPath("$.data[*].id", hasItems("local-password", "oauth-github", "oauth-gitee"))) + .andExpect(jsonPath("$.data.length()").value(2)) + .andExpect(jsonPath("$.data[*].id", hasItems("local-password", "oauth-github"))) .andExpect(jsonPath("$.data[?(@.id=='local-password')].methodType").value(hasItems("PASSWORD"))) .andExpect(jsonPath("$.data[?(@.id=='oauth-github')].actionUrl") .value(hasItems("/oauth2/authorization/github?returnTo=%2Fdashboard%2Fpublish"))); diff --git a/server/skillhub-app/src/test/java/com/iflytek/skillhub/service/AuthMethodCatalogTest.java b/server/skillhub-app/src/test/java/com/iflytek/skillhub/service/AuthMethodCatalogTest.java index 35ca8d75..e9ef372f 100644 --- a/server/skillhub-app/src/test/java/com/iflytek/skillhub/service/AuthMethodCatalogTest.java +++ b/server/skillhub-app/src/test/java/com/iflytek/skillhub/service/AuthMethodCatalogTest.java @@ -16,6 +16,31 @@ import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2Clien class AuthMethodCatalogTest { + @Test + void catalogsShouldHideEmptyAndPlaceholderOAuthProviders() { + OAuth2ClientProperties oauthProperties = new OAuth2ClientProperties(); + oauthProperties.getRegistration().put("valid", registration("production-client", "Valid")); + oauthProperties.getRegistration().put("missing", registration(null, "Missing")); + oauthProperties.getRegistration().put("blank", registration(" ", "Blank")); + oauthProperties.getRegistration().put("placeholder", registration("PLACEHOLDER", "Placeholder")); + oauthProperties.getRegistration().put("local", registration("local-placeholder", "Local")); + + AuthMethodCatalog catalog = new AuthMethodCatalog( + oauthProperties, + new DirectAuthProperties(), + new AuthSessionBootstrapProperties(), + List.of(), + List.of() + ); + + assertThat(catalog.listOAuthProviders(null)) + .extracting(provider -> provider.id()) + .containsExactly("valid"); + assertThat(catalog.listMethods(null)) + .extracting(method -> method.id()) + .containsExactly("local-password", "oauth-valid"); + } + @Test void listMethodsShouldUseProviderDisplayNamesForCompatibleAuthMethods() { OAuth2ClientProperties oauthProperties = new OAuth2ClientProperties(); @@ -122,4 +147,11 @@ class AuthMethodCatalogTest { "bootstrap-private-sso:private-sso" ); } + + private static OAuth2ClientProperties.Registration registration(String clientId, String clientName) { + OAuth2ClientProperties.Registration registration = new OAuth2ClientProperties.Registration(); + registration.setClientId(clientId); + registration.setClientName(clientName); + return registration; + } }