Search in sources :

Example 1 with ApiTokenEntity

use of com.gw2auth.oauth2.server.repository.apitoken.ApiTokenEntity in project oauth2-server by gw2auth.

the class ApiTokenServiceImpl method updateApiToken.

@Override
@Transactional(noRollbackFor = ApiTokenOwnershipMismatchException.class)
public ApiToken updateApiToken(long accountId, UUID gw2AccountId, String gw2ApiToken, String displayName) {
    final OptionalLong optional = this.verificationService.getVerifiedAccountId(gw2AccountId);
    if (optional.isPresent() && optional.getAsLong() != accountId) {
        this.apiTokenRepository.deleteByAccountIdAndGw2AccountId(accountId, gw2AccountId);
        throw new ApiTokenOwnershipMismatchException();
    }
    ApiTokenEntity apiTokenEntity = this.apiTokenRepository.findByAccountIdAndGw2AccountId(accountId, gw2AccountId).orElseThrow(() -> new ApiTokenServiceException(ApiTokenServiceException.API_TOKEN_NOT_FOUND, HttpStatus.NOT_FOUND));
    if (gw2ApiToken != null) {
        final Gw2TokenInfo gw2TokenInfo = this.gw2ApiService.getTokenInfo(gw2ApiToken);
        if (!gw2TokenInfo.permissions().contains(Gw2ApiPermission.ACCOUNT)) {
            throw new ApiTokenServiceException(ApiTokenServiceException.MISSING_ACCOUNT_PERMISSION, HttpStatus.BAD_REQUEST);
        }
        final Gw2Account gw2Account = this.gw2ApiService.getAccount(gw2ApiToken);
        if (!gw2Account.id().equals(gw2AccountId)) {
            throw new ApiTokenServiceException(ApiTokenServiceException.GW2_ACCOUNT_ID_MISMATCH, HttpStatus.BAD_REQUEST);
        }
        apiTokenEntity = apiTokenEntity.withGw2ApiToken(gw2ApiToken).withGw2ApiPermissions(gw2TokenInfo.permissions().stream().map(Gw2ApiPermission::gw2).collect(Collectors.toSet())).withLastValidCheckTime(this.clock.instant(), true);
    }
    if (displayName != null) {
        apiTokenEntity = apiTokenEntity.withDisplayName(displayName);
    }
    return ApiToken.fromEntity(this.apiTokenRepository.save(apiTokenEntity));
}
Also used : ApiTokenEntity(com.gw2auth.oauth2.server.repository.apitoken.ApiTokenEntity) Gw2ApiPermission(com.gw2auth.oauth2.server.service.Gw2ApiPermission) Transactional(org.springframework.transaction.annotation.Transactional)

Example 2 with ApiTokenEntity

use of com.gw2auth.oauth2.server.repository.apitoken.ApiTokenEntity in project oauth2-server by gw2auth.

the class ApiTokenServiceImpl method checkTokenValidity.

@Scheduled(fixedRate = 1000L * 60L * 5L)
public void checkTokenValidity() {
    final Instant now = this.clock.instant();
    final Instant offset = now.minus(VALIDITY_CHECK_INTERVAL);
    final List<ApiTokenEntity> tokensToCheck = this.apiTokenRepository.findAllByLastValidCheckTimeLTE(offset, VALIDITY_CHECK_BATCH_SIZE);
    final List<ApiTokenValidityUpdateEntity> updateEntities = new ArrayList<>(tokensToCheck.size());
    final int[] counts = new int[3];
    for (ApiTokenEntity apiTokenEntity : tokensToCheck) {
        Boolean isValidState;
        try {
            this.gw2ApiService.getTokenInfo(apiTokenEntity.gw2ApiToken());
            isValidState = true;
            counts[0]++;
        } catch (InvalidApiTokenException e) {
            isValidState = false;
            counts[1]++;
        } catch (Gw2ApiServiceException e) {
            isValidState = null;
            counts[2]++;
        }
        if (isValidState != null) {
            updateEntities.add(new ApiTokenValidityUpdateEntity(apiTokenEntity.accountId(), apiTokenEntity.gw2AccountId(), isValidState));
        }
    }
    this.apiTokenRepository.updateApiTokensValid(now, updateEntities);
    LOG.info("updated API-Token validity for {} API-Tokens; valid={} invalid={} unknown={}", tokensToCheck.size(), counts[0], counts[1], counts[2]);
}
Also used : ApiTokenEntity(com.gw2auth.oauth2.server.repository.apitoken.ApiTokenEntity) ApiTokenValidityUpdateEntity(com.gw2auth.oauth2.server.repository.apitoken.ApiTokenValidityUpdateEntity) Instant(java.time.Instant) Scheduled(org.springframework.scheduling.annotation.Scheduled)

