public async void PutAccessContext_Should_Update_If_UserId_CredentialsId_ProviderName_Have_Match()
        {
            string userId        = Guid.NewGuid().ToString();
            string credentialsId = Guid.NewGuid().ToString();
            string providerName  = Guid.NewGuid().ToString();
            string newValue      = "MyNewValue";

            _mockCacheItems.Add(userId, new List <AccountAccessContext> {
                new AccountAccessContext {
                    UserId = userId, CredentialsId = credentialsId, ProviderName = providerName
                }
            });

            SetupCacheGetMethod(userId);

            var newContext = new AccountAccessContext {
                UserId = userId, CredentialsId = credentialsId, ProviderName = providerName, AccessToken = newValue
            };

            SetupCacheSetMethod(userId);

            var result = await _accessContextCachingService.PutAccessContext(newContext);

            Assert.True(result.Success);
            Assert.Single(_mockCacheItems[userId]);
            _mockCache.Verify(x => x.GetAsync(userId, default), Times.Once);
            _mockCache.Verify(x => x.SetAsync(userId, It.IsAny <byte[]>(), It.IsAny <DistributedCacheEntryOptions>(), default), Times.Once);
            Assert.Equal(newValue, _mockCacheItems[userId].Single().AccessToken);
        }
        public async void PutAccessContext_Should_Add_Additional_Item_If_Different_ProviderName()
        {
            string userId        = Guid.NewGuid().ToString();
            string credentialsId = Guid.NewGuid().ToString();
            string providerName  = Guid.NewGuid().ToString();

            _mockCacheItems.Add(userId, new List <AccountAccessContext> {
                new AccountAccessContext {
                    UserId = userId, CredentialsId = credentialsId, ProviderName = providerName
                }
            });

            SetupCacheGetMethod(userId);

            var newContext = new AccountAccessContext {
                UserId = userId, CredentialsId = credentialsId, ProviderName = "newProvider"
            };

            SetupCacheSetMethod(userId);

            var result = await _accessContextCachingService.PutAccessContext(newContext);

            Assert.True(result.Success);
            Assert.Equal(2, _mockCacheItems[userId].Count);
            _mockCache.Verify(x => x.GetAsync(userId, default), Times.Once);
            _mockCache.Verify(x => x.SetAsync(userId, It.IsAny <byte[]>(), It.IsAny <DistributedCacheEntryOptions>(), default), Times.Once);
        }
        public async void RemoveMethod_Should_Remove_Item_If_Matches_UserId_CredentialsId_ProviderName()
        {
            string userId        = Guid.NewGuid().ToString();
            string credentialsId = Guid.NewGuid().ToString();
            string providerName  = Guid.NewGuid().ToString();

            var accessContext = new AccountAccessContext
            {
                UserId = userId, CredentialsId = credentialsId, ProviderName = providerName
            };

            _mockCacheItems.Add(userId, new List <AccountAccessContext> {
                accessContext
            });

            SetupCacheGetMethod(userId);
            SetupCacheSetMethod(userId);

            var result = await _accessContextCachingService.RemoveAccessContext(accessContext);

            Assert.True(result.Success);
            Assert.Empty(_mockCacheItems[userId]);
            _mockCache.Verify(x => x.GetAsync(userId, default), Times.Once);
            _mockCache.Verify(x => x.SetAsync(userId, It.IsAny <byte[]>(), It.IsAny <DistributedCacheEntryOptions>(), default), Times.Once);
        }
        public async Task <ServiceResult> Process(string userId, CallbackRequest callbackData)
        {
            if (!string.IsNullOrEmpty(callbackData.Error))
            {
                return(ServiceResult.Failed(new[] { ErrorMessages.CallbackStatedAccessDenied }));
            }

            var accountContext = new AccountAccessContext
            {
                UserId = userId,
                Code   = callbackData.Code,
                Scopes = callbackData.GetScopes()
            };

            var exchangeCodeResult = await _authorizationService.ExchangeCode(accountContext);

            if (!exchangeCodeResult.Success)
            {
                return(ServiceResult.Failed(exchangeCodeResult.Errors));
            }

            await _userDataCachingService.ClearUserData(userId);

            return(ServiceResult.Succeeded());
        }
        private async Task <ServiceResult> ObtainMetadataAndUpdateCache(AccountAccessContext accessContext)
        {
            var accessMetadataResult =
                await _trueLayerDataRequestExecutor.GetAccessTokenMetadata(accessContext.AccessToken);

            if (!accessMetadataResult.Success)
            {
                return(ServiceResult.Failed(accessMetadataResult.Errors));
            }

            if (accessMetadataResult.Result == null)
            {
                return(ServiceResult.Failed(new List <string> {
                    ErrorMessages.FailedToObtainAccessTokenMetadata
                }));
            }

            var accessMetadata = accessMetadataResult.Result.Results.Single();

            accessContext.ProviderName  = accessMetadata.Provider.DisplayName;
            accessContext.CredentialsId = accessMetadata.CredentialsId;

            await _accessContextCachingService.PutAccessContext(accessContext);

            return(ServiceResult.Succeeded());
        }
