public async Task <GlobalXApiToken> RefreshAndPersistTokenForUser(string userId) { /// First request a lock for this user's token before we do anything with it. /// This does not require the token to exist. /// <see cref="GlobalXApiTokenLockInfo"/> implements <see cref="IDisposable"/> which will /// delete the lock when disposed, so it does not need to be deleted explicitly in this code. using (var lockInfo = await RequestApiTokenLock(userId)) { var existingToken = await _globalXApiTokenRepository.GetTokenForUser(userId); Exception refreshException = null; if (existingToken != null && !string.IsNullOrEmpty(existingToken.RefreshToken)) { try { var refreshedToken = await SendAccessTokenRefreshRequest(existingToken); if (!refreshedToken.AccessTokenHasExpired(_clock)) { return(refreshedToken); } } catch (Exception ex) { refreshException = ex; } } var credentials = await _globalXCredentialsRepository.GetCredentialsForUser(userId); if (credentials is null) { throw new GlobalXApiCredentialsNotFoundException( $"Could not find an API token to refresh, nor credentials to request a new token for user '{userId}'.", refreshException); } var tokenFromCredentials = await SendAccessTokenFromCredentialsRequest(credentials); await _globalXApiTokenRepository.AddOrUpdateGlobalXApiToken(tokenFromCredentials, lockInfo); return(tokenFromCredentials); } }
protected override async Task Handle(StoreGlobalXApiTokenCommand command, CancellationToken token) { if (command is null) { throw new ArgumentNullException(nameof(command)); } await _validator.ValidateAndThrowAsync(command); await _globalXApiTokenRepository.AddOrUpdateGlobalXApiToken(command.GlobalXApiToken, null, overrideAndClearLock : true); }