Example 3 with ApiTokenEntity

use of com.gw2auth.oauth2.server.repository.apitoken.ApiTokenEntity 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());
    }
}
Also used : ApiTokenEntity(com.gw2auth.oauth2.server.repository.apitoken.ApiTokenEntity) Gw2ApiPermission(com.gw2auth.oauth2.server.service.Gw2ApiPermission) ClientRegistrationEntity(com.gw2auth.oauth2.server.repository.client.registration.ClientRegistrationEntity) JsonNode(com.fasterxml.jackson.databind.JsonNode) ClientAuthorizationEntity(com.gw2auth.oauth2.server.repository.client.authorization.ClientAuthorizationEntity) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper)

Example 4 with ApiTokenEntity

use of com.gw2auth.oauth2.server.repository.apitoken.ApiTokenEntity in project oauth2-server by gw2auth.

the class ClientConsentControllerTest method deleteClientConsent.

@WithGw2AuthLogin
public void deleteClientConsent(MockHttpSession session) throws Exception {
    final long accountId = AuthenticationHelper.getUser(session).orElseThrow().getAccountId();
    final ClientRegistrationEntity clientRegistrationA = this.testHelper.createClientRegistration(accountId, "Name");
    final ClientRegistrationEntity clientRegistrationB = this.testHelper.createClientRegistration(accountId, "Name");
    final ApiTokenEntity apiTokenA = this.testHelper.createApiToken(accountId, UUID.randomUUID(), Gw2ApiPermission.all(), "TokenNameA");
    final ApiTokenEntity apiTokenB = this.testHelper.createApiToken(accountId, UUID.randomUUID(), Gw2ApiPermission.all(), "TokenNameB");
    final ApiTokenEntity apiTokenC = this.testHelper.createApiToken(accountId, UUID.randomUUID(), Gw2ApiPermission.all(), "TokenNameC");
    final ClientConsentEntity clientConsentA = this.testHelper.createClientConsent(accountId, clientRegistrationA.id(), Set.of(Gw2ApiPermission.ACCOUNT.oauth2()));
    final ClientConsentEntity clientConsentB = this.testHelper.createClientConsent(accountId, clientRegistrationB.id(), Set.of(Gw2ApiPermission.ACCOUNT.oauth2(), Gw2ApiPermission.GUILDS.oauth2()));
    final String authorizationIdA = this.testHelper.createClientAuthorization(accountId, clientConsentA.clientRegistrationId(), clientConsentA.authorizedScopes()).id();
    final String authorizationIdB = this.testHelper.createClientAuthorization(accountId, clientConsentB.clientRegistrationId(), clientConsentB.authorizedScopes()).id();
    // tokens for authorization A
    this.testHelper.createClientAuthorizationTokens(accountId, authorizationIdA, apiTokenA.gw2AccountId(), apiTokenC.gw2AccountId());
    // tokens for authorization B
    this.testHelper.createClientAuthorizationTokens(accountId, authorizationIdB, apiTokenB.gw2AccountId());
    // logs for authorization A
    this.testHelper.createClientLog(accountId, clientConsentA.clientRegistrationId(), "SomeTypeA", List.of());
    this.testHelper.createClientLog(accountId, clientConsentA.clientRegistrationId(), "SomeTypeA", List.of());
    // logs for authorization B
    this.testHelper.createClientLog(accountId, clientConsentB.clientRegistrationId(), "SomeTypeA", List.of());
    // delete authorization A
    this.mockMvc.perform(delete("/api/client/consent/{clientId}", clientRegistrationA.clientId()).session(session).with(csrf())).andExpect(status().isOk());
    // entity should still be there
    ClientConsentEntity clientConsent = this.clientConsentRepository.findByAccountIdAndClientRegistrationId(accountId, clientConsentA.clientRegistrationId()).orElse(null);
    assertNotNull(clientConsent);
    assertNotEquals(clientConsentA, clientConsent);
    assertTrue(clientConsent.authorizedScopes().isEmpty());
    assertEquals(clientConsentA.accountSub(), clientConsent.accountSub());
    // logs and tokens should be deleted
    assertTrue(this.clientAuthorizationTokenRepository.findAllByAccountIdAndClientAuthorizationId(accountId, authorizationIdA).isEmpty());
    assertTrue(this.clientConsentLogRepository.findByAccountIdAndClientId(accountId, clientRegistrationA.clientId(), 0, 10).findAny().isEmpty());
    // authorization B should still be there (and unchanged)
    clientConsent = this.clientConsentRepository.findByAccountIdAndClientRegistrationId(accountId, clientConsentB.clientRegistrationId()).orElse(null);
    assertEquals(clientConsentB, clientConsent);
    // logs and tokens of B should still be there
    assertEquals(1, this.clientAuthorizationTokenRepository.findAllByAccountIdAndClientAuthorizationId(accountId, authorizationIdB).size());
    assertEquals(1L, this.clientConsentLogRepository.findByAccountIdAndClientId(accountId, clientRegistrationB.clientId(), 0, 10).count());
}
Also used : ApiTokenEntity(com.gw2auth.oauth2.server.repository.apitoken.ApiTokenEntity) ClientRegistrationEntity(com.gw2auth.oauth2.server.repository.client.registration.ClientRegistrationEntity) ClientConsentEntity(com.gw2auth.oauth2.server.repository.client.consent.ClientConsentEntity)

