-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(external): added discord provider
- Loading branch information
1 parent
455a0f8
commit 246dab8
Showing
15 changed files
with
289 additions
and
53 deletions.
There are no files selected for viewing
16 changes: 16 additions & 0 deletions
16
core/src/main/java/dev/cloudeko/zenei/infrastructure/config/AvailableProviders.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package dev.cloudeko.zenei.infrastructure.config; | ||
|
||
public enum AvailableProviders { | ||
GITHUB("github"), | ||
DISCORD("discord"); | ||
|
||
private final String providerName; | ||
|
||
AvailableProviders(String providerName) { | ||
this.providerName = providerName; | ||
} | ||
|
||
public String getProviderName() { | ||
return providerName; | ||
} | ||
} |
28 changes: 20 additions & 8 deletions
28
core/src/test/java/dev/cloudeko/zenei/auth/AuthenticationFlowWithExternalProviderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,50 @@ | ||
package dev.cloudeko.zenei.auth; | ||
|
||
import dev.cloudeko.zenei.application.web.model.response.TokenResponse; | ||
import dev.cloudeko.zenei.resource.MockDiscordAuthorizationServerTestResource; | ||
import dev.cloudeko.zenei.resource.MockGithubAuthorizationServerTestResource; | ||
import dev.cloudeko.zenei.resource.MockServerResource; | ||
import io.quarkus.test.common.WithTestResource; | ||
import io.quarkus.test.junit.QuarkusTest; | ||
import io.restassured.RestAssured; | ||
import jakarta.ws.rs.core.Response; | ||
import org.junit.jupiter.api.BeforeAll; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Order; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.Arguments; | ||
import org.junit.jupiter.params.provider.MethodSource; | ||
|
||
import java.util.stream.Stream; | ||
|
||
import static io.restassured.RestAssured.given; | ||
import static org.hamcrest.Matchers.*; | ||
import static org.hamcrest.Matchers.notNullValue; | ||
|
||
@QuarkusTest | ||
@WithTestResource(MockGithubAuthorizationServerTestResource.class) | ||
@WithTestResource.List({ | ||
@WithTestResource(MockServerResource.class), | ||
@WithTestResource(MockGithubAuthorizationServerTestResource.class), | ||
@WithTestResource(MockDiscordAuthorizationServerTestResource.class) | ||
}) | ||
public class AuthenticationFlowWithExternalProviderTest { | ||
|
||
@BeforeAll | ||
static void setup() { | ||
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails(); | ||
} | ||
|
||
@Test | ||
@MethodSource("createProviderData") | ||
@ParameterizedTest(name = "Test Case for provider: {0}") | ||
@DisplayName("Retrieve a access token using authorization (GET /external/login/github) should return (200 OK)") | ||
void testGetUserInfo() { | ||
given().get("/external/login/github") | ||
void testGetUserInfo(String provider) { | ||
given().get("/external/login/" + provider) | ||
.then() | ||
.statusCode(Response.Status.OK.getStatusCode()) | ||
.body( | ||
"access_token", notNullValue(), | ||
"refresh_token", notNullValue() | ||
); | ||
} | ||
|
||
static Stream<Arguments> createProviderData() { | ||
return Stream.of(Arguments.of("github"), Arguments.of("discord")); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
...rc/test/java/dev/cloudeko/zenei/resource/AbstractMockAuthorizationServerTestResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package dev.cloudeko.zenei.resource; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.github.tomakehurst.wiremock.WireMockServer; | ||
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; | ||
|
||
import java.util.Map; | ||
|
||
public abstract class AbstractMockAuthorizationServerTestResource implements QuarkusTestResourceLifecycleManager { | ||
|
||
protected final ObjectMapper objectMapper = new ObjectMapper(); | ||
|
||
@Override | ||
public Map<String, String> start() { | ||
WireMockServer wireMockServer = MockServerResource.getWireMockServer(); | ||
return providerSpecificStubsAndConfig(wireMockServer); | ||
} | ||
|
||
@Override | ||
public void stop() { | ||
} | ||
|
||
protected abstract Map<String, String> providerSpecificStubsAndConfig(WireMockServer server); | ||
} |
66 changes: 66 additions & 0 deletions
66
...src/test/java/dev/cloudeko/zenei/resource/MockDiscordAuthorizationServerTestResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package dev.cloudeko.zenei.resource; | ||
|
||
import com.github.tomakehurst.wiremock.WireMockServer; | ||
import com.github.tomakehurst.wiremock.client.WireMock; | ||
import dev.cloudeko.zenei.extension.external.web.client.ExternalAccessToken; | ||
import dev.cloudeko.zenei.extension.external.web.external.discord.DiscordUser; | ||
import jakarta.ws.rs.core.Response; | ||
import org.eclipse.microprofile.config.ConfigProvider; | ||
|
||
import java.util.Map; | ||
|
||
public class MockDiscordAuthorizationServerTestResource extends AbstractMockAuthorizationServerTestResource { | ||
|
||
@Override | ||
protected Map<String, String> providerSpecificStubsAndConfig(WireMockServer server) { | ||
final var testPort = ConfigProvider.getConfig().getOptionalValue("quarkus.http.test-port", Integer.class).orElse(8081); | ||
|
||
try { | ||
// Mock the Discord authorization URL | ||
server.stubFor(WireMock.get(WireMock.urlPathEqualTo("/discord/login/oauth/authorize")) | ||
.withQueryParam("client_id", WireMock.matching(".*")) | ||
.withQueryParam("redirect_uri", WireMock.matching(".*")) | ||
.withQueryParam("scope", WireMock.matching(".*")) | ||
.willReturn(WireMock.aResponse() | ||
.withStatus(Response.Status.FOUND.getStatusCode()) | ||
.withHeader("Location", | ||
"http://localhost:" + testPort + "/external/callback/discord?code=mock_code&state=mock_state"))); | ||
|
||
// Mock the Discord access token endpoint | ||
server.stubFor(WireMock.post(WireMock.urlPathEqualTo("/discord/login/oauth/access_token")) | ||
.withQueryParam("client_id", WireMock.matching(".*")) | ||
.withQueryParam("client_secret", WireMock.matching(".*")) | ||
.withQueryParam("code", WireMock.matching(".*")) | ||
.willReturn(WireMock.aResponse() | ||
.withHeader("Content-Type", "application/json") | ||
.withBody(objectMapper.writeValueAsString( | ||
new ExternalAccessToken("mock_access_token", 3600L, "mock_refresh_token", "user,email", | ||
"bearer") | ||
)))); | ||
|
||
// Mock the Discord user data endpoints | ||
server.stubFor(WireMock.get(WireMock.urlPathEqualTo("/discord/users/@me")) | ||
.withHeader("Authorization", WireMock.equalTo("Bearer mock_access_token")) | ||
.willReturn(WireMock.aResponse() | ||
.withHeader("Content-Type", "application/json") | ||
.withBody(objectMapper.writeValueAsString( | ||
new DiscordUser("12345L", "discord-user", "Discord Test User", "1234", "https://example.com/avatar.jpg", | ||
"[email protected]", true) | ||
)))); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
|
||
return Map.of( | ||
"zenei.external.auth.providers.discord.base-uri", server.baseUrl() + "/discord", | ||
"zenei.external.auth.providers.discord.client-id", "mock_client_id", | ||
"zenei.external.auth.providers.discord.client-secret", "mock_client_secret", | ||
"zenei.external.auth.providers.discord.authorization-uri", | ||
server.baseUrl() + "/discord/login/oauth/authorize", | ||
"zenei.external.auth.providers.discord.token-uri", | ||
server.baseUrl() + "/discord/login/oauth/access_token", | ||
"zenei.external.auth.providers.discord.redirect-uri", "http://localhost:8081/external/callback/discord", | ||
"zenei.external.auth.providers.discord.scope", "user,email" | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
core/src/test/java/dev/cloudeko/zenei/resource/MockServerResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package dev.cloudeko.zenei.resource; | ||
|
||
import com.github.tomakehurst.wiremock.WireMockServer; | ||
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; | ||
import lombok.Getter; | ||
|
||
import java.util.Map; | ||
|
||
public class MockServerResource implements QuarkusTestResourceLifecycleManager { | ||
|
||
@Getter | ||
private static WireMockServer wireMockServer; | ||
|
||
@Override | ||
public Map<String, String> start() { | ||
if (wireMockServer == null) { | ||
wireMockServer = new WireMockServer(); | ||
wireMockServer.start(); | ||
} | ||
|
||
return Map.of(); | ||
} | ||
|
||
@Override | ||
public void stop() { | ||
if (wireMockServer != null) { | ||
wireMockServer.stop(); | ||
wireMockServer = null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
...rc/main/java/dev/cloudeko/zenei/extension/external/endpoint/DiscordProviderEndpoints.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package dev.cloudeko.zenei.extension.external.endpoint; | ||
|
||
public class DiscordProviderEndpoints implements DefaultProviderEndpoints { | ||
|
||
@Override | ||
public String getAuthorizationEndpoint() { | ||
return "https://discord.com/api/oauth2/authorize"; | ||
} | ||
|
||
@Override | ||
public String getTokenEndpoint() { | ||
return "https://discord.com/api/oauth2/token"; | ||
} | ||
|
||
@Override | ||
public String getBaseEndpoint() { | ||
return "https://discord.com/api"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.