use of com.gw2auth.oauth2.server.util.QueryParam in project oauth2-server by gw2auth.
the class VerificationControllerTest method startAndSubmitTPBuyOrderChallengeDirectlyFulfilled.
@WithGw2AuthLogin
public void startAndSubmitTPBuyOrderChallengeDirectlyFulfilled(MockHttpSession session) throws Exception {
final UUID gw2AccountId = UUID.randomUUID();
// insert an api token for another account but for the same gw2 account id
final long otherUserAccountId = this.accountRepository.save(new AccountEntity(null, Instant.now())).id();
this.testHelper.createApiToken(otherUserAccountId, gw2AccountId, Set.of(), "Name");
final long accountId = AuthenticationHelper.getUser(session).orElseThrow().getAccountId();
// prepare the testing clock
Clock testingClock = Clock.fixed(Instant.now(), ZoneId.systemDefault());
this.verificationService.setClock(testingClock);
final String gw2ApiToken = TestHelper.randomRootToken();
final String gw2ApiSubtoken = TestHelper.createSubtokenJWT(UUID.randomUUID(), Set.of(Gw2ApiPermission.ACCOUNT, Gw2ApiPermission.TRADINGPOST), testingClock.instant(), Duration.ofMinutes(15L));
// start the challenge
final VerificationChallengeStart challengeStart = this.verificationService.startChallenge(accountId, 2L);
// prepare the gw2 api
this.gw2RestServer.reset();
preparedGw2RestServerForCreateSubtoken(gw2ApiToken, gw2ApiSubtoken, Set.of(Gw2ApiPermission.ACCOUNT, Gw2ApiPermission.TRADINGPOST), testingClock.instant().plus(Duration.ofMinutes(15L)));
preparedGw2RestServerForAccountRequest(gw2AccountId, gw2ApiSubtoken);
prepareGw2RestServerForTransactionsRequest(gw2ApiSubtoken, 20, (int) challengeStart.message().get("gw2ItemId"), 1, (long) challengeStart.message().get("buyOrderCoins"), testingClock.instant());
// submit the challenge
this.mockMvc.perform(post("/api/verification/pending").session(session).with(csrf()).queryParam("token", gw2ApiToken)).andExpect(status().isOk()).andExpect(jsonPath("$.isSuccess").value("true"));
// started challenge should be removed
assertTrue(this.gw2AccountVerificationChallengeRepository.findByAccountIdAndGw2AccountId(accountId, "").isEmpty());
// pending challenge should not be present (either removed or never inserted)
assertTrue(this.gw2AccountVerificationChallengeRepository.findByAccountIdAndGw2AccountId(accountId, gw2AccountId.toString()).isEmpty());
// account should now be verified
final Gw2AccountVerificationEntity accountVerification = this.gw2AccountVerificationRepository.findById(gw2AccountId).orElse(null);
assertNotNull(accountVerification);
assertEquals(accountId, accountVerification.accountId());
// the other users api token should be removed
assertTrue(this.apiTokenRepository.findByAccountIdAndGw2AccountId(otherUserAccountId, gw2AccountId).isEmpty());
}
use of com.gw2auth.oauth2.server.util.QueryParam in project oauth2-server by gw2auth.
the class VerificationControllerTest method startChallengeWithoutWaitingLongEnoughBetween.
@WithGw2AuthLogin
public void startChallengeWithoutWaitingLongEnoughBetween(MockHttpSession session) throws Exception {
final long accountId = AuthenticationHelper.getUser(session).orElseThrow().getAccountId();
// prepare the testing clock
Clock testingClock = Clock.fixed(Instant.now(), ZoneId.systemDefault());
this.verificationService.setClock(testingClock);
this.mockMvc.perform(post("/api/verification").session(session).with(csrf()).queryParam("challengeId", "1")).andExpect(status().isOk()).andExpect(jsonPath("$.challengeId").value("1")).andExpect(jsonPath("$.message.apiTokenName").isString()).andExpect(jsonPath("$.nextAllowedStartTime").isString());
final Gw2AccountVerificationChallengeEntity startedChallenge = this.gw2AccountVerificationChallengeRepository.findByAccountIdAndGw2AccountId(accountId, "").orElse(null);
assertNotNull(startedChallenge);
// wait 29min (not enough)
testingClock = Clock.offset(testingClock, Duration.ofMinutes(29L));
this.verificationService.setClock(testingClock);
// try to start a new challenge
this.mockMvc.perform(post("/api/verification").session(session).with(csrf()).queryParam("challengeId", "2")).andExpect(status().isBadRequest());
// started challenge should not be modified
assertEquals(startedChallenge, this.gw2AccountVerificationChallengeRepository.findByAccountIdAndGw2AccountId(accountId, "").orElse(null));
}
use of com.gw2auth.oauth2.server.util.QueryParam in project oauth2-server by gw2auth.
the class OAuth2ServerTest method consentSubmitWithUnexpectedGW2APIException.
@WithGw2AuthLogin
public void consentSubmitWithUnexpectedGW2APIException(MockHttpSession session) throws Exception {
final long accountId = AuthenticationHelper.getUser(session).orElseThrow().getAccountId();
final ClientRegistrationCreation clientRegistrationCreation = createClientRegistration();
final ClientRegistration clientRegistration = clientRegistrationCreation.clientRegistration();
// perform authorization request (which should redirect to the consent page)
MvcResult result = performAuthorizeWithClient(session, clientRegistration, List.of(Gw2ApiPermission.ACCOUNT.oauth2())).andReturn();
// submit the consent
final String tokenA = TestHelper.randomRootToken();
final String tokenB = TestHelper.randomRootToken();
final String tokenC = TestHelper.randomRootToken();
result = performSubmitConsent(session, clientRegistration, URI.create(Objects.requireNonNull(result.getResponse().getRedirectedUrl())), tokenA, tokenB, tokenC).andReturn();
// verify the consent has been saved
final ClientConsentEntity clientConsentEntity = this.clientConsentRepository.findByAccountIdAndClientRegistrationId(accountId, clientRegistration.id()).orElse(null);
assertNotNull(clientConsentEntity);
assertEquals(Set.of(Gw2ApiPermission.ACCOUNT.oauth2()), clientConsentEntity.authorizedScopes());
// verify the authorization has been saved
final List<ClientAuthorizationEntity> authorizations = this.clientAuthorizationRepository.findAllByAccountIdAndClientRegistrationId(accountId, clientConsentEntity.clientRegistrationId());
assertEquals(1, authorizations.size());
final ClientAuthorizationEntity clientAuthorization = authorizations.get(0);
assertEquals(Set.of(Gw2ApiPermission.ACCOUNT.oauth2()), clientAuthorization.authorizedScopes());
List<ClientAuthorizationTokenEntity> clientAuthorizationTokenEntities = this.clientAuthorizationTokenRepository.findAllByAccountIdAndClientAuthorizationId(accountId, clientAuthorization.id());
assertEquals(2, clientAuthorizationTokenEntities.size());
// set testing clock to token customizer
final Clock testingClock = Clock.fixed(Instant.now(), ZoneId.systemDefault());
this.oAuth2TokenCustomizerService.setClock(testingClock);
// prepare the gw2 api for the next requests
final String dummySubtokenA = TestHelper.createSubtokenJWT(this.gw2AccountId1st, Set.of(Gw2ApiPermission.ACCOUNT), testingClock.instant(), Duration.ofMinutes(30L));
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(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 subtoken;
if (gw2ApiToken.equals(tokenA)) {
subtoken = dummySubtokenA;
} else if (gw2ApiToken.equals(tokenB)) {
throw new RuntimeException("unexpected exception");
} else {
subtoken = null;
}
if (subtoken == null || subtoken.isEmpty()) {
return new MockClientHttpResponse(new byte[0], HttpStatus.UNAUTHORIZED);
}
final MockClientHttpResponse response = new MockClientHttpResponse(new JSONObject(Map.of("subtoken", subtoken)).toString().getBytes(StandardCharsets.UTF_8), HttpStatus.OK);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
return response;
});
// retrieve the initial access and refresh token
final String codeParam = Utils.parseQuery(URI.create(Objects.requireNonNull(result.getResponse().getRedirectedUrl())).getRawQuery()).filter(QueryParam::hasValue).filter((queryParam) -> queryParam.name().equals(OAuth2ParameterNames.CODE)).map(QueryParam::value).findFirst().orElse(null);
assertNotNull(codeParam);
// retrieve an access token
// dont use the user session here!
result = this.mockMvc.perform(post("/oauth2/token").queryParam(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.AUTHORIZATION_CODE.getValue()).queryParam(OAuth2ParameterNames.CODE, codeParam).queryParam(OAuth2ParameterNames.CLIENT_ID, clientRegistrationCreation.clientRegistration().clientId().toString()).queryParam(OAuth2ParameterNames.CLIENT_SECRET, clientRegistrationCreation.clientSecret()).queryParam(OAuth2ParameterNames.REDIRECT_URI, TestHelper.first(clientRegistrationCreation.clientRegistration().redirectUris()).orElseThrow())).andExpectAll(expectValidTokenResponse()).andReturn();
// verify the subtokens have been updated
final Set<String> savedSubtokens = this.apiSubTokenRepository.findAllByAccountIdGw2AccountIdsAndGw2ApiPermissionsBitSet(accountId, Set.of(this.gw2AccountId1st, this.gw2AccountId2nd), Gw2ApiPermission.toBitSet(Set.of(Gw2ApiPermission.ACCOUNT))).stream().map(ApiSubTokenEntity::gw2ApiSubtoken).collect(Collectors.toSet());
assertEquals(1, savedSubtokens.size());
assertTrue(savedSubtokens.contains(dummySubtokenA));
// verify the validity status has been saved
final List<ApiTokenEntity> apiTokenEntities = this.apiTokenRepository.findAllByAccountIdAndGw2AccountIds(accountId, Set.of(this.gw2AccountId1st, this.gw2AccountId2nd));
assertEquals(2, apiTokenEntities.size());
for (ApiTokenEntity apiTokenEntity : apiTokenEntities) {
if (apiTokenEntity.gw2AccountId().equals(this.gw2AccountId1st)) {
assertTrue(apiTokenEntity.isValid());
assertInstantEquals(testingClock.instant(), apiTokenEntity.lastValidCheckTime());
} else {
assertTrue(apiTokenEntity.isValid());
assertTrue(testingClock.instant().isAfter(apiTokenEntity.lastValidCheckTime()));
}
}
// verify the access token
assertTokenResponse(result, () -> Map.of(this.gw2AccountId1st, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "First", "token", dummySubtokenA)), this.gw2AccountId2nd, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "Second", "error", "Failed to obtain new subtoken"))));
}
use of com.gw2auth.oauth2.server.util.QueryParam in project oauth2-server by gw2auth.
the class OAuth2ServerTest method consentSubmitWithLessScopesThanRequested.
@WithGw2AuthLogin
public void consentSubmitWithLessScopesThanRequested(MockHttpSession session) throws Exception {
final long accountId = AuthenticationHelper.getUser(session).orElseThrow().getAccountId();
final ClientRegistrationCreation clientRegistrationCreation = createClientRegistration();
final ClientRegistration clientRegistration = clientRegistrationCreation.clientRegistration();
// perform authorization request (which should redirect to the consent page)
MvcResult result = performAuthorizeWithClient(session, clientRegistration, List.of(Gw2ApiPermission.ACCOUNT.oauth2(), Gw2ApiPermission.TRADINGPOST.oauth2())).andReturn();
// read request information from redirected uri
final Map<String, String> params = Utils.parseQuery(URI.create(result.getResponse().getRedirectedUrl()).getRawQuery()).filter(QueryParam::hasValue).collect(Collectors.toMap(QueryParam::name, QueryParam::value));
assertTrue(params.containsKey(OAuth2ParameterNames.CLIENT_ID));
assertTrue(params.containsKey(OAuth2ParameterNames.STATE));
assertTrue(params.containsKey(OAuth2ParameterNames.SCOPE));
// insert a dummy api token
this.testHelper.createApiToken(accountId, this.gw2AccountId1st, "TokenA", Set.of(Gw2ApiPermission.ACCOUNT, Gw2ApiPermission.TRADINGPOST), "First");
// lookup the consent info (containing the submit uri and parameters that should be submitted)
result = this.mockMvc.perform(get("/api/oauth2/consent").session(session).queryParam(OAuth2ParameterNames.CLIENT_ID, params.get(OAuth2ParameterNames.CLIENT_ID)).queryParam(OAuth2ParameterNames.STATE, params.get(OAuth2ParameterNames.STATE)).queryParam(OAuth2ParameterNames.SCOPE, params.get(OAuth2ParameterNames.SCOPE))).andReturn();
// read the consent info and build the submit request
final ObjectMapper mapper = new ObjectMapper();
final JsonNode consentInfo = mapper.readTree(result.getResponse().getContentAsString());
final String submitUri = consentInfo.get("submitFormUri").textValue();
MockHttpServletRequestBuilder builder = post(submitUri).contentType(MediaType.APPLICATION_FORM_URLENCODED).session(session).with(csrf());
for (Map.Entry<String, JsonNode> entry : (Iterable<? extends Map.Entry<String, JsonNode>>) () -> consentInfo.get("submitFormParameters").fields()) {
final String name = entry.getKey();
final JsonNode values = entry.getValue();
for (int i = 0; i < values.size(); i++) {
final String value = values.get(i).textValue();
// exclude the tradingpost scope
if (!name.equals(OAuth2ParameterNames.SCOPE) || !value.equals(Gw2ApiPermission.TRADINGPOST.oauth2())) {
builder = builder.param(name, value);
}
}
}
final JsonNode apiTokensWithSufficientPermissions = consentInfo.get("apiTokensWithSufficientPermissions");
assertEquals(1, apiTokensWithSufficientPermissions.size());
assertEquals(0, consentInfo.get("apiTokensWithInsufficientPermissions").size());
for (int i = 0; i < apiTokensWithSufficientPermissions.size(); i++) {
builder = builder.param("token:" + apiTokensWithSufficientPermissions.get(i).get("gw2AccountId").textValue(), "");
}
// submit the consent
this.mockMvc.perform(builder).andExpect(status().isBadRequest());
// authorization should not be saved
final ClientConsentEntity clientAuthorization = this.clientConsentRepository.findByAccountIdAndClientRegistrationId(accountId, clientRegistration.id()).orElse(null);
// null is ok too
if (clientAuthorization != null) {
assertTrue(clientAuthorization.authorizedScopes().isEmpty());
}
}
use of com.gw2auth.oauth2.server.util.QueryParam in project oauth2-server by gw2auth.
the class OAuth2ServerTest method revokeAccessTokenWithInvalidClientSecret.
@WithGw2AuthLogin
public void revokeAccessTokenWithInvalidClientSecret(MockHttpSession session) throws Exception {
final long accountId = AuthenticationHelper.getUser(session).orElseThrow().getAccountId();
final ClientRegistrationCreation clientRegistrationCreation = createClientRegistration();
final ClientRegistration clientRegistration = clientRegistrationCreation.clientRegistration();
// perform authorization request (which should redirect to the consent page)
MvcResult result = performAuthorizeWithClient(session, clientRegistration, List.of(Gw2ApiPermission.ACCOUNT.oauth2())).andReturn();
// submit the consent
final String tokenA = TestHelper.randomRootToken();
final String tokenB = TestHelper.randomRootToken();
final String tokenC = TestHelper.randomRootToken();
result = performSubmitConsent(session, clientRegistration, URI.create(Objects.requireNonNull(result.getResponse().getRedirectedUrl())), tokenA, tokenB, tokenC).andReturn();
// set testing clock to token customizer
final Clock testingClock = Clock.fixed(Instant.now(), ZoneId.systemDefault());
this.oAuth2TokenCustomizerService.setClock(testingClock);
// retrieve the initial access and refresh token
final String dummySubtokenA = TestHelper.createSubtokenJWT(this.gw2AccountId1st, Set.of(Gw2ApiPermission.ACCOUNT), testingClock.instant(), Duration.ofMinutes(30L));
final String dummySubtokenB = TestHelper.createSubtokenJWT(this.gw2AccountId2nd, Set.of(Gw2ApiPermission.ACCOUNT), testingClock.instant(), Duration.ofMinutes(30L));
result = performRetrieveTokenByCodeAndExpectValid(clientRegistrationCreation, URI.create(Objects.requireNonNull(result.getResponse().getRedirectedUrl())), Map.of(tokenA, dummySubtokenA, tokenB, dummySubtokenB)).andReturn();
// verify the access token
JsonNode tokenResponse = assertTokenResponse(result, () -> Map.of(this.gw2AccountId1st, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "First", "token", dummySubtokenA)), this.gw2AccountId2nd, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "Second", "token", dummySubtokenB))));
// revoke the access_token
final String accessToken = tokenResponse.get("access_token").textValue();
this.mockMvc.perform(post("/oauth2/revoke").queryParam(OAuth2ParameterNames.CLIENT_ID, clientRegistrationCreation.clientRegistration().clientId().toString()).queryParam(OAuth2ParameterNames.CLIENT_SECRET, "Not the correct client secret").queryParam(OAuth2ParameterNames.TOKEN_TYPE_HINT, OAuth2TokenType.ACCESS_TOKEN.getValue()).queryParam(OAuth2ParameterNames.TOKEN, accessToken)).andExpect(status().isUnauthorized());
// database should still contain the authorization
final List<ClientAuthorizationEntity> clientAuthorizationEntities = this.clientAuthorizationRepository.findAllByAccountIdAndClientRegistrationId(accountId, clientRegistration.id());
assertEquals(1, clientAuthorizationEntities.size());
}
Aggregations