use of com.gw2auth.oauth2.server.repository.client.authorization.ClientAuthorizationEntity in project oauth2-server by gw2auth.
the class ClientAuthorizationControllerTest method getClientAuthorizations.
@WithGw2AuthLogin
public void getClientAuthorizations(MockHttpSession session) throws Exception {
final long accountId = AuthenticationHelper.getUser(session).orElseThrow().getAccountId();
// create client
final ClientRegistrationEntity client = this.testHelper.createClientRegistration(accountId, "Client");
// create consent
this.testHelper.createClientConsent(accountId, client.id(), Set.of(Gw2ApiPermission.ACCOUNT.oauth2(), ClientConsentService.GW2AUTH_VERIFIED_SCOPE));
// create 2 authorizations
final ClientAuthorizationEntity authorization1 = this.testHelper.createClientAuthorization(accountId, client.id(), Set.of(Gw2ApiPermission.ACCOUNT.oauth2()));
final ClientAuthorizationEntity authorization2 = this.testHelper.createClientAuthorization(accountId, client.id(), Set.of(Gw2ApiPermission.ACCOUNT.oauth2(), ClientConsentService.GW2AUTH_VERIFIED_SCOPE));
// insert tokens for these authorizations
final ApiTokenEntity tokenA = this.testHelper.createApiToken(accountId, UUID.randomUUID(), Gw2ApiPermission.all(), "Token A");
final ApiTokenEntity tokenB = this.testHelper.createApiToken(accountId, UUID.randomUUID(), Gw2ApiPermission.all(), "Token B");
final ApiTokenEntity tokenC = this.testHelper.createApiToken(accountId, UUID.randomUUID(), Gw2ApiPermission.all(), "Token C");
final ApiTokenEntity tokenD = this.testHelper.createApiToken(accountId, UUID.randomUUID(), Gw2ApiPermission.all(), "Token D");
this.testHelper.createClientAuthorizationTokens(accountId, authorization1.id(), tokenA.gw2AccountId(), tokenD.gw2AccountId());
this.testHelper.createClientAuthorizationTokens(accountId, authorization2.id(), tokenA.gw2AccountId(), tokenB.gw2AccountId(), tokenC.gw2AccountId());
// query api
final String jsonResponse = this.mockMvc.perform(get("/api/client/authorization/{clientId}", client.clientId()).session(session)).andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
final ObjectMapper mapper = new ObjectMapper();
final JsonNode node = mapper.readTree(jsonResponse);
assertTrue(node.isArray());
assertEquals(2, node.size());
for (int i = 0; i < node.size(); i++) {
final JsonNode authorizationNode = node.get(i);
final String id = authorizationNode.get("id").textValue();
final ClientAuthorizationEntity authorization;
final Map<UUID, ApiTokenEntity> apiTokens;
if (id.equals(authorization1.id())) {
authorization = authorization1;
apiTokens = Map.of(tokenA.gw2AccountId(), tokenA, tokenD.gw2AccountId(), tokenD);
} else if (id.equals(authorization2.id())) {
authorization = authorization2;
apiTokens = Map.of(tokenA.gw2AccountId(), tokenA, tokenB.gw2AccountId(), tokenB, tokenC.gw2AccountId(), tokenC);
} else {
fail("unknown authorization id found in response");
throw new IllegalStateException("");
}
assertInstantEquals(authorization.creationTime(), authorizationNode.get("creationTime").textValue());
assertInstantEquals(authorization.lastUpdateTime(), authorizationNode.get("lastUpdateTime").textValue());
assertEquals(authorization.displayName(), authorizationNode.get("displayName").textValue());
// authorized scopes
final Set<String> expectedAuthorizedScopes = new HashSet<>(authorization.authorizedScopes());
final JsonNode gw2ApiPermissionsNode = authorizationNode.get("authorizedGw2ApiPermissions");
assertTrue(gw2ApiPermissionsNode.isArray());
for (int j = 0; j < gw2ApiPermissionsNode.size(); j++) {
final String gw2ApiPermissionStr = gw2ApiPermissionsNode.get(j).textValue();
final Gw2ApiPermission gw2ApiPermission = Gw2ApiPermission.fromGw2(gw2ApiPermissionStr).orElseThrow();
if (!expectedAuthorizedScopes.remove(gw2ApiPermission.oauth2())) {
fail("received gw2 api permission which is not present in the entity");
}
}
if (authorizationNode.get("authorizedVerifiedInformation").booleanValue()) {
if (!expectedAuthorizedScopes.remove(ClientConsentService.GW2AUTH_VERIFIED_SCOPE)) {
fail("received verified scope but it is not present in the entity");
}
}
assertTrue(expectedAuthorizedScopes.isEmpty());
// tokens
final Map<UUID, ApiTokenEntity> expectedApiTokens = new HashMap<>(apiTokens);
final JsonNode tokensNode = authorizationNode.get("tokens");
assertTrue(tokensNode.isArray());
for (int j = 0; j < tokensNode.size(); j++) {
final JsonNode tokenNode = tokensNode.get(j);
final ApiTokenEntity expectedApiToken = expectedApiTokens.remove(UUID.fromString(tokenNode.get("gw2AccountId").textValue()));
assertNotNull(expectedApiToken);
assertEquals(expectedApiToken.displayName(), tokenNode.get("displayName").textValue());
}
assertTrue(expectedApiTokens.isEmpty());
}
}
use of com.gw2auth.oauth2.server.repository.client.authorization.ClientAuthorizationEntity in project oauth2-server by gw2auth.
the class OAuth2ServerTest method revokeAccessToken.
@WithGw2AuthLogin
public void revokeAccessToken(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, clientRegistrationCreation.clientSecret()).queryParam(OAuth2ParameterNames.TOKEN_TYPE_HINT, OAuth2TokenType.ACCESS_TOKEN.getValue()).queryParam(OAuth2ParameterNames.TOKEN, accessToken)).andExpect(status().isOk());
// database should still contain the authorization
final List<ClientAuthorizationEntity> clientAuthorizationEntities = this.clientAuthorizationRepository.findAllByAccountIdAndClientRegistrationId(accountId, clientRegistration.id());
assertEquals(1, clientAuthorizationEntities.size());
}
use of com.gw2auth.oauth2.server.repository.client.authorization.ClientAuthorizationEntity in project oauth2-server by gw2auth.
the class OAuth2ServerTest method revokeRefreshTokenWithInvalidClientSecret.
@WithGw2AuthLogin
public void revokeRefreshTokenWithInvalidClientSecret(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 refresh_token
final String refreshToken = tokenResponse.get("refresh_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.REFRESH_TOKEN.getValue()).queryParam(OAuth2ParameterNames.TOKEN, refreshToken)).andExpect(status().isUnauthorized());
// database should still contain the authorization
final List<ClientAuthorizationEntity> clientAuthorizationEntities = this.clientAuthorizationRepository.findAllByAccountIdAndClientRegistrationId(accountId, clientRegistration.id());
assertEquals(1, clientAuthorizationEntities.size());
}
use of com.gw2auth.oauth2.server.repository.client.authorization.ClientAuthorizationEntity in project oauth2-server by gw2auth.
the class OAuth2ServerTest method consentSubmitWithLaterRemovedRootApiTokens.
@WithGw2AuthLogin
public void consentSubmitWithLaterRemovedRootApiTokens(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
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 = performRetrieveTokenByCodeAndExpectValid(clientRegistrationCreation, URI.create(Objects.requireNonNull(result.getResponse().getRedirectedUrl())), Map.of(tokenA, dummySubtokenA[0], tokenB, dummySubtokenB[0])).andReturn();
// verify the subtokens have been updated
clientAuthorizationTokenEntities = this.clientAuthorizationTokenRepository.findAllByAccountIdAndClientAuthorizationId(accountId, clientAuthorization.id());
assertEquals(2, clientAuthorizationTokenEntities.size());
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])), this.gw2AccountId2nd, new com.nimbusds.jose.shaded.json.JSONObject(Map.of("name", "Second", "token", dummySubtokenB[0]))));
// remove all Root-Tokens for this authorization
for (ClientAuthorizationTokenEntity clientAuthorizationTokenEntity : clientAuthorizationTokenEntities) {
this.apiTokenRepository.deleteByAccountIdAndGw2AccountId(clientAuthorizationTokenEntity.accountId(), clientAuthorizationTokenEntity.gw2AccountId());
}
// retrieve a new access token using the refresh token
testingClock = Clock.offset(testingClock, Duration.ofMinutes(31L));
this.oAuth2TokenCustomizerService.setClock(testingClock);
final String refreshToken = tokenResponse.get("refresh_token").textValue();
performRetrieveTokensByRefreshToken(clientRegistrationCreation, refreshToken).andExpect(status().isBadRequest()).andExpect(jsonPath("$.error").isString()).andExpect(jsonPath("$.access_token").doesNotExist()).andExpect(jsonPath("$.refresh_token").doesNotExist()).andReturn();
}
use of com.gw2auth.oauth2.server.repository.client.authorization.ClientAuthorizationEntity in project oauth2-server by gw2auth.
the class OAuth2ServerTest method revokeRefreshToken.
@WithGw2AuthLogin
public void revokeRefreshToken(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 & authorization service
Clock testingClock = Clock.fixed(Instant.now(), ZoneId.systemDefault());
this.oAuth2TokenCustomizerService.setClock(testingClock);
this.clientAuthorizationService.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 refresh_token
final String refreshToken = tokenResponse.get("refresh_token").textValue();
this.mockMvc.perform(post("/oauth2/revoke").queryParam(OAuth2ParameterNames.CLIENT_ID, clientRegistrationCreation.clientRegistration().clientId().toString()).queryParam(OAuth2ParameterNames.CLIENT_SECRET, clientRegistrationCreation.clientSecret()).queryParam(OAuth2ParameterNames.TOKEN_TYPE_HINT, OAuth2TokenType.REFRESH_TOKEN.getValue()).queryParam(OAuth2ParameterNames.TOKEN, refreshToken)).andExpect(status().isOk());
// trigger deletion
this.clientAuthorizationService.deleteAllExpiredAuthorizations();
// database should still contain the authorization (access token is still valid)
List<ClientAuthorizationEntity> clientAuthorizationEntities = this.clientAuthorizationRepository.findAllByAccountIdAndClientRegistrationId(accountId, clientRegistration.id());
assertEquals(1, clientAuthorizationEntities.size());
// trigger deletion with current timestamp + 31min
testingClock = Clock.offset(testingClock, Duration.ofMinutes(31L));
this.clientAuthorizationService.setClock(testingClock);
this.clientAuthorizationService.deleteAllExpiredAuthorizations();
// database should not contain the authorization anymore
clientAuthorizationEntities = this.clientAuthorizationRepository.findAllByAccountIdAndClientRegistrationId(accountId, clientRegistration.id());
assertEquals(0, clientAuthorizationEntities.size());
}
Aggregations