Example 5 with ApiTokenEntity

use of com.gw2auth.oauth2.server.repository.apitoken.ApiTokenEntity in project oauth2-server by gw2auth.

the class ApiTokenControllerTest method updateApiToken.

@WithGw2AuthLogin
public void updateApiToken(MockHttpSession session) throws Exception {
    final long accountId = AuthenticationHelper.getUser(session).orElseThrow().getAccountId();
    final UUID gw2AccountId = UUID.randomUUID();
    final ApiTokenEntity apiToken = this.testHelper.createApiToken(accountId, gw2AccountId, Set.of(Gw2ApiPermission.ACCOUNT, Gw2ApiPermission.GUILDS), "TokenA");
    // verified
    this.testHelper.createAccountVerification(accountId, gw2AccountId);
    // register 2 clients
    final ClientRegistrationEntity clientRegistrationA = this.testHelper.createClientRegistration(accountId, "ClientA");
    final ClientRegistrationEntity clientRegistrationB = this.testHelper.createClientRegistration(accountId, "ClientB");
    // authorize 2 clients
    final ClientConsentEntity clientConsentA = this.testHelper.createClientConsent(accountId, clientRegistrationA.id(), Set.of(Gw2ApiPermission.ACCOUNT.oauth2()));
    final ClientConsentEntity clientConsentB = this.testHelper.createClientConsent(accountId, clientRegistrationB.id(), Set.of(Gw2ApiPermission.ACCOUNT.oauth2()));
    final String authorizationIdA = this.testHelper.createClientAuthorization(accountId, clientConsentA.clientRegistrationId(), clientConsentA.authorizedScopes()).id();
    final String authorizationIdB = this.testHelper.createClientAuthorization(accountId, clientConsentB.clientRegistrationId(), clientConsentB.authorizedScopes()).id();
    // use this token in both clients
    this.testHelper.createClientAuthorizationToken(accountId, authorizationIdA, gw2AccountId);
    this.testHelper.createClientAuthorizationToken(accountId, authorizationIdB, gw2AccountId);
    final String gw2ApiToken = TestHelper.randomRootToken();
    // prepare the gw2 rest server
    this.gw2RestServer.reset();
    prepareGw2RestServerForTokenInfoRequest(gw2ApiToken, "Token Name", Set.of(Gw2ApiPermission.ACCOUNT));
    preparedGw2RestServerForAccountRequest(gw2AccountId, gw2ApiToken, "Gw2AccountName.1234");
    final String responseJson = this.mockMvc.perform(patch("/api/token/{gw2AccountId}", gw2AccountId).session(session).with(csrf()).queryParam("gw2ApiToken", gw2ApiToken).queryParam("displayName", "New Display Name")).andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
    final ObjectMapper mapper = new ObjectMapper();
    final JsonNode apiTokenNode = mapper.readTree(responseJson);
    assertExpectedApiToken(new ExpectedApiToken(apiToken, true, List.of(clientRegistrationA, clientRegistrationB)), // display name should be updated
    "New Display Name", // api token should be updated
    gw2ApiToken, // the new api token has less permissions than the original one
    Set.of(Gw2ApiPermission.ACCOUNT.gw2()), apiTokenNode);
}
Also used : ApiTokenEntity(com.gw2auth.oauth2.server.repository.apitoken.ApiTokenEntity) ClientRegistrationEntity(com.gw2auth.oauth2.server.repository.client.registration.ClientRegistrationEntity) JsonNode(com.fasterxml.jackson.databind.JsonNode) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) ClientConsentEntity(com.gw2auth.oauth2.server.repository.client.consent.ClientConsentEntity)