Beispiel #6
0
        public async Task <ServiceObjectResult <ICollection <Account> > > GetAccountsInContext(
            AccountAccessContext accessContext)
        {
            var accountsInContextResult = await _requestExecutor.GetAccounts(accessContext.AccessToken);

            if (!accountsInContextResult.Success || accountsInContextResult.Result.Status != "Succeeded")
            {
                return(ServiceObjectResult <ICollection <Account> > .Failed(null,
                                                                            accountsInContextResult.Errors ?? new List <string>
                {
                    "An error occurred fetching account information"
                }));
            }

            return(ServiceObjectResult <ICollection <Account> > .Succeeded(accountsInContextResult.Result.Results));
        }
        public async void GetAccountsInContext_Should_Return_Failed_If_Executor_Call_Fails()
        {
            var accessContext = new AccountAccessContext
            {
                AccessToken = "AccessToken"
            };

            _mockTrueLayerRequestExecutor.Setup(x => x.GetAccounts(accessContext.AccessToken))
            .ReturnsAsync(ServiceObjectResult <TrueLayerListResponse <Account> > .Failed(null, new List <string> {
                "Value"
            }));

            var result = await _accountService.GetAccountsInContext(accessContext);

            Assert.False(result.Success);
            _mockTrueLayerRequestExecutor.Verify(x => x.GetAccounts(accessContext.AccessToken), Times.Once);
        }
        public async void PutAccessMethod_Should_Create_New_List_If_New_UserId()
        {
            string userId = Guid.NewGuid().ToString();

            SetupCacheGetMethod(userId);
            SetupCacheSetMethod(userId);

            var newContext = new AccountAccessContext {
                UserId = userId, ProviderName = "newProvider"
            };

            var result = await _accessContextCachingService.PutAccessContext(newContext);

            Assert.True(result.Success);
            Assert.NotEmpty(_mockCacheItems[userId]);
            _mockCache.Verify(x => x.GetAsync(userId, default), Times.Once);
            _mockCache.Verify(x => x.SetAsync(userId, It.IsAny <byte[]>(), It.IsAny <DistributedCacheEntryOptions>(), default), Times.Once);
        }
        public async void RemoveMethod_Should_Not_Remove_Item_If_Any_UserId_CredentialsId_ProviderName_Differ()
        {
            string userId        = Guid.NewGuid().ToString();
            string credentialsId = Guid.NewGuid().ToString();
            string providerName  = Guid.NewGuid().ToString();

            var accessContext = new AccountAccessContext
            {
                UserId = userId, CredentialsId = credentialsId, ProviderName = providerName
            };

            _mockCacheItems.Add(userId, new List <AccountAccessContext> {
                accessContext
            });

            SetupCacheGetMethod(userId);
            SetupCacheSetMethod(userId);

            var newUserId = new AccountAccessContext
            {
                CredentialsId = accessContext.CredentialsId,
                UserId        = Guid.NewGuid().ToString(),
                ProviderName  = accessContext.ProviderName
            };

            var result1 = await _accessContextCachingService.RemoveAccessContext(newUserId);

            var newProvider = new AccountAccessContext
            {
                ProviderName  = Guid.NewGuid().ToString(),
                UserId        = accessContext.UserId,
                CredentialsId = accessContext.CredentialsId
            };

            var result2 = await _accessContextCachingService.RemoveAccessContext(newProvider);

            Assert.True(result1.Success);
            Assert.True(result2.Success);
            Assert.Single(_mockCacheItems[userId]);
            Assert.Equal(userId, _mockCacheItems[userId].Single().UserId);
            Assert.Equal(providerName, _mockCacheItems[userId].Single().ProviderName);
            _mockCache.Verify(x => x.GetAsync(userId, default), Times.Exactly(1));
            _mockCache.Verify(x => x.SetAsync(userId, It.IsAny <byte[]>(), It.IsAny <DistributedCacheEntryOptions>(), default), Times.Never);
        }
        public async Task <ServiceObjectResult <AuthResponse> > RefreshAccountAccess(AccountAccessContext accountContext)
        {
            var client = _clientFactory.CreateClient(HttpClients.TrueLayerAuthClientName);

            var formContent = new FormUrlEncodedContent(new List <KeyValuePair <string, string> >
            {
                new KeyValuePair <string, string>("grant_type", "refresh_token"),
                new KeyValuePair <string, string>("client_id", _requestConfiguration.ClientId),
                new KeyValuePair <string, string>("client_secret", _requestConfiguration.ClientSecret),
                new KeyValuePair <string, string>("refresh_token", accountContext.RefreshToken)
            });

            var requestEndpoint = _requestTypeEndpointService.GetEndpoint(RequestType.RefreshAccess);

            using (var response =
                       await client.PostAsync(requestEndpoint, formContent))
            {
                return(await ProcessResponse <AuthResponse>(response, RequestType.RefreshAccess,
                                                            $"{client.BaseAddress}{requestEndpoint}"));
            }
        }
