Skip to content

Commit

Permalink
feat: switch to accesstoken via query
Browse files Browse the repository at this point in the history
  • Loading branch information
its-felix committed Nov 8, 2024
1 parent df289fa commit 2d876d3
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 15 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.gw2auth</groupId>
<artifactId>oauth2-server</artifactId>
<version>1.88.0</version>
<version>1.89.0</version>
<packaging>jar</packaging>

<parent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public interface Gw2ApiService {

String API_VERSION_PARAM = "v";
String API_VERSION = "2021-07-15T13:00:00.000Z";
String ACCESS_TOKEN_PARAM = "access_token";

Gw2TokenInfo getTokenInfo(String gw2ApiToken);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ private <T> T getFromAPI(String url, MultiValueMap<String, String> query, String
query = new LinkedMultiValueMap<>(query);
query.set(API_VERSION_PARAM, API_VERSION);

if (token != null) {
query.set(ACCESS_TOKEN_PARAM, token);
}

final Long timeoutAt = Optional.ofNullable(TIMEOUT_AT_TL.get()).map(Deque::peekLast).orElse(null);

ResponseEntity<Resource> response;
Expand Down Expand Up @@ -179,6 +183,7 @@ private <T> T getFromAPI(String url, MultiValueMap<String, String> query, String
}

private static HttpHeaders buildRequestHeaders(String token) {
/*
if (token == null) {
return HttpHeaders.EMPTY;
}
Expand All @@ -187,6 +192,8 @@ private static HttpHeaders buildRequestHeaders(String token) {
headers.add("Authorization", "Bearer " + token);
return headers;
*/
return HttpHeaders.EMPTY;
}

private static boolean validateToken(String token) {
Expand Down
32 changes: 32 additions & 0 deletions src/test/java/com/gw2auth/oauth2/server/RequestMatchers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.gw2auth.oauth2.server;

import org.hamcrest.core.IsAnything;
import org.hamcrest.core.IsEqual;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.test.web.client.RequestMatcher;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Optional;

import static org.springframework.test.web.client.match.MockRestRequestMatchers.queryParam;

public final class RequestMatchers {

public static RequestMatcher matchAuthorizedRequest() {
return queryParam("access_token", new IsAnything<>());
}

public static RequestMatcher matchAuthorizedRequest(String accessToken) {
return queryParam("access_token", new IsEqual<>(accessToken));
}

public static Optional<String> extractAccessToken(ClientHttpRequest request) {
final String token = UriComponentsBuilder.fromUri(request.getURI())
.build()
.getQueryParams()
.getFirst("access_token");

return Optional.ofNullable(token);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@

import static com.gw2auth.oauth2.server.Assertions.assertInstantEquals;
import static com.gw2auth.oauth2.server.Matchers.*;
import static com.gw2auth.oauth2.server.RequestMatchers.extractAccessToken;
import static com.gw2auth.oauth2.server.RequestMatchers.matchAuthorizedRequest;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.client.ExpectedCount.times;
Expand Down Expand Up @@ -1299,11 +1301,11 @@ public void consentSubmitWithUnexpectedGW2APIException(SessionHandle sessionHand
this.gw2RestServer.reset();
this.gw2RestServer.expect(times(2), requestTo(new StringStartsWith("/v2/createsubtoken")))
.andExpect(method(HttpMethod.GET))
.andExpect(MockRestRequestMatchers.header("Authorization", new StringStartsWith("Bearer ")))
.andExpect(matchAuthorizedRequest())
.andExpect(queryParam("permissions", split(",", containingAll(Gw2ApiPermission.ACCOUNT.gw2()))))
.andExpect(queryParam("expire", asInstant(instantWithinTolerance(Instant.now().plus(Duration.ofMinutes(30L)), Duration.ofSeconds(5L)))))
.andRespond((request) -> {
final String gw2ApiToken = request.getHeaders().getFirst("Authorization").replaceFirst("Bearer ", "");
final String gw2ApiToken = extractAccessToken(request).orElseThrow();
final String subtoken;

if (gw2ApiToken.equals(tokenA)) {
Expand Down Expand Up @@ -2469,11 +2471,11 @@ private void prepareGw2RestServerForCreateSubToken(Map<String, String> subtokenB
if (!subtokenByGw2ApiToken.isEmpty()) {
this.gw2RestServer.expect(times(subtokenByGw2ApiToken.size()), requestTo(new StringStartsWith("/v2/createsubtoken")))
.andExpect(method(HttpMethod.GET))
.andExpect(MockRestRequestMatchers.header("Authorization", new StringStartsWith("Bearer ")))
.andExpect(matchAuthorizedRequest())
.andExpect(queryParam("permissions", split(",", containingAll(expectedGw2ApiPermissionStrs))))
.andExpect(queryParam("expire", asInstant(instantWithinTolerance(Instant.now().plus(Duration.ofMinutes(30L)), Duration.ofSeconds(5L)))))
.andRespond((request) -> {
final String gw2ApiToken = request.getHeaders().getFirst("Authorization").replaceFirst("Bearer ", "");
final String gw2ApiToken = extractAccessToken(request).orElseThrow();
final String subtoken = subtokenByGw2ApiToken.get(gw2ApiToken);

if (subtoken == null || subtoken.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.gw2auth.oauth2.server.repository.gw2account.apitoken.Gw2AccountApiTokenEntity;
import com.gw2auth.oauth2.server.repository.gw2account.apitoken.Gw2AccountApiTokenRepository;
import com.gw2auth.oauth2.server.service.Gw2ApiPermission;
import org.hamcrest.core.IsEqual;
import org.hamcrest.core.StringStartsWith;
import org.json.JSONObject;
import org.junit.jupiter.api.extension.RegisterExtension;
Expand All @@ -20,7 +19,6 @@
import org.springframework.http.MediaType;
import org.springframework.mock.http.client.MockClientHttpResponse;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.test.web.client.match.MockRestRequestMatchers;

import java.nio.charset.StandardCharsets;
import java.time.Clock;
Expand All @@ -32,6 +30,7 @@
import java.util.UUID;

import static com.gw2auth.oauth2.server.Assertions.assertInstantEquals;
import static com.gw2auth.oauth2.server.RequestMatchers.matchAuthorizedRequest;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.springframework.test.web.client.ExpectedCount.times;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
Expand Down Expand Up @@ -95,7 +94,7 @@ public void checkTokenValidityWithUpdatedGw2AccountNames(SessionHandle sessionHa
// prepare the mock server for the upcoming account request
this.gw2RestServer.expect(times(1), requestTo(new StringStartsWith("/v2/account")))
.andExpect(method(HttpMethod.GET))
.andExpect(MockRestRequestMatchers.header("Authorization", new IsEqual<>("Bearer " + gw2ApiToken)))
.andExpect(matchAuthorizedRequest(gw2ApiToken))
.andRespond((request) -> {
final JSONObject responseJson = new JSONObject(Map.of(
"id", gw2AccountId.toString(),
Expand Down Expand Up @@ -153,7 +152,7 @@ public void checkTokenValidityWithFailingGw2ApiRequest(SessionHandle sessionHand
// prepare the mock server for the upcoming account request
this.gw2RestServer.expect(times(1), requestTo(new StringStartsWith("/v2/account")))
.andExpect(method(HttpMethod.GET))
.andExpect(MockRestRequestMatchers.header("Authorization", new IsEqual<>("Bearer " + gw2ApiToken)))
.andExpect(matchAuthorizedRequest(gw2ApiToken))
.andRespond((request) -> {
final MockClientHttpResponse response = new MockClientHttpResponse(
"{}".getBytes(StandardCharsets.UTF_8),
Expand Down Expand Up @@ -207,7 +206,7 @@ public void checkTokenValidityWithInvalidApiToken(SessionHandle sessionHandle) {
// prepare the mock server for the upcoming account request
this.gw2RestServer.expect(times(1), requestTo(new StringStartsWith("/v2/account")))
.andExpect(method(HttpMethod.GET))
.andExpect(MockRestRequestMatchers.header("Authorization", new IsEqual<>("Bearer " + gw2ApiToken)))
.andExpect(matchAuthorizedRequest(gw2ApiToken))
.andRespond((request) -> {
final MockClientHttpResponse response = new MockClientHttpResponse(
"{}".getBytes(StandardCharsets.UTF_8),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.stream.Collectors;

import static com.gw2auth.oauth2.server.Matchers.*;
import static com.gw2auth.oauth2.server.RequestMatchers.matchAuthorizedRequest;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.client.ExpectedCount.max;
Expand Down Expand Up @@ -769,7 +770,7 @@ public void startSubmitAndCancelChallenge(SessionHandle sessionHandle) throws Ex
private void prepareGw2RestServerForTransactionsRequest(String gw2ApiToken, int addDummyValues, int itemId, int quantity, long price, Instant created) {
this.gw2RestServer.expect(requestTo(new StringStartsWith("/v2/commerce/transactions/current/buys")))
.andExpect(method(HttpMethod.GET))
.andExpect(MockRestRequestMatchers.header("Authorization", "Bearer " + gw2ApiToken))
.andExpect(matchAuthorizedRequest(gw2ApiToken))
.andRespond((request) -> {
final org.json.JSONArray result = new org.json.JSONArray();

Expand Down Expand Up @@ -801,7 +802,7 @@ private void prepareGw2RestServerForTransactionsRequest(String gw2ApiToken, int
private void prepareGw2RestServerForTokenInfoRequest(String gw2ApiToken, String apiTokenName, Set<Gw2ApiPermission> gw2ApiPermissions) {
this.gw2RestServer.expect(requestTo(new StringStartsWith("/v2/tokeninfo")))
.andExpect(method(HttpMethod.GET))
.andExpect(MockRestRequestMatchers.header("Authorization", "Bearer " + gw2ApiToken))
.andExpect(matchAuthorizedRequest(gw2ApiToken))
.andRespond((request) -> {
final MockClientHttpResponse response = new MockClientHttpResponse(new JSONObject(Map.of(
"name", apiTokenName,
Expand All @@ -825,7 +826,7 @@ private void prepareGw2RestServerForCharactersRequest(String gw2ApiToken, int ad

this.gw2RestServer.expect(requestTo(new StringStartsWith("/v2/characters")))
.andExpect(method(HttpMethod.GET))
.andExpect(MockRestRequestMatchers.header("Authorization", "Bearer " + gw2ApiToken))
.andExpect(matchAuthorizedRequest(gw2ApiToken))
.andRespond((request) -> {
final MockClientHttpResponse response = new MockClientHttpResponse(new JSONArray(characters).toString().getBytes(StandardCharsets.UTF_8), HttpStatus.OK);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
Expand All @@ -837,7 +838,7 @@ private void prepareGw2RestServerForCharactersRequest(String gw2ApiToken, int ad
private void preparedGw2RestServerForCreateSubtoken(String gw2ApiToken, String gw2ApiSubtoken, Set<Gw2ApiPermission> requestPermissions, Instant expire) {
this.gw2RestServer.expect(requestTo(new StringStartsWith("/v2/createsubtoken")))
.andExpect(method(HttpMethod.GET))
.andExpect(MockRestRequestMatchers.header("Authorization", "Bearer " + gw2ApiToken))
.andExpect(matchAuthorizedRequest(gw2ApiToken))
.andExpect(queryParam("permissions", split(",", containingAll(requestPermissions.stream().map(Gw2ApiPermission::gw2).toArray(String[]::new)))))
.andExpect(queryParam("expire", asInstant(instant(expire))))
.andRespond((request) -> {
Expand All @@ -851,7 +852,7 @@ private void preparedGw2RestServerForCreateSubtoken(String gw2ApiToken, String g
private void preparedGw2RestServerForAccountRequest(UUID gw2AccountId, String gw2ApiToken) {
this.gw2RestServer.expect(max(2), requestTo(new StringStartsWith("/v2/account")))
.andExpect(method(HttpMethod.GET))
.andExpect(MockRestRequestMatchers.header("Authorization", "Bearer " + gw2ApiToken))
.andExpect(matchAuthorizedRequest(gw2ApiToken))
.andRespond((request) -> {
final MockClientHttpResponse response = new MockClientHttpResponse(new JSONObject(Map.of(
"id", gw2AccountId,
Expand Down

0 comments on commit 2d876d3

Please sign in to comment.