Switch from System.Text.Json to Newtonsoft, typify the BTCPayServer.Client

This commit is contained in:
nicolas.dorier
2020-03-20 14:01:51 +09:00
parent 2def9e7bd3
commit a0e638d500
14 changed files with 79 additions and 26 deletions

View File

@@ -5,7 +5,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Text.Json" Version="4.7.1" /> <PackageReference Include="NBitcoin" Version="5.0.20" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -5,23 +5,25 @@ using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Text; using System.Text;
using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json;
namespace BTCPayServer.Client namespace BTCPayServer.Client
{ {
public partial class BTCPayServerClient public partial class BTCPayServerClient
{ {
static BTCPayServerClient()
{
_GlobalSerializer = new JsonSerializerSettings();
Serializer.RegisterConverters(_GlobalSerializer);
}
private readonly string _apiKey; private readonly string _apiKey;
private readonly Uri _btcpayHost; private readonly Uri _btcpayHost;
private readonly HttpClient _httpClient; private readonly HttpClient _httpClient;
public string APIKey => _apiKey; public string APIKey => _apiKey;
private readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions() private static readonly JsonSerializerSettings _GlobalSerializer = new JsonSerializerSettings();
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
public BTCPayServerClient(Uri btcpayHost, HttpClient httpClient = null) public BTCPayServerClient(Uri btcpayHost, HttpClient httpClient = null)
{ {
@@ -45,7 +47,7 @@ namespace BTCPayServer.Client
protected async Task<T> HandleResponse<T>(HttpResponseMessage message) protected async Task<T> HandleResponse<T>(HttpResponseMessage message)
{ {
HandleResponse(message); HandleResponse(message);
return JsonSerializer.Deserialize<T>(await message.Content.ReadAsStringAsync(), _serializerOptions); return JsonConvert.DeserializeObject<T>(await message.Content.ReadAsStringAsync(), _GlobalSerializer);
} }
protected virtual HttpRequestMessage CreateHttpRequest(string path, protected virtual HttpRequestMessage CreateHttpRequest(string path,
@@ -73,7 +75,7 @@ namespace BTCPayServer.Client
var request = CreateHttpRequest(path, queryPayload, method); var request = CreateHttpRequest(path, queryPayload, method);
if (typeof(T).IsPrimitive || !EqualityComparer<T>.Default.Equals(bodyPayload, default(T))) if (typeof(T).IsPrimitive || !EqualityComparer<T>.Default.Equals(bodyPayload, default(T)))
{ {
request.Content = new StringContent(JsonSerializer.Serialize(bodyPayload, _serializerOptions), Encoding.UTF8, "application/json"); request.Content = new StringContent(JsonConvert.SerializeObject(bodyPayload, _GlobalSerializer), Encoding.UTF8, "application/json");
} }
return request; return request;

View File

@@ -0,0 +1,34 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using NBitcoin.JsonConverters;
namespace BTCPayServer.Client.JsonConverters
{
public class PermissionJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Permission).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
if (reader.TokenType != JsonToken.String)
throw new JsonObjectException("Type 'Permission' is expected to be a 'String'", reader);
if (reader.ReadAsString() is String s && Permission.TryParse(s, out var permission))
return permission;
throw new JsonObjectException("Invalid 'Permission' String", reader);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is Permission v)
writer.WriteValue(v.ToString());
}
}
}

View File

@@ -5,6 +5,6 @@ namespace BTCPayServer.Client.Models
public string ApiKey { get; set; } public string ApiKey { get; set; }
public string Label { get; set; } public string Label { get; set; }
public string UserId { get; set; } public string UserId { get; set; }
public string[] Permissions { get; set; } public Permission[] Permissions { get; set; }
} }
} }

View File

