use of com.gw2auth.oauth2.server.service.account.Account 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.service.account.Account in project oauth2-server by gw2auth.
the class ApiTokenController method getApiTokens.
@GetMapping(value = "/api/token", produces = MediaType.APPLICATION_JSON_VALUE)
public List<ApiTokenResponse> getApiTokens(@AuthenticationPrincipal Gw2AuthUser user) {
final List<ApiToken> apiTokens = this.apiTokenService.getApiTokens(user.getAccountId());
// get all gw2 account ids for authorization batch lookup
final Set<UUID> gw2AccountIds = apiTokens.stream().map(ApiToken::gw2AccountId).collect(Collectors.toSet());
// aggregate authorizations for later lookup
final List<ClientAuthorization> clientAuthorizations = this.clientAuthorizationService.getClientAuthorizations(user.getAccountId(), gw2AccountIds);
final Set<Long> clientRegistrationIds = new HashSet<>(clientAuthorizations.size());
final Map<UUID, Set<Long>> clientRegistrationIdsByGw2AccountId = new HashMap<>(clientAuthorizations.size());
for (ClientAuthorization clientAuthorization : clientAuthorizations) {
clientRegistrationIds.add(clientAuthorization.clientRegistrationId());
for (UUID gw2AccountId : clientAuthorization.gw2AccountIds()) {
clientRegistrationIdsByGw2AccountId.computeIfAbsent(gw2AccountId, (k) -> new HashSet<>()).add(clientAuthorization.clientRegistrationId());
}
}
// find all client registrations for the registration ids and remember them by id
final Map<Long, ClientRegistration> clientRegistrationById = this.clientRegistrationService.getClientRegistrations(clientRegistrationIds).stream().collect(Collectors.toMap(ClientRegistration::id, Function.identity()));
// find all verified gw2 account ids for this account (better than querying for every single one)
final Set<UUID> verifiedGw2AccountIds = this.verificationService.getVerifiedGw2AccountIds(user.getAccountId());
final List<ApiTokenResponse> response = new ArrayList<>(apiTokens.size());
for (ApiToken apiToken : apiTokens) {
final Set<Long> clientRegistrationIdsForThisToken = clientRegistrationIdsByGw2AccountId.get(apiToken.gw2AccountId());
final List<ApiTokenResponse.Authorization> authorizations;
if (clientRegistrationIdsForThisToken != null && !clientRegistrationIdsForThisToken.isEmpty()) {
authorizations = new ArrayList<>(clientRegistrationIdsForThisToken.size());
for (long clientRegistrationId : clientRegistrationIdsForThisToken) {
final ClientRegistration clientRegistration = clientRegistrationById.get(clientRegistrationId);
if (clientRegistration != null) {
authorizations.add(ApiTokenResponse.Authorization.create(clientRegistration));
}
}
} else {
authorizations = List.of();
}
response.add(ApiTokenResponse.create(apiToken, verifiedGw2AccountIds.contains(apiToken.gw2AccountId()), authorizations));
}
return response;
}
use of com.gw2auth.oauth2.server.service.account.Account in project oauth2-server by gw2auth.
the class VerificationServiceImpl method submitChallenge.
@Override
@Transactional
public VerificationChallengeSubmit submitChallenge(long accountId, String gw2ApiToken) {
Gw2AccountVerificationChallengeEntity entity = this.gw2AccountVerificationChallengeRepository.findByAccountIdAndGw2AccountId(accountId, STARTED_CHALLENGE_GW2_ACCOUNT_ID).orElseThrow(() -> new Gw2AccountVerificationServiceException(Gw2AccountVerificationServiceException.CHALLENGE_NOT_FOUND, HttpStatus.NOT_FOUND));
this.gw2AccountVerificationChallengeRepository.deleteByAccountIdAndGw2AccountId(accountId, STARTED_CHALLENGE_GW2_ACCOUNT_ID);
final VerificationChallenge<?> challenge = this.challengesById.get(entity.challengeId());
if (challenge == null) {
throw new Gw2AccountVerificationServiceException(Gw2AccountVerificationServiceException.CHALLENGE_NOT_FOUND, HttpStatus.NOT_FOUND);
}
final Instant startTime = this.clock.instant();
final Instant timeout = startTime.plus(challenge.getTimeout());
final Gw2SubToken gw2SubToken = this.gw2ApiService.createSubToken(gw2ApiToken, challenge.getRequiredGw2ApiPermissions(), timeout);
if (!gw2SubToken.permissions().containsAll(challenge.getRequiredGw2ApiPermissions())) {
throw new Gw2AccountVerificationServiceException(Gw2AccountVerificationServiceException.INSUFFICIENT_PERMISSIONS, HttpStatus.BAD_REQUEST);
}
final UUID gw2AccountId = this.gw2ApiService.getAccount(gw2SubToken.value()).id();
final Gw2AccountVerificationChallengeEntity pendingChallengeEntity = this.gw2AccountVerificationChallengeRepository.findByAccountIdAndGw2AccountId(accountId, gw2AccountId.toString()).orElse(null);
if (pendingChallengeEntity != null) {
if (pendingChallengeEntity.challengeId() == VERIFICATION_FAILED_CHALLENGE_ID) {
final Duration timeUntilAvailable = Duration.between(this.clock.instant(), pendingChallengeEntity.timeoutAt());
final long minutes = timeUntilAvailable.toMinutes();
// a verification for this gw2-account failed before
throw new Gw2AccountVerificationServiceException(String.format(Gw2AccountVerificationServiceException.CHALLENGE_FOR_THIS_ACCOUNT_BLOCKED, minutes), HttpStatus.BAD_REQUEST);
} else {
// allow only one active challenge per gw2 account
throw new Gw2AccountVerificationServiceException(Gw2AccountVerificationServiceException.CHALLENGE_FOR_THIS_GW2_ACCOUNT_ALREADY_STARTED, HttpStatus.BAD_REQUEST);
}
} else if (this.gw2AccountVerificationRepository.findById(gw2AccountId).map(Gw2AccountVerificationEntity::accountId).orElse(-1L) == accountId) {
// if this gw2 account is already verified for this same gw2auth account, dont proceed
throw new Gw2AccountVerificationServiceException(Gw2AccountVerificationServiceException.GW2_ACCOUNT_ALREADY_VERIFIED, HttpStatus.BAD_REQUEST);
}
entity = new Gw2AccountVerificationChallengeEntity(entity.accountId(), gw2AccountId.toString(), entity.challengeId(), entity.state(), gw2SubToken.value(), startTime, timeout);
final boolean isVerified = verify(entity);
final VerificationChallengePending verificationChallengePending;
if (isVerified) {
verificationChallengePending = null;
} else {
this.gw2AccountVerificationChallengeRepository.save(entity);
verificationChallengePending = new VerificationChallengePending(entity.challengeId(), gw2AccountId, startTime);
}
return new VerificationChallengeSubmit(verificationChallengePending, isVerified);
}
Aggregations