Greenfield quality of life improvements from feedback (#2880)

* Greenfield quality of life improvements from feedback

fix #2854

* Greenfield quality of life improvements from feedback

fix #2855
This commit is contained in:
Andrew Camilleri 2021-09-25 07:04:34 +02:00 committed by GitHub
parent ef70f4d547
commit 9f6c7180b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 62 additions and 45 deletions

View File

@ -47,7 +47,7 @@ namespace BTCPayServer.Client
public virtual async Task<LightningNetworkPaymentMethodData> UpdateStoreLightningNetworkPaymentMethod(
string storeId,
string cryptoCode, LightningNetworkPaymentMethodData paymentMethod,
string cryptoCode, UpdateLightningNetworkPaymentMethodRequest paymentMethod,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
@ -55,10 +55,5 @@ namespace BTCPayServer.Client
bodyPayload: paymentMethod, method: HttpMethod.Put), token);
return await HandleResponse<LightningNetworkPaymentMethodData>(response);
}
public virtual Task<LightningNetworkPaymentMethodData>
UpdateStoreLightningNetworkPaymentMethodToInternalNode(string storeId,
string cryptoCode, CancellationToken token = default) => UpdateStoreLightningNetworkPaymentMethod(
storeId, cryptoCode, new LightningNetworkPaymentMethodData(cryptoCode, "Internal Node", true), token);
}
}

View File

@ -45,7 +45,7 @@ namespace BTCPayServer.Client
}
public virtual async Task<OnChainPaymentMethodData> UpdateStoreOnChainPaymentMethod(string storeId,
string cryptoCode, OnChainPaymentMethodData paymentMethod,
string cryptoCode, UpdateOnChainPaymentMethodRequest paymentMethod,
CancellationToken token = default)
{
var response = await _httpClient.SendAsync(
@ -56,7 +56,7 @@ namespace BTCPayServer.Client
public virtual async Task<OnChainPaymentMethodPreviewResultData>
PreviewProposedStoreOnChainPaymentMethodAddresses(
string storeId, string cryptoCode, OnChainPaymentMethodData paymentMethod, int offset = 0,
string storeId, string cryptoCode, UpdateOnChainPaymentMethodRequest paymentMethod, int offset = 0,
int amount = 10,
CancellationToken token = default)
{

View File

@ -4,5 +4,6 @@
{
public bool Enabled { get; set; }
public object Data { get; set; }
public string CryptoCode { get; set; }
}
}

View File

@ -16,11 +16,14 @@ namespace BTCPayServer.Client.Models
{
}
public LightningNetworkPaymentMethodData(string cryptoCode, string connectionString, bool enabled)
public LightningNetworkPaymentMethodData(string cryptoCode, string connectionString, bool enabled, string paymentMethod)
{
Enabled = enabled;
CryptoCode = cryptoCode;
ConnectionString = connectionString;
PaymentMethod = paymentMethod;
}
public string PaymentMethod { get; set; }
}
}

View File

@ -30,15 +30,18 @@ namespace BTCPayServer.Client.Models
/// </summary>
public bool Enabled { get; set; }
public string PaymentMethod { get; set; }
public OnChainPaymentMethodData()
{
}
public OnChainPaymentMethodData(string cryptoCode, string derivationScheme, bool enabled, string label, RootedKeyPath accountKeyPath) :
public OnChainPaymentMethodData(string cryptoCode, string derivationScheme, bool enabled, string label, RootedKeyPath accountKeyPath, string paymentMethod) :
base(cryptoCode, derivationScheme, label, accountKeyPath)
{
Enabled = enabled;
PaymentMethod = paymentMethod;
}
}
}

View File

@ -11,8 +11,8 @@ namespace BTCPayServer.Client.Models
}
public OnChainPaymentMethodDataWithSensitiveData(string cryptoCode, string derivationScheme, bool enabled,
string label, RootedKeyPath accountKeyPath, Mnemonic mnemonic) : base(cryptoCode, derivationScheme, enabled,
label, accountKeyPath)
string label, RootedKeyPath accountKeyPath, Mnemonic mnemonic, string paymentMethod) : base(cryptoCode, derivationScheme, enabled,
label, accountKeyPath, paymentMethod)
{
Mnemonic = mnemonic;
}

View File

