async Task TestApiAgainstAccessToken(string accessToken, ServerTester tester, TestAccount testAccount) { var resultUser = await TestApiAgainstAccessToken <string>(accessToken, "api/test/me/id", tester.PayTester.HttpClient); Assert.Equal(testAccount.UserId, resultUser); var secondUser = tester.NewAccount(); secondUser.GrantAccess(); var resultStores = await TestApiAgainstAccessToken <StoreData[]>(accessToken, "api/test/me/stores", tester.PayTester.HttpClient); Assert.Contains(resultStores, data => data.Id.Equals(testAccount.StoreId, StringComparison.InvariantCultureIgnoreCase)); Assert.DoesNotContain(resultStores, data => data.Id.Equals(secondUser.StoreId, StringComparison.InvariantCultureIgnoreCase)); Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"api/test/me/stores/{testAccount.StoreId}/can-edit", tester.PayTester.HttpClient)); Assert.Equal(testAccount.RegisterDetails.IsAdmin, await TestApiAgainstAccessToken <bool>(accessToken, $"api/test/me/is-admin", tester.PayTester.HttpClient)); await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"api/test/me/stores/{secondUser.StoreId}/can-edit", tester.PayTester.HttpClient); }); }
private static async Task <string> RegisterClientCredentialsFlowAndGetAccessToken(TestAccount user, string secret, ServerTester tester) { var id = Guid.NewGuid().ToString(); var openIdClient = await user.RegisterOpenIdClient( new OpenIddictApplicationDescriptor() { ClientId = id, DisplayName = id, Permissions = { OpenIddictConstants.Permissions.GrantTypes.ClientCredentials } }, secret); var httpClient = tester.PayTester.HttpClient; var httpRequest = new HttpRequestMessage(HttpMethod.Post, new Uri(tester.PayTester.ServerUri, "/connect/token")) { Content = new FormUrlEncodedContent(new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("grant_type", OpenIddictConstants.GrantTypes.ClientCredentials), new KeyValuePair <string, string>("client_id", openIdClient.ClientId), new KeyValuePair <string, string>("client_secret", secret) }) }; var response = await httpClient.SendAsync(httpRequest); Assert.True(response.IsSuccessStatusCode); string content = await response.Content.ReadAsStringAsync(); var result = JObject.Parse(content).ToObject <OpenIdConnectResponse>(); Assert.NotEmpty(result.AccessToken); Assert.Null(result.Error); return(result.AccessToken); }
async Task TestApiAgainstAccessToken(string accessToken, ServerTester tester, TestAccount testAccount, string expectedPermissionsString) { var expectedPermissions = Permission.ToPermissions(expectedPermissionsString).ToArray(); expectedPermissions ??= new Permission[0]; var apikeydata = await TestApiAgainstAccessToken <ApiKeyData>(accessToken, $"api/v1/api-keys/current", tester.PayTester.HttpClient); var permissions = apikeydata.Permissions; Assert.Equal(expectedPermissions.Length, permissions.Length); foreach (var expectPermission in expectedPermissions) { Assert.True(permissions.Any(p => p == expectPermission), $"Missing expected permission {expectPermission}"); } if (permissions.Contains(Permission.Create(Policies.CanViewProfile))) { var resultUser = await TestApiAgainstAccessToken <string>(accessToken, $"{TestApiPath}/me/id", tester.PayTester.HttpClient); Assert.Equal(testAccount.UserId, resultUser); } else { await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <string>(accessToken, $"{TestApiPath}/me/id", tester.PayTester.HttpClient); }); } //create a second user to see if any of its data gets messed upin our results. var secondUser = tester.NewAccount(); secondUser.GrantAccess(); var canModifyAllStores = Permission.Create(Policies.CanModifyStoreSettings, null); var canModifyServer = Permission.Create(Policies.CanModifyServerSettings, null); var unrestricted = Permission.Create(Policies.Unrestricted, null); var selectiveStorePermissions = permissions.Where(p => p.StoreId != null && p.Policy == Policies.CanModifyStoreSettings); if (permissions.Contains(canModifyAllStores) || selectiveStorePermissions.Any()) { var resultStores = await TestApiAgainstAccessToken <StoreData[]>(accessToken, $"{TestApiPath}/me/stores", tester.PayTester.HttpClient); foreach (var selectiveStorePermission in selectiveStorePermissions) { Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{selectiveStorePermission.StoreId}/can-edit", tester.PayTester.HttpClient)); Assert.Contains(resultStores, data => data.Id.Equals(selectiveStorePermission.StoreId, StringComparison.InvariantCultureIgnoreCase)); } bool shouldBeAuthorized = false; if (permissions.Contains(canModifyAllStores) || selectiveStorePermissions.Contains(Permission.Create(Policies.CanViewStoreSettings, testAccount.StoreId))) { Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-view", tester.PayTester.HttpClient)); Assert.Contains(resultStores, data => data.Id.Equals(testAccount.StoreId, StringComparison.InvariantCultureIgnoreCase)); shouldBeAuthorized = true; } if (permissions.Contains(canModifyAllStores) || selectiveStorePermissions.Contains(Permission.Create(Policies.CanModifyStoreSettings, testAccount.StoreId))) { Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-view", tester.PayTester.HttpClient)); Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-edit", tester.PayTester.HttpClient)); Assert.Contains(resultStores, data => data.Id.Equals(testAccount.StoreId, StringComparison.InvariantCultureIgnoreCase)); shouldBeAuthorized = true; } if (!shouldBeAuthorized) { await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-edit", tester.PayTester.HttpClient); }); await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-view", tester.PayTester.HttpClient); }); Assert.DoesNotContain(resultStores, data => data.Id.Equals(testAccount.StoreId, StringComparison.InvariantCultureIgnoreCase)); } } else if (!permissions.Contains(unrestricted)) { await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-edit", tester.PayTester.HttpClient); }); } else { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-edit", tester.PayTester.HttpClient); } if (!permissions.Contains(unrestricted)) { await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{secondUser.StoreId}/can-edit", tester.PayTester.HttpClient); }); } else { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{secondUser.StoreId}/can-edit", tester.PayTester.HttpClient); } if (permissions.Contains(canModifyServer)) { Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/is-admin", tester.PayTester.HttpClient)); } else { await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/is-admin", tester.PayTester.HttpClient); }); } }
async Task TestApiAgainstAccessToken(string accessToken, ServerTester tester, TestAccount testAccount, params string[] permissions) { var resultUser = await TestApiAgainstAccessToken <string>(accessToken, $"{TestApiPath}/me/id", tester.PayTester.HttpClient); Assert.Equal(testAccount.UserId, resultUser); //create a second user to see if any of its data gets messed upin our results. var secondUser = tester.NewAccount(); secondUser.GrantAccess(); var selectiveStorePermissions = Permissions.ExtractStorePermissionsIds(permissions); if (permissions.Contains(Permissions.StoreManagement) || selectiveStorePermissions.Any()) { var resultStores = await TestApiAgainstAccessToken <StoreData[]>(accessToken, $"{TestApiPath}/me/stores", tester.PayTester.HttpClient); foreach (string selectiveStorePermission in selectiveStorePermissions) { Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{selectiveStorePermission}/can-edit", tester.PayTester.HttpClient)); Assert.Contains(resultStores, data => data.Id.Equals(selectiveStorePermission, StringComparison.InvariantCultureIgnoreCase)); } if (permissions.Contains(Permissions.StoreManagement)) { Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/actions", tester.PayTester.HttpClient)); Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-edit", tester.PayTester.HttpClient)); Assert.Contains(resultStores, data => data.Id.Equals(testAccount.StoreId, StringComparison.InvariantCultureIgnoreCase)); } else { await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/actions", tester.PayTester.HttpClient); }); } Assert.DoesNotContain(resultStores, data => data.Id.Equals(secondUser.StoreId, StringComparison.InvariantCultureIgnoreCase)); } else { await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-edit", tester.PayTester.HttpClient); }); } await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{secondUser.StoreId}/can-edit", tester.PayTester.HttpClient); }); if (permissions.Contains(Permissions.ServerManagement)) { Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/is-admin", tester.PayTester.HttpClient)); } }
private static async Task CanCreateRefundsCore(SeleniumTester s, TestAccount user, bool multiCurrency, string rateSelection) { s.GoToHome(); s.Server.PayTester.ChangeRate("BTC_USD", new Rating.BidAsk(5000.0m, 5100.0m)); var invoice = await user.BitPay.CreateInvoiceAsync(new NBitpayClient.Invoice() { Currency = "USD", Price = 5000.0m }); var info = invoice.CryptoInfo.First(o => o.CryptoCode == "BTC"); var totalDue = decimal.Parse(info.TotalDue, CultureInfo.InvariantCulture); var paid = totalDue + 0.1m; await s.Server.ExplorerNode.SendToAddressAsync(BitcoinAddress.Create(info.Address, Network.RegTest), Money.Coins(paid)); await s.Server.ExplorerNode.GenerateAsync(1); await TestUtils.EventuallyAsync(async() => { invoice = await user.BitPay.GetInvoiceAsync(invoice.Id); Assert.Equal("confirmed", invoice.Status); }); // BTC crash by 50% s.Server.PayTester.ChangeRate("BTC_USD", new Rating.BidAsk(5000.0m / 2.0m, 5100.0m / 2.0m)); s.GoToStore(); s.Driver.FindElement(By.Id("BOLT11Expiration")).Clear(); s.Driver.FindElement(By.Id("BOLT11Expiration")).SendKeys("5" + Keys.Enter); s.GoToInvoice(invoice.Id); s.Driver.FindElement(By.Id("refundlink")).Click(); if (multiCurrency) { s.Driver.FindElement(By.Id("SelectedPaymentMethod")).SendKeys("BTC" + Keys.Enter); s.Driver.FindElement(By.Id("ok")).Click(); } Assert.Contains("$5,500.00", s.Driver.PageSource); // Should propose reimburse in fiat Assert.Contains("1.10000000 ₿", s.Driver.PageSource); // Should propose reimburse in BTC at the rate of before Assert.Contains("2.20000000 ₿", s.Driver.PageSource); // Should propose reimburse in BTC at the current rate s.Driver.FindElement(By.Id(rateSelection)).Click(); s.Driver.FindElement(By.Id("ok")).Click(); Assert.Contains("pull-payments", s.Driver.Url); if (rateSelection == "FiatText") { Assert.Contains("$5,500.00", s.Driver.PageSource); } if (rateSelection == "CurrentRateText") { Assert.Contains("2.20000000 ₿", s.Driver.PageSource); } if (rateSelection == "RateThenText") { Assert.Contains("1.10000000 ₿", s.Driver.PageSource); } s.GoToInvoice(invoice.Id); s.Driver.FindElement(By.Id("refundlink")).Click(); Assert.Contains("pull-payments", s.Driver.Url); var client = await user.CreateClient(); var ppid = s.Driver.Url.Split('/').Last(); var pps = await client.GetPullPayments(user.StoreId); var pp = Assert.Single(pps, p => p.Id == ppid); Assert.Equal(TimeSpan.FromDays(5.0), pp.BOLT11Expiration); }