diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java index 1948cc4dbeab4e..8c02255bfab71b 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java @@ -1081,6 +1081,7 @@ public static enum Provider { GITHUB, GOOGLE, MICROSOFT, + SPOTIFY, TWITTER } diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/providers/KnownOidcProviders.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/providers/KnownOidcProviders.java index c02ea11da47b6b..88933c4e90da26 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/providers/KnownOidcProviders.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/providers/KnownOidcProviders.java @@ -20,6 +20,8 @@ public static OidcTenantConfig provider(OidcTenantConfig.Provider provider) { return microsoft(); } else if (OidcTenantConfig.Provider.FACEBOOK == provider) { return facebook(); + } else if (OidcTenantConfig.Provider.SPOTIFY == provider) { + return spotify(); } else if (OidcTenantConfig.Provider.TWITTER == provider) { return twitter(); } @@ -98,4 +100,23 @@ private static OidcTenantConfig apple() { ret.getCredentials().getJwt().setAudience("https://appleid.apple.com/"); return ret; } + + private static OidcTenantConfig spotify() { + // See https://developer.spotify.com/documentation/general/guides/authorization/code-flow/ + OidcTenantConfig ret = new OidcTenantConfig(); + ret.setAuthServerUrl("https://accounts.spotify.com/"); + ret.setApplicationType(OidcTenantConfig.ApplicationType.WEB_APP); + ret.setDiscoveryEnabled(false); + ret.setAuthorizationPath("https://accounts.spotify.com/authorize"); + ret.setTokenPath("https://accounts.spotify.com/api/token"); + ret.setUserInfoPath("https://api.spotify.com/v1/me"); + + OidcTenantConfig.Authentication authentication = ret.getAuthentication(); + authentication.setAddOpenidScope(false); + authentication.setScopes(List.of("user-read-email")); + authentication.setUserInfoRequired(true); + authentication.setPkceRequired(true); + + return ret; + } } diff --git a/extensions/oidc/runtime/src/test/java/io/quarkus/oidc/runtime/OidcUtilsTest.java b/extensions/oidc/runtime/src/test/java/io/quarkus/oidc/runtime/OidcUtilsTest.java index 1d877bd773a04f..61135a454d51ab 100644 --- a/extensions/oidc/runtime/src/test/java/io/quarkus/oidc/runtime/OidcUtilsTest.java +++ b/extensions/oidc/runtime/src/test/java/io/quarkus/oidc/runtime/OidcUtilsTest.java @@ -291,6 +291,39 @@ public void testOverrideAppleProperties() throws Exception { assertEquals(SignatureAlgorithm.ES256.getAlgorithm(), config.credentials.jwt.signatureAlgorithm.get()); } + @Test + public void testAcceptSpotifyProperties() { + OidcTenantConfig tenant = new OidcTenantConfig(); + tenant.setTenantId(OidcUtils.DEFAULT_TENANT_ID); + OidcTenantConfig config = OidcUtils.mergeTenantConfig(tenant, KnownOidcProviders.provider(Provider.SPOTIFY)); + + assertEquals(OidcUtils.DEFAULT_TENANT_ID, config.getTenantId().get()); + assertEquals(ApplicationType.WEB_APP, config.getApplicationType().get()); + assertEquals("https://accounts.spotify.com/", config.getAuthServerUrl().get()); + assertEquals(List.of("user-read-email"), config.authentication.scopes.get()); + } + + @Test + public void testOverrideSpotifyProperties() { + OidcTenantConfig tenant = new OidcTenantConfig(); + tenant.setTenantId(OidcUtils.DEFAULT_TENANT_ID); + + tenant.setApplicationType(ApplicationType.HYBRID); + tenant.setAuthServerUrl("http://localhost/wiremock"); + tenant.getToken().setIssuer("http://localhost/wiremock"); + tenant.authentication.setScopes(List.of("write")); + tenant.authentication.setForceRedirectHttpsScheme(false); + + OidcTenantConfig config = OidcUtils.mergeTenantConfig(tenant, KnownOidcProviders.provider(Provider.SPOTIFY)); + + assertEquals(OidcUtils.DEFAULT_TENANT_ID, config.getTenantId().get()); + assertEquals(ApplicationType.HYBRID, config.getApplicationType().get()); + assertEquals("http://localhost/wiremock", config.getAuthServerUrl().get()); + assertEquals(List.of("write"), config.authentication.scopes.get()); + assertEquals("http://localhost/wiremock", config.getToken().getIssuer().get()); + assertFalse(config.authentication.forceRedirectHttpsScheme.get()); + } + @Test public void testCorrectTokenType() throws Exception { OidcTenantConfig.Token tokenClaims = new OidcTenantConfig.Token();