@ -1466,7 +1466,7 @@ namespace BTCPayServer.Tests
Assert.Empty(await client.GetStoreOnChainPaymentMethods(store.Id));
await AssertHttpError(403, async () =>
{
await viewOnlyClient.UpdateStoreOnChainPaymentMethod(store.Id, "BTC", new OnChainPaymentMethodData() { });
await viewOnlyClient.UpdateStoreOnChainPaymentMethod(store.Id, "BTC", new UpdateOnChainPaymentMethodRequest() { });
});
var xpriv = new Mnemonic("all all all all all all all all all all all all").DeriveExtKey()
@ -1479,15 +1479,15 @@ namespace BTCPayServer.Tests
});
Assert.Equal(firstAddress, (await viewOnlyClient.PreviewProposedStoreOnChainPaymentMethodAddresses(store.Id, "BTC",
new OnChainPaymentMethodData() { Enabled = true, DerivationScheme = xpub })).Addresses.First().Address);
new UpdateOnChainPaymentMethodRequest() { Enabled = true, DerivationScheme = xpub })).Addresses.First().Address);
var method = await client.UpdateStoreOnChainPaymentMethod(store.Id, "BTC",
new OnChainPaymentMethodData() { Enabled = true, DerivationScheme = xpub });
new UpdateOnChainPaymentMethodRequest() { Enabled = true, DerivationScheme = xpub });
Assert.Equal(xpub, method.DerivationScheme);
method = await client.UpdateStoreOnChainPaymentMethod(store.Id, "BTC",
new OnChainPaymentMethodData() { Enabled = true, DerivationScheme = xpub, Label = "lol", AccountKeyPath = RootedKeyPath.Parse("01020304/1/2/3") });
new UpdateOnChainPaymentMethodRequest() { Enabled = true, DerivationScheme = xpub, Label = "lol", AccountKeyPath = RootedKeyPath.Parse("01020304/1/2/3") });
method = await client.GetStoreOnChainPaymentMethod(store.Id, "BTC");
@ -1583,7 +1583,7 @@ namespace BTCPayServer.Tests
Assert.Empty(await adminClient.GetStoreLightningNetworkPaymentMethods(store.Id));
await AssertHttpError(403, async () =>
{
await viewOnlyClient.UpdateStoreLightningNetworkPaymentMethod(store.Id, "BTC", new LightningNetworkPaymentMethodData() { });
await viewOnlyClient.UpdateStoreLightningNetworkPaymentMethod(store.Id, "BTC", new UpdateLightningNetworkPaymentMethodRequest() { });
});
await AssertHttpError(404, async () =>
{
@ -1618,37 +1618,33 @@ namespace BTCPayServer.Tests
{
var ex = await AssertValidationError(new[] { "ConnectionString" }, async () =>
{
await adminClient.UpdateStoreLightningNetworkPaymentMethod(store.Id, "BTC", new LightningNetworkPaymentMethodData()
await adminClient.UpdateStoreLightningNetworkPaymentMethod(store.Id, "BTC", new UpdateLightningNetworkPaymentMethodRequest()
{
ConnectionString = forbidden,
CryptoCode = "BTC",
Enabled = true
});
});
Assert.Contains("btcpay.server.canmodifyserversettings", ex.Message);
// However, the other client should work because he has `btcpay.server.canmodifyserversettings`
await admin2Client.UpdateStoreLightningNetworkPaymentMethod(admin2.StoreId, "BTC", new LightningNetworkPaymentMethodData()
await admin2Client.UpdateStoreLightningNetworkPaymentMethod(admin2.StoreId, "BTC", new UpdateLightningNetworkPaymentMethodRequest()
{
ConnectionString = forbidden,
CryptoCode = "BTC",
Enabled = true
});
}
// Allowed ip should be ok
await adminClient.UpdateStoreLightningNetworkPaymentMethod(store.Id, "BTC", new LightningNetworkPaymentMethodData()
await adminClient.UpdateStoreLightningNetworkPaymentMethod(store.Id, "BTC", new UpdateLightningNetworkPaymentMethodRequest()
{
ConnectionString = "type=clightning;server=tcp://8.8.8.8",
CryptoCode = "BTC",
Enabled = true
});
// If we strip the admin's right, he should not be able to set unsafe anymore, even if the API key is still valid
await admin2.MakeAdmin(false);
await AssertValidationError(new[] { "ConnectionString" }, async () =>
{
await admin2Client.UpdateStoreLightningNetworkPaymentMethod(admin2.StoreId, "BTC", new LightningNetworkPaymentMethodData()
await admin2Client.UpdateStoreLightningNetworkPaymentMethod(admin2.StoreId, "BTC", new UpdateLightningNetworkPaymentMethodRequest()
{
ConnectionString = "type=clightning;server=tcp://127.0.0.1",
CryptoCode = "BTC",
Enabled = true
});
});
@ -1666,14 +1662,22 @@ namespace BTCPayServer.Tests
});
await Assert.ThrowsAsync<GreenFieldValidationException>(async () =>
{
await nonAdminUserClient.UpdateStoreLightningNetworkPaymentMethod(nonAdminUser.StoreId, "BTC", method);
await nonAdminUserClient.UpdateStoreLightningNetworkPaymentMethod(nonAdminUser.StoreId, "BTC", new UpdateLightningNetworkPaymentMethodRequest()
{
Enabled = method.Enabled,
ConnectionString = method.ConnectionString
});
});
settings = await tester.PayTester.GetService<SettingsRepository>().GetSettingAsync<PoliciesSettings>();
settings.AllowLightningInternalNodeForAll = true;
await tester.PayTester.GetService<SettingsRepository>().UpdateSetting(settings);
await nonAdminUserClient.UpdateStoreLightningNetworkPaymentMethod(nonAdminUser.StoreId, "BTC", method);
await nonAdminUserClient.UpdateStoreLightningNetworkPaymentMethod(nonAdminUser.StoreId, "BTC", new UpdateLightningNetworkPaymentMethodRequest()
{
Enabled = method.Enabled,
ConnectionString = method.ConnectionString
});
}
[Fact(Timeout = 60 * 2 * 1000)]
@ -1953,7 +1957,7 @@ namespace BTCPayServer.Tests
Assert.Empty(await adminClient.GetStorePaymentMethods(store.Id));
await adminClient.UpdateStoreLightningNetworkPaymentMethodToInternalNode(admin.StoreId, "BTC");
await adminClient.UpdateStoreLightningNetworkPaymentMethod(admin.StoreId, "BTC", new UpdateLightningNetworkPaymentMethodRequest("Internal Node", true));
void VerifyLightning(Dictionary<string, GenericPaymentMethodData> dictionary)
{
@ -1968,7 +1972,7 @@ namespace BTCPayServer.Tests
var randK = new Mnemonic(Wordlist.English, WordCount.Twelve).DeriveExtKey().Neuter().ToString(Network.RegTest);
await adminClient.UpdateStoreOnChainPaymentMethod(admin.StoreId, "BTC",
new OnChainPaymentMethodData("BTC", randK, true, "testing", null));
new UpdateOnChainPaymentMethodRequest(true, randK, "testing", null));
void VerifyOnChain(Dictionary<string, GenericPaymentMethodData> dictionary)
{

View File

@ -518,7 +518,7 @@ namespace BTCPayServer.Controllers.GreenField
}
public override async Task<OnChainPaymentMethodData> UpdateStoreOnChainPaymentMethod(string storeId,
string cryptoCode, OnChainPaymentMethodData paymentMethod,
string cryptoCode, UpdateOnChainPaymentMethodRequest paymentMethod,
CancellationToken token = default)
{
return GetFromActionResult<OnChainPaymentMethodData>(
@ -532,7 +532,7 @@ namespace BTCPayServer.Controllers.GreenField
public override Task<OnChainPaymentMethodPreviewResultData> PreviewProposedStoreOnChainPaymentMethodAddresses(
string storeId, string cryptoCode,
OnChainPaymentMethodData paymentMethod, int offset = 0, int amount = 10, CancellationToken token = default)
UpdateOnChainPaymentMethodRequest paymentMethod, int offset = 0, int amount = 10, CancellationToken token = default)
{
return Task.FromResult(GetFromActionResult<OnChainPaymentMethodPreviewResultData>(
_chainPaymentMethodsController.GetProposedOnChainPaymentMethodPreview(storeId, cryptoCode,
@ -772,7 +772,7 @@ namespace BTCPayServer.Controllers.GreenField
public override async Task<LightningNetworkPaymentMethodData> UpdateStoreLightningNetworkPaymentMethod(
string storeId, string cryptoCode,
LightningNetworkPaymentMethodData paymentMethod, CancellationToken token = default)
UpdateLightningNetworkPaymentMethodRequest paymentMethod, CancellationToken token = default)
{
return GetFromActionResult<LightningNetworkPaymentMethodData>(await
_storeLightningNetworkPaymentMethodsController.UpdateLightningNetworkPaymentMethod(storeId, cryptoCode,
@ -878,13 +878,6 @@ namespace BTCPayServer.Controllers.GreenField
return Task.FromResult(GetFromActionResult<PermissionMetadata[]>(_homeController.Permissions()));
}
public override async Task<LightningNetworkPaymentMethodData> UpdateStoreLightningNetworkPaymentMethodToInternalNode(string storeId, string cryptoCode,
CancellationToken token = default)
{
//nothing to change, just local client sugar
return await base.UpdateStoreLightningNetworkPaymentMethodToInternalNode(storeId, cryptoCode, token);
}
public override Task<Dictionary<string, GenericPaymentMethodData>> GetStorePaymentMethods(string storeId, bool? enabled = null, CancellationToken token = default)
{
return Task.FromResult(GetFromActionResult(_storePaymentMethodsController.GetStorePaymentMethods(storeId, enabled)));

View File

@ -58,7 +58,8 @@ namespace BTCPayServer.Controllers.GreenField
paymentMethod.PaymentId.CryptoCode,
paymentMethod.GetExternalLightningUrl()?.ToString() ??
paymentMethod.GetDisplayableConnectionString(),
!excludedPaymentMethods.Match(paymentMethod.PaymentId)
!excludedPaymentMethods.Match(paymentMethod.PaymentId),
paymentMethod.PaymentId.ToStringNormalized()
)
)
.Where((result) => enabled is null || enabled == result.Enabled)
@ -205,7 +206,8 @@ namespace BTCPayServer.Controllers.GreenField
return paymentMethod is null
? null
: new LightningNetworkPaymentMethodData(paymentMethod.PaymentId.CryptoCode,
paymentMethod.GetDisplayableConnectionString(), !excluded);
paymentMethod.GetDisplayableConnectionString(), !excluded,
paymentMethod.PaymentId.ToStringNormalized());
}
private bool GetNetwork(string cryptoCode, [MaybeNullWhen(false)] out BTCPayNetwork network)

View File

@ -91,7 +91,7 @@ namespace BTCPayServer.Controllers.GreenField
await _storeRepository.UpdateStore(store);
var rawResult = GetExistingBtcLikePaymentMethod(cryptoCode, store);
var result = new OnChainPaymentMethodDataWithSensitiveData(rawResult.CryptoCode, rawResult.DerivationScheme,
rawResult.Enabled, rawResult.Label, rawResult.AccountKeyPath, response.GetMnemonic());
rawResult.Enabled, rawResult.Label, rawResult.AccountKeyPath, response.GetMnemonic(), derivationSchemeSettings.PaymentId.ToStringNormalized());
return Ok(result);
}

View File

@ -57,7 +57,9 @@ namespace BTCPayServer.Controllers.GreenField
.OfType<DerivationSchemeSettings>()
.Select(strategy =>
new OnChainPaymentMethodData(strategy.PaymentId.CryptoCode,
strategy.AccountDerivation.ToString(), !excludedPaymentMethods.Match(strategy.PaymentId), strategy.Label, strategy.GetSigningAccountKeySettings().GetRootedKeyPath()))
strategy.AccountDerivation.ToString(), !excludedPaymentMethods.Match(strategy.PaymentId),
strategy.Label, strategy.GetSigningAccountKeySettings().GetRootedKeyPath(),
strategy.PaymentId.ToStringNormalized()))
.Where((result) => enabled is null || enabled == result.Enabled)
.ToList();
}
@ -144,7 +146,7 @@ namespace BTCPayServer.Controllers.GreenField
public IActionResult GetProposedOnChainPaymentMethodPreview(
string storeId,
string cryptoCode,
[FromBody] OnChainPaymentMethodDataPreview paymentMethodData,
[FromBody] UpdateOnChainPaymentMethodRequest paymentMethodData,
int offset = 0, int amount = 10)
{
if (!GetCryptoCodeWallet(cryptoCode, out var network, out BTCPayWallet _))
@ -291,7 +293,8 @@ namespace BTCPayServer.Controllers.GreenField
? null
: new OnChainPaymentMethodData(paymentMethod.PaymentId.CryptoCode,
paymentMethod.AccountDerivation.ToString(), !excluded, paymentMethod.Label,
paymentMethod.GetSigningAccountKeySettings().GetRootedKeyPath());
paymentMethod.GetSigningAccountKeySettings().GetRootedKeyPath(),
paymentMethod.PaymentId.ToStringNormalized());
}
}
}

View File

@ -38,6 +38,7 @@ namespace BTCPayServer.Controllers.GreenField
method => method.PaymentId.ToStringNormalized(),
method => new GenericPaymentMethodData()
{
CryptoCode = method.PaymentId.CryptoCode,
Enabled = enabled.GetValueOrDefault(!excludedPaymentMethods.Match(method.PaymentId)),
Data = method.PaymentId.PaymentType.GetGreenfieldData(method)
}));

View File

@ -64,6 +64,10 @@
"type": "boolean",
"description": "Whether the payment method is enabled"
},
"cryptoCode": {
"type": "boolean",
"description": "The currency code of the payment method"
},
"data": {
"type": "object",
"additionalProperties": false,

View File

@ -271,6 +271,10 @@
"cryptoCode": {
"type": "string",
"description": "Crypto code of the payment method"
},
"paymentMethod": {
"type": "string",
"description": "The payment method"
}
}
},

View File

@ -463,6 +463,10 @@
"enabled": {
"type": "boolean",
"description": "Whether the payment method is enabled"
},
"paymentMethod": {
"type": "string",
"description": "The payment method"
}
}
},