feat(auth): OidcProviderNameDeriver — issuer URI → display label
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package com.cameleer.server.app.security;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Pure utility — derives a display label for an OIDC provider from its issuer URI.
|
||||
* Used by {@link AuthCapabilitiesController} so the SPA can render
|
||||
* "Sign in with {providerName}" on the login page.
|
||||
*
|
||||
* <p>Pattern-match only — never network-discover. If the issuer doesn't match a
|
||||
* known vendor pattern, we return the generic "Single Sign-On" label rather than
|
||||
* leaking hostnames into the UI.
|
||||
*/
|
||||
public final class OidcProviderNameDeriver {
|
||||
|
||||
private static final String GENERIC = "Single Sign-On";
|
||||
|
||||
private OidcProviderNameDeriver() {}
|
||||
|
||||
public static String deriveName(String issuerUri) {
|
||||
if (issuerUri == null || issuerUri.isBlank()) {
|
||||
return GENERIC;
|
||||
}
|
||||
String host;
|
||||
try {
|
||||
URI uri = URI.create(issuerUri.trim());
|
||||
host = uri.getHost();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return GENERIC;
|
||||
}
|
||||
if (host == null || host.isBlank()) {
|
||||
return GENERIC;
|
||||
}
|
||||
String h = host.toLowerCase();
|
||||
if (h.contains("logto")) return "Logto";
|
||||
if (h.contains("keycloak")) return "Keycloak";
|
||||
if (h.endsWith("auth0.com")) return "Auth0";
|
||||
if (h.endsWith("okta.com") || h.endsWith("oktapreview.com")) return "Okta";
|
||||
return GENERIC;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.cameleer.server.app.security;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/** Unit tests for {@link OidcProviderNameDeriver}. No Spring context. */
|
||||
class OidcProviderNameDeriverTest {
|
||||
|
||||
@Test
|
||||
void logtoIssuer_returnsLogto() {
|
||||
assertThat(OidcProviderNameDeriver.deriveName("https://auth.logto.example/")).isEqualTo("Logto");
|
||||
assertThat(OidcProviderNameDeriver.deriveName("https://logto.cameleer.local")).isEqualTo("Logto");
|
||||
}
|
||||
|
||||
@Test
|
||||
void keycloakIssuer_returnsKeycloak() {
|
||||
assertThat(OidcProviderNameDeriver.deriveName("https://keycloak.example/realms/cameleer")).isEqualTo("Keycloak");
|
||||
}
|
||||
|
||||
@Test
|
||||
void auth0Issuer_returnsAuth0() {
|
||||
assertThat(OidcProviderNameDeriver.deriveName("https://example.auth0.com/")).isEqualTo("Auth0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void oktaIssuer_returnsOkta() {
|
||||
assertThat(OidcProviderNameDeriver.deriveName("https://dev-123.okta.com/")).isEqualTo("Okta");
|
||||
assertThat(OidcProviderNameDeriver.deriveName("https://login.oktapreview.com/")).isEqualTo("Okta");
|
||||
}
|
||||
|
||||
@Test
|
||||
void unknownIssuer_returnsGenericLabel() {
|
||||
assertThat(OidcProviderNameDeriver.deriveName("https://idp.example.com/")).isEqualTo("Single Sign-On");
|
||||
}
|
||||
|
||||
@Test
|
||||
void blankOrNullIssuer_returnsGenericLabel() {
|
||||
assertThat(OidcProviderNameDeriver.deriveName("")).isEqualTo("Single Sign-On");
|
||||
assertThat(OidcProviderNameDeriver.deriveName(null)).isEqualTo("Single Sign-On");
|
||||
assertThat(OidcProviderNameDeriver.deriveName(" ")).isEqualTo("Single Sign-On");
|
||||
}
|
||||
|
||||
@Test
|
||||
void malformedUri_returnsGenericLabel() {
|
||||
assertThat(OidcProviderNameDeriver.deriveName("not a url")).isEqualTo("Single Sign-On");
|
||||
}
|
||||
|
||||
@Test
|
||||
void caseInsensitiveMatching() {
|
||||
assertThat(OidcProviderNameDeriver.deriveName("https://AUTH.LOGTO.EXAMPLE/")).isEqualTo("Logto");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user