use of com.gw2auth.oauth2.server.service.client.registration.ClientRegistration in project oauth2-server by gw2auth.
the class OAuth2ServerTest method consentSubmitAndSubmitAgainWithLessScopes.
@WithGw2AuthLogin
public void consentSubmitAndSubmitAgainWithLessScopes(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.UNLOCKS.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, Set.of(Gw2ApiPermission.ACCOUNT, Gw2ApiPermission.UNLOCKS)).andReturn();
// verify the consent has been saved
ClientConsentEntity clientConsentEntity = this.clientConsentRepository.findByAccountIdAndClientRegistrationId(accountId, clientRegistration.id()).orElse(null);
assertNotNull(clientConsentEntity);
assertEquals(Set.of(Gw2ApiPermission.ACCOUNT.oauth2(), Gw2ApiPermission.UNLOCKS.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(), Gw2ApiPermission.UNLOCKS.oauth2()), clientAuthorization.authorizedScopes());
List<ClientAuthorizationTokenEntity> clientAuthorizationTokenEntities = this.clientAuthorizationTokenRepository.findAllByAccountIdAndClientAuthorizationId(accountId, clientAuthorization.id());
assertEquals(2, clientAuthorizationTokenEntities.size());
// set testing clock to token customizer
Clock testingClock = Clock.fixed(Instant.now(), ZoneId.systemDefault());
this.oAuth2TokenCustomizerService.setClock(testingClock);
// retrieve the initial access and refresh token
final String[] dummySubtokenA = new String[] { TestHelper.createSubtokenJWT(this.gw2AccountId1st, Set.of(Gw2ApiPermission.ACCOUNT, Gw2ApiPermission.UNLOCKS), testingClock.instant(), Duration.ofMinutes(30L)) };
final String[] dummySubtokenB = new String[] { TestHelper.createSubtokenJWT(this.gw2AccountId2nd, Set.of(Gw2ApiPermission.ACCOUNT, Gw2ApiPermission.UNLOCKS), testingClock.instant(), Duration.ofMinutes(30L)) };
result = performRetrieveTokenByCode(clientRegistrationCreation, URI.create(Objects.requireNonNull(result.getResponse().getRedirectedUrl())), Map.of(tokenA, dummySubtokenA[0], tokenB, dummySubtokenB[0]), Set.of(Gw2ApiPermission.ACCOUNT, Gw2ApiPermission.UNLOCKS)).andExpectAll(expectValidTokenResponse(Gw2ApiPermission.ACCOUNT.oauth2(), Gw2ApiPermission.UNLOCKS.oauth2())).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[0])), this.gw2AccountId2nd, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "Second", "token", dummySubtokenB[0]))), Set.of(Gw2ApiPermission.ACCOUNT, Gw2ApiPermission.UNLOCKS));
final String firstAuthorizationSubtokenA = dummySubtokenA[0];
final String firstAuthorizationSubtokenB = dummySubtokenB[0];
final JsonNode firstAuthorizationResponse = tokenResponse;
// perform a new authorization
// perform authorization request (which should redirect to application)
result = performAuthorizeWithClient(session, clientRegistration, List.of(Gw2ApiPermission.ACCOUNT.oauth2()), false).andReturn();
// verify the consent is unchanged
clientConsentEntity = this.clientConsentRepository.findByAccountIdAndClientRegistrationId(accountId, clientRegistration.id()).orElse(null);
assertNotNull(clientConsentEntity);
assertEquals(Set.of(Gw2ApiPermission.ACCOUNT.oauth2(), Gw2ApiPermission.UNLOCKS.oauth2()), clientConsentEntity.authorizedScopes());
// verify both authorizations exist
clientAuthorizationTokenEntities = this.clientAuthorizationTokenRepository.findAllByAccountIdAndClientAuthorizationId(accountId, clientAuthorization.id());
assertEquals(2, clientAuthorizationTokenEntities.size());
// retrieve the initial access and refresh token
dummySubtokenA[0] = TestHelper.createSubtokenJWT(this.gw2AccountId1st, Set.of(Gw2ApiPermission.ACCOUNT), testingClock.instant(), Duration.ofMinutes(30L));
dummySubtokenB[0] = 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[0], tokenB, dummySubtokenB[0])).andReturn();
// verify the access token
tokenResponse = assertTokenResponse(result, () -> Map.of(this.gw2AccountId1st, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "First", "token", dummySubtokenA[0])), this.gw2AccountId2nd, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "Second", "token", dummySubtokenB[0]))));
// retrieve a new access and refresh token for the first authorization
result = performRetrieveTokensByRefreshToken(clientRegistrationCreation, firstAuthorizationResponse.get("refresh_token").textValue()).andExpectAll(expectValidTokenResponse(Gw2ApiPermission.ACCOUNT.oauth2(), Gw2ApiPermission.UNLOCKS.oauth2())).andReturn();
// verify the access token
tokenResponse = assertTokenResponse(result, () -> Map.of(this.gw2AccountId1st, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "First", "token", firstAuthorizationSubtokenA)), this.gw2AccountId2nd, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "Second", "token", firstAuthorizationSubtokenB))), Set.of(Gw2ApiPermission.ACCOUNT, Gw2ApiPermission.UNLOCKS));
}
use of com.gw2auth.oauth2.server.service.client.registration.ClientRegistration in project oauth2-server by gw2auth.
the class OAuth2ServerTest method consentSubmitWithGw2AuthVerifiedScope.
@WithGw2AuthLogin
public void consentSubmitWithGw2AuthVerifiedScope(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(), ClientConsentService.GW2AUTH_VERIFIED_SCOPE)).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(), ClientConsentService.GW2AUTH_VERIFIED_SCOPE), 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(), ClientConsentService.GW2AUTH_VERIFIED_SCOPE), clientAuthorization.authorizedScopes());
List<ClientAuthorizationTokenEntity> clientAuthorizationTokenEntities = this.clientAuthorizationTokenRepository.findAllByAccountIdAndClientAuthorizationId(accountId, clientAuthorization.id());
assertEquals(2, clientAuthorizationTokenEntities.size());
// save account verification for one account
this.gw2AccountVerificationRepository.save(new Gw2AccountVerificationEntity(this.gw2AccountId1st, accountId));
// set testing clock to token customizer
Clock testingClock = Clock.fixed(Instant.now(), ZoneId.systemDefault());
this.oAuth2TokenCustomizerService.setClock(testingClock);
// retrieve the initial access and refresh token
final String[] dummySubtokenA = new String[] { TestHelper.createSubtokenJWT(this.gw2AccountId1st, Set.of(Gw2ApiPermission.ACCOUNT), testingClock.instant(), Duration.ofMinutes(30L)) };
final String[] dummySubtokenB = new String[] { TestHelper.createSubtokenJWT(this.gw2AccountId2nd, Set.of(Gw2ApiPermission.ACCOUNT), testingClock.instant(), Duration.ofMinutes(30L)) };
result = performRetrieveTokenByCode(clientRegistrationCreation, URI.create(Objects.requireNonNull(result.getResponse().getRedirectedUrl())), Map.of(tokenA, dummySubtokenA[0], tokenB, dummySubtokenB[0]), Set.of(Gw2ApiPermission.ACCOUNT)).andExpectAll(expectValidTokenResponse(Gw2ApiPermission.ACCOUNT.oauth2(), ClientConsentService.GW2AUTH_VERIFIED_SCOPE)).andReturn();
// verify the authorized tokens have been updated
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(2, savedSubtokens.size());
assertTrue(savedSubtokens.contains(dummySubtokenA[0]));
assertTrue(savedSubtokens.contains(dummySubtokenB[0]));
// 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());
assertTrue(apiTokenEntities.get(0).isValid());
assertInstantEquals(testingClock.instant(), apiTokenEntities.get(0).lastValidCheckTime());
assertTrue(apiTokenEntities.get(1).isValid());
assertInstantEquals(testingClock.instant(), apiTokenEntities.get(1).lastValidCheckTime());
// 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[0], "verified", true)), this.gw2AccountId2nd, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "Second", "token", dummySubtokenB[0], "verified", false))));
// remove the verification for the first account and save one for the second
this.gw2AccountVerificationRepository.deleteById(this.gw2AccountId1st);
this.gw2AccountVerificationRepository.save(new Gw2AccountVerificationEntity(this.gw2AccountId2nd, accountId));
// retrieve a new access token using the refresh token
final String refreshToken = tokenResponse.get("refresh_token").textValue();
result = performRetrieveTokensByRefreshToken(clientRegistrationCreation, refreshToken).andExpectAll(expectValidTokenResponse(Gw2ApiPermission.ACCOUNT.oauth2(), ClientConsentService.GW2AUTH_VERIFIED_SCOPE)).andReturn();
tokenResponse = assertTokenResponse(result, () -> Map.of(this.gw2AccountId1st, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "First", "token", dummySubtokenA[0], "verified", false)), this.gw2AccountId2nd, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "Second", "token", dummySubtokenB[0], "verified", true))));
}
use of com.gw2auth.oauth2.server.service.client.registration.ClientRegistration in project oauth2-server by gw2auth.
the class OAuth2ServerTest method authorizationCodeRequestWithExistingConsentButWithoutAPITokens.
@WithGw2AuthLogin
public void authorizationCodeRequestWithExistingConsentButWithoutAPITokens(MockHttpSession session) throws Exception {
final long accountId = AuthenticationHelper.getUser(session).orElseThrow().getAccountId();
final ClientRegistration clientRegistration = createClientRegistration().clientRegistration();
this.clientConsentRepository.save(new ClientConsentEntity(accountId, clientRegistration.id(), UUID.randomUUID(), Set.of(Gw2ApiPermission.ACCOUNT.oauth2())));
performAuthorizeWithClient(session, clientRegistration, List.of(Gw2ApiPermission.ACCOUNT.oauth2())).andExpect(status().is3xxRedirection()).andExpect(header().string("Location", asUri(new AllOf<>(new Matchers.MappingMatcher<>("Path", UriComponents::getPath, new IsEqual<>("/oauth2/consent")), new Matchers.MappingMatcher<>("Query", UriComponents::getQueryParams, new AllOf<>(hasQueryParam(OAuth2ParameterNames.SCOPE), hasQueryParam(OAuth2ParameterNames.CLIENT_ID), hasQueryParam(OAuth2ParameterNames.STATE)))))));
}
use of com.gw2auth.oauth2.server.service.client.registration.ClientRegistration in project oauth2-server by gw2auth.
the class ClientConsentControllerTest method getClientConsentLogPage.
@WithGw2AuthLogin
public void getClientConsentLogPage(MockHttpSession session) throws Exception {
final long accountId = AuthenticationHelper.getUser(session).orElseThrow().getAccountId();
final ClientRegistrationEntity clientRegistration = this.testHelper.createClientRegistration(accountId, "Name");
final ClientConsentEntity clientAuthorization = this.testHelper.createClientConsent(accountId, clientRegistration.id(), Set.of(Gw2ApiPermission.ACCOUNT.oauth2()));
final Queue<ClientConsentLogEntity> insertedLogs = new PriorityQueue<>(Comparator.comparing(ClientConsentLogEntity::timestamp).reversed());
for (int i = 0; i < 143; i++) {
final int generateMessageCount = ThreadLocalRandom.current().nextInt(20);
final List<String> messages = new ArrayList<>(generateMessageCount);
for (int j = 0; j < generateMessageCount; j++) {
messages.add(UUID.randomUUID().toString());
}
insertedLogs.offer(this.testHelper.createClientLog(accountId, clientAuthorization.clientRegistrationId(), UUID.randomUUID().toString(), messages));
}
final ObjectMapper mapper = new ObjectMapper();
int page = 0;
do {
final String responseJson = this.mockMvc.perform(get("/api/client/consent/{clientId}/logs", clientRegistration.clientId()).session(session).queryParam("page", Integer.toString(page))).andExpect(status().isOk()).andExpect(jsonPath("$.page").exists()).andExpect(jsonPath("$.nextPage").exists()).andExpect(jsonPath("$.logs").exists()).andReturn().getResponse().getContentAsString();
final JsonNode responseNode = mapper.readTree(responseJson);
final int nextPage = responseNode.get("nextPage").intValue();
assertEquals(page, responseNode.get("page").intValue());
assertTrue(nextPage == page + 1 || nextPage == -1);
final JsonNode logsNode = responseNode.get("logs");
assertTrue(logsNode.isArray());
for (int i = 0; i < logsNode.size(); i++) {
final ClientConsentLogEntity expectedLog = insertedLogs.poll();
assertNotNull(expectedLog);
final JsonNode logNode = logsNode.get(i);
assertInstantEquals(expectedLog.timestamp(), logNode.get("timestamp").textValue());
assertEquals(expectedLog.type(), logNode.get("type").textValue());
final JsonNode messagesNode = logNode.get("messages");
assertTrue(messagesNode.isArray());
for (int j = 0; j < messagesNode.size(); j++) {
assertEquals(expectedLog.messages().get(j), messagesNode.get(j).textValue());
}
}
page = nextPage;
} while (page != -1);
assertTrue(insertedLogs.isEmpty());
}
use of com.gw2auth.oauth2.server.service.client.registration.ClientRegistration in project oauth2-server by gw2auth.
the class OAuth2ConsentController method oauth2ConsentInformation.
@GetMapping(value = "/api/oauth2/consent", produces = MediaType.APPLICATION_JSON_VALUE)
public OAuth2ConsentInfoResponse oauth2ConsentInformation(@AuthenticationPrincipal Gw2AuthUser user, @RequestParam(OAuth2ParameterNames.CLIENT_ID) UUID clientId, @RequestParam(OAuth2ParameterNames.STATE) String state, @RequestParam(OAuth2ParameterNames.SCOPE) String scopes) {
final ClientRegistration clientRegistration = this.clientRegistrationService.getClientRegistration(clientId).orElseThrow();
final Set<String> requestedScopes = Utils.split(scopes, " ").collect(Collectors.toSet());
final Set<Gw2ApiPermission> requestedGw2ApiPermissions = requestedScopes.stream().flatMap((scope) -> Gw2ApiPermission.fromOAuth2(scope).stream()).collect(Collectors.toSet());
final boolean requestedVerifiedInformation = requestedScopes.contains(ClientConsentService.GW2AUTH_VERIFIED_SCOPE);
final List<ApiToken> apiTokens = this.apiTokenService.getApiTokens(user.getAccountId());
final List<OAuth2ConsentInfoResponse.MinimalApiToken> apiTokensWithSufficientPermissionResponses = new ArrayList<>();
final List<OAuth2ConsentInfoResponse.MinimalApiToken> apiTokensWithInsufficientPermissionResponses = new ArrayList<>();
final Set<UUID> verifiedGw2AccountIds;
if (apiTokens.isEmpty() || !requestedVerifiedInformation) {
verifiedGw2AccountIds = Set.of();
} else {
verifiedGw2AccountIds = this.verificationService.getVerifiedGw2AccountIds(user.getAccountId());
}
for (ApiToken apiToken : apiTokens) {
final OAuth2ConsentInfoResponse.MinimalApiToken resultApiToken = OAuth2ConsentInfoResponse.MinimalApiToken.create(apiToken, verifiedGw2AccountIds.contains(apiToken.gw2AccountId()));
if (apiToken.gw2ApiPermissions().containsAll(requestedGw2ApiPermissions)) {
apiTokensWithSufficientPermissionResponses.add(resultApiToken);
} else {
apiTokensWithInsufficientPermissionResponses.add(resultApiToken);
}
}
final Set<UUID> previouslyConsentedGw2AccountIds = this.clientAuthorizationService.getLatestClientAuthorization(user.getAccountId(), clientRegistration.id(), requestedScopes).map(ClientAuthorization::gw2AccountIds).orElseGet(Set::of);
final MultiValueMap<String, String> submitFormParameters = new LinkedMultiValueMap<>();
submitFormParameters.set(OAuth2ParameterNames.CLIENT_ID, clientId.toString());
submitFormParameters.set(OAuth2ParameterNames.STATE, state);
requestedScopes.forEach((scope) -> submitFormParameters.add(OAuth2ParameterNames.SCOPE, scope));
final String cancelUri = UriComponentsBuilder.fromPath("/api/oauth2/consent-deny").replaceQueryParam(OAuth2ParameterNames.CLIENT_ID, clientId).replaceQueryParam(OAuth2ParameterNames.STATE, state).toUriString();
return new OAuth2ConsentInfoResponse(ClientRegistrationPublicResponse.create(clientRegistration), requestedGw2ApiPermissions, requestedVerifiedInformation, "/oauth2/authorize", submitFormParameters, cancelUri, apiTokensWithSufficientPermissionResponses, apiTokensWithInsufficientPermissionResponses, previouslyConsentedGw2AccountIds);
}
Aggregations