@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.Json.Serialization;
namespace BTCPayServer.Client namespace BTCPayServer.Client
{ {

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
using BTCPayServer.Client.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client
{
public class Serializer
{
public static void RegisterConverters(JsonSerializerSettings settings)
{
if (settings == null)
throw new ArgumentNullException(nameof(settings));
settings.Converters.Add(new PermissionJsonConverter());
}
}
}

View File

@@ -165,7 +165,7 @@ namespace BTCPayServer.Tests
var expectedPermissions = Permission.ToPermissions(expectedPermissionsString).ToArray(); var expectedPermissions = Permission.ToPermissions(expectedPermissionsString).ToArray();
expectedPermissions ??= new Permission[0]; expectedPermissions ??= new Permission[0];
var apikeydata = await TestApiAgainstAccessToken<ApiKeyData>(accessToken, $"api/v1/api-keys/current", tester.PayTester.HttpClient); var apikeydata = await TestApiAgainstAccessToken<ApiKeyData>(accessToken, $"api/v1/api-keys/current", tester.PayTester.HttpClient);
var permissions = Permission.ToPermissions(apikeydata.Permissions).ToArray(); var permissions = apikeydata.Permissions;
Assert.Equal(expectedPermissions.Length, permissions.Length); Assert.Equal(expectedPermissions.Length, permissions.Length);
foreach (var expectPermission in expectedPermissions) foreach (var expectPermission in expectedPermissions)
{ {

View File

@@ -331,7 +331,6 @@ namespace BTCPayServer.Controllers
} }
public string Label { get; set; } public string Label { get; set; }
public StoreData[] Stores { get; set; } public StoreData[] Stores { get; set; }
ApiKeyStoreMode _StoreMode;
public ApiKeyStoreMode StoreMode { get; set; } public ApiKeyStoreMode StoreMode { get; set; }
public List<string> SpecificStores { get; set; } = new List<string>(); public List<string> SpecificStores { get; set; } = new List<string>();
public PermissionValueItem StoreManagementPermission { get; set; } public PermissionValueItem StoreManagementPermission { get; set; }

View File

@@ -45,7 +45,7 @@ namespace BTCPayServer.Controllers.RestApi.ApiKeys
{ {
return new ApiKeyData() return new ApiKeyData()
{ {
Permissions = Permission.ToPermissions(data.Permissions).Select(c => c.ToString()).ToArray(), Permissions = Permission.ToPermissions(data.Permissions).ToArray(),
ApiKey = data.Id, ApiKey = data.Id,
UserId = data.UserId, UserId = data.UserId,
Label = data.Label Label = data.Label

View File

@@ -387,7 +387,7 @@ namespace BTCPayServer.Controllers
private async Task<bool> CanUseHotWallet() private async Task<bool> CanUseHotWallet()
{ {
var isAdmin = (await _authorizationService.AuthorizeAsync(User, Permission.CanModifyServerSettings)).Succeeded; var isAdmin = (await _authorizationService.AuthorizeAsync(User, Policies.CanModifyServerSettings)).Succeeded;
if (isAdmin) if (isAdmin)
return true; return true;
var policies = await _settingsRepository.GetSettingAsync<PoliciesSettings>(); var policies = await _settingsRepository.GetSettingAsync<PoliciesSettings>();

View File

@@ -128,7 +128,7 @@ namespace BTCPayServer.Controllers
} }
await websocketHelper.Send("{ \"info\": \"ready\"}", cancellationToken); await websocketHelper.Send("{ \"info\": \"ready\"}", cancellationToken);
o = JObject.Parse(await websocketHelper.NextMessageAsync(cancellationToken)); o = JObject.Parse(await websocketHelper.NextMessageAsync(cancellationToken));
var authorization = await _authorizationService.AuthorizeAsync(User, Permission.CanModifyStoreSettings); var authorization = await _authorizationService.AuthorizeAsync(User, Policies.CanModifyStoreSettings);
if (!authorization.Succeeded) if (!authorization.Succeeded)
{ {
await websocketHelper.Send("{ \"error\": \"not-authorized\"}", cancellationToken); await websocketHelper.Send("{ \"error\": \"not-authorized\"}", cancellationToken);

View File

@@ -36,13 +36,13 @@ namespace BTCPayServer.Security.APIKeys
bool success = false; bool success = false;
switch (requirement.Policy) switch (requirement.Policy)
{ {
case Permission.CanModifyProfile: case Policies.CanModifyProfile:
case Permission.CanViewProfile: case Policies.CanViewProfile:
success = context.HasPermission(Permission.Create(requirement.Policy)); success = context.HasPermission(Permission.Create(requirement.Policy));
break; break;
case Permission.CanViewStoreSettings: case Policies.CanViewStoreSettings:
case Permission.CanModifyStoreSettings: case Policies.CanModifyStoreSettings:
var storeId = _HttpContext.GetImplicitStoreId(); var storeId = _HttpContext.GetImplicitStoreId();
var userid = _userManager.GetUserId(context.User); var userid = _userManager.GetUserId(context.User);
// Specific store action // Specific store action
@@ -72,8 +72,8 @@ namespace BTCPayServer.Security.APIKeys
success = true; success = true;
} }
break; break;
case Permission.CanCreateUser: case Policies.CanCreateUser:
case Permission.CanModifyServerSettings: case Policies.CanModifyServerSettings:
if (context.HasPermission(Permission.Create(requirement.Policy))) if (context.HasPermission(Permission.Create(requirement.Policy)))
{ {
var user = await _userManager.GetUserAsync(context.User); var user = await _userManager.GetUserAsync(context.User);

View File

@@ -55,7 +55,7 @@ namespace BTCPayServer.Security.Bitpay
var anyoneCanInvoice = store.GetStoreBlob().AnyoneCanInvoice; var anyoneCanInvoice = store.GetStoreBlob().AnyoneCanInvoice;
switch (requirement.Policy) switch (requirement.Policy)
{ {
case Permission.CanCreateInvoice: case Policies.CanCreateInvoice:
if (!isAnonymous || (isAnonymous && anyoneCanInvoice)) if (!isAnonymous || (isAnonymous && anyoneCanInvoice))
{ {
context.Succeed(requirement); context.Succeed(requirement);
@@ -63,7 +63,7 @@ namespace BTCPayServer.Security.Bitpay
return; return;
} }
break; break;
case Policies.CanGetRates.Key: case ServerPolicies.CanGetRates.Key:
context.Succeed(requirement); context.Succeed(requirement);
_HttpContext.SetStoreData(store); _HttpContext.SetStoreData(store);
return; return;

View File

@@ -36,7 +36,7 @@ namespace BTCPayServer.Security
var isAdmin = context.User.IsInRole(Roles.ServerAdmin); var isAdmin = context.User.IsInRole(Roles.ServerAdmin);
switch (requirement.Policy) switch (requirement.Policy)
{ {
case Permission.CanModifyServerSettings: case Policies.CanModifyServerSettings:
if (isAdmin) if (isAdmin)
context.Succeed(requirement); context.Succeed(requirement);
return; return;
@@ -57,11 +57,11 @@ namespace BTCPayServer.Security
bool success = false; bool success = false;
switch (requirement.Policy) switch (requirement.Policy)
{ {
case Permission.CanModifyStoreSettings: case Policies.CanModifyStoreSettings:
if (store.Role == StoreRoles.Owner || isAdmin) if (store.Role == StoreRoles.Owner || isAdmin)
success = true; success = true;
break; break;
case Permission.CanCreateInvoice: case Policies.CanCreateInvoice:
if (store.Role == StoreRoles.Owner || if (store.Role == StoreRoles.Owner ||
store.Role == StoreRoles.Guest || store.Role == StoreRoles.Guest ||
isAdmin || isAdmin ||