Beispiel #11
0
        private void SetupAccountContexts(bool expired, bool hasRefreshToken)
        {
            var accountContext = new AccountAccessContext {
                AccessTokenExpiry = DateTime.UtcNow.AddMonths(1)
            };

            if (expired)
            {
                accountContext.AccessTokenExpiry = DateTime.UtcNow;
            }

            if (hasRefreshToken)
            {
                accountContext.RefreshToken = "string";
            }

            _mockAccessContextCachingService.Setup(x => x.RetrieveAccessContexts(It.IsAny <string>(), null))
            .ReturnsAsync(
                ServiceObjectResult <ICollection <AccountAccessContext> > .Succeeded(new List <AccountAccessContext> {
                accountContext
            }));
        }
        public async Task <ServiceObjectResult <AuthResponse> > ExchangeCode(AccountAccessContext accountContext)
        {
            var client = _clientFactory.CreateClient(HttpClients.TrueLayerAuthClientName);

            var formContent = new FormUrlEncodedContent(new List <KeyValuePair <string, string> >
            {
                new KeyValuePair <string, string>("grant_type", "authorization_code"),
                new KeyValuePair <string, string>("client_id", _requestConfiguration.ClientId),
                new KeyValuePair <string, string>("client_secret", _requestConfiguration.ClientSecret),
                new KeyValuePair <string, string>("redirect_uri", $"{_requestConfiguration.CallbackUrlBase}{accountContext.UserId}"),
                new KeyValuePair <string, string>("code", accountContext.Code)
            });

            var requestEndpoint = _requestTypeEndpointService.GetEndpoint(RequestType.ExchangeCode);

            using (var response =
                       await client.PostAsync(requestEndpoint, formContent))
            {
                return(await ProcessResponse <AuthResponse>(response, RequestType.ExchangeCode,
                                                            $"{client.BaseAddress}{requestEndpoint}"));
            }
        }
        public async Task <ServiceObjectResult <AccountAccessContext> > ExchangeCode(AccountAccessContext accessContext)
        {
            var exchangeCodeResult = await _trueLayerDataRequestExecutor.ExchangeCode(accessContext);

            if (!exchangeCodeResult.Success)
            {
                return(ServiceObjectResult <AccountAccessContext> .Failed(accessContext, exchangeCodeResult.Errors));
            }

            accessContext.AccessToken       = exchangeCodeResult.Result.AccessToken;
            accessContext.RefreshToken      = exchangeCodeResult.Result.RefreshToken;
            accessContext.AccessTokenExpiry = DateTime.UtcNow.AddSeconds(exchangeCodeResult.Result.ExpiresIn);

            var saveContextResult = await ObtainMetadataAndUpdateCache(accessContext);

            if (!saveContextResult.Success)
            {
                return(ServiceObjectResult <AccountAccessContext> .Failed(null, saveContextResult.Errors));
            }

            return(ServiceObjectResult <AccountAccessContext> .Succeeded(accessContext));
        }
        public async void GetAccountsInContext_Should_Call_Executor_Method_With_Context_Token()
        {
            var accessContext = new AccountAccessContext
            {
                AccessToken = "AccessToken"
            };

            _mockTrueLayerRequestExecutor.Setup(x => x.GetAccounts(accessContext.AccessToken))
            .ReturnsAsync(ServiceObjectResult <TrueLayerListResponse <Account> > .Succeeded(
                              new TrueLayerListResponse <Account>
            {
                Status  = "Succeeded",
                Results = new List <Account>
                {
                    new Account()
                }
            }));

            var result = await _accountService.GetAccountsInContext(accessContext);

            Assert.True(result.Success);
            _mockTrueLayerRequestExecutor.Verify(x => x.GetAccounts(accessContext.AccessToken), Times.Once);
        }
        public async Task <ServiceResult> RemoveAccessContext(AccountAccessContext accessContext)
        {
            var userAccessContexts = await _cache.Get <List <AccountAccessContext> >(accessContext.UserId);

            if (userAccessContexts == null)
            {
                return(ServiceResult.Succeeded());
            }

            var existingAccessContext = userAccessContexts.FirstOrDefault(x =>
                                                                          x.UserId == accessContext.UserId &&
                                                                          x.ProviderName == accessContext.ProviderName);

            if (existingAccessContext == null)
            {
                return(ServiceResult.Succeeded());
            }

            userAccessContexts.Remove(existingAccessContext);

            await _cache.SetValueObject(accessContext.UserId, userAccessContexts);

            return(ServiceResult.Succeeded());
        }