Aggregations

ApiTokenEntity (com.gw2auth.oauth2.server.repository.apitoken.ApiTokenEntity)14 JsonNode (com.fasterxml.jackson.databind.JsonNode)9 ClientConsentEntity (com.gw2auth.oauth2.server.repository.client.consent.ClientConsentEntity)9 ClientAuthorizationEntity (com.gw2auth.oauth2.server.repository.client.authorization.ClientAuthorizationEntity)8 ClientAuthorizationTokenEntity (com.gw2auth.oauth2.server.repository.client.authorization.ClientAuthorizationTokenEntity)6 ClientRegistration (com.gw2auth.oauth2.server.service.client.registration.ClientRegistration)6 ClientRegistrationCreation (com.gw2auth.oauth2.server.service.client.registration.ClientRegistrationCreation)6 Clock (java.time.Clock)6 JSONObject (org.json.JSONObject)6 MvcResult (org.springframework.test.web.servlet.MvcResult)6 ClientRegistrationEntity (com.gw2auth.oauth2.server.repository.client.registration.ClientRegistrationEntity)5 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)4 Gw2ApiPermission (com.gw2auth.oauth2.server.service.Gw2ApiPermission)4 ApiSubTokenEntity (com.gw2auth.oauth2.server.repository.apisubtoken.ApiSubTokenEntity)3 Instant (java.time.Instant)3 Gw2AccountVerificationEntity (com.gw2auth.oauth2.server.repository.verification.Gw2AccountVerificationEntity)2 com.gw2auth.oauth2.server (com.gw2auth.oauth2.server)1 Assertions.assertInstantEquals (com.gw2auth.oauth2.server.Assertions.assertInstantEquals)1 Matchers (com.gw2auth.oauth2.server.Matchers)1 ApiSubTokenRepository (com.gw2auth.oauth2.server.repository.apisubtoken.ApiSubTokenRepository)1